#include "duckdb.hpp"



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/standard_entry.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class SchemaCatalogEntry;

//! A StandardEntry is a catalog entry that is a member of a schema
class StandardEntry : public CatalogEntry {
public:
	StandardEntry(CatalogType type, SchemaCatalogEntry *schema, Catalog *catalog, string name)
	    : CatalogEntry(type, catalog, name), schema(schema) {
	}
	virtual ~StandardEntry() {
	}

	//! The schema the entry belongs to
	SchemaCatalogEntry *schema;
};
} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_aggregate_function_info.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_function_info.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct CreateFunctionInfo : public CreateInfo {
	CreateFunctionInfo(CatalogType type) : CreateInfo(type) {
		assert(type == CatalogType::SCALAR_FUNCTION || type == CatalogType::AGGREGATE_FUNCTION);
	}

	//! Function name
	string name;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/function_set.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/aggregate_function.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/vector_operations/aggregate_executor.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/vector_operations/vector_operations.hpp
//
//
//===----------------------------------------------------------------------===//






#include <functional>

namespace duckdb {

// VectorOperations contains a set of operations that operate on sets of
// vectors. In general, the operators must all have the same type, otherwise an
// exception is thrown. Note that the functions underneath use restrict
// pointers, hence the data that the vectors point to (and hence the vector
// themselves) should not be equal! For example, if you call the function Add(A,
// B, A) then ASSERT_RESTRICT will be triggered. Instead call AddInPlace(A, B)
// or Add(A, B, C)
struct VectorOperations {
	//===--------------------------------------------------------------------===//
	// In-Place Operators
	//===--------------------------------------------------------------------===//
	//! A += B
	static void AddInPlace(Vector &A, int64_t B, idx_t count);

	//===--------------------------------------------------------------------===//
	// NULL Operators
	//===--------------------------------------------------------------------===//
	//! result = IS NOT NULL(A)
	static void IsNotNull(Vector &A, Vector &result, idx_t count);
	//! result = IS NULL (A)
	static void IsNull(Vector &A, Vector &result, idx_t count);
	// Returns whether or not a vector has a NULL value
	static bool HasNull(Vector &A, idx_t count);
	static bool HasNotNull(Vector &A, idx_t count);

	//===--------------------------------------------------------------------===//
	// Boolean Operations
	//===--------------------------------------------------------------------===//
	// result = A && B
	static void And(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = A || B
	static void Or(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = NOT(A)
	static void Not(Vector &A, Vector &result, idx_t count);

	//===--------------------------------------------------------------------===//
	// Comparison Operations
	//===--------------------------------------------------------------------===//
	// result = A == B
	static void Equals(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = A != B
	static void NotEquals(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = A > B
	static void GreaterThan(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = A >= B
	static void GreaterThanEquals(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = A < B
	static void LessThan(Vector &A, Vector &B, Vector &result, idx_t count);
	// result = A <= B
	static void LessThanEquals(Vector &A, Vector &B, Vector &result, idx_t count);

	//===--------------------------------------------------------------------===//
	// Scatter methods
	//===--------------------------------------------------------------------===//
	// make sure dest.count is set for gather methods!
	struct Gather {
		//! dest.data[i] = ptr[i]. NullValue<T> is checked for and converted to the nullmask in dest. The source
		//! addresses are incremented by the size of the type.
		static void Set(Vector &source, Vector &dest, idx_t count);
	};

	//===--------------------------------------------------------------------===//
	// Hash functions
	//===--------------------------------------------------------------------===//
	// result = HASH(A)
	static void Hash(Vector &input, Vector &hashes, idx_t count);
	static void Hash(Vector &input, Vector &hashes, const SelectionVector &rsel, idx_t count);
	// A ^= HASH(B)
	static void CombineHash(Vector &hashes, Vector &B, idx_t count);
	static void CombineHash(Vector &hashes, Vector &B, const SelectionVector &rsel, idx_t count);

	//===--------------------------------------------------------------------===//
	// Generate functions
	//===--------------------------------------------------------------------===//
	static void GenerateSequence(Vector &result, idx_t count, int64_t start = 0, int64_t increment = 1);
	static void GenerateSequence(Vector &result, idx_t count, const SelectionVector &sel, int64_t start = 0,
	                             int64_t increment = 1);
	//===--------------------------------------------------------------------===//
	// Helpers
	//===--------------------------------------------------------------------===//
	// Cast the data from the source type to the target type
	static void Cast(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count);
	// Cast the data from the source type to the target type
	static void Cast(Vector &source, Vector &result, idx_t count);

	// Copy the data of <source> to the target vector
	static void Copy(Vector &source, Vector &target, idx_t source_count, idx_t source_offset, idx_t target_offset);
	static void Copy(Vector &source, Vector &target, const SelectionVector &sel, idx_t source_count,
	                 idx_t source_offset, idx_t target_offset);

	// Copy the data of <source> to the target location, setting null values to
	// NullValue<T>. Used to store data without separate NULL mask.
	static void WriteToStorage(Vector &source, idx_t count, data_ptr_t target);
	// Reads the data of <source> to the target vector, setting the nullmask
	// for any NullValue<T> of source. Used to go back from storage to a proper vector
	static void ReadFromStorage(data_ptr_t source, idx_t count, Vector &result);
};
} // namespace duckdb


namespace duckdb {

class AggregateExecutor {
private:
	template <class STATE_TYPE, class INPUT_TYPE, class OP>
	static inline void UnaryFlatLoop(INPUT_TYPE *__restrict idata, STATE_TYPE **__restrict states, nullmask_t &nullmask,
	                                 idx_t count) {
		if (OP::IgnoreNull() && nullmask.any()) {
			// potential NULL values and NULL values are ignored
			for (idx_t i = 0; i < count; i++) {
				if (!nullmask[i]) {
					OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[i], idata, nullmask, i);
				}
			}
		} else {
			// quick path: no NULL values or NULL values are not ignored
			for (idx_t i = 0; i < count; i++) {
				OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[i], idata, nullmask, i);
			}
		}
	}
	template <class STATE_TYPE, class INPUT_TYPE, class OP>
	static inline void UnaryScatterLoop(INPUT_TYPE *__restrict idata, STATE_TYPE **__restrict states,
	                                    const SelectionVector &isel, const SelectionVector &ssel, nullmask_t &nullmask,
	                                    idx_t count) {
		if (OP::IgnoreNull() && nullmask.any()) {
			// potential NULL values and NULL values are ignored
			for (idx_t i = 0; i < count; i++) {
				auto idx = isel.get_index(i);
				auto sidx = ssel.get_index(i);
				if (!nullmask[idx]) {
					OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], idata, nullmask, idx);
				}
			}
		} else {
			// quick path: no NULL values or NULL values are not ignored
			for (idx_t i = 0; i < count; i++) {
				auto idx = isel.get_index(i);
				auto sidx = ssel.get_index(i);
				OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], idata, nullmask, idx);
			}
		}
	}

	template <class STATE_TYPE, class INPUT_TYPE, class OP, bool HAS_SEL_VECTOR>
	static inline void UnaryUpdateLoop(INPUT_TYPE *__restrict idata, STATE_TYPE *__restrict state, idx_t count,
	                                   nullmask_t &nullmask, const SelectionVector *__restrict sel_vector) {
		if (OP::IgnoreNull() && nullmask.any()) {
			// potential NULL values and NULL values are ignored
			for (idx_t i = 0; i < count; i++) {
				auto idx = HAS_SEL_VECTOR ? sel_vector->get_index(i) : i;
				if (!nullmask[idx]) {
					OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, idata, nullmask, idx);
				}
			}
		} else {
			// quick path: no NULL values or NULL values are not ignored
			for (idx_t i = 0; i < count; i++) {
				auto idx = HAS_SEL_VECTOR ? sel_vector->get_index(i) : i;
				OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, idata, nullmask, idx);
			}
		}
	}

	template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
	static inline void BinaryScatterLoop(A_TYPE *__restrict adata, B_TYPE *__restrict bdata,
	                                     STATE_TYPE **__restrict states, idx_t count, const SelectionVector &asel,
	                                     const SelectionVector &bsel, const SelectionVector &ssel,
	                                     nullmask_t &anullmask, nullmask_t &bnullmask) {
		if (OP::IgnoreNull() && (anullmask.any() || bnullmask.any())) {
			// potential NULL values and NULL values are ignored
			for (idx_t i = 0; i < count; i++) {
				auto aidx = asel.get_index(i);
				auto bidx = bsel.get_index(i);
				auto sidx = ssel.get_index(i);
				if (!anullmask[aidx] && !bnullmask[bidx]) {
					OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], adata, bdata, anullmask,
					                                                       bnullmask, aidx, bidx);
				}
			}
		} else {
			// quick path: no NULL values or NULL values are not ignored
			for (idx_t i = 0; i < count; i++) {
				auto aidx = asel.get_index(i);
				auto bidx = bsel.get_index(i);
				auto sidx = ssel.get_index(i);
				OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], adata, bdata, anullmask, bnullmask,
				                                                       aidx, bidx);
			}
		}
	}

	template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
	static inline void BinaryUpdateLoop(A_TYPE *__restrict adata, B_TYPE *__restrict bdata,
	                                    STATE_TYPE *__restrict state, idx_t count, const SelectionVector &asel,
	                                    const SelectionVector &bsel, nullmask_t &anullmask, nullmask_t &bnullmask) {
		if (OP::IgnoreNull() && (anullmask.any() || bnullmask.any())) {
			// potential NULL values and NULL values are ignored
			for (idx_t i = 0; i < count; i++) {
				auto aidx = asel.get_index(i);
				auto bidx = bsel.get_index(i);
				if (!anullmask[aidx] && !bnullmask[bidx]) {
					OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, adata, bdata, anullmask, bnullmask,
					                                                       aidx, bidx);
				}
			}
		} else {
			// quick path: no NULL values or NULL values are not ignored
			for (idx_t i = 0; i < count; i++) {
				auto aidx = asel.get_index(i);
				auto bidx = bsel.get_index(i);
				OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, adata, bdata, anullmask, bnullmask, aidx,
				                                                       bidx);
			}
		}
	}

public:
	template <class STATE_TYPE, class INPUT_TYPE, class OP>
	static void UnaryScatter(Vector &input, Vector &states, idx_t count) {
		if (input.vector_type == VectorType::CONSTANT_VECTOR && states.vector_type == VectorType::CONSTANT_VECTOR) {
			if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
				// constant NULL input in function that ignores NULL values
				return;
			}
			// regular constant: get first state
			auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
			auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
			OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>(*sdata, idata, ConstantVector::Nullmask(input),
			                                                           count);
		} else if (input.vector_type == VectorType::FLAT_VECTOR && states.vector_type == VectorType::FLAT_VECTOR) {
			auto idata = FlatVector::GetData<INPUT_TYPE>(input);
			auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
			UnaryFlatLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, sdata, FlatVector::Nullmask(input), count);
		} else {
			VectorData idata, sdata;
			input.Orrify(count, idata);
			states.Orrify(count, sdata);
			UnaryScatterLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, (STATE_TYPE **)sdata.data,
			                                             *idata.sel, *sdata.sel, *idata.nullmask, count);
		}
	}

	template <class STATE_TYPE, class INPUT_TYPE, class OP>
	static void UnaryUpdate(Vector &input, data_ptr_t state, idx_t count) {
		switch (input.vector_type) {
		case VectorType::CONSTANT_VECTOR: {
			if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
				return;
			}
			auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
			OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>((STATE_TYPE *)state, idata,
			                                                           ConstantVector::Nullmask(input), count);
			break;
		}
		case VectorType::FLAT_VECTOR: {
			auto idata = FlatVector::GetData<INPUT_TYPE>(input);
			UnaryUpdateLoop<STATE_TYPE, INPUT_TYPE, OP, false>(idata, (STATE_TYPE *)state, count,
			                                                   FlatVector::Nullmask(input), nullptr);
			break;
		}
		default: {
			VectorData idata;
			input.Orrify(count, idata);
			UnaryUpdateLoop<STATE_TYPE, INPUT_TYPE, OP, true>((INPUT_TYPE *)idata.data, (STATE_TYPE *)state, count,
			                                                  *idata.nullmask, idata.sel);
			break;
		}
		}
	}

	template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
	static void BinaryScatter(Vector &a, Vector &b, Vector &states, idx_t count) {
		VectorData adata, bdata, sdata;

		a.Orrify(count, adata);
		b.Orrify(count, bdata);
		states.Orrify(count, sdata);

		BinaryScatterLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, (B_TYPE *)bdata.data,
		                                                  (STATE_TYPE **)sdata.data, count, *adata.sel, *bdata.sel,
		                                                  *sdata.sel, *adata.nullmask, *bdata.nullmask);
	}

	template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
	static void BinaryUpdate(Vector &a, Vector &b, data_ptr_t state, idx_t count) {
		VectorData adata, bdata;

		a.Orrify(count, adata);
		b.Orrify(count, bdata);

		BinaryUpdateLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, (B_TYPE *)bdata.data,
		                                                 (STATE_TYPE *)state, count, *adata.sel, *bdata.sel,
		                                                 *adata.nullmask, *bdata.nullmask);
	}

	template <class STATE_TYPE, class OP> static void Combine(Vector &source, Vector &target, idx_t count) {
		auto sdata = FlatVector::GetData<STATE_TYPE>(source);
		auto tdata = FlatVector::GetData<STATE_TYPE *>(target);

		for (idx_t i = 0; i < count; i++) {
			OP::template Combine<STATE_TYPE, OP>(sdata[i], tdata[i]);
		}
	}

	template <class STATE_TYPE, class RESULT_TYPE, class OP>
	static void Finalize(Vector &states, Vector &result, idx_t count) {
		if (states.vector_type == VectorType::CONSTANT_VECTOR) {
			result.vector_type = VectorType::CONSTANT_VECTOR;

			auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
			auto rdata = ConstantVector::GetData<RESULT_TYPE>(result);
			OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, *sdata, rdata, ConstantVector::Nullmask(result), 0);
		} else {
			assert(states.vector_type == VectorType::FLAT_VECTOR);
			result.vector_type = VectorType::FLAT_VECTOR;

			auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
			auto rdata = FlatVector::GetData<RESULT_TYPE>(result);
			for (idx_t i = 0; i < count; i++) {
				OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, sdata[i], rdata, FlatVector::Nullmask(result),
				                                               i);
			}
		}
	}

	template <class STATE_TYPE, class OP> static void Destroy(Vector &states, idx_t count) {
		auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
		for (idx_t i = 0; i < count; i++) {
			OP::template Destroy<STATE_TYPE>(sdata[i]);
		}
	}
};

} // namespace duckdb


namespace duckdb {

class BoundAggregateExpression;

//! The type used for sizing hashed aggregate function states
typedef idx_t (*aggregate_size_t)();
//! The type used for initializing hashed aggregate function states
typedef void (*aggregate_initialize_t)(data_ptr_t state);
//! The type used for updating hashed aggregate functions
typedef void (*aggregate_update_t)(Vector inputs[], idx_t input_count, Vector &state, idx_t count);
//! The type used for combining hashed aggregate states (optional)
typedef void (*aggregate_combine_t)(Vector &state, Vector &combined, idx_t count);
//! The type used for finalizing hashed aggregate function payloads
typedef void (*aggregate_finalize_t)(Vector &state, Vector &result, idx_t count);
//! Binds the scalar function and creates the function data
typedef unique_ptr<FunctionData> (*bind_aggregate_function_t)(BoundAggregateExpression &expr, ClientContext &context,
                                                              SQLType &return_type);
//! The type used for the aggregate destructor method. NOTE: this method is used in destructors and MAY NOT throw.
typedef void (*aggregate_destructor_t)(Vector &state, idx_t count);

//! The type used for updating simple (non-grouped) aggregate functions
typedef void (*aggregate_simple_update_t)(Vector inputs[], idx_t input_count, data_ptr_t state, idx_t count);

class AggregateFunction : public SimpleFunction {
public:
	AggregateFunction(string name, vector<SQLType> arguments, SQLType return_type, aggregate_size_t state_size,
	                  aggregate_initialize_t initialize, aggregate_update_t update, aggregate_combine_t combine,
	                  aggregate_finalize_t finalize, aggregate_simple_update_t simple_update = nullptr,
	                  bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr)
	    : SimpleFunction(name, arguments, return_type, false), state_size(state_size), initialize(initialize),
	      update(update), combine(combine), finalize(finalize), simple_update(simple_update), bind(bind),
	      destructor(destructor) {
	}

	AggregateFunction(vector<SQLType> arguments, SQLType return_type, aggregate_size_t state_size,
	                  aggregate_initialize_t initialize, aggregate_update_t update, aggregate_combine_t combine,
	                  aggregate_finalize_t finalize, aggregate_simple_update_t simple_update = nullptr,
	                  bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr)
	    : AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize,
	                        simple_update, bind, destructor) {
	}

	//! The hashed aggregate state sizing function
	aggregate_size_t state_size;
	//! The hashed aggregate state initialization function
	aggregate_initialize_t initialize;
	//! The hashed aggregate update state function
	aggregate_update_t update;
	//! The hashed aggregate combine states function
	aggregate_combine_t combine;
	//! The hashed aggregate finalization function
	aggregate_finalize_t finalize;
	//! The simple aggregate update function (may be null)
	aggregate_simple_update_t simple_update;

	//! The bind function (may be null)
	bind_aggregate_function_t bind;
	//! The destructor method (may be null)
	aggregate_destructor_t destructor;

	bool operator==(const AggregateFunction &rhs) const {
		return state_size == rhs.state_size && initialize == rhs.initialize && update == rhs.update &&
		       combine == rhs.combine && finalize == rhs.finalize;
	}
	bool operator!=(const AggregateFunction &rhs) const {
		return !(*this == rhs);
	}

public:
	template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
	static AggregateFunction UnaryAggregate(SQLType input_type, SQLType return_type) {
		return AggregateFunction(
		    {input_type}, return_type, AggregateFunction::StateSize<STATE>,
		    AggregateFunction::StateInitialize<STATE, OP>, AggregateFunction::UnaryScatterUpdate<STATE, INPUT_TYPE, OP>,
		    AggregateFunction::StateCombine<STATE, OP>, AggregateFunction::StateFinalize<STATE, RESULT_TYPE, OP>,
		    AggregateFunction::UnaryUpdate<STATE, INPUT_TYPE, OP>);
	};
	template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
	static AggregateFunction UnaryAggregateDestructor(SQLType input_type, SQLType return_type) {
		auto aggregate = UnaryAggregate<STATE, INPUT_TYPE, RESULT_TYPE, OP>(input_type, return_type);
		aggregate.destructor = AggregateFunction::StateDestroy<STATE, OP>;
		return aggregate;
	};
	template <class STATE, class A_TYPE, class B_TYPE, class RESULT_TYPE, class OP>
	static AggregateFunction BinaryAggregate(SQLType a_type, SQLType b_type, SQLType return_type) {
		return AggregateFunction({a_type, b_type}, return_type, AggregateFunction::StateSize<STATE>,
		                         AggregateFunction::StateInitialize<STATE, OP>,
		                         AggregateFunction::BinaryScatterUpdate<STATE, A_TYPE, B_TYPE, OP>,
		                         AggregateFunction::StateCombine<STATE, OP>,
		                         AggregateFunction::StateFinalize<STATE, RESULT_TYPE, OP>,
		                         AggregateFunction::BinaryUpdate<STATE, A_TYPE, B_TYPE, OP>);
	};
	template <class STATE, class A_TYPE, class B_TYPE, class RESULT_TYPE, class OP>
	static AggregateFunction BinaryAggregateDestructor(SQLType a_type, SQLType b_type, SQLType return_type) {
		auto aggregate = BinaryAggregate<STATE, A_TYPE, B_TYPE, RESULT_TYPE, OP>(a_type, b_type, return_type);
		aggregate.destructor = AggregateFunction::StateDestroy<STATE, OP>;
		return aggregate;
	};

public:
	template <class OP> static AggregateFunction GetNumericUnaryAggregate(SQLType type) {
		switch (type.id) {
		case SQLTypeId::TINYINT:
			return UnaryAggregate<int8_t, int8_t, int8_t, OP>(type, type);
		case SQLTypeId::SMALLINT:
			return UnaryAggregate<int16_t, int16_t, int16_t, OP>(type, type);
		case SQLTypeId::INTEGER:
			return UnaryAggregate<int32_t, int32_t, int32_t, OP>(type, type);
		case SQLTypeId::BIGINT:
			return UnaryAggregate<int64_t, int64_t, int64_t, OP>(type, type);
		case SQLTypeId::FLOAT:
			return UnaryAggregate<float, float, float, OP>(type, type);
		case SQLTypeId::DOUBLE:
			return UnaryAggregate<double, double, double, OP>(type, type);
		case SQLTypeId::DECIMAL:
			return UnaryAggregate<double, double, double, OP>(type, type);
		default:
			throw NotImplementedException("Unimplemented numeric type");
		}
	}

	template <class OP> static AggregateFunction GetUnaryAggregate(SQLType type) {
		switch (type.id) {
		case SQLTypeId::BOOLEAN:
			return UnaryAggregate<int8_t, int8_t, int8_t, OP>(type, type);
		case SQLTypeId::TINYINT:
		case SQLTypeId::SMALLINT:
		case SQLTypeId::INTEGER:
		case SQLTypeId::BIGINT:
		case SQLTypeId::FLOAT:
		case SQLTypeId::DOUBLE:
		case SQLTypeId::DECIMAL:
			return GetNumericUnaryAggregate<OP>(type);
		case SQLTypeId::DATE:
			return UnaryAggregate<date_t, date_t, date_t, OP>(type, type);
		case SQLTypeId::TIMESTAMP:
			return UnaryAggregate<timestamp_t, timestamp_t, timestamp_t, OP>(type, type);
		case SQLTypeId::VARCHAR:
			return UnaryAggregate<string_t, string_t, string_t, OP>(type, type);
		default:
			throw NotImplementedException("Unimplemented type for unary aggregate");
		}
	}

public:
	template <class STATE> static idx_t StateSize() {
		return sizeof(STATE);
	}

	template <class STATE, class OP> static void StateInitialize(data_ptr_t state) {
		OP::Initialize((STATE *)state);
	}

	template <class STATE, class T, class OP>
	static void UnaryScatterUpdate(Vector inputs[], idx_t input_count, Vector &states, idx_t count) {
		assert(input_count == 1);
		AggregateExecutor::UnaryScatter<STATE, T, OP>(inputs[0], states, count);
	}

	template <class STATE, class INPUT_TYPE, class OP>
	static void UnaryUpdate(Vector inputs[], idx_t input_count, data_ptr_t state, idx_t count) {
		assert(input_count == 1);
		AggregateExecutor::UnaryUpdate<STATE, INPUT_TYPE, OP>(inputs[0], state, count);
	}

	template <class STATE, class A_TYPE, class B_TYPE, class OP>
	static void BinaryScatterUpdate(Vector inputs[], idx_t input_count, Vector &states, idx_t count) {
		assert(input_count == 2);
		AggregateExecutor::BinaryScatter<STATE, A_TYPE, B_TYPE, OP>(inputs[0], inputs[1], states, count);
	}

	template <class STATE, class A_TYPE, class B_TYPE, class OP>
	static void BinaryUpdate(Vector inputs[], idx_t input_count, data_ptr_t state, idx_t count) {
		assert(input_count == 2);
		AggregateExecutor::BinaryUpdate<STATE, A_TYPE, B_TYPE, OP>(inputs[0], inputs[1], state, count);
	}

	template <class STATE, class OP> static void StateCombine(Vector &source, Vector &target, idx_t count) {
		AggregateExecutor::Combine<STATE, OP>(source, target, count);
	}

	template <class STATE, class RESULT_TYPE, class OP>
	static void StateFinalize(Vector &states, Vector &result, idx_t count) {
		AggregateExecutor::Finalize<STATE, RESULT_TYPE, OP>(states, result, count);
	}

	template <class STATE, class OP> static void StateDestroy(Vector &states, idx_t count) {
		AggregateExecutor::Destroy<STATE, OP>(states, count);
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar_function.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/vector_operations/unary_executor.hpp
//
//
//===----------------------------------------------------------------------===//







#include <functional>

namespace duckdb {

struct UnaryOperatorWrapper {
	template <class FUNC, class OP, class INPUT_TYPE, class RESULT_TYPE>
	static inline RESULT_TYPE Operation(FUNC fun, INPUT_TYPE input) {
		return OP::template Operation<INPUT_TYPE, RESULT_TYPE>(input);
	}
};

struct UnaryLambdaWrapper {
	template <class FUNC, class OP, class INPUT_TYPE, class RESULT_TYPE>
	static inline RESULT_TYPE Operation(FUNC fun, INPUT_TYPE input) {
		return fun(input);
	}
};

struct UnaryExecutor {
private:
	template <class INPUT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC, bool IGNORE_NULL>
	static inline void ExecuteLoop(INPUT_TYPE *__restrict ldata, RESULT_TYPE *__restrict result_data, idx_t count,
	                               const SelectionVector *__restrict sel_vector, nullmask_t &nullmask,
	                               nullmask_t &result_nullmask, FUNC fun) {
		ASSERT_RESTRICT(ldata, ldata + count, result_data, result_data + count);

		if (nullmask.any()) {
			for (idx_t i = 0; i < count; i++) {
				auto idx = sel_vector->get_index(i);
				if (!nullmask[idx]) {
					result_data[i] = OPWRAPPER::template Operation<FUNC, OP, INPUT_TYPE, RESULT_TYPE>(fun, ldata[idx]);
				} else {
					result_nullmask[i] = true;
				}
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				auto idx = sel_vector->get_index(i);
				result_data[i] = OPWRAPPER::template Operation<FUNC, OP, INPUT_TYPE, RESULT_TYPE>(fun, ldata[idx]);
			}
		}
	}

	template <class INPUT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC, bool IGNORE_NULL>
	static inline void ExecuteFlat(INPUT_TYPE *__restrict ldata, RESULT_TYPE *__restrict result_data, idx_t count,
	                               nullmask_t &nullmask, nullmask_t &result_nullmask, FUNC fun) {
		ASSERT_RESTRICT(ldata, ldata + count, result_data, result_data + count);

		if (IGNORE_NULL && nullmask.any()) {
			result_nullmask = nullmask;
			for (idx_t i = 0; i < count; i++) {
				if (!nullmask[i]) {
					result_data[i] = OPWRAPPER::template Operation<FUNC, OP, INPUT_TYPE, RESULT_TYPE>(fun, ldata[i]);
				}
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				result_data[i] = OPWRAPPER::template Operation<FUNC, OP, INPUT_TYPE, RESULT_TYPE>(fun, ldata[i]);
			}
		}
	}

	template <class INPUT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC, bool IGNORE_NULL>
	static inline void ExecuteStandard(Vector &input, Vector &result, idx_t count, FUNC fun) {
		switch (input.vector_type) {
		case VectorType::CONSTANT_VECTOR: {
			result.vector_type = VectorType::CONSTANT_VECTOR;
			auto result_data = ConstantVector::GetData<RESULT_TYPE>(result);
			auto ldata = ConstantVector::GetData<INPUT_TYPE>(input);

			if (ConstantVector::IsNull(input)) {
				ConstantVector::SetNull(result, true);
			} else {
				ConstantVector::SetNull(result, false);
				*result_data = OPWRAPPER::template Operation<FUNC, OP, INPUT_TYPE, RESULT_TYPE>(fun, *ldata);
			}
			break;
		}
		case VectorType::FLAT_VECTOR: {
			result.vector_type = VectorType::FLAT_VECTOR;
			auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
			auto ldata = FlatVector::GetData<INPUT_TYPE>(input);

			FlatVector::SetNullmask(result, FlatVector::Nullmask(input));

			ExecuteFlat<INPUT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL>(
			    ldata, result_data, count, FlatVector::Nullmask(input), FlatVector::Nullmask(result), fun);
			break;
		}
		default: {
			VectorData vdata;
			input.Orrify(count, vdata);

			result.vector_type = VectorType::FLAT_VECTOR;
			auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
			auto ldata = (INPUT_TYPE *)vdata.data;

			ExecuteLoop<INPUT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL>(
			    ldata, result_data, count, vdata.sel, *vdata.nullmask, FlatVector::Nullmask(result), fun);
			break;
		}
		}
	}

public:
	template <class INPUT_TYPE, class RESULT_TYPE, class OP, bool IGNORE_NULL = false>
	static void Execute(Vector &input, Vector &result, idx_t count) {
		ExecuteStandard<INPUT_TYPE, RESULT_TYPE, UnaryOperatorWrapper, OP, bool, IGNORE_NULL>(input, result, count,
		                                                                                      false);
	}

	template <class INPUT_TYPE, class RESULT_TYPE, bool IGNORE_NULL = false,
	          class FUNC = std::function<RESULT_TYPE(INPUT_TYPE)>>
	static void Execute(Vector &input, Vector &result, idx_t count, FUNC fun) {
		ExecuteStandard<INPUT_TYPE, RESULT_TYPE, UnaryLambdaWrapper, bool, FUNC, IGNORE_NULL>(input, result, count,
		                                                                                      fun);
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/vector_operations/binary_executor.hpp
//
//
//===----------------------------------------------------------------------===//






#include <functional>

namespace duckdb {

struct DefaultNullCheckOperator {
	template <class LEFT_TYPE, class RIGHT_TYPE> static inline bool Operation(LEFT_TYPE left, RIGHT_TYPE right) {
		return false;
	}
};

struct BinaryStandardOperatorWrapper {
	template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
	static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, nullmask_t &nullmask, idx_t idx) {
		return OP::template Operation<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(left, right);
	}
};

struct BinarySingleArgumentOperatorWrapper {
	template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
	static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, nullmask_t &nullmask, idx_t idx) {
		return OP::template Operation<LEFT_TYPE>(left, right);
	}
};

struct BinaryLambdaWrapper {
	template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
	static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, nullmask_t &nullmask, idx_t idx) {
		return fun(left, right);
	}
};

struct BinaryExecutor {
private:
	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
	          bool IGNORE_NULL, bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
	static void ExecuteFlatLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                            RESULT_TYPE *__restrict result_data, idx_t count, nullmask_t &nullmask, FUNC fun) {
		if (!LEFT_CONSTANT) {
			ASSERT_RESTRICT(ldata, ldata + count, result_data, result_data + count);
		}
		if (!RIGHT_CONSTANT) {
			ASSERT_RESTRICT(rdata, rdata + count, result_data, result_data + count);
		}
		if (IGNORE_NULL && nullmask.any()) {
			for (idx_t i = 0; i < count; i++) {
				if (!nullmask[i]) {
					auto lentry = ldata[LEFT_CONSTANT ? 0 : i];
					auto rentry = rdata[RIGHT_CONSTANT ? 0 : i];
					result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
					    fun, lentry, rentry, nullmask, i);
				}
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				auto lentry = ldata[LEFT_CONSTANT ? 0 : i];
				auto rentry = rdata[RIGHT_CONSTANT ? 0 : i];
				result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
				    fun, lentry, rentry, nullmask, i);
			}
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
	          bool IGNORE_NULL>
	static void ExecuteConstant(Vector &left, Vector &right, Vector &result, FUNC fun) {
		result.vector_type = VectorType::CONSTANT_VECTOR;

		auto ldata = ConstantVector::GetData<LEFT_TYPE>(left);
		auto rdata = ConstantVector::GetData<RIGHT_TYPE>(right);
		auto result_data = ConstantVector::GetData<RESULT_TYPE>(result);

		if (ConstantVector::IsNull(left) || ConstantVector::IsNull(right)) {
			ConstantVector::SetNull(result, true);
			return;
		}
		*result_data = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
		    fun, *ldata, *rdata, ConstantVector::Nullmask(result), 0);
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
	          bool IGNORE_NULL, bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
	static void ExecuteFlat(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
		auto ldata = FlatVector::GetData<LEFT_TYPE>(left);
		auto rdata = FlatVector::GetData<RIGHT_TYPE>(right);

		if ((LEFT_CONSTANT && ConstantVector::IsNull(left)) || (RIGHT_CONSTANT && ConstantVector::IsNull(right))) {
			// either left or right is constant NULL: result is constant NULL
			result.vector_type = VectorType::CONSTANT_VECTOR;
			ConstantVector::SetNull(result, true);
			return;
		}

		result.vector_type = VectorType::FLAT_VECTOR;
		auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
		if (LEFT_CONSTANT) {
			FlatVector::SetNullmask(result, FlatVector::Nullmask(right));
		} else if (RIGHT_CONSTANT) {
			FlatVector::SetNullmask(result, FlatVector::Nullmask(left));
		} else {
			FlatVector::SetNullmask(result, FlatVector::Nullmask(left) | FlatVector::Nullmask(right));
		}
		ExecuteFlatLoop<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL, LEFT_CONSTANT,
		                RIGHT_CONSTANT>(ldata, rdata, result_data, count, FlatVector::Nullmask(result), fun);
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
	          bool IGNORE_NULL>
	static void ExecuteGenericLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                               RESULT_TYPE *__restrict result_data, const SelectionVector *__restrict lsel,
	                               const SelectionVector *__restrict rsel, idx_t count, nullmask_t &lnullmask,
	                               nullmask_t &rnullmask, nullmask_t &result_nullmask, FUNC fun) {
		if (lnullmask.any() || rnullmask.any()) {
			for (idx_t i = 0; i < count; i++) {
				auto lindex = lsel->get_index(i);
				auto rindex = rsel->get_index(i);
				if (!lnullmask[lindex] && !rnullmask[rindex]) {
					auto lentry = ldata[lindex];
					auto rentry = rdata[rindex];
					result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
					    fun, lentry, rentry, result_nullmask, i);
				} else {
					result_nullmask[i] = true;
				}
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				auto lentry = ldata[lsel->get_index(i)];
				auto rentry = rdata[rsel->get_index(i)];
				result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
				    fun, lentry, rentry, result_nullmask, i);
			}
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
	          bool IGNORE_NULL>
	static void ExecuteGeneric(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
		VectorData ldata, rdata;

		left.Orrify(count, ldata);
		right.Orrify(count, rdata);

		result.vector_type = VectorType::FLAT_VECTOR;
		auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
		ExecuteGenericLoop<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL>(
		    (LEFT_TYPE *)ldata.data, (RIGHT_TYPE *)rdata.data, result_data, ldata.sel, rdata.sel, count,
		    *ldata.nullmask, *rdata.nullmask, FlatVector::Nullmask(result), fun);
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
	          bool IGNORE_NULL>
	static void ExecuteSwitch(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
		if (left.vector_type == VectorType::CONSTANT_VECTOR && right.vector_type == VectorType::CONSTANT_VECTOR) {
			ExecuteConstant<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL>(left, right, result,
			                                                                                      fun);
		} else if (left.vector_type == VectorType::FLAT_VECTOR && right.vector_type == VectorType::CONSTANT_VECTOR) {
			ExecuteFlat<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL, false, true>(
			    left, right, result, count, fun);
		} else if (left.vector_type == VectorType::CONSTANT_VECTOR && right.vector_type == VectorType::FLAT_VECTOR) {
			ExecuteFlat<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL, true, false>(
			    left, right, result, count, fun);
		} else if (left.vector_type == VectorType::FLAT_VECTOR && right.vector_type == VectorType::FLAT_VECTOR) {
			ExecuteFlat<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL, false, false>(
			    left, right, result, count, fun);
		} else {
			ExecuteGeneric<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, IGNORE_NULL>(left, right, result,
			                                                                                     count, fun);
		}
	}

public:
	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, bool IGNORE_NULL = false,
	          class FUNC = std::function<RESULT_TYPE(LEFT_TYPE, RIGHT_TYPE)>>
	static void Execute(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
		ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, BinaryLambdaWrapper, bool, FUNC, IGNORE_NULL>(
		    left, right, result, count, fun);
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OP, bool IGNORE_NULL = false,
	          class OPWRAPPER = BinarySingleArgumentOperatorWrapper>
	static void Execute(Vector &left, Vector &right, Vector &result, idx_t count) {
		ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, bool, IGNORE_NULL>(left, right, result, count,
		                                                                                    false);
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OP, bool IGNORE_NULL = false>
	static void ExecuteStandard(Vector &left, Vector &right, Vector &result, idx_t count) {
		ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, BinaryStandardOperatorWrapper, OP, bool, IGNORE_NULL>(
		    left, right, result, count, false);
	}

public:
	template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
	static idx_t SelectConstant(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
	                            SelectionVector *true_sel, SelectionVector *false_sel) {
		auto ldata = ConstantVector::GetData<LEFT_TYPE>(left);
		auto rdata = ConstantVector::GetData<RIGHT_TYPE>(right);

		// both sides are constant, return either 0 or the count
		// in this case we do not fill in the result selection vector at all
		if (ConstantVector::IsNull(left) || ConstantVector::IsNull(right) || !OP::Operation(*ldata, *rdata)) {
			if (false_sel) {
				for (idx_t i = 0; i < count; i++) {
					false_sel->set_index(i, sel->get_index(i));
				}
			}
			return 0;
		} else {
			if (true_sel) {
				for (idx_t i = 0; i < count; i++) {
					true_sel->set_index(i, sel->get_index(i));
				}
			}
			return count;
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT, bool NO_NULL,
	          bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
	static inline idx_t SelectFlatLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                                   const SelectionVector *sel, idx_t count, nullmask_t &nullmask,
	                                   SelectionVector *true_sel, SelectionVector *false_sel) {
		idx_t true_count = 0, false_count = 0;
		for (idx_t i = 0; i < count; i++) {
			idx_t result_idx = sel->get_index(i);
			idx_t lidx = LEFT_CONSTANT ? 0 : i;
			idx_t ridx = RIGHT_CONSTANT ? 0 : i;
			if ((NO_NULL || !nullmask[i]) && OP::Operation(ldata[lidx], rdata[ridx])) {
				if (HAS_TRUE_SEL) {
					true_sel->set_index(true_count++, result_idx);
				}
			} else {
				if (HAS_FALSE_SEL) {
					false_sel->set_index(false_count++, result_idx);
				}
			}
		}
		if (HAS_TRUE_SEL) {
			return true_count;
		} else {
			return count - false_count;
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT, bool NO_NULL>
	static inline idx_t SelectFlatLoopSelSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                                            const SelectionVector *sel, idx_t count, nullmask_t &nullmask,
	                                            SelectionVector *true_sel, SelectionVector *false_sel) {
		if (true_sel && false_sel) {
			return SelectFlatLoop<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, NO_NULL, true, true>(
			    ldata, rdata, sel, count, nullmask, true_sel, false_sel);
		} else if (true_sel) {
			return SelectFlatLoop<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, NO_NULL, true, false>(
			    ldata, rdata, sel, count, nullmask, true_sel, false_sel);
		} else {
			assert(false_sel);
			return SelectFlatLoop<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, NO_NULL, false, true>(
			    ldata, rdata, sel, count, nullmask, true_sel, false_sel);
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
	static inline idx_t SelectFlatLoopSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                                         const SelectionVector *sel, idx_t count, nullmask_t &nullmask,
	                                         SelectionVector *true_sel, SelectionVector *false_sel) {
		if (nullmask.any()) {
			return SelectFlatLoopSelSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, false>(
			    ldata, rdata, sel, count, nullmask, true_sel, false_sel);
		} else {
			return SelectFlatLoopSelSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, true>(
			    ldata, rdata, sel, count, nullmask, true_sel, false_sel);
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
	static idx_t SelectFlat(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
	                        SelectionVector *true_sel, SelectionVector *false_sel) {
		auto ldata = FlatVector::GetData<LEFT_TYPE>(left);
		auto rdata = FlatVector::GetData<RIGHT_TYPE>(right);

		if (LEFT_CONSTANT && ConstantVector::IsNull(left)) {
			return 0;
		}
		if (RIGHT_CONSTANT && ConstantVector::IsNull(right)) {
			return 0;
		}

		if (LEFT_CONSTANT) {
			return SelectFlatLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT>(
			    ldata, rdata, sel, count, FlatVector::Nullmask(right), true_sel, false_sel);
		} else if (RIGHT_CONSTANT) {
			return SelectFlatLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT>(
			    ldata, rdata, sel, count, FlatVector::Nullmask(left), true_sel, false_sel);
		} else {
			auto nullmask = FlatVector::Nullmask(left) | FlatVector::Nullmask(right);
			return SelectFlatLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT>(
			    ldata, rdata, sel, count, nullmask, true_sel, false_sel);
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
	static inline idx_t
	SelectGenericLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata, const SelectionVector *__restrict lsel,
	                  const SelectionVector *__restrict rsel, const SelectionVector *__restrict result_sel, idx_t count,
	                  nullmask_t &lnullmask, nullmask_t &rnullmask, SelectionVector *true_sel,
	                  SelectionVector *false_sel) {
		idx_t true_count = 0, false_count = 0;
		for (idx_t i = 0; i < count; i++) {
			auto result_idx = result_sel->get_index(i);
			auto lindex = lsel->get_index(i);
			auto rindex = rsel->get_index(i);
			if ((NO_NULL || (!lnullmask[lindex] && !rnullmask[rindex])) &&
			    OP::Operation(ldata[lindex], rdata[rindex])) {
				if (HAS_TRUE_SEL) {
					true_sel->set_index(true_count++, result_idx);
				}
			} else {
				if (HAS_FALSE_SEL) {
					false_sel->set_index(false_count++, result_idx);
				}
			}
		}
		if (HAS_TRUE_SEL) {
			return true_count;
		} else {
			return count - false_count;
		}
	}
	template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool NO_NULL>
	static inline idx_t
	SelectGenericLoopSelSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                           const SelectionVector *__restrict lsel, const SelectionVector *__restrict rsel,
	                           const SelectionVector *__restrict result_sel, idx_t count, nullmask_t &lnullmask,
	                           nullmask_t &rnullmask, SelectionVector *true_sel, SelectionVector *false_sel) {
		if (true_sel && false_sel) {
			return SelectGenericLoop<LEFT_TYPE, RIGHT_TYPE, OP, NO_NULL, true, true>(
			    ldata, rdata, lsel, rsel, result_sel, count, lnullmask, rnullmask, true_sel, false_sel);
		} else if (true_sel) {
			return SelectGenericLoop<LEFT_TYPE, RIGHT_TYPE, OP, NO_NULL, true, false>(
			    ldata, rdata, lsel, rsel, result_sel, count, lnullmask, rnullmask, true_sel, false_sel);
		} else {
			assert(false_sel);
			return SelectGenericLoop<LEFT_TYPE, RIGHT_TYPE, OP, NO_NULL, false, true>(
			    ldata, rdata, lsel, rsel, result_sel, count, lnullmask, rnullmask, true_sel, false_sel);
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
	static inline idx_t
	SelectGenericLoopSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
	                        const SelectionVector *__restrict lsel, const SelectionVector *__restrict rsel,
	                        const SelectionVector *__restrict result_sel, idx_t count, nullmask_t &lnullmask,
	                        nullmask_t &rnullmask, SelectionVector *true_sel, SelectionVector *false_sel) {
		if (lnullmask.any() || rnullmask.any()) {
			return SelectGenericLoopSelSwitch<LEFT_TYPE, RIGHT_TYPE, OP, false>(
			    ldata, rdata, lsel, rsel, result_sel, count, lnullmask, rnullmask, true_sel, false_sel);
		} else {
			return SelectGenericLoopSelSwitch<LEFT_TYPE, RIGHT_TYPE, OP, true>(
			    ldata, rdata, lsel, rsel, result_sel, count, lnullmask, rnullmask, true_sel, false_sel);
		}
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
	static idx_t SelectGeneric(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
	                           SelectionVector *true_sel, SelectionVector *false_sel) {
		VectorData ldata, rdata;

		left.Orrify(count, ldata);
		right.Orrify(count, rdata);

		return SelectGenericLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP>((LEFT_TYPE *)ldata.data, (RIGHT_TYPE *)rdata.data,
		                                                          ldata.sel, rdata.sel, sel, count, *ldata.nullmask,
		                                                          *rdata.nullmask, true_sel, false_sel);
	}

	template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
	static idx_t Select(Vector &left, Vector &right, const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
	                    SelectionVector *false_sel) {
		if (!sel) {
			sel = &FlatVector::IncrementalSelectionVector;
		}
		if (left.vector_type == VectorType::CONSTANT_VECTOR && right.vector_type == VectorType::CONSTANT_VECTOR) {
			return SelectConstant<LEFT_TYPE, RIGHT_TYPE, OP>(left, right, sel, count, true_sel, false_sel);
		} else if (left.vector_type == VectorType::CONSTANT_VECTOR && right.vector_type == VectorType::FLAT_VECTOR) {
			return SelectFlat<LEFT_TYPE, RIGHT_TYPE, OP, true, false>(left, right, sel, count, true_sel, false_sel);
		} else if (left.vector_type == VectorType::FLAT_VECTOR && right.vector_type == VectorType::CONSTANT_VECTOR) {
			return SelectFlat<LEFT_TYPE, RIGHT_TYPE, OP, false, true>(left, right, sel, count, true_sel, false_sel);
		} else if (left.vector_type == VectorType::FLAT_VECTOR && right.vector_type == VectorType::FLAT_VECTOR) {
			return SelectFlat<LEFT_TYPE, RIGHT_TYPE, OP, false, false>(left, right, sel, count, true_sel, false_sel);
		} else {
			return SelectGeneric<LEFT_TYPE, RIGHT_TYPE, OP>(left, right, sel, count, true_sel, false_sel);
		}
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/expression_executor_state.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class Expression;
class ExpressionExecutor;
struct ExpressionExecutorState;

struct ExpressionState {
	ExpressionState(Expression &expr, ExpressionExecutorState &root) : expr(expr), root(root) {
	}
	virtual ~ExpressionState() {
	}

	Expression &expr;
	ExpressionExecutorState &root;
	vector<unique_ptr<ExpressionState>> child_states;

public:
	void AddChild(Expression *expr);
};

struct ExpressionExecutorState {
	unique_ptr<ExpressionState> root_state;
	ExpressionExecutor *executor;
};

} // namespace duckdb


namespace duckdb {
class BoundFunctionExpression;
class ScalarFunctionCatalogEntry;

//! The type used for scalar functions
typedef void (*scalar_function_t)(DataChunk &input, ExpressionState &state, Vector &result);
//! Binds the scalar function and creates the function data
typedef unique_ptr<FunctionData> (*bind_scalar_function_t)(BoundFunctionExpression &expr, ClientContext &context);
//! Adds the dependencies of this BoundFunctionExpression to the set of dependencies
typedef void (*dependency_function_t)(BoundFunctionExpression &expr, unordered_set<CatalogEntry *> &dependencies);

class ScalarFunction : public SimpleFunction {
public:
	ScalarFunction(string name, vector<SQLType> arguments, SQLType return_type, scalar_function_t function,
	               bool has_side_effects = false, bind_scalar_function_t bind = nullptr,
	               dependency_function_t dependency = nullptr)
	    : SimpleFunction(name, arguments, return_type, has_side_effects), function(function), bind(bind),
	      dependency(dependency) {
	}

	ScalarFunction(vector<SQLType> arguments, SQLType return_type, scalar_function_t function,
	               bool has_side_effects = false, bind_scalar_function_t bind = nullptr,
	               dependency_function_t dependency = nullptr)
	    : ScalarFunction(string(), arguments, return_type, function, has_side_effects, bind, dependency) {
	}

	//! The main scalar function to execute
	scalar_function_t function;
	//! The bind function (if any)
	bind_scalar_function_t bind;
	// The dependency function (if any)
	dependency_function_t dependency;

	static unique_ptr<BoundFunctionExpression> BindScalarFunction(ClientContext &context, string schema, string name,
	                                                              vector<SQLType> &arguments,
	                                                              vector<unique_ptr<Expression>> children,
	                                                              bool is_operator = false);
	static unique_ptr<BoundFunctionExpression>
	BindScalarFunction(ClientContext &context, ScalarFunctionCatalogEntry &function, vector<SQLType> &arguments,
	                   vector<unique_ptr<Expression>> children, bool is_operator = false);

	bool operator==(const ScalarFunction &rhs) const {
		return function == rhs.function && bind == rhs.bind && dependency == rhs.dependency;
	}
	bool operator!=(const ScalarFunction &rhs) const {
		return !(*this == rhs);
	}

public:
	static void NopFunction(DataChunk &input, ExpressionState &state, Vector &result) {
		assert(input.column_count() >= 1);
		result.Reference(input.data[0]);
	};

	template <class TA, class TR, class OP, bool SKIP_NULLS = false>
	static void UnaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
		assert(input.column_count() >= 1);
		UnaryExecutor::Execute<TA, TR, OP, SKIP_NULLS>(input.data[0], result, input.size());
	};

	template <class TA, class TB, class TR, class OP, bool IGNORE_NULL = false>
	static void BinaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
		assert(input.column_count() == 2);
		BinaryExecutor::ExecuteStandard<TA, TB, TR, OP, IGNORE_NULL>(input.data[0], input.data[1], result,
		                                                             input.size());
	};

public:
	template <class OP> static scalar_function_t GetScalarUnaryFunction(SQLType type) {
		switch (type.id) {
		case SQLTypeId::TINYINT:
			return ScalarFunction::UnaryFunction<int8_t, int8_t, OP>;
		case SQLTypeId::SMALLINT:
			return ScalarFunction::UnaryFunction<int16_t, int16_t, OP>;
		case SQLTypeId::INTEGER:
			return ScalarFunction::UnaryFunction<int32_t, int32_t, OP>;
		case SQLTypeId::BIGINT:
			return ScalarFunction::UnaryFunction<int64_t, int64_t, OP>;
		case SQLTypeId::FLOAT:
			return ScalarFunction::UnaryFunction<float, float, OP>;
		case SQLTypeId::DOUBLE:
			return ScalarFunction::UnaryFunction<double, double, OP>;
		case SQLTypeId::DECIMAL:
			return ScalarFunction::UnaryFunction<double, double, OP>;
		default:
			throw NotImplementedException("Unimplemented type for GetScalarUnaryFunction");
		}
	}

	template <class TR, class OP> static scalar_function_t GetScalarUnaryFunctionFixedReturn(SQLType type) {
		switch (type.id) {
		case SQLTypeId::TINYINT:
			return ScalarFunction::UnaryFunction<int8_t, TR, OP>;
		case SQLTypeId::SMALLINT:
			return ScalarFunction::UnaryFunction<int16_t, TR, OP>;
		case SQLTypeId::INTEGER:
			return ScalarFunction::UnaryFunction<int32_t, TR, OP>;
		case SQLTypeId::BIGINT:
			return ScalarFunction::UnaryFunction<int64_t, TR, OP>;
		case SQLTypeId::FLOAT:
			return ScalarFunction::UnaryFunction<float, TR, OP>;
		case SQLTypeId::DOUBLE:
			return ScalarFunction::UnaryFunction<double, TR, OP>;
		case SQLTypeId::DECIMAL:
			return ScalarFunction::UnaryFunction<double, TR, OP>;
		default:
			throw NotImplementedException("Unimplemented type for GetScalarUnaryFunctionFixedReturn");
		}
	}

	template <class OP> static scalar_function_t GetScalarIntegerBinaryFunction(SQLType type) {
		switch (type.id) {
		case SQLTypeId::TINYINT:
			return ScalarFunction::BinaryFunction<int8_t, int8_t, int8_t, OP>;
		case SQLTypeId::SMALLINT:
			return ScalarFunction::BinaryFunction<int16_t, int16_t, int16_t, OP>;
		case SQLTypeId::INTEGER:
			return ScalarFunction::BinaryFunction<int32_t, int32_t, int32_t, OP>;
		case SQLTypeId::BIGINT:
			return ScalarFunction::BinaryFunction<int64_t, int64_t, int64_t, OP>;
		default:
			throw NotImplementedException("Unimplemented type for GetScalarIntegerBinaryFunction");
		}
	}

	template <class OP> static scalar_function_t GetScalarBinaryFunction(SQLType type) {
		switch (type.id) {
		case SQLTypeId::TINYINT:
			return ScalarFunction::BinaryFunction<int8_t, int8_t, int8_t, OP>;
		case SQLTypeId::SMALLINT:
			return ScalarFunction::BinaryFunction<int16_t, int16_t, int16_t, OP>;
		case SQLTypeId::INTEGER:
			return ScalarFunction::BinaryFunction<int32_t, int32_t, int32_t, OP>;
		case SQLTypeId::BIGINT:
			return ScalarFunction::BinaryFunction<int64_t, int64_t, int64_t, OP>;
		case SQLTypeId::FLOAT:
			return ScalarFunction::BinaryFunction<float, float, float, OP>;
		case SQLTypeId::DOUBLE:
			return ScalarFunction::BinaryFunction<double, double, double, OP>;
		case SQLTypeId::DECIMAL:
			return ScalarFunction::BinaryFunction<double, double, double, OP>;
		default:
			throw NotImplementedException("Unimplemented type for GetScalarBinaryFunction");
		}
	}
};

} // namespace duckdb


namespace duckdb {

template <class T> class FunctionSet {
public:
	FunctionSet(string name) : name(name) {
	}

	//! The name of the function set
	string name;
	//! The set of functions
	vector<T> functions;

public:
	void AddFunction(T function) {
		function.name = name;
		functions.push_back(function);
	}
};

class ScalarFunctionSet : public FunctionSet<ScalarFunction> {
public:
	ScalarFunctionSet(string name) : FunctionSet(move(name)) {
	}
};

class AggregateFunctionSet : public FunctionSet<AggregateFunction> {
public:
	AggregateFunctionSet(string name) : FunctionSet(move(name)) {
	}
};

} // namespace duckdb


namespace duckdb {

struct CreateAggregateFunctionInfo : public CreateFunctionInfo {
	CreateAggregateFunctionInfo(AggregateFunction function)
	    : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION), functions(function.name) {
		this->name = function.name;
		functions.AddFunction(move(function));
	}

	CreateAggregateFunctionInfo(AggregateFunctionSet set)
	    : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION), functions(move(set)) {
		this->name = functions.name;
	}

	AggregateFunctionSet functions;
};

} // namespace duckdb


namespace duckdb {

//! An aggregate function in the catalog
class AggregateFunctionCatalogEntry : public StandardEntry {
public:
	AggregateFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateAggregateFunctionInfo *info)
	    : StandardEntry(CatalogType::AGGREGATE_FUNCTION, schema, catalog, info->name),
	      functions(info->functions.functions) {
	}

	//! The aggregate functions
	vector<AggregateFunction> functions;
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/index_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_index_info.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/index_type.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//===--------------------------------------------------------------------===//
// Index Types
//===--------------------------------------------------------------------===//
enum class IndexType {
	INVALID = 0, // invalid index type
	ART = 1      // Adaptive Radix Tree
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/basetableref.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents a TableReference to a base table in the schema
class BaseTableRef : public TableRef {
public:
	BaseTableRef() : TableRef(TableReferenceType::BASE_TABLE), schema_name(INVALID_SCHEMA) {
	}

	//! Schema name
	string schema_name;
	//! Table name
	string table_name;

public:
	string ToString() const override {
		return "GET(" + schema_name + "." + table_name + ")";
	}

	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a BaseTableRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a BaseTableRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb



namespace duckdb {

struct CreateIndexInfo : public CreateInfo {
	CreateIndexInfo() : CreateInfo(CatalogType::INDEX) {
	}

	//! Index Type (e.g., B+-tree, Skip-List, ...)
	IndexType index_type;
	//! Name of the Index
	string index_name;
	//! If it is an unique index
	bool unique = false;
	//! The table to create the index on
	unique_ptr<BaseTableRef> table;
	//! Set of expressions to index by
	vector<unique_ptr<ParsedExpression>> expressions;
};

} // namespace duckdb


namespace duckdb {

//! An index catalog entry
class IndexCatalogEntry : public StandardEntry {
public:
	//! Create a real TableCatalogEntry and initialize storage for it
	IndexCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateIndexInfo *info)
	    : StandardEntry(CatalogType::INDEX, schema, catalog, info->index_name) {
		// FIXME: add more information for drop index support
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/prepared_statement_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/main/prepared_statement_data.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
class CatalogEntry;
class PhysicalOperator;

struct PreparedValueEntry {
	unique_ptr<Value> value;
	SQLType target_type;
};

class PreparedStatementData {
public:
	PreparedStatementData(StatementType type);
	~PreparedStatementData();

	StatementType statement_type;
	//! The fully prepared physical plan of the prepared statement
	unique_ptr<PhysicalOperator> plan;
	//! The map of parameter index to the actual value entry
	unordered_map<idx_t, PreparedValueEntry> value_map;
	//! Any internal catalog dependencies of the prepared statement
	unordered_set<CatalogEntry *> dependencies;

	//! The result names of the transaction
	vector<string> names;
	//! The (internal) result types of the statement
	vector<TypeId> types;
	//! The result SQL types of the transaction
	vector<SQLType> sql_types;

	//! Whether or not the statement is a read-only statement, or whether it can result in changes to the database
	bool read_only;
	//! Whether or not the statement requires a valid transaction. Almost all statements require this, with the
	//! exception of
	bool requires_valid_transaction;

public:
	//! Bind a set of values to the prepared statement data
	void Bind(vector<Value> values);
	//! Get the expected SQL Type of the bound parameter
	SQLType GetType(idx_t param_index);
};

} // namespace duckdb


namespace duckdb {

//! A view catalog entry
class PreparedStatementCatalogEntry : public CatalogEntry {
public:
	PreparedStatementCatalogEntry(string name, unique_ptr<PreparedStatementData> prepared_data)
	    : CatalogEntry(CatalogType::PREPARED_STATEMENT, nullptr, name), prepared(move(prepared_data)) {
	}

	unique_ptr<PreparedStatementData> prepared;
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/scalar_function_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_scalar_function_info.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

struct CreateScalarFunctionInfo : public CreateFunctionInfo {
	CreateScalarFunctionInfo(ScalarFunction function) : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION) {
		this->name = function.name;
		functions.push_back(function);
	}
	CreateScalarFunctionInfo(ScalarFunctionSet set)
	    : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION), functions(move(set.functions)) {
		this->name = set.name;
	}

	vector<ScalarFunction> functions;
};

} // namespace duckdb


namespace duckdb {

//! A table function in the catalog
class ScalarFunctionCatalogEntry : public StandardEntry {
public:
	ScalarFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateScalarFunctionInfo *info)
	    : StandardEntry(CatalogType::SCALAR_FUNCTION, schema, catalog, info->name), functions(info->functions) {
	}

	//! The scalar functions
	vector<ScalarFunction> functions;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_sequence_info.hpp
//
//
//===----------------------------------------------------------------------===//





#include <limits>

namespace duckdb {

struct CreateSequenceInfo : public CreateInfo {
	CreateSequenceInfo()
	    : CreateInfo(CatalogType::SEQUENCE), name(string()), usage_count(0), increment(1), min_value(1),
	      max_value(std::numeric_limits<int64_t>::max()), start_value(1), cycle(false) {
	}

	//! Sequence name to create
	string name;
	//! Usage count of the sequence
	uint64_t usage_count;
	//! The increment value
	int64_t increment;
	//! The minimum value of the sequence
	int64_t min_value;
	//! The maximum value of the sequence
	int64_t max_value;
	//! The start value of the sequence
	int64_t start_value;
	//! Whether or not the sequence cycles
	bool cycle;
};

} // namespace duckdb


#include <atomic>
#include <mutex>

namespace duckdb {

struct SequenceValue {
	SequenceValue() : usage_count(0), counter(-1) {
	}
	SequenceValue(uint64_t usage_count, int64_t counter) : usage_count(usage_count), counter(counter) {
	}

	uint64_t usage_count;
	int64_t counter;
};

//! A sequence catalog entry
class SequenceCatalogEntry : public StandardEntry {
public:
	//! Create a real TableCatalogEntry and initialize storage for it
	SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info);

	//! Lock for getting a value on the sequence
	std::mutex lock;
	//! The amount of times the sequence has been used
	uint64_t usage_count;
	//! The sequence counter
	int64_t counter;
	//! The increment value
	int64_t increment;
	//! The minimum value of the sequence
	int64_t start_value;
	//! The minimum value of the sequence
	int64_t min_value;
	//! The maximum value of the sequence
	int64_t max_value;
	//! Whether or not the sequence cycles
	bool cycle;

public:
	//! Serialize the meta information of the SequenceCatalogEntry a serializer
	virtual void Serialize(Serializer &serializer);
	//! Deserializes to a CreateTableInfo
	static unique_ptr<CreateSequenceInfo> Deserialize(Deserializer &source);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/table_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/constraint.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class Serializer;
class Deserializer;

//===--------------------------------------------------------------------===//
// Constraint Types
//===--------------------------------------------------------------------===//
enum class ConstraintType : uint8_t {
	INVALID = 0,    // invalid constraint type
	NOT_NULL = 1,   // NOT NULL constraint
	CHECK = 2,      // CHECK constraint
	UNIQUE = 3,     // UNIQUE constraint
	FOREIGN_KEY = 4 // FOREIGN KEY constraint
};

//! Constraint is the base class of any type of table constraint.
class Constraint {
public:
	Constraint(ConstraintType type) : type(type){};
	virtual ~Constraint() {
	}

	ConstraintType type;

public:
	virtual string ToString() const = 0;
	void Print();

	virtual unique_ptr<Constraint> Copy() = 0;
	//! Serializes a Constraint to a stand-alone binary blob
	virtual void Serialize(Serializer &serializer);
	//! Deserializes a blob back into a Constraint, returns NULL if
	//! deserialization is not possible
	static unique_ptr<Constraint> Deserialize(Deserializer &source);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/bound_constraint.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Bound equivalent of Constraint
class BoundConstraint {
public:
	BoundConstraint(ConstraintType type) : type(type){};
	virtual ~BoundConstraint() {
	}

	ConstraintType type;
};
} // namespace duckdb



namespace duckdb {

class ColumnStatistics;
class DataTable;
struct CreateTableInfo;
struct BoundCreateTableInfo;

//! A table catalog entry
class TableCatalogEntry : public StandardEntry {
public:
	//! Create a real TableCatalogEntry and initialize storage for it
	TableCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, BoundCreateTableInfo *info,
	                  std::shared_ptr<DataTable> inherited_storage = nullptr);

	//! A reference to the underlying storage unit used for this table
	std::shared_ptr<DataTable> storage;
	//! A list of columns that are part of this table
	vector<ColumnDefinition> columns;
	//! A list of constraints that are part of this table
	vector<unique_ptr<Constraint>> constraints;
	//! A list of constraints that are part of this table
	vector<unique_ptr<BoundConstraint>> bound_constraints;
	//! A map of column name to column index
	unordered_map<string, column_t> name_map;

public:
	unique_ptr<CatalogEntry> AlterEntry(ClientContext &context, AlterInfo *info) override;
	//! Returns whether or not a column with the given name exists
	bool ColumnExists(const string &name);
	//! Returns a reference to the column of the specified name. Throws an
	//! exception if the column does not exist.
	ColumnDefinition &GetColumn(const string &name);
	//! Returns a list of types of the table
	vector<TypeId> GetTypes();
	//! Returns a list of types of the specified columns of the table
	vector<TypeId> GetTypes(const vector<column_t> &column_ids);

	//! Serialize the meta information of the TableCatalogEntry a serializer
	virtual void Serialize(Serializer &serializer);
	//! Deserializes to a CreateTableInfo
	static unique_ptr<CreateTableInfo> Deserialize(Deserializer &source);

	unique_ptr<CatalogEntry> Copy(ClientContext &context) override;

};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class Catalog;
class Constraint;

struct CreateTableFunctionInfo;

//! A table function in the catalog
class TableFunctionCatalogEntry : public StandardEntry {
public:
	TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info);

	//! The table function
	TableFunction function;
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/catalog/catalog_entry/view_catalog_entry.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class ColumnStatistics;
class DataTable;
struct CreateViewInfo;

//! A view catalog entry
class ViewCatalogEntry : public StandardEntry {
public:
	//! Create a real TableCatalogEntry and initialize storage for it
	ViewCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateViewInfo *info);

	//! The query of the view
	unique_ptr<QueryNode> query;
	//! The set of aliases associated with the view
	vector<string> aliases;

public:
	//! Serialize the meta information of the ViewCatalogEntry a serializer
	virtual void Serialize(Serializer &serializer);
	//! Deserializes to a CreateTableInfo
	static unique_ptr<CreateViewInfo> Deserialize(Deserializer &source);

private:
	void Initialize(CreateViewInfo *info);
};
} // namespace duckdb




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/function_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents a function call
class FunctionExpression : public ParsedExpression {
public:
	FunctionExpression(string schema_name, string function_name, vector<unique_ptr<ParsedExpression>> &children,
	                   bool distinct = false, bool is_operator = false);
	FunctionExpression(string function_name, vector<unique_ptr<ParsedExpression>> &children, bool distinct = false,
	                   bool is_operator = false);

	//! Schema of the function
	string schema;
	//! Function name
	string function_name;
	//! Whether or not the function is an operator, only used for rendering
	bool is_operator;
	//! List of arguments to the function
	vector<unique_ptr<ParsedExpression>> children;
	//! Whether or not the aggregate function is distinct, only used for aggregates
	bool distinct;

public:
	string ToString() const override;

	unique_ptr<ParsedExpression> Copy() const override;

	static bool Equals(const FunctionExpression *a, const FunctionExpression *b);
	hash_t Hash() const override;

	//! Serializes a FunctionExpression to a stand-alone binary blob
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into an FunctionExpression
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/alter_table_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

enum class AlterType : uint8_t { INVALID = 0, ALTER_TABLE = 1 };

struct AlterInfo : public ParseInfo {
	AlterInfo(AlterType type) : type(type) {
	}
	virtual ~AlterInfo() {
	}

	AlterType type;

	virtual void Serialize(Serializer &serializer);
	static unique_ptr<AlterInfo> Deserialize(Deserializer &source);
};

enum class AlterTableType : uint8_t { INVALID = 0, RENAME_COLUMN = 1, RENAME_TABLE = 2};

struct AlterTableInfo : public AlterInfo {
	AlterTableInfo(AlterTableType type, string schema, string table)
	    : AlterInfo(AlterType::ALTER_TABLE), alter_table_type(type), schema(schema), table(table) {
	}
	virtual ~AlterTableInfo() override {
	}

	AlterTableType alter_table_type;
	//! Schema name to alter to
	string schema;
	//! Table name to alter to
	string table;

	virtual void Serialize(Serializer &serializer) override;
	static unique_ptr<AlterInfo> Deserialize(Deserializer &source);
};

struct RenameColumnInfo : public AlterTableInfo {
	RenameColumnInfo(string schema, string table, string name, string new_name)
	    : AlterTableInfo(AlterTableType::RENAME_COLUMN, schema, table), name(name), new_name(new_name) {
	}
	~RenameColumnInfo() override {
	}

	//! Column old name
	string name;
	//! Column new name
	string new_name;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<AlterInfo> Deserialize(Deserializer &source, string schema, string table);
};

struct RenameTableInfo : public AlterTableInfo {
    RenameTableInfo(string schema, string table, string new_name)
            : AlterTableInfo(AlterTableType::RENAME_TABLE, schema, table), new_table_name(new_name) {
    }
    ~RenameTableInfo() override {
    }

    //! Table new name
    string new_table_name;

    void Serialize(Serializer &serializer) override;
    static unique_ptr<AlterInfo> Deserialize(Deserializer &source, string schema, string table);
};

} // namespace duckdb




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_schema_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct CreateSchemaInfo : public CreateInfo {
	CreateSchemaInfo() : CreateInfo(CatalogType::SCHEMA) {
	}
};

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_view_info.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct CreateViewInfo : public CreateInfo {
	CreateViewInfo() : CreateInfo(CatalogType::VIEW) {
	}
	CreateViewInfo(string schema, string view_name) : CreateInfo(CatalogType::VIEW, schema), view_name(view_name) {
	}

	//! Table name to insert to
	string view_name;
	//! Aliases of the
	vector<string> aliases;
	//! The QueryNode of the view
	unique_ptr<QueryNode> query;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/drop_info.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct DropInfo : public ParseInfo {
	DropInfo() : schema(INVALID_SCHEMA), if_exists(false), cascade(false) {
	}

	//! The catalog type to drop
	CatalogType type;
	//! Schema name to drop from, if any
	string schema;
	//! Element name to drop
	string name;
	//! Ignore if the entry does not exist instead of failing
	bool if_exists = false;
	//! Cascade drop (drop all dependents instead of throwing an error if there
	//! are any)
	bool cascade = false;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/parsed_data/bound_create_table_info.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/parsed_data/bound_create_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class SchemaCatalogEntry;

struct BoundCreateInfo {
	BoundCreateInfo() {
	}
	BoundCreateInfo(unique_ptr<CreateInfo> base) : base(move(base)) {
	}
	virtual ~BoundCreateInfo() {
	}

	//! The schema to create the table in
	SchemaCatalogEntry *schema;
	//! The base CreateInfo object
	unique_ptr<CreateInfo> base;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/create_table_info.hpp
//
//
//===----------------------------------------------------------------------===//









namespace duckdb {

struct CreateTableInfo : public CreateInfo {
	CreateTableInfo() : CreateInfo(CatalogType::TABLE, INVALID_SCHEMA) {
	}
	CreateTableInfo(string schema, string name) : CreateInfo(CatalogType::TABLE, schema), table(name) {
	}

	//! Table name to insert to
	string table;
	//! List of columns of the table
	vector<ColumnDefinition> columns;
	//! List of constraints on the table
	vector<unique_ptr<Constraint>> constraints;
	//! CREATE TABLE from QUERY
	unique_ptr<SelectStatement> query;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_select_statement.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/bound_query_node.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

struct BoundOrderByNode {
	BoundOrderByNode() {
	}
	BoundOrderByNode(OrderType type, unique_ptr<Expression> expression) : type(type), expression(move(expression)) {
	}

	OrderType type;
	unique_ptr<Expression> expression;
};

//! Bound equivalent of QueryNode
class BoundQueryNode {
public:
	BoundQueryNode(QueryNodeType type) : type(type) {
	}
	virtual ~BoundQueryNode() {
	}

	//! The type of the query node, either SetOperation or Select
	QueryNodeType type;
	//! DISTINCT or not
	bool select_distinct = false;
	//! List of order nodes
	vector<BoundOrderByNode> orders;
	//! List of target nodes for DISTINCT ON
	vector<unique_ptr<Expression>> target_distincts;
	//! LIMIT count
	int64_t limit = -1;
	//! OFFSET
	int64_t offset = -1;

	//! The names returned by this QueryNode.
	vector<string> names;
	//! The types returned by this QueryNode.
	vector<SQLType> types;

public:
	virtual idx_t GetRootIndex() = 0;
};

}; // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/bound_sql_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Bound equivalent of SQLStatement
class BoundSQLStatement {
public:
	BoundSQLStatement(StatementType type) : type(type){};
	virtual ~BoundSQLStatement() {
	}

	virtual vector<string> GetNames() = 0;
	virtual vector<SQLType> GetTypes() = 0;

	StatementType type;
};
} // namespace duckdb


namespace duckdb {

//! Bound equivalent to SelectStatement
class BoundSelectStatement : public BoundSQLStatement {
public:
	BoundSelectStatement() : BoundSQLStatement(StatementType::SELECT) {
	}

	//! The main query node
	unique_ptr<BoundQueryNode> node;

public:
	vector<string> GetNames() override {
		return node->names;
	}
	vector<SQLType> GetTypes() override {
		return node->types;
	}
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/persistent_segment.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/column_segment.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/block.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/storage_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The version number of the database storage format
extern const uint64_t VERSION_NUMBER;

using block_id_t = int64_t;

#define INVALID_BLOCK -1

// maximum block id, 2^62
#define MAXIMUM_BLOCK 4611686018427388000LL

//! The MainHeader is the first header in the storage file. The MainHeader is typically written only once for a database
//! file.
struct MainHeader {
	//! The version of the database
	uint64_t version_number;
	//! The set of flags used by the database
	uint64_t flags[4];
};

//! The DatabaseHeader contains information about the current state of the database. Every storage file has two
//! DatabaseHeaders. On startup, the DatabaseHeader with the highest iteration count is used as the active header. When
//! a checkpoint is performed, the active DatabaseHeader is switched by increasing the iteration count of the
//! DatabaseHeader.
struct DatabaseHeader {
	//! The iteration count, increases by 1 every time the storage is checkpointed.
	uint64_t iteration;
	//! A pointer to the initial meta block
	block_id_t meta_block;
	//! A pointer to the block containing the free list
	block_id_t free_list;
	//! The number of blocks that is in the file as of this database header. If the file is larger than BLOCK_SIZE *
	//! block_count any blocks appearing AFTER block_count are implicitly part of the free_list.
	uint64_t block_count;
};

} // namespace duckdb



namespace duckdb {

class Block : public FileBuffer {
public:
	Block(block_id_t id);

	block_id_t id;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/segment_tree.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/storage_lock.hpp
//
//
//===----------------------------------------------------------------------===//




#include <atomic>
#include <mutex>

namespace duckdb {
class StorageLock;

enum class StorageLockType { SHARED = 0, EXCLUSIVE = 1 };

class StorageLockKey {
public:
	StorageLockKey(StorageLock &lock, StorageLockType type);
	~StorageLockKey();

private:
	StorageLock &lock;
	StorageLockType type;
};

class StorageLock {
	friend class StorageLockKey;

public:
	StorageLock();

	//! Get an exclusive lock
	unique_ptr<StorageLockKey> GetExclusiveLock();
	//! Get a shared lock
	unique_ptr<StorageLockKey> GetSharedLock();

private:
	std::mutex exclusive_lock;
	std::atomic<idx_t> read_count;

private:
	//! Release an exclusive lock
	void ReleaseExclusiveLock();
	//! Release a shared lock
	void ReleaseSharedLock();
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/segment_base.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class SegmentBase {
public:
	SegmentBase(idx_t start, idx_t count) : start(start), count(count) {
	}
	virtual ~SegmentBase() {
	}

	//! The start row id of this chunk
	idx_t start;
	//! The amount of entries in this storage chunk
	idx_t count;
	//! The next segment after this one
	unique_ptr<SegmentBase> next;
};

} // namespace duckdb


#include <mutex>

namespace duckdb {

struct SegmentNode {
	idx_t row_start;
	SegmentBase *node;
};

//! The SegmentTree maintains a list of all segments of a specific column in a table, and allows searching for a segment
//! by row number
class SegmentTree {
public:
	//! The initial segment of the tree
	unique_ptr<SegmentBase> root_node;
	//! The nodes in the tree, can be binary searched
	vector<SegmentNode> nodes;
	//! Lock to access or modify the nodes
	std::mutex node_lock;

public:
	//! Gets a pointer to the first segment. Useful for scans.
	SegmentBase *GetRootSegment();
	//! Gets a pointer to the last segment. Useful for appends.
	SegmentBase *GetLastSegment();
	//! Gets a pointer to a specific column segment for the given row
	SegmentBase *GetSegment(idx_t row_number);
	//! Append a column segment to the tree
	void AppendSegment(unique_ptr<SegmentBase> segment);

	//! Get the segment index of the column segment for the given row (does not lock the segment tree!)
	idx_t GetSegmentIndex(idx_t row_number);
};

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/buffer_manager.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/buffer/buffer_handle.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class BufferManager;
class FileBuffer;

class BufferHandle {
public:
	BufferHandle(BufferManager &manager, block_id_t block_id, FileBuffer *node);
	~BufferHandle();

	BufferManager &manager;
	//! The block id of the block
	block_id_t block_id;
	//! The managed buffer node
	FileBuffer *node;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/buffer/buffer_list.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct BufferEntry {
	BufferEntry(unique_ptr<FileBuffer> buffer) : buffer(move(buffer)), ref_count(1), prev(nullptr) {
	}
	~BufferEntry() {
		while (next) {
			next = move(next->next);
		}
	}

	//! The actual buffer
	unique_ptr<FileBuffer> buffer;
	//! The amount of references to this entry
	idx_t ref_count;
	//! Next node
	unique_ptr<BufferEntry> next;
	//! Prev entry
	BufferEntry *prev;
};

class BufferList {
public:
	BufferList() : last(nullptr), count(0) {
	}

public:
	//! Removes the first element (root) from the buffer list and returns it, O(1)
	unique_ptr<BufferEntry> Pop();
	//! Erase the specified element from the list and returns it, O(1)
	unique_ptr<BufferEntry> Erase(BufferEntry *entry);
	//! Insert an entry to the back of the list
	void Append(unique_ptr<BufferEntry> entry);

private:
	//! Root pointer
	unique_ptr<BufferEntry> root;
	//! Pointer to last element in list
	BufferEntry *last;
	//! The amount of entries in the list
	idx_t count;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/buffer/managed_buffer.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class BufferManager;

//! Managed buffer is an arbitrarily-sized buffer that is at least of size >= BLOCK_SIZE
class ManagedBuffer : public FileBuffer {
public:
	ManagedBuffer(BufferManager &manager, idx_t size, bool can_destroy, block_id_t id);

	//! The buffer manager this buffer belongs to
	BufferManager &manager;
	//! Whether or not the managed buffer can be freely destroyed when unpinned.
	//! - If can_destroy is true, the buffer can be destroyed when unpinned and hence be unrecoverable. After being
	//! destroyed, Pin() will return false.
	//! - If can_destroy is false, the buffer will instead be written to a temporary file on disk when unloaded from
	//! memory, and read back into memory when Pin() is called.
	bool can_destroy;
	//! The internal id of the buffer
	block_id_t id;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/block_manager.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
//! BlockManager is an abstract representation to manage blocks on DuckDB. When writing or reading blocks, the
//! BlockManager creates and accesses blocks. The concrete types implements how blocks are stored.
class BlockManager {
public:
	virtual ~BlockManager() = default;

	//! Creates a new block inside the block manager
	virtual unique_ptr<Block> CreateBlock() = 0;
	//! Return the next free block id
	virtual block_id_t GetFreeBlockId() = 0;
	//! Get the first meta block id
	virtual block_id_t GetMetaBlock() = 0;
	//! Read the content of the block from disk
	virtual void Read(Block &block) = 0;
	//! Writes the block to disk
	virtual void Write(FileBuffer &block, block_id_t block_id) = 0;
	//! Writes the block to disk
	void Write(Block &block) {
		Write(block, block.id);
	}
	//! Write the header; should be the final step of a checkpoint
	virtual void WriteHeader(DatabaseHeader header) = 0;
};
} // namespace duckdb




#include <mutex>

namespace duckdb {

//! The buffer manager is in charge of handling memory management for the database. It hands out memory buffers that can
//! be used by the database internally.
class BufferManager {
	friend class BufferHandle;

public:
	BufferManager(FileSystem &fs, BlockManager &manager, string temp_directory, idx_t maximum_memory);
	~BufferManager();

	//! Pin a block id, returning a block handle holding a pointer to the block
	unique_ptr<BufferHandle> Pin(block_id_t block, bool can_destroy = false);

	//! Allocate a buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or not the
	//! buffer can be destroyed when unpinned, or whether or not it needs to be written to a temporary file so it can be
	//! reloaded.
	unique_ptr<BufferHandle> Allocate(idx_t alloc_size, bool can_destroy = false);
	//! Destroy the managed buffer with the specified buffer_id, freeing its memory
	void DestroyBuffer(block_id_t buffer_id, bool can_destroy = false);

	//! Set a new memory limit to the buffer manager, throws an exception if the new limit is too low and not enough
	//! blocks can be evicted
	void SetLimit(idx_t limit = (idx_t)-1);

	static BufferManager &GetBufferManager(ClientContext &context);

private:
	unique_ptr<BufferHandle> PinBlock(block_id_t block_id);
	unique_ptr<BufferHandle> PinBuffer(block_id_t block_id, bool can_destroy = false);

	//! Unpin a block id, decreasing its reference count and potentially allowing it to be freed.
	void Unpin(block_id_t block);

	//! Evict the least recently used block from the buffer manager, or throws an exception if there are no blocks
	//! available to evict
	unique_ptr<Block> EvictBlock();

	//! Add a reference to the refcount of a buffer entry
	void AddReference(BufferEntry *entry);

	//! Write a temporary buffer to disk
	void WriteTemporaryBuffer(ManagedBuffer &buffer);
	//! Read a temporary buffer from disk
	unique_ptr<BufferHandle> ReadTemporaryBuffer(block_id_t id);
	//! Get the path of the temporary buffer
	string GetTemporaryPath(block_id_t id);

	void DeleteTemporaryFile(block_id_t id);

private:
	FileSystem &fs;
	//! The block manager
	BlockManager &manager;
	//! The current amount of memory that is occupied by the buffer manager (in bytes)
	idx_t current_memory;
	//! The maximum amount of memory that the buffer manager can keep (in bytes)
	idx_t maximum_memory;
	//! The directory name where temporary files are stored
	string temp_directory;
	//! The lock for the set of blocks
	std::mutex block_lock;
	//! A mapping of block id -> BufferEntry
	unordered_map<block_id_t, BufferEntry *> blocks;
	//! A linked list of buffer entries that are in use
	BufferList used_list;
	//! LRU list of unused blocks
	BufferList lru;
	//! The temporary id used for managed buffers
	block_id_t temporary_id;
};
} // namespace duckdb


namespace duckdb {
class BlockManager;
class ColumnSegment;
class ColumnData;
class Transaction;

struct ColumnFetchState;
struct ColumnScanState;

enum class ColumnSegmentType : uint8_t { TRANSIENT, PERSISTENT };

class SegmentStatistics {
public:
	SegmentStatistics(TypeId type, idx_t type_size);
	SegmentStatistics(TypeId type, idx_t type_size, data_t stats_min[], data_t stats_max[]);
	TypeId type;
	idx_t type_size;
	//! The minimum value of the segment
	unique_ptr<data_t[]> minimum;
	//! The maximum value of the segment
	unique_ptr<data_t[]> maximum;
	//! Whether or not the segment has NULL values
	bool has_null;
	//! The maximum string length, only used for string columns
	idx_t max_string_length;
	//! Whether or not the segment contains any big strings in overflow blocks, only used for string columns
	bool has_overflow_strings;

public:
	void Reset();
};

class ColumnSegment : public SegmentBase {
public:
	//! Initialize an empty column segment of the specified type
	ColumnSegment(TypeId type, ColumnSegmentType segment_type, idx_t start, idx_t count = 0);

	ColumnSegment(TypeId type, ColumnSegmentType segment_type, idx_t start, idx_t count, data_t stats_min[],
	              data_t stats_max[]);

	virtual ~ColumnSegment() = default;

	//! The type stored in the column
	TypeId type;
	//! The size of the type
	idx_t type_size;
	//! The column segment type (transient or persistent)
	ColumnSegmentType segment_type;
	//! The statistics for the segment
	SegmentStatistics stats;

public:
	virtual void InitializeScan(ColumnScanState &state) = 0;
	//! Scan one vector from this segment
	virtual void Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result) = 0;
	//! Scan one vector from this segment, throwing an exception if there are any outstanding updates
	virtual void IndexScan(ColumnScanState &state, Vector &result) = 0;

	//! Fetch the base table vector index that belongs to this row
	virtual void Fetch(ColumnScanState &state, idx_t vector_index, Vector &result) = 0;
	//! Fetch a value of the specific row id and append it to the result
	virtual void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
	                      idx_t result_idx) = 0;

	//! Perform an update within the segment
	virtual void Update(ColumnData &column_data, Transaction &transaction, Vector &updates, row_t *ids,
	                    idx_t count) = 0;
};

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/uncompressed_segment.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/scan_state.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
class LocalTableStorage;
class Index;
class PersistentSegment;
class TransientSegment;

struct IndexScanState {
	vector<column_t> column_ids;

	IndexScanState(vector<column_t> column_ids) : column_ids(column_ids) {
	}
	virtual ~IndexScanState() {
	}
};

typedef unordered_map<block_id_t, unique_ptr<BufferHandle>> buffer_handle_set_t;

struct ColumnScanState {
	//! The column segment that is currently being scanned
	ColumnSegment *current;
	//! The vector index of the transient segment
	idx_t vector_index;
	//! The primary buffer handle
	unique_ptr<BufferHandle> primary_handle;
	//! The set of pinned block handles for this scan
	buffer_handle_set_t handles;
	//! The locks that are held during the scan, only used by the index scan
	vector<unique_ptr<StorageLockKey>> locks;
	//! Whether or not InitializeState has been called for this segment
	bool initialized;

public:
	//! Move on to the next vector in the scan
	void Next();
};

struct ColumnFetchState {
	//! The set of pinned block handles for this set of fetches
	buffer_handle_set_t handles;
};

struct LocalScanState {
	LocalTableStorage *storage = nullptr;

	idx_t chunk_index;
	idx_t max_index;
	idx_t last_chunk_count;
};

class TableScanState {
public:
	TableScanState(){};
	idx_t current_persistent_row, max_persistent_row;
	idx_t current_transient_row, max_transient_row;
	unique_ptr<ColumnScanState[]> column_scans;
	idx_t offset;
	vector<column_t> column_ids;
	LocalScanState local_state;
	void NextVector();
};

class CreateIndexScanState : public TableScanState {
public:
	vector<unique_ptr<StorageLockKey>> locks;
	std::unique_lock<std::mutex> append_lock;
};

struct TableIndexScanState {
	Index *index;
	unique_ptr<IndexScanState> index_state;
	ColumnFetchState fetch_state;
	LocalScanState local_state;
	vector<column_t> column_ids;
};

} // namespace duckdb


namespace duckdb {
class BufferManager;
class ColumnData;
class Transaction;

struct ColumnAppendState;
struct UpdateInfo;

//! An uncompressed segment represents an uncompressed segment of a column residing in a block
class UncompressedSegment {
public:
	UncompressedSegment(BufferManager &manager, TypeId type, idx_t row_start);
	virtual ~UncompressedSegment();

	//! The buffer manager
	BufferManager &manager;
	//! Type of the uncompressed segment
	TypeId type;
	//! The block id that this segment relates to
	block_id_t block_id;
	//! The size of a vector of this type
	idx_t vector_size;
	//! The maximum amount of vectors that can be stored in this segment
	idx_t max_vector_count;
	//! The current amount of tuples that are stored in this segment
	idx_t tuple_count;
	//! The starting row of this segment
	idx_t row_start;
	//! Version chains for each of the vectors
	unique_ptr<UpdateInfo *[]> versions;
	//! The lock for the uncompressed segment
	StorageLock lock;

public:
	virtual void InitializeScan(ColumnScanState &state) {
	}
	//! Fetch the vector at index "vector_index" from the uncompressed segment, storing it in the result vector
	void Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result);
	//! Fetch the vector at index "vector_index" from the uncompressed segment, throwing an exception if there are any
	//! outstanding updates
	void IndexScan(ColumnScanState &state, idx_t vector_index, Vector &result);

	//! Fetch a single vector from the base table
	void Fetch(ColumnScanState &state, idx_t vector_index, Vector &result);
	//! Fetch a single value and append it to the vector
	virtual void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
	                      idx_t result_idx) = 0;

	//! Append a part of a vector to the uncompressed segment with the given append state, updating the provided stats
	//! in the process. Returns the amount of tuples appended. If this is less than `count`, the uncompressed segment is
	//! full.
	virtual idx_t Append(SegmentStatistics &stats, Vector &data, idx_t offset, idx_t count) = 0;

	//! Update a set of row identifiers to the specified set of updated values
	void Update(ColumnData &data, SegmentStatistics &stats, Transaction &transaction, Vector &update, row_t *ids,
	            idx_t count, row_t offset);

	//! Rollback a previous update
	virtual void RollbackUpdate(UpdateInfo *info) = 0;
	//! Cleanup an update, removing it from the version chain. This should only be called if an exclusive lock is held
	//! on the segment
	void CleanupUpdate(UpdateInfo *info);

	//! Convert a persistently backed uncompressed segment (i.e. one where block_id refers to an on-disk block) to a
	//! temporary in-memory one
	void ToTemporary();

	//! Get the amount of tuples in a vector
	idx_t GetVectorCount(idx_t vector_index) {
		assert(vector_index < max_vector_count);
		assert(vector_index * STANDARD_VECTOR_SIZE <= tuple_count);
		return std::min((idx_t)STANDARD_VECTOR_SIZE, tuple_count - vector_index * STANDARD_VECTOR_SIZE);
	}

protected:
	virtual void Update(ColumnData &data, SegmentStatistics &stats, Transaction &transaction, Vector &update,
	                    row_t *ids, idx_t count, idx_t vector_index, idx_t vector_offset, UpdateInfo *node) = 0;
	//! Fetch base table data
	virtual void FetchBaseData(ColumnScanState &state, idx_t vector_index, Vector &result) = 0;
	//! Fetch update data from an UpdateInfo version
	virtual void FetchUpdateData(ColumnScanState &state, Transaction &transaction, UpdateInfo *version,
	                             Vector &result) = 0;

	//! Create a new update info for the specified transaction reflecting an update of the specified rows
	UpdateInfo *CreateUpdateInfo(ColumnData &data, Transaction &transaction, row_t *ids, idx_t count,
	                             idx_t vector_index, idx_t vector_offset, idx_t type_size);
};

} // namespace duckdb


namespace duckdb {

class PersistentSegment : public ColumnSegment {
public:
	PersistentSegment(BufferManager &manager, block_id_t id, idx_t offset, TypeId type, idx_t start, idx_t count,
	                  data_t stats_min[], data_t stats_max[]);

	//! The buffer manager
	BufferManager &manager;
	//! The block id that this segment relates to
	block_id_t block_id;
	//! The offset into the block
	idx_t offset;
	//! The uncompressed segment that the data of the persistent segment is loaded into
	unique_ptr<UncompressedSegment> data;

public:
	void InitializeScan(ColumnScanState &state) override;
	//! Scan one vector from this transient segment
	void Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result) override;
	//! Scan one vector from this transient segment, throwing an exception if there are any outstanding updates
	void IndexScan(ColumnScanState &state, Vector &result) override;

	//! Fetch the base table vector index that belongs to this row
	void Fetch(ColumnScanState &state, idx_t vector_index, Vector &result) override;
	//! Fetch a value of the specific row id and append it to the result
	void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
	              idx_t result_idx) override;

	//! Perform an update within the segment
	void Update(ColumnData &column_data, Transaction &transaction, Vector &updates, row_t *ids, idx_t count) override;
};

} // namespace duckdb


namespace duckdb {
class CatalogEntry;

struct BoundCreateTableInfo : public BoundCreateInfo {
	BoundCreateTableInfo(unique_ptr<CreateInfo> base) : BoundCreateInfo(move(base)) {
	}
	//! The map of column names -> column index, used during binding
	unordered_map<string, column_t> name_map;
	//! List of constraints on the table
	vector<unique_ptr<Constraint>> constraints;
	//! List of bound constraints on the table
	vector<unique_ptr<BoundConstraint>> bound_constraints;
	//! Bound default values
	vector<unique_ptr<Expression>> bound_defaults;
	//! Dependents of the table (in e.g. default values)
	unordered_set<CatalogEntry *> dependencies;
	//! The existing table data on disk (if any)
	unique_ptr<vector<unique_ptr<PersistentSegment>>[]> data;
	//! CREATE TABLE from QUERY
	unique_ptr<BoundSelectStatement> query;

	CreateTableInfo &Base() {
		return (CreateTableInfo &)*base;
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/storage_manager.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/data_table.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/index.hpp
//
//
//===----------------------------------------------------------------------===//









//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/expression_executor.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

//! ExpressionExecutor is responsible for executing a set of expressions and storing the result in a data chunk
class ExpressionExecutor {
public:
	ExpressionExecutor();
	ExpressionExecutor(Expression *expression);
	ExpressionExecutor(Expression &expression);
	ExpressionExecutor(vector<unique_ptr<Expression>> &expressions);

	//! Add an expression to the set of to-be-executed expressions of the executor
	void AddExpression(Expression &expr);

	//! Execute the set of expressions with the given input chunk and store the result in the output chunk
	void Execute(DataChunk *input, DataChunk &result);
	void Execute(DataChunk &input, DataChunk &result) {
		Execute(&input, result);
	}
	void Execute(DataChunk &result) {
		Execute(nullptr, result);
	}

	//! Execute the ExpressionExecutor and put the result in the result vector; this should only be used for expression
	//! executors with a single expression
	void ExecuteExpression(DataChunk &input, Vector &result);
	//! Execute the ExpressionExecutor and put the result in the result vector; this should only be used for expression
	//! executors with a single expression
	void ExecuteExpression(Vector &result);
	//! Execute the ExpressionExecutor and generate a selection vector from all true values in the result; this should
	//! only be used with a single boolean expression
	idx_t SelectExpression(DataChunk &input, SelectionVector &sel);

	//! Execute the expression with index `expr_idx` and store the result in the result vector
	void ExecuteExpression(idx_t expr_idx, Vector &result);
	//! Evaluate a scalar expression and fold it into a single value
	static Value EvaluateScalar(Expression &expr);

	//! Initialize the state of a given expression
	static unique_ptr<ExpressionState> InitializeState(Expression &expr, ExpressionExecutorState &state);

	void SetChunk(DataChunk *chunk) {
		this->chunk = chunk;
	}
	void SetChunk(DataChunk &chunk) {
		SetChunk(&chunk);
	}

	//! The expressions of the executor
	vector<Expression *> expressions;
	//! The data chunk of the current physical operator, used to resolve
	//! column references and determines the output cardinality
	DataChunk *chunk = nullptr;

protected:
	void Initialize(Expression &expr, ExpressionExecutorState &state);

	static unique_ptr<ExpressionState> InitializeState(BoundReferenceExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundBetweenExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundCaseExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundCastExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundComparisonExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundConjunctionExpression &expr,
	                                                   ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundConstantExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundFunctionExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundOperatorExpression &expr, ExpressionExecutorState &state);
	static unique_ptr<ExpressionState> InitializeState(BoundParameterExpression &expr, ExpressionExecutorState &state);

	void Execute(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count, Vector &result);

	void Execute(BoundBetweenExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundCaseExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundCastExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundComparisonExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundConjunctionExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundConstantExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundFunctionExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundOperatorExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundParameterExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);
	void Execute(BoundReferenceExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             Vector &result);

	//! Execute the (boolean-returning) expression and generate a selection vector with all entries that are "true" in
	//! the result
	idx_t Select(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             SelectionVector *true_sel, SelectionVector *false_sel);
	idx_t DefaultSelect(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	                    SelectionVector *true_sel, SelectionVector *false_sel);

	idx_t Select(BoundBetweenExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             SelectionVector *true_sel, SelectionVector *false_sel);
	idx_t Select(BoundComparisonExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             SelectionVector *true_sel, SelectionVector *false_sel);
	idx_t Select(BoundConjunctionExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
	             SelectionVector *true_sel, SelectionVector *false_sel);

	//! Verify that the output of a step in the ExpressionExecutor is correct
	void Verify(Expression &expr, Vector &result, idx_t count);

private:
	//! The states of the expression executor; this holds any intermediates and temporary states of expressions
	vector<unique_ptr<ExpressionExecutorState>> states;
};
} // namespace duckdb


namespace duckdb {

class ClientContext;
class DataTable;
class Transaction;

struct IndexLock;

//! The index is an abstract base class that serves as the basis for indexes
class Index {
public:
	Index(IndexType type, DataTable &table, vector<column_t> column_ids,
	      vector<unique_ptr<Expression>> unbound_expressions);
	virtual ~Index() = default;

	//! Lock used for updating the index
	std::mutex lock;
	//! The type of the index
	IndexType type;
	//! The table
	DataTable &table;
	//! Column identifiers to extract from the base table
	vector<column_t> column_ids;
	//! unordered_set of column_ids used by the index
	unordered_set<column_t> column_id_set;
	//! Unbound expressions used by the index
	vector<unique_ptr<Expression>> unbound_expressions;
	//! The types of the expressions
	vector<TypeId> types;

public:
	//! Initialize a scan on the index with the given expression and column ids
	//! to fetch from the base table when we only have one query predicate
	virtual unique_ptr<IndexScanState> InitializeScanSinglePredicate(Transaction &transaction,
	                                                                 vector<column_t> column_ids, Value value,
	                                                                 ExpressionType expressionType) = 0;
	//! Initialize a scan on the index with the given expression and column ids
	//! to fetch from the base table for two query predicates
	virtual unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction,
	                                                               vector<column_t> column_ids, Value low_value,
	                                                               ExpressionType low_expression_type, Value high_value,
	                                                               ExpressionType high_expression_type) = 0;
	//! Perform a lookup on the index
	virtual void Scan(Transaction &transaction, TableIndexScanState &state, DataChunk &result) = 0;

	//! Obtain a lock on the index
	virtual void InitializeLock(IndexLock &state);
	//! Called when data is appended to the index. The lock obtained from InitializeAppend must be held
	virtual bool Append(IndexLock &state, DataChunk &entries, Vector &row_identifiers) = 0;
	bool Append(DataChunk &entries, Vector &row_identifiers);
	//! Verify that data can be appended to the index
	virtual void VerifyAppend(DataChunk &chunk) {
	}

	//! Called when data inside the index is Deleted
	virtual void Delete(IndexLock &state, DataChunk &entries, Vector &row_identifiers) = 0;
	void Delete(DataChunk &entries, Vector &row_identifiers);

	//! Insert data into the index. Does not lock the index.
	virtual bool Insert(IndexLock &lock, DataChunk &input, Vector &row_identifiers) = 0;

	//! Returns true if the index is affected by updates on the specified column ids, and false otherwise
	bool IndexIsUpdated(vector<column_t> &column_ids);

protected:
	void ExecuteExpressions(DataChunk &input, DataChunk &result);

private:
	//! Bound expressions used by the index
	vector<unique_ptr<Expression>> bound_expressions;
	//! Expression executor for the index expressions
	ExpressionExecutor executor;

	unique_ptr<Expression> BindExpression(unique_ptr<Expression> expr);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table_statistics.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct TableStatistics {
	idx_t estimated_cardinality;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/column_data.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/append_state.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class TransientSegment;

struct ColumnAppendState {
	//! The current segment of the append
	TransientSegment *current;
	//! The write lock that is held by the append
	unique_ptr<StorageLockKey> lock;
};

struct IndexLock {
	std::unique_lock<std::mutex> index_lock;
};

struct TableAppendState {
	std::unique_lock<std::mutex> append_lock;
	unique_ptr<IndexLock[]> index_locks;
	unique_ptr<ColumnAppendState[]> states;
	row_t row_start;
	row_t current_row;
};

} // namespace duckdb




namespace duckdb {
class DataTable;
class PersistentSegment;
class Transaction;

class ColumnData {
public:
	ColumnData();
	//! Set up the column data with the set of persistent segments, returns the amount of rows
	void Initialize(vector<unique_ptr<PersistentSegment>> &segments);

	//! The type of the column
	TypeId type;
	//! The table of the column
	DataTable *table;
	//! The column index of the column
	idx_t column_idx;
	//! The segments holding the data of the column
	SegmentTree data;
	//! The amount of persistent rows
	idx_t persistent_rows;

public:
	//! Initialize a scan of the column
	void InitializeScan(ColumnScanState &state);
	//! Scan the next vector from the column
	void Scan(Transaction &transaction, ColumnScanState &state, Vector &result);
	//! Scan the next vector from the column, throwing an exception if there are any outstanding updates
	void IndexScan(ColumnScanState &state, Vector &result);

	//! Initialize an appending phase for this column
	void InitializeAppend(ColumnAppendState &state);
	//! Append a vector of type [type] to the end of the column
	void Append(ColumnAppendState &state, Vector &vector, idx_t count);
	//! Revert a set of appends to the ColumnData
	void RevertAppend(row_t start_row);

	//! Update the specified row identifiers
	void Update(Transaction &transaction, Vector &updates, Vector &row_ids, idx_t count);

	//! Fetch the vector from the column data that belongs to this specific row
	void Fetch(ColumnScanState &state, row_t row_id, Vector &result);
	//! Fetch a specific row id and append it to the vector
	void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result, idx_t result_idx);

private:
	//! Append a transient segment
	void AppendTransientSegment(idx_t start_row);
};

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/version_manager.hpp
//
//
//===----------------------------------------------------------------------===//







//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/chunk_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
struct SelectionVector;
class Transaction;
class VersionManager;

enum class ChunkInfoType : uint8_t { DELETE_INFO, INSERT_INFO };

class ChunkInfo {
public:
	ChunkInfo(VersionManager &manager, idx_t start_row, ChunkInfoType type)
	    : manager(manager), start(start_row), type(type) {
	}
	virtual ~ChunkInfo() {
	}

	//! The version manager
	VersionManager &manager;
	//! The start row of the chunk
	idx_t start;
	//! The ChunkInfo type
	ChunkInfoType type;

public:
	virtual idx_t GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) = 0;
	//! Returns whether or not a single row in the ChunkInfo should be used or not for the given transaction
	virtual bool Fetch(Transaction &transaction, row_t row) = 0;
	//! Marks the set of tuples inside the chunk as deleted
	virtual void Delete(Transaction &transaction, row_t rows[], idx_t count) = 0;
	//! Mark the rows as committed
	virtual void CommitDelete(transaction_t commit_id, row_t rows[], idx_t count) = 0;
};

class ChunkDeleteInfo : public ChunkInfo {
public:
	ChunkDeleteInfo(VersionManager &manager, idx_t start_row, ChunkInfoType type = ChunkInfoType::DELETE_INFO);
	ChunkDeleteInfo(ChunkDeleteInfo &info, ChunkInfoType type);

	//! The transaction ids of the transactions that deleted the tuples (if any)
	transaction_t deleted[STANDARD_VECTOR_SIZE];

public:
	idx_t GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) override;
	bool Fetch(Transaction &transaction, row_t row) override;

	void Delete(Transaction &transaction, row_t rows[], idx_t count) override;
	void CommitDelete(transaction_t commit_id, row_t rows[], idx_t count) override;
};

class ChunkInsertInfo : public ChunkDeleteInfo {
public:
	ChunkInsertInfo(VersionManager &manager, idx_t start_row);
	ChunkInsertInfo(ChunkDeleteInfo &info);

	//! The transaction ids of the transactions that inserted the tuples (if any)
	transaction_t inserted[STANDARD_VECTOR_SIZE];

public:
	idx_t GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) override;
	bool Fetch(Transaction &transaction, row_t row) override;
};

} // namespace duckdb



namespace duckdb {
class DataTable;
class Transaction;
class VersionManager;

class VersionManager {
public:
	VersionManager(DataTable &table) : table(table), max_row(0), base_row(0) {
	}

	//! The DataTable
	DataTable &table;
	//! The read/write lock for the delete info and insert info
	StorageLock lock;
	//! The info for each of the chunks
	unordered_map<idx_t, unique_ptr<ChunkInfo>> info;
	//! The maximum amount of rows managed by the version manager
	idx_t max_row;
	//! The base row of the version manager, i.e. when passing row = base_row, it will be treated as row = 0
	idx_t base_row;

public:
	//! For a given chunk index, fills the selection vector with the relevant tuples for a given transaction. If count
	//! == max_count, all tuples are relevant and the selection vector is not set
	idx_t GetSelVector(Transaction &transaction, idx_t index, SelectionVector &sel_vector, idx_t max_count);

	//! Fetch a specific row from the VersionManager, returns true if the row should be used for the transaction and
	//! false otherwise.
	bool Fetch(Transaction &transaction, idx_t row);

	//! Delete the given set of rows in the version manager
	void Delete(Transaction &transaction, Vector &row_ids, idx_t count);
	//! Append a set of rows to the version manager, setting their inserted id to the given commit_id
	void Append(Transaction &transaction, row_t row_start, idx_t count, transaction_t commit_id);
	//! Revert a set of appends made to the version manager from the rows [row_start] until [row_end]
	void RevertAppend(row_t row_start, row_t row_end);

private:
	ChunkInsertInfo *GetInsertInfo(idx_t chunk_idx);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/local_storage.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class DataTable;
class WriteAheadLog;
struct TableAppendState;

class LocalTableStorage {
public:
	LocalTableStorage(DataTable &table);
	~LocalTableStorage();

	//! The main chunk collection holding the data
	ChunkCollection collection;
	//! The set of unique indexes
	vector<unique_ptr<Index>> indexes;
	//! The set of deleted entries
	unordered_map<idx_t, unique_ptr<bool[]>> deleted_entries;
	//! The max row
	row_t max_row;

public:
	void InitializeScan(LocalScanState &state);

	void Clear();
};

//! The LocalStorage class holds appends that have not been committed yet
class LocalStorage {
public:
	struct CommitState {
		unordered_map<DataTable *, unique_ptr<TableAppendState>> append_states;
	};

public:
	//! Initialize a scan of the local storage
	void InitializeScan(DataTable *table, LocalScanState &state);
	//! Scan
	void Scan(LocalScanState &state, const vector<column_t> &column_ids, DataChunk &result);

	//! Append a chunk to the local storage
	void Append(DataTable *table, DataChunk &chunk);
	//! Delete a set of rows from the local storage
	void Delete(DataTable *table, Vector &row_ids, idx_t count);
	//! Update a set of rows in the local storage
	void Update(DataTable *table, Vector &row_ids, vector<column_t> &column_ids, DataChunk &data);

	//! Commits the local storage, writing it to the WAL and completing the commit
	void Commit(LocalStorage::CommitState &commit_state, Transaction &transaction, WriteAheadLog *log,
	            transaction_t commit_id);
	//! Revert the commit made so far by the LocalStorage
	void RevertCommit(LocalStorage::CommitState &commit_state);

	bool ChangesMade() noexcept {
		return table_storage.size() > 0;
	}

private:
	LocalTableStorage *GetStorage(DataTable *table);

	template <class T> bool ScanTableStorage(DataTable *table, LocalTableStorage *storage, T &&fun);

private:
	unordered_map<DataTable *, unique_ptr<LocalTableStorage>> table_storage;
};

} // namespace duckdb


#include <atomic>
#include <mutex>
#include <vector>

namespace duckdb {
class ClientContext;
class ColumnDefinition;
class StorageManager;
class TableCatalogEntry;
class Transaction;

typedef unique_ptr<vector<unique_ptr<PersistentSegment>>[]> persistent_data_t;
//! TableFilter represents a filter pushed down into the table scan.
class TableFilter {
public:
	TableFilter(Value constant, ExpressionType comparison_type, idx_t column_index)
	    : constant(constant), comparison_type(comparison_type), column_index(column_index){};
	Value constant;
	ExpressionType comparison_type;
	idx_t column_index;
};

//! DataTable represents a physical table on disk
class DataTable {
public:
	DataTable(StorageManager &storage, string schema, string table, vector<TypeId> types, persistent_data_t data);

	//! The amount of elements in the table. Note that this number signifies the amount of COMMITTED entries in the
	//! table. It can be inaccurate inside of transactions. More work is needed to properly support that.
	std::atomic<idx_t> cardinality;
	// schema of the table
	string schema;
	// name of the table
	string table;
	//! Types managed by data table
	vector<TypeId> types;
	//! A reference to the base storage manager
	StorageManager &storage;
	//! Indexes
	vector<unique_ptr<Index>> indexes;

public:
	void InitializeScan(TableScanState &state, vector<column_t> column_ids);
	void InitializeScan(Transaction &transaction, TableScanState &state, vector<column_t> column_ids);
	//! Scans up to STANDARD_VECTOR_SIZE elements from the table starting
	// from offset and store them in result. Offset is incremented with how many
	// elements were returned.
	void Scan(Transaction &transaction, DataChunk &result, TableScanState &state, vector<TableFilter> &table_filters);

	//! Initialize an index scan with a single predicate and a comparison type (= <= < > >=)
	void InitializeIndexScan(Transaction &transaction, TableIndexScanState &state, Index &index, Value value,
	                         ExpressionType expr_type, vector<column_t> column_ids);
	//! Initialize an index scan with two predicates and two comparison types (> >= < <=)
	void InitializeIndexScan(Transaction &transaction, TableIndexScanState &state, Index &index, Value low_value,
	                         ExpressionType low_type, Value high_value, ExpressionType high_type,
	                         vector<column_t> column_ids);
	//! Scans up to STANDARD_VECTOR_SIZE elements from the table from the given index structure
	void IndexScan(Transaction &transaction, DataChunk &result, TableIndexScanState &state);

	//! Fetch data from the specific row identifiers from the base table
	void Fetch(Transaction &transaction, DataChunk &result, vector<column_t> &column_ids, Vector &row_ids,
	           idx_t fetch_count, TableIndexScanState &state);

	//! Append a DataChunk to the table. Throws an exception if the columns don't match the tables' columns.
	void Append(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk);
	//! Delete the entries with the specified row identifier from the table
	void Delete(TableCatalogEntry &table, ClientContext &context, Vector &row_ids, idx_t count);
	//! Update the entries with the specified row identifier from the table
	void Update(TableCatalogEntry &table, ClientContext &context, Vector &row_ids, vector<column_t> &column_ids,
	            DataChunk &data);

	//! Add an index to the DataTable
	void AddIndex(unique_ptr<Index> index, vector<unique_ptr<Expression>> &expressions);

	//! Begin appending structs to this table, obtaining necessary locks, etc
	void InitializeAppend(TableAppendState &state);
	//! Append a chunk to the table using the AppendState obtained from BeginAppend
	void Append(Transaction &transaction, transaction_t commit_id, DataChunk &chunk, TableAppendState &state);
	//! Revert a set of appends made by the given AppendState, used to revert appends in the event of an error during
	//! commit (e.g. because of an I/O exception)
	void RevertAppend(TableAppendState &state);

	//! Append a chunk with the row ids [row_start, ..., row_start + chunk.size()] to all indexes of the table, returns
	//! whether or not the append succeeded
	bool AppendToIndexes(TableAppendState &state, DataChunk &chunk, row_t row_start);
	//! Remove a chunk with the row ids [row_start, ..., row_start + chunk.size()] from all indexes of the table
	void RemoveFromIndexes(TableAppendState &state, DataChunk &chunk, row_t row_start);
	//! Remove the chunk with the specified set of row identifiers from all indexes of the table
	void RemoveFromIndexes(TableAppendState &state, DataChunk &chunk, Vector &row_identifiers);
	//! Remove the row identifiers from all the indexes of the table
	void RemoveFromIndexes(Vector &row_identifiers, idx_t count);
	//! Is this a temporary table?
	bool IsTemporary();

private:
	//! Verify constraints with a chunk from the Append containing all columns of the table
	void VerifyAppendConstraints(TableCatalogEntry &table, DataChunk &chunk);
	//! Verify constraints with a chunk from the Update containing only the specified column_ids
	void VerifyUpdateConstraints(TableCatalogEntry &table, DataChunk &chunk, vector<column_t> &column_ids);

	void InitializeIndexScan(Transaction &transaction, TableIndexScanState &state, Index &index,
	                         vector<column_t> column_ids);

	bool CheckZonemap(TableScanState &state, vector<TableFilter> &table_filters, idx_t &current_row);
	bool ScanBaseTable(Transaction &transaction, DataChunk &result, TableScanState &state, idx_t &current_row,
	                   idx_t max_row, idx_t base_row, VersionManager &manager, vector<TableFilter> &table_filters);
	bool ScanCreateIndex(CreateIndexScanState &state, DataChunk &result, idx_t &current_row, idx_t max_row,
	                     idx_t base_row);

	//! Figure out which of the row ids to use for the given transaction by looking at inserted/deleted data. Returns
	//! the amount of rows to use and places the row_ids in the result_rows array.
	idx_t FetchRows(Transaction &transaction, Vector &row_identifiers, idx_t fetch_count, row_t result_rows[]);

	//! The CreateIndexScan is a special scan that is used to create an index on the table, it keeps locks on the table
	void InitializeCreateIndexScan(CreateIndexScanState &state, vector<column_t> column_ids);
	void CreateIndexScan(CreateIndexScanState &structure, DataChunk &result);
	//! Lock for appending entries to the table
	std::mutex append_lock;
	//! The version manager of the persistent segments of the tree
	VersionManager persistent_manager;
	//! The version manager of the transient segments of the tree
	VersionManager transient_manager;
	//! The physical columns of the table
	unique_ptr<ColumnData[]> columns;
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/write_ahead_log.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/wal_type.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

enum class WALType : uint8_t {
	INVALID = 0,
	// -----------------------------
	// Catalog
	// -----------------------------
	CREATE_TABLE = 1,
	DROP_TABLE = 2,

	CREATE_SCHEMA = 3,
	DROP_SCHEMA = 4,

	CREATE_VIEW = 5,
	DROP_VIEW = 6,

	CREATE_SEQUENCE = 8,
	DROP_SEQUENCE = 9,
	SEQUENCE_VALUE = 10,

	ALTER_INFO = 20,
	// -----------------------------
	// Data
	// -----------------------------
	USE_TABLE = 25,
	INSERT_TUPLE = 26,
	DELETE_TUPLE = 27,
	UPDATE_TUPLE = 28,
	// -----------------------------
	// Flush
	// -----------------------------
	WAL_FLUSH = 100
};

}

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/serializer/buffered_file_writer.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

#define FILE_BUFFER_SIZE 4096

class BufferedFileWriter : public Serializer {
public:
	//! Serializes to a buffer allocated by the serializer, will expand when
	//! writing past the initial threshold
	BufferedFileWriter(FileSystem &fs, const char *path, bool append = false);

	FileSystem &fs;
	unique_ptr<data_t[]> data;
	idx_t offset;
	unique_ptr<FileHandle> handle;

public:
	void WriteData(const_data_ptr_t buffer, uint64_t write_size) override;
	//! Flush the buffer to disk and sync the file to ensure writing is completed
	void Sync();
	//! Returns the current size of the file
	int64_t GetFileSize();
	//! Truncate the size to a previous size (given that size <= GetFileSize())
	void Truncate(int64_t size);

private:
	//! Flush the buffer to the file
	void Flush();
};

} // namespace duckdb



namespace duckdb {

struct AlterInfo;

class BufferedSerializer;
class Catalog;
class DuckDB;
class SchemaCatalogEntry;
class SequenceCatalogEntry;
class ViewCatalogEntry;
class TableCatalogEntry;
class Transaction;
class TransactionManager;

//! The WriteAheadLog (WAL) is a log that is used to provide durability. Prior
//! to committing a transaction it writes the changes the transaction made to
//! the database to the log, which can then be replayed upon startup in case the
//! server crashes or is shut down.
class WriteAheadLog {
public:
	WriteAheadLog(DuckDB &database);

	//! Whether or not the WAL has been initialized
	bool initialized;

public:
	//! Replay the WAL
	static void Replay(DuckDB &database, string &path);

	//! Initialize the WAL in the specified directory
	void Initialize(string &path);
	//! Returns the current size of the WAL in bytes
	int64_t GetWALSize();

	void WriteCreateTable(TableCatalogEntry *entry);
	void WriteDropTable(TableCatalogEntry *entry);

	void WriteCreateSchema(SchemaCatalogEntry *entry);
	void WriteDropSchema(SchemaCatalogEntry *entry);

	void WriteCreateView(ViewCatalogEntry *entry);
	void WriteDropView(ViewCatalogEntry *entry);

	void WriteCreateSequence(SequenceCatalogEntry *entry);
	void WriteDropSequence(SequenceCatalogEntry *entry);
	void WriteSequenceValue(SequenceCatalogEntry *entry, SequenceValue val);

	//! Sets the table used for subsequent insert/delete/update commands
	void WriteSetTable(string &schema, string &table);

	void WriteAlter(AlterInfo &info);

	void WriteInsert(DataChunk &chunk);
	void WriteDelete(DataChunk &chunk);
	void WriteUpdate(DataChunk &chunk, column_t col_idx);

	//! Truncate the WAL to a previous size, and clear anything currently set in the writer
	void Truncate(int64_t size);
	void Flush();

private:
	DuckDB &database;
	unique_ptr<BufferedFileWriter> writer;
};

} // namespace duckdb


namespace duckdb {
class BlockManager;
class Catalog;
class DuckDB;
class TransactionManager;
class TableCatalogEntry;

//! StorageManager is responsible for managing the physical storage of the
//! database on disk
class StorageManager {
public:
	StorageManager(DuckDB &database, string path, bool read_only);
	~StorageManager();

	//! Initialize a database or load an existing database from the given path
	void Initialize();
	//! Get the WAL of the StorageManager, returns nullptr if in-memory
	WriteAheadLog *GetWriteAheadLog() {
		return wal.initialized ? &wal : nullptr;
	}

	DuckDB &GetDatabase() {
		return database;
	}
	//! The BlockManager to read/store meta information and data in blocks
	unique_ptr<BlockManager> block_manager;
	//! The BufferManager of the database
	unique_ptr<BufferManager> buffer_manager;
	//! The database this storagemanager belongs to
	DuckDB &database;

private:
	//! Load the database from a directory
	void LoadDatabase();
	//! Create a checkpoint of the database
	void Checkpoint(string wal_path);

	//! The path of the database
	string path;
	//! The WriteAheadLog of the storage manager
	WriteAheadLog wal;

	//! Whether or not the database is opened in read-only mode
	bool read_only;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

Catalog::Catalog(StorageManager &storage) : storage(storage), schemas(*this), dependency_manager(*this) {
}

Catalog &Catalog::GetCatalog(ClientContext &context) {
	return context.catalog;
}

CatalogEntry *Catalog::CreateTable(ClientContext &context, BoundCreateTableInfo *info) {
	auto schema = GetSchema(context, info->base->schema);
	return schema->CreateTable(context, info);
}

CatalogEntry *Catalog::CreateView(ClientContext &context, CreateViewInfo *info) {
	auto schema = GetSchema(context, info->schema);
	return schema->CreateView(context, info);
}

CatalogEntry *Catalog::CreateSequence(ClientContext &context, CreateSequenceInfo *info) {
	auto schema = GetSchema(context, info->schema);
	return schema->CreateSequence(context, info);
}

CatalogEntry *Catalog::CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info) {
	auto schema = GetSchema(context, info->schema);
	return schema->CreateTableFunction(context, info);
}

CatalogEntry *Catalog::CreateFunction(ClientContext &context, CreateFunctionInfo *info) {
	auto schema = GetSchema(context, info->schema);
	return schema->CreateFunction(context, info);
}

CatalogEntry *Catalog::CreateSchema(ClientContext &context, CreateSchemaInfo *info) {
	if (info->schema == INVALID_SCHEMA) {
		throw CatalogException("Schema not specified");
	}
	if (info->schema == TEMP_SCHEMA) {
		throw CatalogException("Cannot create built-in schema \"%s\"", info->schema.c_str());
	}

	unordered_set<CatalogEntry *> dependencies;
	auto entry = make_unique<SchemaCatalogEntry>(this, info->schema);
	auto result = entry.get();
	if (!schemas.CreateEntry(context.ActiveTransaction(), info->schema, move(entry), dependencies)) {
		if (info->on_conflict == OnCreateConflict::ERROR) {
			throw CatalogException("Schema with name %s already exists!", info->schema.c_str());
		} else {
			assert(info->on_conflict == OnCreateConflict::IGNORE);
		}
		return nullptr;
	}
	return result;
}

void Catalog::DropSchema(ClientContext &context, DropInfo *info) {
	if (info->name == INVALID_SCHEMA) {
		throw CatalogException("Schema not specified");
	}
	if (info->name == DEFAULT_SCHEMA || info->name == TEMP_SCHEMA) {
		throw CatalogException("Cannot drop schema \"%s\" because it is required by the database system",
		                       info->name.c_str());
	}

	if (!schemas.DropEntry(context.ActiveTransaction(), info->name, info->cascade)) {
		if (!info->if_exists) {
			throw CatalogException("Schema with name \"%s\" does not exist!", info->name.c_str());
		}
	}
}

void Catalog::DropEntry(ClientContext &context, DropInfo *info) {
	if (info->type == CatalogType::SCHEMA) {
		// DROP SCHEMA
		DropSchema(context, info);
	} else {
		if (info->schema == INVALID_SCHEMA) {
			// invalid schema: check if the entry is in the temp schema
			auto entry = GetEntry(context, info->type, TEMP_SCHEMA, info->name, true);
			info->schema = entry ? TEMP_SCHEMA : DEFAULT_SCHEMA;
		}
		auto schema = GetSchema(context, info->schema);
		schema->DropEntry(context, info);
	}
}

SchemaCatalogEntry *Catalog::GetSchema(ClientContext &context, const string &schema_name) {
	if (schema_name == INVALID_SCHEMA) {
		throw CatalogException("Schema not specified");
	}
	if (schema_name == TEMP_SCHEMA) {
		return context.temporary_objects.get();
	}
	auto entry = schemas.GetEntry(context.ActiveTransaction(), schema_name);
	if (!entry) {
		throw CatalogException("Schema with name %s does not exist!", schema_name.c_str());
	}
	return (SchemaCatalogEntry *)entry;
}

CatalogEntry *Catalog::GetEntry(ClientContext &context, CatalogType type, string schema_name, const string &name,
                                bool if_exists) {
	if (schema_name == INVALID_SCHEMA) {
		// invalid schema: first search the temporary schema
		auto entry = GetEntry(context, type, TEMP_SCHEMA, name, true);
		if (entry) {
			return entry;
		}
		// if the entry does not exist in the temp schema, search in the default schema
		schema_name = DEFAULT_SCHEMA;
	}
	auto schema = GetSchema(context, schema_name);
	return schema->GetEntry(context, type, name, if_exists);
}

template <>
TableCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name, bool if_exists) {
	auto entry = GetEntry(context, CatalogType::TABLE, move(schema_name), name, if_exists);
	if (!entry) {
		return nullptr;
	}
	if (entry->type != CatalogType::TABLE) {
		throw CatalogException("%s is not a table", name.c_str());
	}
	return (TableCatalogEntry *)entry;
}

template <>
SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
                                        bool if_exists) {
	return (SequenceCatalogEntry *)GetEntry(context, CatalogType::SEQUENCE, move(schema_name), name, if_exists);
}

template <>
TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
                                             bool if_exists) {
	return (TableFunctionCatalogEntry *)GetEntry(context, CatalogType::TABLE_FUNCTION, move(schema_name), name,
	                                             if_exists);
}

template <>
AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
                                                 bool if_exists) {
	auto entry = GetEntry(context, CatalogType::AGGREGATE_FUNCTION, move(schema_name), name, if_exists);
	if (entry->type != CatalogType::AGGREGATE_FUNCTION) {
		throw CatalogException("%s is not an aggregate function", name.c_str());
	}
	return (AggregateFunctionCatalogEntry *)entry;
}

void Catalog::AlterTable(ClientContext &context, AlterTableInfo *info) {
	if (info->schema == INVALID_SCHEMA) {
		// invalid schema, look for table in temp schema
		auto entry = GetEntry(context, CatalogType::TABLE, TEMP_SCHEMA, info->table, true);
		info->schema = entry ? TEMP_SCHEMA : DEFAULT_SCHEMA;
	}
	auto schema = GetSchema(context, info->schema);
	schema->AlterTable(context, info);
}

void Catalog::ParseRangeVar(string input, string &schema, string &name) {
	idx_t idx = 0;
	vector<string> entries;
	string entry;
normal:
	// quote
	for (; idx < input.size(); idx++) {
		if (input[idx] == '"') {
			idx++;
			goto quoted;
		} else if (input[idx] == '.') {
			goto separator;
		}
		entry += input[idx];
	}
	goto end;
separator:
	entries.push_back(entry);
	entry = "";
	idx++;
	goto normal;
quoted:
	// look for another quote
	for (; idx < input.size(); idx++) {
		if (input[idx] == '"') {
			// unquote
			idx++;
			goto normal;
		}
		entry += input[idx];
	}
	throw ParserException("Unterminated quote in range var!");
end:
	if (entries.size() == 0) {
		schema = INVALID_SCHEMA;
		name = entry;
	} else if (entries.size() == 1) {
		schema = entries[0];
		name = entry;
	} else {
		throw ParserException("Expected schema.entry or entry: too many entries found");
	}
}




















//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/transaction.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/undo_buffer.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/undo_flags.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

enum class UndoFlags : uint8_t {
	EMPTY_ENTRY = 0,
	CATALOG_ENTRY = 1,
	INSERT_TUPLE = 2,
	DELETE_TUPLE = 3,
	UPDATE_TUPLE = 4
};

} // namespace duckdb


#include <memory>
#include <vector>

namespace duckdb {

class WriteAheadLog;

struct UndoChunk {
	UndoChunk(idx_t size);
	~UndoChunk();

	data_ptr_t WriteEntry(UndoFlags type, uint32_t len);

	unique_ptr<data_t[]> data;
	idx_t current_position;
	idx_t maximum_size;
	unique_ptr<UndoChunk> next;
	UndoChunk *prev;
};

//! The undo buffer of a transaction is used to hold previous versions of tuples
//! that might be required in the future (because of rollbacks or previous
//! transactions accessing them)
class UndoBuffer {
public:
	struct IteratorState {
		UndoChunk *current;
		data_ptr_t start;
		data_ptr_t end;
	};

public:
	UndoBuffer();

	//! Reserve space for an entry of the specified type and length in the undo
	//! buffer
	data_ptr_t CreateEntry(UndoFlags type, idx_t len);

	bool ChangesMade();

	//! Cleanup the undo buffer
	void Cleanup();
	//! Commit the changes made in the UndoBuffer: should be called on commit
	void Commit(UndoBuffer::IteratorState &iterator_state, WriteAheadLog *log, transaction_t commit_id);
	//! Revert committed changes made in the UndoBuffer up until the currently committed state
	void RevertCommit(UndoBuffer::IteratorState &iterator_state, transaction_t transaction_id);
	//! Rollback the changes made in this UndoBuffer: should be called on
	//! rollback
	void Rollback() noexcept;

private:
	unique_ptr<UndoChunk> head;
	UndoChunk *tail;

private:
	template <class T> void IterateEntries(UndoBuffer::IteratorState &state, T &&callback);
	template <class T>
	void IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback);
	template <class T> void ReverseIterateEntries(T &&callback);
};

} // namespace duckdb



namespace duckdb {
class SequenceCatalogEntry;

class ClientContext;
class CatalogEntry;
class DataTable;
class WriteAheadLog;

class ChunkInfo;

struct DeleteInfo;
struct UpdateInfo;

//! The transaction object holds information about a currently running or past
//! transaction

class Transaction {
public:
	Transaction(transaction_t start_time, transaction_t transaction_id, timestamp_t start_timestamp)
	    : start_time(start_time), transaction_id(transaction_id), commit_id(0), highest_active_query(0),
	      active_query(MAXIMUM_QUERY_ID), start_timestamp(start_timestamp), is_invalidated(false) {
	}

	//! The start timestamp of this transaction
	transaction_t start_time;
	//! The transaction id of this transaction
	transaction_t transaction_id;
	//! The commit id of this transaction, if it has successfully been committed
	transaction_t commit_id;
	//! Highest active query when the transaction finished, used for cleaning up
	transaction_t highest_active_query;
	//! The current active query for the transaction. Set to MAXIMUM_QUERY_ID if
	//! no query is active.
	transaction_t active_query;
	//! The timestamp when the transaction started
	timestamp_t start_timestamp;
	//! The set of uncommitted appends for the transaction
	LocalStorage storage;
	//! Map of all sequences that were used during the transaction and the value they had in this transaction
	unordered_map<SequenceCatalogEntry *, SequenceValue> sequence_usage;
	//! Whether or not the transaction has been invalidated
	bool is_invalidated;

public:
	static Transaction &GetTransaction(ClientContext &context);

	void PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data = nullptr, idx_t extra_data_size = 0);

	//! Commit the current transaction with the given commit identifier. Returns an error message if the transaction
	//! commit failed, or an empty string if the commit was sucessful
	string Commit(WriteAheadLog *log, transaction_t commit_id) noexcept;
	//! Rollback
	void Rollback() noexcept {
		undo_buffer.Rollback();
	}
	//! Cleanup the undo buffer
	void Cleanup() {
		undo_buffer.Cleanup();
	}

	timestamp_t GetCurrentTransactionStartTimestamp() {
		return start_timestamp;
	}

	void PushDelete(ChunkInfo *vinfo, row_t rows[], idx_t count, idx_t base_row);

	UpdateInfo *CreateUpdateInfo(idx_t type_size, idx_t entries);
private:
	//! The undo buffer is used to store old versions of rows that are updated
	//! or deleted
	UndoBuffer undo_buffer;

	Transaction(const Transaction &) = delete;
};

} // namespace duckdb


#include <algorithm>

using namespace duckdb;
using namespace std;

SchemaCatalogEntry::SchemaCatalogEntry(Catalog *catalog, string name)
    : CatalogEntry(CatalogType::SCHEMA, catalog, name), tables(*catalog), indexes(*catalog), table_functions(*catalog),
      functions(*catalog), sequences(*catalog) {
}

CatalogEntry *SchemaCatalogEntry::AddEntry(ClientContext &context, unique_ptr<StandardEntry> entry,
                                           OnCreateConflict on_conflict, unordered_set<CatalogEntry *> dependencies) {
	auto entry_name = entry->name;
	auto entry_type = entry->type;
	auto result = entry.get();
	auto &transaction = Transaction::GetTransaction(context);

	// first find the set for this entry
	auto &set = GetCatalogSet(entry_type);

	if (name != TEMP_SCHEMA) {
		dependencies.insert(this);
	} else {
		entry->temporary = true;
	}
	if (on_conflict == OnCreateConflict::REPLACE) {
		// CREATE OR REPLACE: first try to drop the entry
		auto old_entry = set.GetEntry(transaction, entry_name);
		if (old_entry) {
			if (old_entry->type != entry_type) {
				throw CatalogException("Existing object %s is of type %s, trying to replace with type %s",
				                       entry_name.c_str(), CatalogTypeToString(old_entry->type).c_str(),
				                       CatalogTypeToString(entry_type).c_str());
			}
			(void)set.DropEntry(transaction, entry_name, false);
		}
	}
	// now try to add the entry
	if (!set.CreateEntry(transaction, entry_name, move(entry), dependencies)) {
		// entry already exists!
		if (on_conflict == OnCreateConflict::ERROR) {
			throw CatalogException("%s with name \"%s\" already exists!", CatalogTypeToString(entry_type).c_str(),
			                       entry_name.c_str());
		} else {
			return nullptr;
		}
	}
	return result;
}

CatalogEntry *SchemaCatalogEntry::AddEntry(ClientContext &context, unique_ptr<StandardEntry> entry,
                                           OnCreateConflict on_conflict) {
	unordered_set<CatalogEntry *> dependencies;
	return AddEntry(context, move(entry), on_conflict, dependencies);
}

CatalogEntry *SchemaCatalogEntry::CreateSequence(ClientContext &context, CreateSequenceInfo *info) {
	auto sequence = make_unique<SequenceCatalogEntry>(catalog, this, info);
	return AddEntry(context, move(sequence), info->on_conflict);
}

CatalogEntry *SchemaCatalogEntry::CreateTable(ClientContext &context, BoundCreateTableInfo *info) {
	auto table = make_unique<TableCatalogEntry>(catalog, this, info);
	return AddEntry(context, move(table), info->Base().on_conflict, info->dependencies);
}

CatalogEntry *SchemaCatalogEntry::CreateView(ClientContext &context, CreateViewInfo *info) {
	auto view = make_unique<ViewCatalogEntry>(catalog, this, info);
	return AddEntry(context, move(view), info->on_conflict);
}

CatalogEntry *SchemaCatalogEntry::CreateIndex(ClientContext &context, CreateIndexInfo *info) {
	auto index = make_unique<IndexCatalogEntry>(catalog, this, info);
	return AddEntry(context, move(index), info->on_conflict);
}

CatalogEntry *SchemaCatalogEntry::CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info) {
	auto table_function = make_unique<TableFunctionCatalogEntry>(catalog, this, info);
	return AddEntry(context, move(table_function), info->on_conflict);
}

CatalogEntry *SchemaCatalogEntry::CreateFunction(ClientContext &context, CreateFunctionInfo *info) {
	unique_ptr<StandardEntry> function;
	if (info->type == CatalogType::SCALAR_FUNCTION) {
		// create a scalar function
		function = make_unique_base<StandardEntry, ScalarFunctionCatalogEntry>(catalog, this,
		                                                                       (CreateScalarFunctionInfo *)info);
	} else {
		assert(info->type == CatalogType::AGGREGATE_FUNCTION);
		// create an aggregate function
		function = make_unique_base<StandardEntry, AggregateFunctionCatalogEntry>(catalog, this,
		                                                                          (CreateAggregateFunctionInfo *)info);
	}
	return AddEntry(context, move(function), info->on_conflict);
}

void SchemaCatalogEntry::DropEntry(ClientContext &context, DropInfo *info) {
	auto &set = GetCatalogSet(info->type);
	auto &transaction = Transaction::GetTransaction(context);

	// first find the entry
	auto existing_entry = set.GetEntry(transaction, info->name);
	if (!existing_entry) {
		if (!info->if_exists) {
			throw CatalogException("%s with name \"%s\" does not exist!", CatalogTypeToString(info->type).c_str(),
			                       info->name.c_str());
		}
		return;
	}
	if (existing_entry->type != info->type) {
		throw CatalogException("Existing object %s is of type %s, trying to replace with type %s", info->name.c_str(),
		                       CatalogTypeToString(existing_entry->type).c_str(),
		                       CatalogTypeToString(info->type).c_str());
	}
	if (!set.DropEntry(transaction, info->name, info->cascade)) {
		throw InternalException("Could not drop element because of an internal error");
	}
}

void SchemaCatalogEntry::AlterTable(ClientContext &context, AlterTableInfo *info) {
    switch (info->alter_table_type)	{
        case AlterTableType::RENAME_TABLE: {
            auto &transaction = Transaction::GetTransaction(context);
            auto entry = tables.GetEntry(transaction, info->table);
            if(entry == nullptr) {
                throw CatalogException("Table \"%s\" doesn't exist!", info->table.c_str());
            }
            assert(entry->type == CatalogType::TABLE);

            auto copied_entry = entry->Copy(context);

            // Drop the old table entry
            if (!tables.DropEntry(transaction, info->table, false)) {
                throw CatalogException("Could not drop \"%s\" entry!", info->table.c_str());
            }

            // Create a new table entry
            auto &new_table = ((RenameTableInfo *)info)->new_table_name;
            unordered_set<CatalogEntry *> dependencies;
            copied_entry->name = new_table;
            if (!tables.CreateEntry(transaction, new_table, move(copied_entry), dependencies)) {
                throw CatalogException("Could not create \"%s\" entry!", new_table.c_str());
            }
            break;
        }
        default:
            if (!tables.AlterEntry(context, info->table, info)) {
                throw CatalogException("Table with name \"%s\" does not exist!", info->table.c_str());
            }
    } // end switch
}

CatalogEntry *SchemaCatalogEntry::GetEntry(ClientContext &context, CatalogType type, const string &name,
                                           bool if_exists) {
	auto &set = GetCatalogSet(type);
	auto &transaction = Transaction::GetTransaction(context);

	auto entry = set.GetEntry(transaction, name);
	if (!entry) {
		if (!if_exists) {
			throw CatalogException("%s with name %s does not exist!", CatalogTypeToString(type).c_str(), name.c_str());
		}
		return nullptr;
	}
	return entry;
}

void SchemaCatalogEntry::Serialize(Serializer &serializer) {
	serializer.WriteString(name);
}

unique_ptr<CreateSchemaInfo> SchemaCatalogEntry::Deserialize(Deserializer &source) {
	auto info = make_unique<CreateSchemaInfo>();
	info->schema = source.Read<string>();
	return info;
}

CatalogSet &SchemaCatalogEntry::GetCatalogSet(CatalogType type) {
	switch (type) {
	case CatalogType::VIEW:
	case CatalogType::TABLE:
		return tables;
	case CatalogType::INDEX:
		return indexes;
	case CatalogType::TABLE_FUNCTION:
		return table_functions;
	case CatalogType::AGGREGATE_FUNCTION:
	case CatalogType::SCALAR_FUNCTION:
		return functions;
	case CatalogType::SEQUENCE:
		return sequences;
	default:
		throw CatalogException("Unsupported catalog type in schema");
	}
}







#include <algorithm>

using namespace duckdb;
using namespace std;

SequenceCatalogEntry::SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info)
    : StandardEntry(CatalogType::SEQUENCE, schema, catalog, info->name), usage_count(info->usage_count),
      counter(info->start_value), increment(info->increment), start_value(info->start_value),
      min_value(info->min_value), max_value(info->max_value), cycle(info->cycle) {
	this->temporary = info->temporary;
}

void SequenceCatalogEntry::Serialize(Serializer &serializer) {
	serializer.WriteString(schema->name);
	serializer.WriteString(name);
	// serializer.Write<int64_t>(counter);
	serializer.Write<uint64_t>(usage_count);
	serializer.Write<int64_t>(increment);
	serializer.Write<int64_t>(min_value);
	serializer.Write<int64_t>(max_value);
	serializer.Write<int64_t>(counter);
	serializer.Write<bool>(cycle);
}

unique_ptr<CreateSequenceInfo> SequenceCatalogEntry::Deserialize(Deserializer &source) {
	auto info = make_unique<CreateSequenceInfo>();
	info->schema = source.Read<string>();
	info->name = source.Read<string>();
	// info->counter = source.Read<int64_t>();
	info->usage_count = source.Read<uint64_t>();
	info->increment = source.Read<int64_t>();
	info->min_value = source.Read<int64_t>();
	info->max_value = source.Read<int64_t>();
	info->start_value = source.Read<int64_t>();
	info->cycle = source.Read<bool>();
	return info;
}








//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/constraints/check_constraint.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! The CheckConstraint contains an expression that must evaluate to TRUE for
//! every row in a table
class CheckConstraint : public Constraint {
public:
	CheckConstraint(unique_ptr<ParsedExpression> expression)
	    : Constraint(ConstraintType::CHECK), expression(move(expression)){};

	unique_ptr<ParsedExpression> expression;

public:
	string ToString() const override;

	unique_ptr<Constraint> Copy() override;

	//! Serialize to a stand-alone binary blob
	void Serialize(Serializer &serializer) override;
	//! Deserializes a CheckConstraint
	static unique_ptr<Constraint> Deserialize(Deserializer &source);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/constraints/not_null_constraint.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class NotNullConstraint : public Constraint {
public:
	NotNullConstraint(column_t index) : Constraint(ConstraintType::NOT_NULL), index(index){};
	virtual ~NotNullConstraint() {
	}

	//! Column index this constraint pertains to
	column_t index;

public:
	string ToString() const override;

	unique_ptr<Constraint> Copy() override;

	//! Serialize to a stand-alone binary blob
	void Serialize(Serializer &serializer) override;
	//! Deserializes a NotNullConstraint
	static unique_ptr<Constraint> Deserialize(Deserializer &source);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/constraints/unique_constraint.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class UniqueConstraint : public Constraint {
public:
	UniqueConstraint(uint64_t index, bool is_primary_key)
	    : Constraint(ConstraintType::UNIQUE), index(index), is_primary_key(is_primary_key) {
	}
	UniqueConstraint(vector<string> columns, bool is_primary_key)
	    : Constraint(ConstraintType::UNIQUE), index(INVALID_INDEX), columns(columns), is_primary_key(is_primary_key) {
	}

	//! The index of the column for which this constraint holds. Only used when the constraint relates to a single
	//! column, equal to INVALID_INDEX if not used
	uint64_t index;
	//! The set of columns for which this constraint holds by name. Only used when the index field is not used.
	vector<string> columns;
	//! Whether or not this is a PRIMARY KEY constraint, or a UNIQUE constraint.
	bool is_primary_key;

public:
	string ToString() const override;

	unique_ptr<Constraint> Copy() override;

	//! Serialize to a stand-alone binary blob
	void Serialize(Serializer &serializer) override;
	//! Deserializes a ParsedConstraint
	static unique_ptr<Constraint> Deserialize(Deserializer &source);
};

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/constraints/bound_not_null_constraint.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundNotNullConstraint : public BoundConstraint {
public:
	BoundNotNullConstraint(column_t index) : BoundConstraint(ConstraintType::NOT_NULL), index(index) {
	}

	//! Column index this constraint pertains to
	column_t index;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/constraints/bound_unique_constraint.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class BoundUniqueConstraint : public BoundConstraint {
public:
	BoundUniqueConstraint(unordered_set<idx_t> keys, bool is_primary_key)
	    : BoundConstraint(ConstraintType::UNIQUE), keys(keys), is_primary_key(is_primary_key) {
	}

	//! The same keys but represented as an unordered set
	unordered_set<idx_t> keys;
	//! Whether or not the unique constraint is a primary key
	bool is_primary_key;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_constant_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class BoundConstantExpression : public Expression {
public:
	BoundConstantExpression(Value value);

	Value value;

public:
	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;
	hash_t Hash() const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/binder.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tokens.hpp
//
//
//===----------------------------------------------------------------------===//



namespace duckdb {

//===--------------------------------------------------------------------===//
// Statements
//===--------------------------------------------------------------------===//
class SQLStatement;

class AlterTableStatement;
class CopyStatement;
class CreateStatement;
class DeleteStatement;
class DropStatement;
class InsertStatement;
class SelectStatement;
class TransactionStatement;
class UpdateStatement;
class PrepareStatement;
class ExecuteStatement;
class PragmaStatement;
class ExplainStatement;
class VacuumStatement;

//===--------------------------------------------------------------------===//
// Query Node
//===--------------------------------------------------------------------===//
class QueryNode;
class SelectNode;
class SetOperationNode;
class RecursiveCTENode;

//===--------------------------------------------------------------------===//
// Expressions
//===--------------------------------------------------------------------===//
class ParsedExpression;

class BetweenExpression;
class CaseExpression;
class CastExpression;
class ColumnRefExpression;
class ComparisonExpression;
class ConjunctionExpression;
class ConstantExpression;
class DefaultExpression;
class FunctionExpression;
class OperatorExpression;
class ParameterExpression;
class StarExpression;
class SubqueryExpression;
class WindowExpression;

//===--------------------------------------------------------------------===//
// Constraints
//===--------------------------------------------------------------------===//
class Constraint;

class NotNullConstraint;
class CheckConstraint;
class UniqueConstraint;

//===--------------------------------------------------------------------===//
// TableRefs
//===--------------------------------------------------------------------===//
class TableRef;

class BaseTableRef;
class CrossProductRef;
class JoinRef;
class SubqueryRef;
class TableFunctionRef;
class EmptyTableRef;
class ExpressionListRef;

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/bind_context.hpp
//
//
//===----------------------------------------------------------------------===//








//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/columnref_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a reference to a column from either the FROM clause or from an
//! alias
class ColumnRefExpression : public ParsedExpression {
public:
	//! Specify both the column and table name
	ColumnRefExpression(string column_name, string table_name);
	//! Only specify the column name, the table name will be derived later
	ColumnRefExpression(string column_name);

	//! Column name that is referenced
	string column_name;
	//! Table name of the column name that is referenced (optional)
	string table_name;

public:
	bool IsScalar() const override {
		return false;
	}

	string GetName() const override;
	string ToString() const override;

	static bool Equals(const ColumnRefExpression *a, const ColumnRefExpression *b);
	hash_t Hash() const override;

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/bound_expression.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! BoundExpression is an intermediate dummy class used by the binder. It is a ParsedExpression but holds an Expression.
//! It represents a successfully bound expression. It is used in the Binder to prevent re-binding of already bound parts
//! when dealing with subqueries.
class BoundExpression : public ParsedExpression {
public:
	BoundExpression(unique_ptr<Expression> expr, unique_ptr<ParsedExpression> parsed_expr, SQLType sql_type)
	    : ParsedExpression(ExpressionType::INVALID, ExpressionClass::BOUND_EXPRESSION), expr(move(expr)),
	      parsed_expr(move(parsed_expr)), sql_type(sql_type) {
	}

	unique_ptr<Expression> expr;
	unique_ptr<ParsedExpression> parsed_expr;
	SQLType sql_type;

public:
	string ToString() const override {
		return expr->ToString();
	}

	bool Equals(const BaseExpression *other) const override {
		return parsed_expr->Equals(other);
	}
	hash_t Hash() const override {
		return parsed_expr->Hash();
	}

	unique_ptr<ParsedExpression> Copy() const override {
		throw SerializationException("Cannot copy or serialize bound expression");
	}
};

} // namespace duckdb




namespace duckdb {

class Binder;
class ClientContext;
class SelectNode;

class AggregateFunctionCatalogEntry;
class ScalarFunctionCatalogEntry;
class SimpleFunction;

struct BindResult {
	BindResult(string error) : error(error) {
	}
	BindResult(unique_ptr<Expression> expr, SQLType sql_type) : expression(move(expr)), sql_type(sql_type) {
	}

	bool HasError() {
		return !error.empty();
	}

	unique_ptr<Expression> expression;
	SQLType sql_type;
	string error;
};

class ExpressionBinder {
public:
	ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder = false);
	virtual ~ExpressionBinder();

	unique_ptr<Expression> Bind(unique_ptr<ParsedExpression> &expr, SQLType *result_type = nullptr,
	                            bool root_expression = true);

	//! Returns whether or not any columns have been bound by the expression binder
	bool BoundColumns() {
		return bound_columns;
	}

	string Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, bool root_expression = false);

	// Bind table names to ColumnRefExpressions
	void BindTableNames(ParsedExpression &expr);

	bool BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr);

	//! The target type that should result from the binder. If the result is not of this type, a cast to this type will
	//! be added. Defaults to INVALID.
	SQLType target_type;

protected:
	virtual BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false);

	BindResult BindExpression(CaseExpression &expr, idx_t depth);
	BindResult BindExpression(CastExpression &expr, idx_t depth);
	BindResult BindExpression(ColumnRefExpression &expr, idx_t depth);
	BindResult BindExpression(ComparisonExpression &expr, idx_t depth);
	BindResult BindExpression(ConjunctionExpression &expr, idx_t depth);
	BindResult BindExpression(ConstantExpression &expr, idx_t depth);
	BindResult BindExpression(FunctionExpression &expr, idx_t depth);
	BindResult BindExpression(OperatorExpression &expr, idx_t depth);
	BindResult BindExpression(ParameterExpression &expr, idx_t depth);
	BindResult BindExpression(StarExpression &expr, idx_t depth);
	BindResult BindExpression(SubqueryExpression &expr, idx_t depth);

	void BindChild(unique_ptr<ParsedExpression> &expr, idx_t depth, string &error);

protected:
	static void ExtractCorrelatedExpressions(Binder &binder, Expression &expr);

	virtual BindResult BindFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth);
	virtual BindResult BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function, idx_t depth);
	virtual BindResult BindUnnest(FunctionExpression &expr, idx_t depth);


	virtual string UnsupportedAggregateMessage();
	virtual string UnsupportedUnnestMessage();

	Binder &binder;
	ClientContext &context;
	ExpressionBinder *stored_binder;
	bool bound_columns = false;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/table_binding.hpp
//
//
//===----------------------------------------------------------------------===//









namespace duckdb {
class BindContext;
class BoundBaseTableRef;
class BoundQueryNode;
class ColumnRefExpression;
class SubqueryRef;
class TableCatalogEntry;
class TableFunctionCatalogEntry;

enum class BindingType : uint8_t { TABLE = 0, SUBQUERY = 1, TABLE_FUNCTION = 2, GENERIC = 3 };

//! A Binding represents a binding to a table, table-producing function or subquery with a specified table index. Used
//! in the binder.
struct Binding {
	Binding(BindingType type, const string &alias, idx_t index) : type(type), alias(alias), index(index) {
	}
	virtual ~Binding() = default;

	BindingType type;
	string alias;
	idx_t index;

public:
	virtual bool HasMatchingBinding(const string &column_name) = 0;
	virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth) = 0;
	virtual void GenerateAllColumnExpressions(BindContext &context,
	                                          vector<unique_ptr<ParsedExpression>> &select_list) = 0;
};

//! Represents a binding to a base table
struct TableBinding : public Binding {
	TableBinding(const string &alias, BoundBaseTableRef *bound);

	BoundBaseTableRef *bound;

public:
	bool HasMatchingBinding(const string &column_name) override;
	BindResult Bind(ColumnRefExpression &colref, idx_t depth) override;
	void GenerateAllColumnExpressions(BindContext &context, vector<unique_ptr<ParsedExpression>> &select_list) override;
};

//! Represents a binding to a subquery
struct SubqueryBinding : public Binding {
	SubqueryBinding(const string &alias, SubqueryRef &ref, BoundQueryNode &subquery, idx_t index);

	BoundQueryNode &subquery;
	//! Column names of the subquery
	vector<string> names;
	//! Name -> index for the names
	unordered_map<string, uint64_t> name_map;

public:
	bool HasMatchingBinding(const string &column_name) override;
	BindResult Bind(ColumnRefExpression &colref, idx_t depth) override;
	void GenerateAllColumnExpressions(BindContext &context, vector<unique_ptr<ParsedExpression>> &select_list) override;

private:
	void AddName(string &name);
};

//! Represents a generic binding with types and names
struct GenericBinding : public Binding {
	GenericBinding(const string &alias, vector<SQLType> types, vector<string> names, idx_t index);

	vector<SQLType> types;
	//! Column names of the subquery
	vector<string> names;
	//! Name -> index for the names
	unordered_map<string, uint64_t> name_map;

public:
	bool HasMatchingBinding(const string &column_name) override;
	BindResult Bind(ColumnRefExpression &colref, idx_t depth) override;
	void GenerateAllColumnExpressions(BindContext &context, vector<unique_ptr<ParsedExpression>> &select_list) override;
};

} // namespace duckdb


namespace duckdb {
class BoundQueryNode;

//! The BindContext object keeps track of all the tables and columns that are
//! encountered during the binding process.
class BindContext {
public:
	//! Given a column name, find the matching table it belongs to. Throws an
	//! exception if no table has a column of the given name.
	string GetMatchingBinding(const string &column_name);

	Binding *GetCTEBinding(const string &ctename);
	//! Binds a column expression to the base table. Returns the bound expression
	//! or throws an exception if the column could not be bound.
	BindResult BindColumn(ColumnRefExpression &colref, idx_t depth);

	//! Generate column expressions for all columns that are present in the
	//! referenced tables. This is used to resolve the * expression in a
	//! selection list.
	void GenerateAllColumnExpressions(vector<unique_ptr<ParsedExpression>> &new_select_list, string relation_name = "");

	//! Adds a base table with the given alias to the BindContext.
	void AddBaseTable(BoundBaseTableRef *bound, const string &alias);
	//! Adds a subquery with a given alias to the BindContext.
	void AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery);
	//! Adds a base table with the given alias to the BindContext.
	void AddGenericBinding(idx_t index, const string &alias, vector<string> names, vector<SQLType> types);

	//! Adds a base table with the given alias to the CTE BindContext.
	//! We need this to correctly bind recursive CTEs with multiple references.
	void AddCTEBinding(idx_t index, const string &alias, vector<string> names, vector<SQLType> types);

	unordered_set<string> hidden_columns;

	//! Keep track of recursive CTE references
	unordered_map<string, std::shared_ptr<idx_t>> cte_references;

	unordered_map<string, std::shared_ptr<Binding>> GetCTEBindings() {
		return cte_bindings;
	}
	void SetCTEBindings(unordered_map<string, std::shared_ptr<Binding>> bindings) {
		cte_bindings = bindings;
	}

private:
	void AddBinding(const string &alias, unique_ptr<Binding> binding);

	//! The set of bindings
	unordered_map<string, unique_ptr<Binding>> bindings;
	//! The list of bindings in insertion order
	vector<std::pair<string, Binding *>> bindings_list;

	//! The set of CTE bindings
	unordered_map<string, std::shared_ptr<Binding>> cte_bindings;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_columnref_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! A BoundColumnRef expression represents a ColumnRef expression that was bound to an actual table and column index. It
//! is not yet executable, however. The ColumnBindingResolver transforms the BoundColumnRefExpressions into
//! BoundExpressions, which refer to indexes into the physical chunks that pass through the executor.
class BoundColumnRefExpression : public Expression {
public:
	BoundColumnRefExpression(TypeId type, ColumnBinding binding, idx_t depth = 0);
	BoundColumnRefExpression(string alias, TypeId type, ColumnBinding binding, idx_t depth = 0);

	//! Column index set by the binder, used to generate the final BoundExpression
	ColumnBinding binding;
	//! The subquery depth (i.e. depth 0 = current query, depth 1 = parent query, depth 2 = parent of parent, etc...).
	//! This is only non-zero for correlated expressions inside subqueries.
	idx_t depth;

public:
	bool IsScalar() const override {
		return false;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;
	hash_t Hash() const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


namespace duckdb {
class ClientContext;
class ExpressionBinder;
struct CreateInfo;
struct BoundCreateInfo;

struct CorrelatedColumnInfo {
	ColumnBinding binding;
	TypeId type;
	string name;
	idx_t depth;

	CorrelatedColumnInfo(BoundColumnRefExpression &expr)
	    : binding(expr.binding), type(expr.return_type), name(expr.GetName()), depth(expr.depth) {
	}

	bool operator==(const CorrelatedColumnInfo &rhs) const {
		return binding == rhs.binding;
	}
};

//! Bind the parsed query tree to the actual columns present in the catalog.
/*!
  The binder is responsible for binding tables and columns to actual physical
  tables and columns in the catalog. In the process, it also resolves types of
  all expressions.
*/
class Binder {
public:
	Binder(ClientContext &context, Binder *parent = nullptr);

	//! The client context
	ClientContext &context;
	//! A mapping of names to common table expressions
	unordered_map<string, QueryNode *> CTE_bindings;
	//! The bind context
	BindContext bind_context;
	//! The set of correlated columns bound by this binder (FIXME: this should probably be an unordered_set and not a
	//! vector)
	vector<CorrelatedColumnInfo> correlated_columns;
	//! The set of parameter expressions bound by this binder
	vector<BoundParameterExpression *> *parameters;
	//! Whether or not the bound statement is read-only
	bool read_only;

public:
	unique_ptr<BoundSQLStatement> Bind(SQLStatement &statement);
	unique_ptr<BoundQueryNode> Bind(QueryNode &node);

	unique_ptr<BoundCreateInfo> BindCreateInfo(unique_ptr<CreateInfo> info);

	//! Generates an unused index for a table
	idx_t GenerateTableIndex();

	//! Add a common table expression to the binder
	void AddCTE(const string &name, QueryNode *cte);
	//! Find a common table expression by name; returns nullptr if none exists
	unique_ptr<QueryNode> FindCTE(const string &name);

	void PushExpressionBinder(ExpressionBinder *binder);
	void PopExpressionBinder();
	void SetActiveBinder(ExpressionBinder *binder);
	ExpressionBinder *GetActiveBinder();
	bool HasActiveBinder();

	vector<ExpressionBinder *> &GetActiveBinders();

	void MergeCorrelatedColumns(vector<CorrelatedColumnInfo> &other);
	//! Add a correlated column to this binder (if it does not exist)
	void AddCorrelatedColumn(CorrelatedColumnInfo info);

private:
	//! The parent binder (if any)
	Binder *parent;
	//! The vector of active binders
	vector<ExpressionBinder *> active_binders;
	//! The count of bound_tables
	idx_t bound_tables;

private:
	//! Bind the default values of the columns of a table
	void BindDefaultValues(vector<ColumnDefinition> &columns, vector<unique_ptr<Expression>> &bound_defaults);

	//! Move correlated expressions from the child binder to this binder
	void MoveCorrelatedExpressions(Binder &other);

	unique_ptr<BoundSQLStatement> Bind(SelectStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(InsertStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(CopyStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(DeleteStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(UpdateStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(CreateStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(ExecuteStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(DropStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(AlterTableStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(TransactionStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(PragmaStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(ExplainStatement &stmt);
	unique_ptr<BoundSQLStatement> Bind(VacuumStatement &stmt);

	unique_ptr<BoundQueryNode> Bind(SelectNode &node);
	unique_ptr<BoundQueryNode> Bind(SetOperationNode &node);
	unique_ptr<BoundQueryNode> Bind(RecursiveCTENode &node);

	unique_ptr<BoundTableRef> Bind(TableRef &ref);
	unique_ptr<BoundTableRef> Bind(BaseTableRef &ref);
	unique_ptr<BoundTableRef> Bind(CrossProductRef &ref);
	unique_ptr<BoundTableRef> Bind(JoinRef &ref);
	unique_ptr<BoundTableRef> Bind(SubqueryRef &ref);
	unique_ptr<BoundTableRef> Bind(TableFunctionRef &ref);
	unique_ptr<BoundTableRef> Bind(EmptyTableRef &ref);
	unique_ptr<BoundTableRef> Bind(ExpressionListRef &ref);

	unique_ptr<BoundCreateInfo> BindCreateIndexInfo(unique_ptr<CreateInfo> info);
	unique_ptr<BoundCreateInfo> BindCreateTableInfo(unique_ptr<CreateInfo> info);
	unique_ptr<BoundCreateInfo> BindCreateViewInfo(unique_ptr<CreateInfo> info);
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/art.hpp
//
//
//===----------------------------------------------------------------------===//










//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/art_key.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class Key {
public:
	Key(unique_ptr<data_t[]> data, idx_t len);

	idx_t len;
	unique_ptr<data_t[]> data;

public:
	template <class T> static unique_ptr<Key> CreateKey(T element, bool is_little_endian) {
		auto data = Key::CreateData<T>(element, is_little_endian);
		return make_unique<Key>(move(data), sizeof(element));
	}

public:
	data_t &operator[](std::size_t i) {
		return data[i];
	}
	const data_t &operator[](std::size_t i) const {
		return data[i];
	}
	bool operator>(const Key &k) const;
	bool operator<(const Key &k) const;
	bool operator>=(const Key &k) const;
	bool operator==(const Key &k) const;

	string ToString(bool is_little_endian, TypeId type);

	static uint32_t EncodeFloat(float x);
	static uint64_t EncodeDouble(double x);

private:
	template <class T> static unique_ptr<data_t[]> CreateData(T value, bool is_little_endian) {
		throw NotImplementedException("Cannot create data from this type");
	}
};

template <> unique_ptr<data_t[]> Key::CreateData(int8_t value, bool is_little_endian);
template <> unique_ptr<data_t[]> Key::CreateData(int16_t value, bool is_little_endian);
template <> unique_ptr<data_t[]> Key::CreateData(int32_t value, bool is_little_endian);
template <> unique_ptr<data_t[]> Key::CreateData(int64_t value, bool is_little_endian);
template <> unique_ptr<data_t[]> Key::CreateData(double value, bool is_little_endian);
template <> unique_ptr<data_t[]> Key::CreateData(float value, bool is_little_endian);

template <> unique_ptr<Key> Key::CreateKey(string_t value, bool is_little_endian);
template <> unique_ptr<Key> Key::CreateKey(const char *value, bool is_little_endian);

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/leaf.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/node.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
enum class NodeType : uint8_t { N4 = 0, N16 = 1, N48 = 2, N256 = 3, NLeaf = 4 };

class ART;

class Node {
public:
	static const uint8_t EMPTY_MARKER = 48;

public:
	Node(ART &art, NodeType type, size_t compressedPrefixSize);
	virtual ~Node() {
	}

	//! length of the compressed path (prefix)
	uint32_t prefix_length;
	//! number of non-null children
	uint16_t count;
	//! node type
	NodeType type;
	//! compressed path (prefix)
	unique_ptr<uint8_t[]> prefix;

public:
	//! Get the position of a child corresponding exactly to the specific byte, returns INVALID_INDEX if not exists
	virtual idx_t GetChildPos(uint8_t k) {
		return INVALID_INDEX;
	}
	//! Get the position of the first child that is greater or equal to the specific byte, or INVALID_INDEX if there are
	//! no children matching the criteria
	virtual idx_t GetChildGreaterEqual(uint8_t k) {
		return INVALID_INDEX;
	}
	//! Get the position of the biggest element in node
	virtual idx_t GetMin();
	//! Get the next position in the node, or INVALID_INDEX if there is no next position. if pos == INVALID_INDEX, then
	//! the first valid position in the node will be returned.
	virtual idx_t GetNextPos(idx_t pos) {
		return INVALID_INDEX;
	}
	//! Get the child at the specified position in the node. pos should be between [0, count). Throws an assertion if
	//! the element is not found.
	virtual unique_ptr<Node> *GetChild(idx_t pos);

	//! Compare the key with the prefix of the node, return the number matching bytes
	static uint32_t PrefixMismatch(ART &art, Node *node, Key &key, uint64_t depth);
	//! Insert leaf into inner node
	static void InsertLeaf(ART &art, unique_ptr<Node> &node, uint8_t key, unique_ptr<Node> &newNode);
	//! Erase entry from node
	static void Erase(ART &art, unique_ptr<Node> &node, idx_t pos);

protected:
	//! Copies the prefix from the source to the destination node
	static void CopyPrefix(ART &art, Node *src, Node *dst);
};

} // namespace duckdb


namespace duckdb {

class Leaf : public Node {
public:
	Leaf(ART &art, unique_ptr<Key> value, row_t row_id);

	unique_ptr<Key> value;
	idx_t capacity;
	idx_t num_elements;

	row_t GetRowId(idx_t index) {
		return row_ids[index];
	}

public:
	void Insert(row_t row_id);
	void Remove(row_t row_id);

private:
	unique_ptr<row_t[]> row_ids;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/node4.hpp
//
//
//===----------------------------------------------------------------------===//




namespace duckdb {

class Node4 : public Node {
public:
	Node4(ART &art, size_t compressionLength);

	uint8_t key[4];
	unique_ptr<Node> child[4];

public:
	//! Get position of a byte, returns -1 if not exists
	idx_t GetChildPos(uint8_t k) override;
	//! Get the position of the first child that is greater or equal to the specific byte, or INVALID_INDEX if there are
	//! no children matching the criteria
	idx_t GetChildGreaterEqual(uint8_t k) override;
	//! Get the next position in the node, or INVALID_INDEX if there is no next position
	idx_t GetNextPos(idx_t pos) override;
	//! Get Node4 Child
	unique_ptr<Node> *GetChild(idx_t pos) override;

	idx_t GetMin() override;

	//! Insert Leaf to the Node4
	static void insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child);
	//! Remove Leaf from Node4
	static void erase(ART &art, unique_ptr<Node> &node, int pos);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/node16.hpp
//
//
//===----------------------------------------------------------------------===//




namespace duckdb {

class Node16 : public Node {
public:
	Node16(ART &art, size_t compressionLength);

	uint8_t key[16];
	unique_ptr<Node> child[16];

public:
	//! Get position of a byte, returns -1 if not exists
	idx_t GetChildPos(uint8_t k) override;
	//! Get the position of the first child that is greater or equal to the specific byte, or INVALID_INDEX if there are
	//! no children matching the criteria
	idx_t GetChildGreaterEqual(uint8_t k) override;
	//! Get the next position in the node, or INVALID_INDEX if there is no next position
	idx_t GetNextPos(idx_t pos) override;
	//! Get Node16 Child
	unique_ptr<Node> *GetChild(idx_t pos) override;

	idx_t GetMin() override;

	//! Insert node into Node16
	static void insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child);
	//! Shrink to node 4
	static void erase(ART &art, unique_ptr<Node> &node, int pos);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/node48.hpp
//
//
//===----------------------------------------------------------------------===//




namespace duckdb {

class Node48 : public Node {
public:
	Node48(ART &art, size_t compressionLength);

	uint8_t childIndex[256];
	unique_ptr<Node> child[48];

public:
	//! Get position of a byte, returns -1 if not exists
	idx_t GetChildPos(uint8_t k) override;
	//! Get the position of the first child that is greater or equal to the specific byte, or INVALID_INDEX if there are
	//! no children matching the criteria
	idx_t GetChildGreaterEqual(uint8_t k) override;
	//! Get the next position in the node, or INVALID_INDEX if there is no next position
	idx_t GetNextPos(idx_t pos) override;
	//! Get Node48 Child
	unique_ptr<Node> *GetChild(idx_t pos) override;

	idx_t GetMin() override;

	//! Insert node in Node48
	static void insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child);

	//! Shrink to node 16
	static void erase(ART &art, unique_ptr<Node> &node, int pos);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/index/art/node256.hpp
//
//
//===----------------------------------------------------------------------===//




namespace duckdb {

class Node256 : public Node {
public:
	Node256(ART &art, size_t compressionLength);

	unique_ptr<Node> child[256];

public:
	//! Get position of a specific byte, returns INVALID_INDEX if not exists
	idx_t GetChildPos(uint8_t k) override;
	//! Get the position of the first child that is greater or equal to the specific byte, or INVALID_INDEX if there are
	//! no children matching the criteria
	idx_t GetChildGreaterEqual(uint8_t k) override;
	//! Get the next position in the node, or INVALID_INDEX if there is no next position
	idx_t GetNextPos(idx_t pos) override;
	//! Get Node256 Child
	unique_ptr<Node> *GetChild(idx_t pos) override;

	idx_t GetMin() override;

	//! Insert node From Node256
	static void insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child);

	//! Shrink to node 48
	static void erase(ART &art, unique_ptr<Node> &node, int pos);
};
} // namespace duckdb


namespace duckdb {
struct IteratorEntry {
	Node *node = nullptr;
	idx_t pos = 0;
};

struct Iterator {
	//! The current Leaf Node, valid if depth>0
	Leaf *node = nullptr;
	//! The current depth
	int32_t depth = 0;
	//! Stack, actually the size is determined at runtime
	IteratorEntry stack[9];

	bool start = false;
};

struct ARTIndexScanState : public IndexScanState {
	ARTIndexScanState(vector<column_t> column_ids) : IndexScanState(column_ids), checked(false), result_index(0) {
	}

	Value values[2];
	ExpressionType expressions[2];
	bool checked;
	idx_t result_index = 0;
	vector<row_t> result_ids;
	Iterator iterator;
};

class ART : public Index {
public:
	ART(DataTable &table, vector<column_t> column_ids, vector<unique_ptr<Expression>> unbound_expressions,
	    bool is_unique = false);
	~ART();

	//! Root of the tree
	unique_ptr<Node> tree;
	//! True if machine is little endian
	bool is_little_endian;
	//! Whether or not the ART is an index built to enforce a UNIQUE constraint
	bool is_unique;

public:
	//! Initialize a scan on the index with the given expression and column ids
	//! to fetch from the base table for a single predicate
	unique_ptr<IndexScanState> InitializeScanSinglePredicate(Transaction &transaction, vector<column_t> column_ids,
	                                                         Value value, ExpressionType expressionType) override;

	//! Initialize a scan on the index with the given expression and column ids
	//! to fetch from the base table for two predicates
	unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction, vector<column_t> column_ids,
	                                                       Value low_value, ExpressionType low_expression_type,
	                                                       Value high_value,
	                                                       ExpressionType high_expression_type) override;

	//! Perform a lookup on the index
	void Scan(Transaction &transaction, TableIndexScanState &state, DataChunk &result) override;
	//! Append entries to the index
	bool Append(IndexLock &lock, DataChunk &entries, Vector &row_identifiers) override;
	//! Verify that data can be appended to the index
	void VerifyAppend(DataChunk &chunk) override;
	//! Delete entries in the index
	void Delete(IndexLock &lock, DataChunk &entries, Vector &row_identifiers) override;

	//! Insert data into the index.
	bool Insert(IndexLock &lock, DataChunk &data, Vector &row_ids) override;

private:
	DataChunk expression_result;

private:
	//! Insert a row id into a leaf node
	bool InsertToLeaf(Leaf &leaf, row_t row_id);
	//! Insert the leaf value into the tree
	bool Insert(unique_ptr<Node> &node, unique_ptr<Key> key, unsigned depth, row_t row_id);

	//! Erase element from leaf (if leaf has more than one value) or eliminate the leaf itself
	void Erase(unique_ptr<Node> &node, Key &key, unsigned depth, row_t row_id);

	//! Check if the key of the leaf is equal to the searched key
	bool LeafMatches(Node *node, Key &key, unsigned depth);

	//! Find the node with a matching key, optimistic version
	Node *Lookup(unique_ptr<Node> &node, Key &key, unsigned depth);

	//! Find the first node that is bigger (or equal to) a specific key
	bool Bound(unique_ptr<Node> &node, Key &key, Iterator &iterator, bool inclusive);

	//! Gets next node for range queries
	bool IteratorNext(Iterator &iter);

	void SearchEqual(vector<row_t> &result_ids, ARTIndexScanState *state);
	void SearchGreater(vector<row_t> &result_ids, ARTIndexScanState *state, bool inclusive);
	void SearchLess(vector<row_t> &result_ids, ARTIndexScanState *state, bool inclusive);
	void SearchCloseRange(vector<row_t> &result_ids, ARTIndexScanState *state, bool left_inclusive,
	                      bool right_inclusive);

private:
	template <bool HAS_BOUND, bool INCLUSIVE>
	void IteratorScan(ARTIndexScanState *state, Iterator *it, vector<row_t> &result_ids, Key *upper_bound);

	void GenerateKeys(DataChunk &input, vector<unique_ptr<Key>> &keys);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_reference_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! A BoundReferenceExpression represents a physical index into a DataChunk
class BoundReferenceExpression : public Expression {
public:
	BoundReferenceExpression(string alias, TypeId type, idx_t index);
	BoundReferenceExpression(TypeId type, idx_t index);

	//! Index used to access data in the chunks
	idx_t index;

public:
	bool IsScalar() const override {
		return false;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override;

	hash_t Hash() const override;
	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


#include <algorithm>

using namespace duckdb;
using namespace std;

TableCatalogEntry::TableCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, BoundCreateTableInfo *info,
                                     std::shared_ptr<DataTable> inherited_storage)
    : StandardEntry(CatalogType::TABLE, schema, catalog, info->Base().table), storage(inherited_storage),
      columns(move(info->Base().columns)), constraints(move(info->Base().constraints)),
      bound_constraints(move(info->bound_constraints)), name_map(info->name_map) {
	this->temporary = info->Base().temporary;
	// add the "rowid" alias, if there is no rowid column specified in the table
	if (name_map.find("rowid") == name_map.end()) {
		name_map["rowid"] = COLUMN_IDENTIFIER_ROW_ID;
	}
	if (!storage) {
		// create the physical storage
		storage = make_shared<DataTable>(catalog->storage, schema->name, name, GetTypes(), move(info->data));

		// create the unique indexes for the UNIQUE and PRIMARY KEY constraints
		for (idx_t i = 0; i < bound_constraints.size(); i++) {
			auto &constraint = bound_constraints[i];
			if (constraint->type == ConstraintType::UNIQUE) {
				// unique constraint: create a unique index
				auto &unique = (BoundUniqueConstraint &)*constraint;
				// fetch types and create expressions for the index from the columns
				vector<column_t> column_ids;
				vector<unique_ptr<Expression>> unbound_expressions;
				vector<unique_ptr<Expression>> bound_expressions;
				idx_t key_nr = 0;
				for (auto &key : unique.keys) {
					TypeId column_type = GetInternalType(columns[key].type);
					assert(key < columns.size());

					unbound_expressions.push_back(
					    make_unique<BoundColumnRefExpression>(column_type, ColumnBinding(0, column_ids.size())));
					bound_expressions.push_back(make_unique<BoundReferenceExpression>(column_type, key_nr++));
					column_ids.push_back(key);
				}
				// create an adaptive radix tree around the expressions
				auto art = make_unique<ART>(*storage, column_ids, move(unbound_expressions), true);

				if (unique.is_primary_key) {
					// if this is a primary key index, also create a NOT NULL constraint for each of the columns
					for (auto &column_index : unique.keys) {
						bound_constraints.push_back(make_unique<BoundNotNullConstraint>(column_index));
					}
				}
				storage->AddIndex(move(art), bound_expressions);
			}
		}
	}
}

bool TableCatalogEntry::ColumnExists(const string &name) {
	return name_map.find(name) != name_map.end();
}

unique_ptr<CatalogEntry> TableCatalogEntry::AlterEntry(ClientContext &context, AlterInfo *info) {
    if (info->type != AlterType::ALTER_TABLE) {
        throw CatalogException("Can only modify table with ALTER TABLE statement");
    }
    if (constraints.size() > 0) {
        throw CatalogException("Cannot modify a table with constraints");
    }
    auto table_info = (AlterTableInfo *)info;
    switch (table_info->alter_table_type) {
    case AlterTableType::RENAME_COLUMN: {
        auto rename_info = (RenameColumnInfo *)table_info;
        auto create_info = make_unique<CreateTableInfo>(schema->name, name);
        create_info->temporary = temporary;
        bool found = false;
        for (idx_t i = 0; i < columns.size(); i++) {
            ColumnDefinition copy(columns[i].name, columns[i].type);
            copy.oid = columns[i].oid;
            copy.default_value = columns[i].default_value ? columns[i].default_value->Copy() : nullptr;

            create_info->columns.push_back(move(copy));
            if (rename_info->name == columns[i].name) {
                assert(!found);
                create_info->columns[i].name = rename_info->new_name;
                found = true;
            }
        }
        if (!found) {
            throw CatalogException("Table does not have a column with name \"%s\"", rename_info->name.c_str());
        }
        assert(constraints.size() == 0);
        // create_info->constraints.resize(constraints.size());
        // for (idx_t i = 0; i < constraints.size(); i++) {
        // 	create_info->constraints[i] = constraints[i]->Copy();
        // }
        Binder binder(context);
        auto bound_create_info = binder.BindCreateInfo(move(create_info));
        return make_unique<TableCatalogEntry>(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(),
                                              storage);
	}
    case AlterTableType::RENAME_TABLE: {
        auto rename_info = (RenameTableInfo *)table_info;
        auto copied_table = Copy(context);
        copied_table->name = rename_info->new_table_name;
        return copied_table;
    }
    default:
        throw CatalogException("Unrecognized alter table type!");
    }
}

ColumnDefinition &TableCatalogEntry::GetColumn(const string &name) {
	auto entry = name_map.find(name);
	if (entry == name_map.end() || entry->second == COLUMN_IDENTIFIER_ROW_ID) {
		throw CatalogException("Column with name %s does not exist!", name.c_str());
	}
	return columns[entry->second];
}

vector<TypeId> TableCatalogEntry::GetTypes() {
	vector<TypeId> types;
	for (auto &it : columns) {
		types.push_back(GetInternalType(it.type));
	}
	return types;
}

vector<TypeId> TableCatalogEntry::GetTypes(const vector<column_t> &column_ids) {
	vector<TypeId> result;
	for (auto &index : column_ids) {
		if (index == COLUMN_IDENTIFIER_ROW_ID) {
			result.push_back(TypeId::INT64);
		} else {
			result.push_back(GetInternalType(columns[index].type));
		}
	}
	return result;
}

void TableCatalogEntry::Serialize(Serializer &serializer) {
	serializer.WriteString(schema->name);
	serializer.WriteString(name);
	assert(columns.size() <= std::numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)columns.size());
	for (auto &column : columns) {
		serializer.WriteString(column.name);
		column.type.Serialize(serializer);
		serializer.WriteOptional(column.default_value);
	}
	assert(constraints.size() <= std::numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)constraints.size());
	for (auto &constraint : constraints) {
		constraint->Serialize(serializer);
	}
}

unique_ptr<CreateTableInfo> TableCatalogEntry::Deserialize(Deserializer &source) {
	auto info = make_unique<CreateTableInfo>();

	info->schema = source.Read<string>();
	info->table = source.Read<string>();
	auto column_count = source.Read<uint32_t>();

	for (uint32_t i = 0; i < column_count; i++) {
		auto column_name = source.Read<string>();
		auto column_type = SQLType::Deserialize(source);
		auto default_value = source.ReadOptional<ParsedExpression>();
		info->columns.push_back(ColumnDefinition(column_name, column_type, move(default_value)));
	}
	auto constraint_count = source.Read<uint32_t>();

	for (uint32_t i = 0; i < constraint_count; i++) {
		auto constraint = Constraint::Deserialize(source);
		info->constraints.push_back(move(constraint));
	}
	return info;
}

unique_ptr<CatalogEntry> TableCatalogEntry::Copy(ClientContext &context) {
    auto create_info = make_unique<CreateTableInfo>(schema->name, name);
    for (idx_t i = 0; i < columns.size(); i++) {
        ColumnDefinition copy(columns[i].name, columns[i].type);
        copy.oid = columns[i].oid;
        copy.default_value = columns[i].default_value ? columns[i].default_value->Copy() : nullptr;
        create_info->columns.push_back(move(copy));
    }

   for (idx_t i = 0; i < constraints.size(); i++) {
        auto constraint = constraints[i]->Copy();
        create_info->constraints.push_back(move(constraint));
    }

    Binder binder(context);
    auto bound_create_info = binder.BindCreateInfo(move(create_info));
    return make_unique<TableCatalogEntry>(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage);
}







#include <algorithm>

using namespace duckdb;
using namespace std;

TableFunctionCatalogEntry::TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema,
                                                     CreateTableFunctionInfo *info)
    : StandardEntry(CatalogType::TABLE_FUNCTION, schema, catalog, info->name), function(info->function) {
}







#include <algorithm>

using namespace duckdb;
using namespace std;

void ViewCatalogEntry::Initialize(CreateViewInfo *info) {
	query = move(info->query);
	aliases = info->aliases;
	this->temporary = info->temporary;
}

ViewCatalogEntry::ViewCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateViewInfo *info)
    : StandardEntry(CatalogType::VIEW, schema, catalog, info->view_name) {
	Initialize(info);
}

void ViewCatalogEntry::Serialize(Serializer &serializer) {
	serializer.WriteString(schema->name);
	serializer.WriteString(name);
	query->Serialize(serializer);
	assert(aliases.size() <= numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)aliases.size());
	for (auto &s : aliases) {
		serializer.WriteString(s);
	}
}

unique_ptr<CreateViewInfo> ViewCatalogEntry::Deserialize(Deserializer &source) {
	auto info = make_unique<CreateViewInfo>();
	info->schema = source.Read<string>();
	info->view_name = source.Read<string>();
	info->query = QueryNode::Deserialize(source);
	auto alias_count = source.Read<uint32_t>();
	for (uint32_t i = 0; i < alias_count; i++) {
		info->aliases.push_back(source.Read<string>());
	}
	return info;
}




using namespace duckdb;
using namespace std;

CatalogEntry::~CatalogEntry() {
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/transaction_manager.hpp
//
//
//===----------------------------------------------------------------------===//






#include <atomic>
#include <memory>
#include <mutex>

namespace duckdb {

class ClientContext;
class StorageManager;
class Transaction;

struct StoredCatalogSet {
	//! Stored catalog set
	unique_ptr<CatalogSet> stored_set;
	//! The highest active query number when the catalog set was stored; used for cleaning up
	transaction_t highest_active_query;
};

//! The Transaction Manager is responsible for creating and managing
//! transactions
class TransactionManager {
public:
	TransactionManager(StorageManager &storage);
	~TransactionManager();

	//! Start a new transaction
	Transaction *StartTransaction();
	//! Commit the given transaction
	string CommitTransaction(Transaction *transaction);
	//! Rollback the given transaction
	void RollbackTransaction(Transaction *transaction);
	//! Add the catalog set
	void AddCatalogSet(ClientContext &context, unique_ptr<CatalogSet> catalog_set);

	transaction_t GetQueryNumber() {
		return current_query_number++;
	}

private:
	//! Remove the given transaction from the list of active transactions
	void RemoveTransaction(Transaction *transaction) noexcept;

	//! The current query number
	std::atomic<transaction_t> current_query_number;
	//! The current start timestamp used by transactions
	transaction_t current_start_timestamp;
	//! The current transaction ID used by transactions
	transaction_t current_transaction_id;
	//! Set of currently running transactions
	vector<unique_ptr<Transaction>> active_transactions;
	//! Set of recently committed transactions
	vector<unique_ptr<Transaction>> recently_committed_transactions;
	//! Transactions awaiting GC
	vector<unique_ptr<Transaction>> old_transactions;
	//! Catalog sets
	vector<StoredCatalogSet> old_catalog_sets;
	//! The lock used for transaction operations
	std::mutex transaction_lock;
	//! The storage manager
	StorageManager &storage;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/serializer/buffered_serializer.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

#define SERIALIZER_DEFAULT_SIZE 1024

struct BinaryData {
	unique_ptr<data_t[]> data;
	idx_t size;
};

class BufferedSerializer : public Serializer {
public:
	//! Serializes to a buffer allocated by the serializer, will expand when
	//! writing past the initial threshold
	BufferedSerializer(idx_t maximum_size = SERIALIZER_DEFAULT_SIZE);
	//! Serializes to a provided (owned) data pointer
	BufferedSerializer(unique_ptr<data_t[]> data, idx_t size);

	idx_t maximum_size;
	data_ptr_t data;

	BinaryData blob;

public:
	void WriteData(const_data_ptr_t buffer, uint64_t write_size) override;

	//! Retrieves the data after the writing has been completed
	BinaryData GetData() {
		return std::move(blob);
	}
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

CatalogSet::CatalogSet(Catalog &catalog) : catalog(catalog) {
}

bool CatalogSet::CreateEntry(Transaction &transaction, const string &name, unique_ptr<CatalogEntry> value,
                             unordered_set<CatalogEntry *> &dependencies) {
	// lock the catalog for writing
	lock_guard<mutex> write_lock(catalog.write_lock);
	// lock this catalog set to disallow reading
	lock_guard<mutex> read_lock(catalog_lock);

	// first check if the entry exists in the unordered set
	auto entry = data.find(name);
	if (entry == data.end()) {
		// if it does not: entry has never been created

		// first create a dummy deleted entry for this entry
		// so transactions started before the commit of this transaction don't
		// see it yet
		auto dummy_node = make_unique<CatalogEntry>(CatalogType::INVALID, value->catalog, name);
		dummy_node->timestamp = 0;
		dummy_node->deleted = true;
		dummy_node->set = this;
		data[name] = move(dummy_node);
	} else {
		// if it does, we have to check version numbers
		CatalogEntry &current = *entry->second;
		if (HasConflict(transaction, current)) {
			// current version has been written to by a currently active
			// transaction
			throw TransactionException("Catalog write-write conflict on create with \"%s\"", current.name.c_str());
		}
		// there is a current version that has been committed
		// if it has not been deleted there is a conflict
		if (!current.deleted) {
			return false;
		}
	}
	// create a new entry and replace the currently stored one
	// set the timestamp to the timestamp of the current transaction
	// and point it at the dummy node
	value->timestamp = transaction.transaction_id;
	value->set = this;

	// now add the dependency set of this object to the dependency manager
	catalog.dependency_manager.AddObject(transaction, value.get(), dependencies);

	value->child = move(data[name]);
	value->child->parent = value.get();
	// push the old entry in the undo buffer for this transaction
	transaction.PushCatalogEntry(value->child.get());
	data[name] = move(value);
	return true;
}

bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInfo *alter_info) {
	auto &transaction = Transaction::GetTransaction(context);
	// lock the catalog for writing
	lock_guard<mutex> write_lock(catalog.write_lock);

	// first check if the entry exists in the unordered set
	auto entry = data.find(name);
	if (entry == data.end()) {
		// if it does not: entry has never been created and cannot be altered
		return false;
	}
	// if it does: we have to retrieve the entry and to check version numbers
	CatalogEntry &current = *entry->second;
	if (HasConflict(transaction, current)) {
		// current version has been written to by a currently active
		// transaction
		throw TransactionException("Catalog write-write conflict on alter with \"%s\"", current.name.c_str());
	}

	// lock this catalog set to disallow reading
	lock_guard<mutex> read_lock(catalog_lock);

	// create a new entry and replace the currently stored one
	// set the timestamp to the timestamp of the current transaction
	// and point it to the updated table node
	auto value = current.AlterEntry(context, alter_info);

	// now transfer all dependencies from the old table to the new table
	catalog.dependency_manager.AlterObject(transaction, data[name].get(), value.get());

	value->timestamp = transaction.transaction_id;
	value->child = move(data[name]);
	value->child->parent = value.get();
	value->set = this;

	// serialize the AlterInfo into a temporary buffer
	BufferedSerializer serializer;
	alter_info->Serialize(serializer);
	BinaryData serialized_alter = serializer.GetData();

	// push the old entry in the undo buffer for this transaction
	transaction.PushCatalogEntry(value->child.get(), serialized_alter.data.get(), serialized_alter.size);
	data[name] = move(value);

	return true;
}

bool CatalogSet::DropEntry(Transaction &transaction, const string &name, bool cascade) {
	// lock the catalog for writing
	lock_guard<mutex> write_lock(catalog.write_lock);
	// we can only delete an entry that exists
	auto entry = data.find(name);
	if (entry == data.end()) {
		return false;
	}
	if (HasConflict(transaction, *entry->second)) {
		// current version has been written to by a currently active transaction
		throw TransactionException("Catalog write-write conflict on drop with \"%s\"", name.c_str());
	}
	// there is a current version that has been committed by this transaction
	if (entry->second->deleted) {
		// if the entry was already deleted, it now does not exist anymore
		// so we return that we could not find it
		return false;
	}

	// lock this catalog for reading
	// create the lock set for this delete operation
	set_lock_map_t lock_set;
	// now drop the entry
	DropEntryInternal(transaction, *entry->second, cascade, lock_set);

	return true;
}

void CatalogSet::DropEntryInternal(Transaction &transaction, CatalogEntry &current, bool cascade,
                                   set_lock_map_t &lock_set) {
	assert(data.find(current.name) != data.end());
	// first check any dependencies of this object
	current.catalog->dependency_manager.DropObject(transaction, &current, cascade, lock_set);

	// add this catalog to the lock set, if it is not there yet
	if (lock_set.find(this) == lock_set.end()) {
		lock_set.insert(make_pair(this, unique_lock<mutex>(catalog_lock)));
	}

	// create a new entry and replace the currently stored one
	// set the timestamp to the timestamp of the current transaction
	// and point it at the dummy node
	auto value = make_unique<CatalogEntry>(CatalogType::DELETED_ENTRY, current.catalog, current.name);
	value->timestamp = transaction.transaction_id;
	value->child = move(data[current.name]);
	value->child->parent = value.get();
	value->set = this;
	value->deleted = true;

	// push the old entry in the undo buffer for this transaction
	transaction.PushCatalogEntry(value->child.get());

	data[current.name] = move(value);
}

bool CatalogSet::HasConflict(Transaction &transaction, CatalogEntry &current) {
	return (current.timestamp >= TRANSACTION_ID_START && current.timestamp != transaction.transaction_id) ||
	       (current.timestamp < TRANSACTION_ID_START && current.timestamp > transaction.start_time);
}

CatalogEntry *CatalogSet::GetEntryForTransaction(Transaction &transaction, CatalogEntry *current) {
	while (current->child) {
		if (current->timestamp == transaction.transaction_id) {
			// we created this version
			break;
		}
		if (current->timestamp < transaction.start_time) {
			// this version was commited before we started the transaction
			break;
		}
		current = current->child.get();
		assert(current);
	}
	return current;
}

CatalogEntry *CatalogSet::GetEntry(Transaction &transaction, const string &name) {
	lock_guard<mutex> lock(catalog_lock);

	auto entry = data.find(name);
	if (entry == data.end()) {
		return nullptr;
	}
	// if it does, we have to check version numbers
	CatalogEntry *current = GetEntryForTransaction(transaction, entry->second.get());
	if (current->deleted) {
		return nullptr;
	}
	return current;
}

CatalogEntry *CatalogSet::GetRootEntry(const string &name) {
	lock_guard<mutex> lock(catalog_lock);
	auto entry = data.find(name);
	return entry == data.end() ? nullptr : entry->second.get();
}

void CatalogSet::Undo(CatalogEntry *entry) {
	lock_guard<mutex> lock(catalog_lock);

	// entry has to be restored
	// and entry->parent has to be removed ("rolled back")

	// i.e. we have to place (entry) as (entry->parent) again
	auto &to_be_removed_node = entry->parent;
	if (!to_be_removed_node->deleted) {
		// delete the entry from the dependency manager as well
		catalog.dependency_manager.EraseObject(to_be_removed_node);
	}
	if (to_be_removed_node->parent) {
		// if the to be removed node has a parent, set the child pointer to the
		// to be restored node
		to_be_removed_node->parent->child = move(to_be_removed_node->child);
		entry->parent = to_be_removed_node->parent;
	} else {
		// otherwise we need to update the base entry tables
		auto &name = entry->name;
		data[name] = move(to_be_removed_node->child);
		entry->parent = nullptr;
	}
}




using namespace duckdb;
using namespace std;

DependencyManager::DependencyManager(Catalog &catalog) : catalog(catalog) {
}

void DependencyManager::AddObject(Transaction &transaction, CatalogEntry *object,
                                  unordered_set<CatalogEntry *> &dependencies) {
	// check for each object in the sources if they were not deleted yet
	for (auto &dependency : dependencies) {
		auto entry = dependency->set->data.find(dependency->name);
		assert(entry != dependency->set->data.end());

		if (CatalogSet::HasConflict(transaction, *entry->second)) {
			// transaction conflict with this entry
			throw TransactionException("Catalog write-write conflict on create with \"%s\"", object->name.c_str());
		}
	}
	// add the object to the dependents_map of each object that it depends on
	for (auto &dependency : dependencies) {
		dependents_map[dependency].insert(object);
	}
	// create the dependents map for this object: it starts out empty
	dependents_map[object] = unordered_set<CatalogEntry *>();
	dependencies_map[object] = dependencies;
}

void DependencyManager::DropObject(Transaction &transaction, CatalogEntry *object, bool cascade,
                                   set_lock_map_t &lock_set) {
	assert(dependents_map.find(object) != dependents_map.end());

	// first check the objects that depend on this object
	auto &dependent_objects = dependents_map[object];
	for (auto &dep : dependent_objects) {
		// look up the entry in the catalog set
		auto &catalog_set = *dep->set;
		auto entry = catalog_set.data.find(dep->name);
		assert(entry != catalog_set.data.end());
		if (CatalogSet::HasConflict(transaction, *entry->second)) {
			// current version has been written to by a currently active transaction
			throw TransactionException("Catalog write-write conflict on drop with \"%s\": conflict with dependency",
			                           object->name.c_str());
		}
		// there is a current version that has been committed
		if (entry->second->deleted) {
			// the dependent object was already deleted, no conflict
			continue;
		}
		// conflict: attempting to delete this object but the dependent object still exists
		if (cascade) {
			// cascade: drop the dependent object
			catalog_set.DropEntryInternal(transaction, *entry->second, cascade, lock_set);
		} else {
			// no cascade and there are objects that depend on this object: throw error
			throw CatalogException("Cannot drop entry \"%s\" because there are entries that "
			                       "depend on it. Use DROP...CASCADE to drop all dependents.",
			                       object->name.c_str());
		}
	}
}

void DependencyManager::AlterObject(Transaction &transaction, CatalogEntry *old_obj, CatalogEntry *new_obj) {
	assert(dependents_map.find(old_obj) != dependents_map.end());
	assert(dependencies_map.find(old_obj) != dependencies_map.end());

	// first check the objects that depend on this object
	auto &dependent_objects = dependents_map[old_obj];
	for (auto &dep : dependent_objects) {
		// look up the entry in the catalog set
		auto &catalog_set = *dep->set;
		auto entry = catalog_set.data.find(dep->name);
		assert(entry != catalog_set.data.end());
		if (CatalogSet::HasConflict(transaction, *entry->second)) {
			// current version has been written to by a currently active transaction
			throw TransactionException("Catalog write-write conflict on drop with \"%s\"", old_obj->name.c_str());
		}
		// there is a current version that has been committed
		if (entry->second->deleted) {
			// the dependent object was already deleted, no conflict
			continue;
		}
		// conflict: attempting to alter this object but the dependent object still exists
		// no cascade and there are objects that depend on this object: throw error
		throw CatalogException("Cannot alter entry \"%s\" because there are entries that "
		                       "depend on it.",
		                       old_obj->name.c_str());
	}
	// add the new object to the dependents_map of each object that it depents on
	auto &old_dependencies = dependencies_map[old_obj];
	for (auto &dependency : old_dependencies) {
		dependents_map[dependency].insert(new_obj);
	}
	// add the new object to the dependency manager
	dependents_map[new_obj] = unordered_set<CatalogEntry *>();
	dependencies_map[new_obj] = old_dependencies;
}

void DependencyManager::EraseObject(CatalogEntry *object) {
	// obtain the writing lock
	lock_guard<mutex> write_lock(catalog.write_lock);
	EraseObjectInternal(object);
}

void DependencyManager::EraseObjectInternal(CatalogEntry *object) {
	if (dependents_map.find(object) == dependents_map.end()) {
		// dependencies already removed
		return;
	}
	assert(dependents_map.find(object) != dependents_map.end());
	assert(dependencies_map.find(object) != dependencies_map.end());
	// now for each of the dependencies, erase the entries from the dependents_map
	for (auto &dependency : dependencies_map[object]) {
		auto entry = dependents_map.find(dependency);
		if (entry != dependents_map.end()) {
			assert(entry->second.find(object) != entry->second.end());
			entry->second.erase(object);
		}
	}
	// erase the dependents and dependencies for this object
	dependents_map.erase(object);
	dependencies_map.erase(object);
}

void DependencyManager::ClearDependencies(CatalogSet &set) {
	// obtain the writing lock
	lock_guard<mutex> write_lock(catalog.write_lock);

	// iterate over the objects in the CatalogSet
	for (auto &entry : set.data) {
		CatalogEntry *centry = entry.second.get();
		while (centry) {
			EraseObjectInternal(centry);
			centry = centry->child.get();
		}
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/checksum.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Compute a checksum over a buffer of size size
uint64_t Checksum(uint8_t *buffer, size_t size);

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/types/hash.hpp
//
//
//===----------------------------------------------------------------------===//





#include <memory.h>

namespace duckdb {

// efficient hash function that maximizes the avalanche effect and minimizes
// bias
// see: https://nullprogram.com/blog/2018/07/31/
inline hash_t murmurhash32(uint32_t x) {
	return x * UINT32_C(0x85ebca6b);
}

inline hash_t murmurhash64(uint64_t x) {
	return x * UINT64_C(0xbf58476d1ce4e5b9);
}

template <class T> hash_t Hash(T value) {
	return murmurhash32(value);
}

//! Combine two hashes by XORing them
inline hash_t CombineHash(hash_t left, hash_t right) {
	return left ^ right;
}

template <> hash_t Hash(uint64_t val);
template <> hash_t Hash(int64_t val);
template <> hash_t Hash(float val);
template <> hash_t Hash(double val);
template <> hash_t Hash(const char *val);
template <> hash_t Hash(char *val);
template <> hash_t Hash(string_t val);
hash_t Hash(const char *val, size_t size);
hash_t Hash(char *val, size_t size);
hash_t Hash(uint8_t *val, size_t size);

} // namespace duckdb


using namespace std;

namespace duckdb {

uint64_t Checksum(uint8_t *buffer, size_t size) {
	uint64_t result = 5381;
	uint64_t *ptr = (uint64_t *)buffer;
	size_t i;
	// for efficiency, we first hash uint64_t values
	for (i = 0; i < size / 8; i++) {
		result ^= Hash(ptr[i]);
	}
	if (size - i * 8 > 0) {
		// the remaining 0-7 bytes we hash using a string hash
		result ^= Hash(buffer + i * 8, size - i * 8);
	}
	return result;
}

} // namespace duckdb


#include <limits>

using namespace duckdb;
using namespace std;

namespace duckdb {

const idx_t INVALID_INDEX = (idx_t)-1;
const row_t MAX_ROW_ID = 4611686018427388000ULL; // 2^62
const column_t COLUMN_IDENTIFIER_ROW_ID = (column_t)-1;
const sel_t ZERO_VECTOR[STANDARD_VECTOR_SIZE] = {0};
const double PI = 3.141592653589793;

const transaction_t TRANSACTION_ID_START = 4611686018427388000ULL;                  // 2^62
const transaction_t NOT_DELETED_ID = std::numeric_limits<transaction_t>::max() - 1; // 2^64 - 1
const transaction_t MAXIMUM_QUERY_ID = std::numeric_limits<transaction_t>::max();   // 2^64

uint64_t NextPowerOfTwo(uint64_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v |= v >> 16;
	v |= v >> 32;
	v++;
	return v;
}

} // namespace duckdb




using namespace std;

namespace duckdb {

string CatalogTypeToString(CatalogType type) {
	switch (type) {
	case CatalogType::TABLE:
		return "Table";
	case CatalogType::SCHEMA:
		return "Schema";
	case CatalogType::TABLE_FUNCTION:
		return "Table Function";
	case CatalogType::SCALAR_FUNCTION:
		return "Scalar Function";
	case CatalogType::AGGREGATE_FUNCTION:
		return "Aggregate Function";
	case CatalogType::VIEW:
		return "View";
	case CatalogType::INDEX:
		return "Index";
	case CatalogType::PREPARED_STATEMENT:
		return "Prepared Statement";
	case CatalogType::SEQUENCE:
		return "Sequence";
	default:
		return "Unknown";
	}
}

} // namespace duckdb




using namespace std;

namespace duckdb {

string ExpressionTypeToString(ExpressionType type) {
	switch (type) {
	case ExpressionType::OPERATOR_CAST:
		return "CAST";
	case ExpressionType::OPERATOR_NOT:
		return "NOT";
	case ExpressionType::OPERATOR_IS_NULL:
		return "IS_NULL";
	case ExpressionType::OPERATOR_IS_NOT_NULL:
		return "IS_NOT_NULL";
	case ExpressionType::COMPARE_EQUAL:
		return "EQUAL";
	case ExpressionType::COMPARE_NOTEQUAL:
		return "NOTEQUAL";
	case ExpressionType::COMPARE_LESSTHAN:
		return "LESSTHAN";
	case ExpressionType::COMPARE_GREATERTHAN:
		return "GREATERTHAN";
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return "LESSTHANOREQUALTO";
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		return "GREATERTHANOREQUALTO";
	case ExpressionType::COMPARE_IN:
		return "IN";
	case ExpressionType::COMPARE_DISTINCT_FROM:
		return "DISTINCT_FROM";
	case ExpressionType::CONJUNCTION_AND:
		return "AND";
	case ExpressionType::CONJUNCTION_OR:
		return "OR";
	case ExpressionType::VALUE_CONSTANT:
		return "CONSTANT";
	case ExpressionType::VALUE_PARAMETER:
		return "PARAMETER";
	case ExpressionType::VALUE_TUPLE:
		return "TUPLE";
	case ExpressionType::VALUE_TUPLE_ADDRESS:
		return "TUPLE_ADDRESS";
	case ExpressionType::VALUE_NULL:
		return "NULL";
	case ExpressionType::VALUE_VECTOR:
		return "VECTOR";
	case ExpressionType::VALUE_SCALAR:
		return "SCALAR";
	case ExpressionType::AGGREGATE:
		return "AGGREGATE";
	case ExpressionType::WINDOW_AGGREGATE:
		return "WINDOW_AGGREGATE";
	case ExpressionType::WINDOW_RANK:
		return "RANK";
	case ExpressionType::WINDOW_RANK_DENSE:
		return "RANK_DENSE";
	case ExpressionType::WINDOW_PERCENT_RANK:
		return "PERCENT_RANK";
	case ExpressionType::WINDOW_ROW_NUMBER:
		return "ROW_NUMBER";
	case ExpressionType::WINDOW_FIRST_VALUE:
		return "FIRST_VALUE";
	case ExpressionType::WINDOW_LAST_VALUE:
		return "LAST_VALUE";
	case ExpressionType::WINDOW_CUME_DIST:
		return "CUME_DIST";
	case ExpressionType::WINDOW_LEAD:
		return "LEAD";
	case ExpressionType::WINDOW_LAG:
		return "LAG";
	case ExpressionType::WINDOW_NTILE:
		return "NTILE";
	case ExpressionType::FUNCTION:
		return "FUNCTION";
	case ExpressionType::CASE_EXPR:
		return "CASE";
	case ExpressionType::OPERATOR_NULLIF:
		return "NULLIF";
	case ExpressionType::OPERATOR_COALESCE:
		return "COALESCE";
	case ExpressionType::SUBQUERY:
		return "SUBQUERY";
	case ExpressionType::STAR:
		return "STAR";
	case ExpressionType::PLACEHOLDER:
		return "PLACEHOLDER";
	case ExpressionType::COLUMN_REF:
		return "COLUMN_REF";
	case ExpressionType::FUNCTION_REF:
		return "FUNCTION_REF";
	case ExpressionType::TABLE_REF:
		return "TABLE_REF";
	case ExpressionType::CAST:
		return "CAST";
	case ExpressionType::COMPARE_NOT_IN:
		return "COMPARE_NOT_IN";
	case ExpressionType::COMPARE_BETWEEN:
		return "COMPARE_BETWEEN";
	case ExpressionType::COMPARE_NOT_BETWEEN:
		return "COMPARE_NOT_BETWEEN";
	case ExpressionType::VALUE_DEFAULT:
		return "VALUE_DEFAULT";
	case ExpressionType::COMMON_SUBEXPRESSION:
		return "COMMON_SUBEXPRESSION";
	case ExpressionType::BOUND_REF:
		return "BOUND_REF";
	case ExpressionType::BOUND_COLUMN_REF:
		return "BOUND_COLUMN_REF";
	case ExpressionType::BOUND_FUNCTION:
		return "BOUND_FUNCTION";
	case ExpressionType::BOUND_AGGREGATE:
		return "BOUND_AGGREGATE";
	case ExpressionType::INVALID:
	default:
		return "INVALID";
	}
}

string ExpressionTypeToOperator(ExpressionType type) {
	switch (type) {
	case ExpressionType::OPERATOR_NOT:
		return "!";
	case ExpressionType::COMPARE_EQUAL:
		return "=";
	case ExpressionType::COMPARE_NOTEQUAL:
		return "!=";
	case ExpressionType::COMPARE_LESSTHAN:
		return "<";
	case ExpressionType::COMPARE_GREATERTHAN:
		return ">";
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return "<=";
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		return ">=";
	case ExpressionType::CONJUNCTION_AND:
		return "AND";
	case ExpressionType::CONJUNCTION_OR:
		return "OR";
	case ExpressionType::STAR:
		return "*";
	default:
		return "";
	}
}

ExpressionType NegateComparisionExpression(ExpressionType type) {
	ExpressionType negated_type = ExpressionType::INVALID;
	switch (type) {
	case ExpressionType::COMPARE_EQUAL:
		negated_type = ExpressionType::COMPARE_NOTEQUAL;
		break;
	case ExpressionType::COMPARE_NOTEQUAL:
		negated_type = ExpressionType::COMPARE_EQUAL;
		break;
	case ExpressionType::COMPARE_LESSTHAN:
		negated_type = ExpressionType::COMPARE_GREATERTHANOREQUALTO;
		break;
	case ExpressionType::COMPARE_GREATERTHAN:
		negated_type = ExpressionType::COMPARE_LESSTHANOREQUALTO;
		break;
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		negated_type = ExpressionType::COMPARE_GREATERTHAN;
		break;
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		negated_type = ExpressionType::COMPARE_LESSTHAN;
		break;

	default:
		throw Exception("Unsupported comparison type in negation");
	}
	return negated_type;
}

ExpressionType FlipComparisionExpression(ExpressionType type) {
	ExpressionType flipped_type = ExpressionType::INVALID;
	switch (type) {
	case ExpressionType::COMPARE_NOTEQUAL:
	case ExpressionType::COMPARE_EQUAL:
		flipped_type = type;
		break;
	case ExpressionType::COMPARE_LESSTHAN:
		flipped_type = ExpressionType::COMPARE_GREATERTHAN;
		break;
	case ExpressionType::COMPARE_GREATERTHAN:
		flipped_type = ExpressionType::COMPARE_LESSTHAN;
		break;
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		flipped_type = ExpressionType::COMPARE_GREATERTHANOREQUALTO;
		break;
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		flipped_type = ExpressionType::COMPARE_LESSTHANOREQUALTO;
		break;

	default:
		throw Exception("Unsupported comparison type in flip");
	}
	return flipped_type;
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/join_type.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//===--------------------------------------------------------------------===//
// Join Types
//===--------------------------------------------------------------------===//
enum class JoinType : uint8_t {
	INVALID = 0, // invalid join type
	LEFT = 1,    // left
	RIGHT = 2,   // right
	INNER = 3,   // inner
	OUTER = 4,   // outer
	SEMI = 5,    // SEMI join returns left side row ONLY if it has a join partner, no duplicates
	ANTI = 6,    // ANTI join returns left side row ONLY if it has NO join partner, no duplicates
	MARK = 7,    // MARK join returns marker indicating whether or not there is a join partner (true), there is no join
	             // partner (false)
	SINGLE = 8   // SINGLE join is like LEFT OUTER JOIN, BUT returns at most one join partner per entry on the LEFT side
	             // (and NULL if no partner is found)
};

string JoinTypeToString(JoinType type);

} // namespace duckdb


using namespace std;

namespace duckdb {

string JoinTypeToString(JoinType type) {
	switch (type) {
	case JoinType::LEFT:
		return "LEFT";
	case JoinType::RIGHT:
		return "RIGHT";
	case JoinType::INNER:
		return "INNER";
	case JoinType::OUTER:
		return "OUTER";
	case JoinType::SEMI:
		return "SEMI";
	case JoinType::ANTI:
		return "ANTI";
	case JoinType::SINGLE:
		return "SINGLE";
	case JoinType::MARK:
		return "MARK";
	case JoinType::INVALID:
	default:
		return "INVALID";
	}
}

} // namespace duckdb


using namespace std;

namespace duckdb {

//===--------------------------------------------------------------------===//
// Value <--> String Utilities
//===--------------------------------------------------------------------===//
string LogicalOperatorToString(LogicalOperatorType type) {
	switch (type) {
	case LogicalOperatorType::GET:
		return "GET";
	case LogicalOperatorType::CHUNK_GET:
		return "CHUNK_GET";
	case LogicalOperatorType::DELIM_GET:
		return "DELIM_GET";
	case LogicalOperatorType::EMPTY_RESULT:
		return "EMPTY_RESULT";
	case LogicalOperatorType::ANY_JOIN:
		return "ANY_JOIN";
	case LogicalOperatorType::COMPARISON_JOIN:
		return "COMPARISON_JOIN";
	case LogicalOperatorType::DELIM_JOIN:
		return "DELIM_JOIN";
	case LogicalOperatorType::PROJECTION:
		return "PROJECTION";
	case LogicalOperatorType::FILTER:
		return "FILTER";
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY:
		return "AGGREGATE_AND_GROUP_BY";
	case LogicalOperatorType::WINDOW:
		return "WINDOW";
	case LogicalOperatorType::UNNEST:
		return "UNNEST";
	case LogicalOperatorType::LIMIT:
		return "LIMIT";
	case LogicalOperatorType::ORDER_BY:
		return "ORDER_BY";
	case LogicalOperatorType::TOP_N:
		return "TOP_N";
	case LogicalOperatorType::COPY_TO_FILE:
		return "COPY_TO_FILE";
	case LogicalOperatorType::COPY_FROM_FILE:
		return "COPY_FROM_FILE";
	case LogicalOperatorType::JOIN:
		return "JOIN";
	case LogicalOperatorType::CROSS_PRODUCT:
		return "CROSS_PRODUCT";
	case LogicalOperatorType::UNION:
		return "UNION";
	case LogicalOperatorType::EXCEPT:
		return "EXCEPT";
	case LogicalOperatorType::INTERSECT:
		return "INTERSECT";
	case LogicalOperatorType::INSERT:
		return "INSERT";
	case LogicalOperatorType::DISTINCT:
		return "DISTINCT";
	case LogicalOperatorType::DELETE:
		return "DELETE";
	case LogicalOperatorType::UPDATE:
		return "UPDATE";
	case LogicalOperatorType::PREPARE:
		return "PREPARE";
	case LogicalOperatorType::PRUNE_COLUMNS:
		return "PRUNE";
	case LogicalOperatorType::TABLE_FUNCTION:
		return "TABLE_FUNCTION";
	case LogicalOperatorType::CREATE_INDEX:
		return "CREATE_INDEX";
	case LogicalOperatorType::CREATE_TABLE:
		return "CREATE_TABLE";
	case LogicalOperatorType::EXPLAIN:
		return "EXPLAIN";
	case LogicalOperatorType::EXECUTE:
		return "EXECUTE";
	case LogicalOperatorType::VACUUM:
		return "VACUUM";
	case LogicalOperatorType::INDEX_SCAN:
		return "INDEX_SCAN";
	case LogicalOperatorType::RECURSIVE_CTE:
		return "REC_CTE";
	case LogicalOperatorType::CTE_REF:
		return "CTE_SCAN";
	case LogicalOperatorType::INVALID:
	default:
		return "INVALID";
	}
}

} // namespace duckdb


using namespace std;

namespace duckdb {

string PhysicalOperatorToString(PhysicalOperatorType type) {
	switch (type) {
	case PhysicalOperatorType::LEAF:
		return "LEAF";
	case PhysicalOperatorType::DUMMY_SCAN:
		return "DUMMY_SCAN";
	case PhysicalOperatorType::SEQ_SCAN:
		return "SEQ_SCAN";
	case PhysicalOperatorType::INDEX_SCAN:
		return "INDEX_SCAN";
	case PhysicalOperatorType::CHUNK_SCAN:
		return "CHUNK_SCAN";
	case PhysicalOperatorType::DELIM_SCAN:
		return "DELIM_SCAN";
	case PhysicalOperatorType::EXTERNAL_FILE_SCAN:
		return "EXTERNAL_FILE_SCAN";
	case PhysicalOperatorType::QUERY_DERIVED_SCAN:
		return "QUERY_DERIVED_SCAN";
	case PhysicalOperatorType::ORDER_BY:
		return "ORDER_BY";
	case PhysicalOperatorType::LIMIT:
		return "LIMIT";
	case PhysicalOperatorType::TOP_N:
		return "TOP_N";
	case PhysicalOperatorType::AGGREGATE:
		return "AGGREGATE";
	case PhysicalOperatorType::WINDOW:
		return "WINDOW";
	case PhysicalOperatorType::UNNEST:
		return "UNNEST";
	case PhysicalOperatorType::DISTINCT:
		return "DISTINCT";
	case PhysicalOperatorType::SIMPLE_AGGREGATE:
		return "SIMPLE_AGGREGATE";
	case PhysicalOperatorType::HASH_GROUP_BY:
		return "HASH_GROUP_BY";
	case PhysicalOperatorType::SORT_GROUP_BY:
		return "SORT_GROUP_BY";
	case PhysicalOperatorType::FILTER:
		return "FILTER";
	case PhysicalOperatorType::PROJECTION:
		return "PROJECTION";
	case PhysicalOperatorType::COPY_FROM_FILE:
		return "COPY_FROM_FILE";
	case PhysicalOperatorType::COPY_TO_FILE:
		return "COPY_TO_FILE";
	case PhysicalOperatorType::DELIM_JOIN:
		return "DELIM_JOIN";
	case PhysicalOperatorType::BLOCKWISE_NL_JOIN:
		return "BLOCKWISE_NL_JOIN";
	case PhysicalOperatorType::NESTED_LOOP_JOIN:
		return "NESTED_LOOP_JOIN";
	case PhysicalOperatorType::HASH_JOIN:
		return "HASH_JOIN";
	case PhysicalOperatorType::PIECEWISE_MERGE_JOIN:
		return "PIECEWISE_MERGE_JOIN";
	case PhysicalOperatorType::CROSS_PRODUCT:
		return "CROSS_PRODUCT";
	case PhysicalOperatorType::UNION:
		return "UNION";
	case PhysicalOperatorType::INSERT:
		return "INSERT";
	case PhysicalOperatorType::INSERT_SELECT:
		return "INSERT_SELECT";
	case PhysicalOperatorType::DELETE:
		return "DELETE";
	case PhysicalOperatorType::UPDATE:
		return "UPDATE";
	case PhysicalOperatorType::EXPORT_EXTERNAL_FILE:
		return "EXPORT_EXTERNAL_FILE";
	case PhysicalOperatorType::PRUNE_COLUMNS:
		return "PRUNE";
	case PhysicalOperatorType::EMPTY_RESULT:
		return "EMPTY_RESULT";
	case PhysicalOperatorType::TABLE_FUNCTION:
		return "TABLE_FUNCTION";
	case PhysicalOperatorType::CREATE:
		return "CREATE";
	case PhysicalOperatorType::CREATE_INDEX:
		return "CREATE_INDEX";
	case PhysicalOperatorType::EXPLAIN:
		return "EXPLAIN";
	case PhysicalOperatorType::EXECUTE:
		return "EXECUTE";
	case PhysicalOperatorType::VACUUM:
		return "VACUUM";
	case PhysicalOperatorType::RECURSIVE_CTE:
		return "REC_CTE";
	case PhysicalOperatorType::INVALID:
	default:
		return "INVALID";
	}
}

} // namespace duckdb


using namespace std;

namespace duckdb {

string StatementTypeToString(StatementType type) {
	switch (type) {
	case StatementType::SELECT:
		return "SELECT";
	case StatementType::INSERT:
		return "INSERT";
	case StatementType::UPDATE:
		return "UPDATE";
	case StatementType::DELETE:
		return "DELETE";
	case StatementType::PREPARE:
		return "PREPARE";
	case StatementType::EXECUTE:
		return "EXECUTE";
	case StatementType::ALTER:
		return "ALTER";
	case StatementType::TRANSACTION:
		return "TRANSACTION";
	case StatementType::COPY:
		return "COPY";
	case StatementType::ANALYZE:
		return "ANALYZE";
	case StatementType::VARIABLE_SET:
		return "VARIABLE_SET";
	case StatementType::CREATE_FUNC:
		return "CREATE_FUNC";
	case StatementType::EXPLAIN:
		return "EXPLAIN";
	case StatementType::CREATE:
		return "CREATE";
	case StatementType::DROP:
		return "DROP";
	case StatementType::PRAGMA:
		return "PRAGMA";
	case StatementType::VACUUM:
		return "VACUUM";
	default:
		return "INVALID";
	}
}

} // namespace duckdb



using namespace duckdb;
using namespace std;

#define FORMAT_CONSTRUCTOR(msg)                                                                                        \
	va_list ap;                                                                                                        \
	va_start(ap, msg);                                                                                                 \
	Format(ap);                                                                                                        \
	va_end(ap);

Exception::Exception(string message) : std::exception(), type(ExceptionType::INVALID) {
	exception_message_ = message;
}

Exception::Exception(ExceptionType exception_type, string message) : std::exception(), type(exception_type) {
	exception_message_ = ExceptionTypeToString(exception_type) + ": " + message;
}

const char *Exception::what() const noexcept {
	return exception_message_.c_str();
}

void Exception::Format(va_list ap) {
	exception_message_ = StringUtil::VFormat(exception_message_, ap);
}

string Exception::ExceptionTypeToString(ExceptionType type) {
	switch (type) {
	case ExceptionType::INVALID:
		return "Invalid";
	case ExceptionType::OUT_OF_RANGE:
		return "Out of Range";
	case ExceptionType::CONVERSION:
		return "Conversion";
	case ExceptionType::UNKNOWN_TYPE:
		return "Unknown Type";
	case ExceptionType::DECIMAL:
		return "Decimal";
	case ExceptionType::MISMATCH_TYPE:
		return "Mismatch Type";
	case ExceptionType::DIVIDE_BY_ZERO:
		return "Divide by Zero";
	case ExceptionType::OBJECT_SIZE:
		return "Object Size";
	case ExceptionType::INVALID_TYPE:
		return "Invalid type";
	case ExceptionType::SERIALIZATION:
		return "Serialization";
	case ExceptionType::TRANSACTION:
		return "TransactionContext";
	case ExceptionType::NOT_IMPLEMENTED:
		return "Not implemented";
	case ExceptionType::EXPRESSION:
		return "Expression";
	case ExceptionType::CATALOG:
		return "Catalog";
	case ExceptionType::PARSER:
		return "Parser";
	case ExceptionType::PLANNER:
		return "Planner";
	case ExceptionType::SCHEDULER:
		return "Scheduler";
	case ExceptionType::EXECUTOR:
		return "Executor";
	case ExceptionType::CONSTRAINT:
		return "Constraint";
	case ExceptionType::INDEX:
		return "Index";
	case ExceptionType::STAT:
		return "Stat";
	case ExceptionType::CONNECTION:
		return "Connection";
	case ExceptionType::SYNTAX:
		return "Syntax";
	case ExceptionType::SETTINGS:
		return "Settings";
	case ExceptionType::OPTIMIZER:
		return "Optimizer";
	case ExceptionType::NULL_POINTER:
		return "NullPointer";
	case ExceptionType::IO:
		return "IO";
	case ExceptionType::INTERRUPT:
		return "INTERRUPT";
	case ExceptionType::FATAL:
		return "FATAL";
	case ExceptionType::INTERNAL:
		return "INTERNAL";
	default:
		return "Unknown";
	}
}

CastException::CastException(const TypeId origType, const TypeId newType)
    : Exception(ExceptionType::CONVERSION,
                "Type " + TypeIdToString(origType) + " can't be cast as " + TypeIdToString(newType)) {
}

ValueOutOfRangeException::ValueOutOfRangeException(const int64_t value, const TypeId origType, const TypeId newType)
    : Exception(ExceptionType::CONVERSION, "Type " + TypeIdToString(origType) + " with value " +
                                               std::to_string((intmax_t)value) +
                                               " can't be cast because the value is out of range "
                                               "for the destination type " +
                                               TypeIdToString(newType)) {
}

ValueOutOfRangeException::ValueOutOfRangeException(const double value, const TypeId origType, const TypeId newType)
    : Exception(ExceptionType::CONVERSION, "Type " + TypeIdToString(origType) + " with value " + std::to_string(value) +
                                               " can't be cast because the value is out of range "
                                               "for the destination type " +
                                               TypeIdToString(newType)) {
}

ValueOutOfRangeException::ValueOutOfRangeException(const TypeId varType, const idx_t length)
    : Exception(ExceptionType::OUT_OF_RANGE, "The value is too long to fit into type " + TypeIdToString(varType) + "(" +
                                                 std::to_string(length) + ")"){};

ConversionException::ConversionException(string msg, ...) : Exception(ExceptionType::CONVERSION, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

InvalidTypeException::InvalidTypeException(TypeId type, string msg)
    : Exception(ExceptionType::INVALID_TYPE, "Invalid Type [" + TypeIdToString(type) + "]: " + msg) {
}

TypeMismatchException::TypeMismatchException(const TypeId type_1, const TypeId type_2, string msg)
    : Exception(ExceptionType::MISMATCH_TYPE,
                "Type " + TypeIdToString(type_1) + " does not match with " + TypeIdToString(type_2) + ". " + msg) {
}

TransactionException::TransactionException(string msg, ...) : Exception(ExceptionType::TRANSACTION, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

NotImplementedException::NotImplementedException(string msg, ...) : Exception(ExceptionType::NOT_IMPLEMENTED, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

OutOfRangeException::OutOfRangeException(string msg, ...) : Exception(ExceptionType::OUT_OF_RANGE, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

CatalogException::CatalogException(string msg, ...) : StandardException(ExceptionType::CATALOG, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

ParserException::ParserException(string msg, ...) : StandardException(ExceptionType::PARSER, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

SyntaxException::SyntaxException(string msg, ...) : Exception(ExceptionType::SYNTAX, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

ConstraintException::ConstraintException(string msg, ...) : Exception(ExceptionType::CONSTRAINT, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

BinderException::BinderException(string msg, ...) : StandardException(ExceptionType::BINDER, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

IOException::IOException(string msg, ...) : Exception(ExceptionType::IO, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

SerializationException::SerializationException(string msg, ...) : Exception(ExceptionType::SERIALIZATION, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

SequenceException::SequenceException(string msg, ...) : Exception(ExceptionType::SERIALIZATION, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

InterruptException::InterruptException() : Exception(ExceptionType::INTERRUPT, "Interrupted!") {
}

FatalException::FatalException(string msg, ...) : Exception(ExceptionType::FATAL, msg) {
	FORMAT_CONSTRUCTOR(msg);
}

InternalException::InternalException(string msg, ...) : Exception(ExceptionType::INTERNAL, msg) {
	FORMAT_CONSTRUCTOR(msg);
}






#include <cstring>

using namespace duckdb;
using namespace std;

FileBuffer::FileBuffer(FileBufferType type, uint64_t bufsiz) : type(type) {
	const int SECTOR_SIZE = Storage::SECTOR_SIZE;
	// round up to the nearest SECTOR_SIZE, thi sis only really necessary if the file buffer will be used for Direct IO
	if (bufsiz % SECTOR_SIZE != 0) {
		bufsiz += SECTOR_SIZE - (bufsiz % SECTOR_SIZE);
	}
	assert(bufsiz % SECTOR_SIZE == 0);
	assert(bufsiz >= SECTOR_SIZE);
	// we add (SECTOR_SIZE - 1) to ensure that we can align the buffer to SECTOR_SIZE
	malloced_buffer = (data_ptr_t)malloc(bufsiz + (SECTOR_SIZE - 1));
	if (!malloced_buffer) {
		throw std::bad_alloc();
	}
	// round to multiple of SECTOR_SIZE
	uint64_t num = (uint64_t)malloced_buffer;
	uint64_t remainder = num % SECTOR_SIZE;
	if (remainder != 0) {
		num = num + SECTOR_SIZE - remainder;
	}
	assert(num % SECTOR_SIZE == 0);
	assert(num + bufsiz <= ((uint64_t)malloced_buffer + bufsiz + (SECTOR_SIZE - 1)));
	assert(num >= (uint64_t)malloced_buffer);
	// construct the FileBuffer object
	internal_buffer = (data_ptr_t)num;
	internal_size = bufsiz;
	buffer = internal_buffer + Storage::BLOCK_HEADER_SIZE;
	size = internal_size - Storage::BLOCK_HEADER_SIZE;
}

FileBuffer::~FileBuffer() {
	free(malloced_buffer);
}

void FileBuffer::Read(FileHandle &handle, uint64_t location) {
	// read the buffer from disk
	handle.Read(internal_buffer, internal_size, location);
	// compute the checksum
	uint64_t stored_checksum = *((uint64_t *)internal_buffer);
	uint64_t computed_checksum = Checksum(buffer, size);
	// verify the checksum
	if (stored_checksum != computed_checksum) {
		throw IOException("Corrupt database file: computed checksum %llu does not match stored checksum %llu in block",
		                  computed_checksum, stored_checksum);
	}
}

void FileBuffer::Write(FileHandle &handle, uint64_t location) {
	// compute the checksum and write it to the start of the buffer
	uint64_t checksum = Checksum(buffer, size);
	*((uint64_t *)internal_buffer) = checksum;
	// now write the buffer
	handle.Write(internal_buffer, internal_size, location);
}

void FileBuffer::Clear() {
	memset(internal_buffer, 0, internal_size);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/fstream_util.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/fstream.hpp
//
//
//===----------------------------------------------------------------------===//



#include <fstream>
#include <iosfwd>

namespace duckdb {
using std::endl;
using std::fstream;
using std::ifstream;
using std::ios;
using std::ios_base;
using std::ofstream;
} // namespace duckdb


namespace duckdb {
/**
 * Fstream Utility Functions
 */
class FstreamUtil {
public:
	/**
	 * Opens a file for the given name and returns it (default mode : ios_base::in | ios_base::out)
	 */
	static void OpenFile(const string &, fstream &,
	                     ios_base::openmode mode = ios_base::in | ios_base::out | ios::binary);

	/**
	 * Closes the given file or throws an exception otherwise
	 */
	static void CloseFile(fstream &);

	/**
	 * Returns the size in bytes of the given file
	 */
	static idx_t GetFileSize(fstream &);

	/**
	 * Reads the given file as a binary
	 */
	static data_ptr ReadBinary(fstream &);
};
} // namespace duckdb


using namespace std;
using namespace duckdb;

void FstreamUtil::OpenFile(const string &file_path, fstream &new_file, ios_base::openmode mode) {
	new_file.open(file_path, mode);
	if (!new_file.good()) {
		throw IOException("Could not open File!" + file_path);
	}
}

void FstreamUtil::CloseFile(fstream &file) {
	file.close();
	// check the success of the write
	if (file.fail()) {
		throw IOException("Failed to close the file!");
	}
}

idx_t FstreamUtil::GetFileSize(fstream &file) {
	file.seekg(0, ios::end);
	return file.tellg();
}

data_ptr FstreamUtil::ReadBinary(fstream &file) {
	auto file_size = GetFileSize(file);
	file.seekg(0, ios::beg);
	auto result = data_ptr(new char[file_size]);
	file.read(result.get(), file_size);

	return result;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/gzip_stream.hpp
//
//
//===----------------------------------------------------------------------===//





#include <fstream>
#include <sstream>

namespace duckdb {

class GzipStreamBuf : public std::streambuf {
public:
	GzipStreamBuf(std::string filename) : filename(filename) {
	}

	GzipStreamBuf(const GzipStreamBuf &) = delete;
	GzipStreamBuf(GzipStreamBuf &&) = default;
	GzipStreamBuf &operator=(const GzipStreamBuf &) = delete;
	GzipStreamBuf &operator=(GzipStreamBuf &&) = default;

	~GzipStreamBuf();

	std::streambuf::int_type underflow() override;

private:
	void initialize();
	std::fstream input;
	idx_t data_start = 0;
	void *mz_stream_ptr = nullptr; // void* so we don't have to include the header
	data_ptr_t in_buff = nullptr, in_buff_start, in_buff_end, out_buff = nullptr; // various buffers & pointers
	bool is_initialized = false;
	std::string filename;
	idx_t BUFFER_SIZE = 1024;
};

class GzipStream : public std::istream {
public:
	GzipStream(std::string filename) : std::istream(new GzipStreamBuf(filename)) {
		exceptions(std::ios_base::badbit);
	}
	~GzipStream() {
		if (rdbuf())
			delete rdbuf();
	}
}; // class istream

} // namespace duckdb






/* miniz.c 2.0.8 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
   See "unlicense" statement at the end of this file.
   Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
   Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt

   Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
   MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).

   * Low-level Deflate/Inflate implementation notes:

     Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
     greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
     approximately as well as zlib.

     Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
     coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
     block large enough to hold the entire file.

     The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.

   * zlib-style API notes:

     miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
     zlib replacement in many apps:
        The z_stream struct, optional memory allocation callbacks
        deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
        inflateInit/inflateInit2/inflate/inflateEnd
        compress, compress2, compressBound, uncompress
        CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
        Supports raw deflate streams or standard zlib streams with adler-32 checking.

     Limitations:
      The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
      I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
      there are no guarantees that miniz.c pulls this off perfectly.

   * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
     Alex Evans. Supports 1-4 bytes/pixel images.

   * ZIP archive API notes:

     The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
     get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
     existing archives, create new archives, append new files to existing archives, or clone archive data from
     one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
     or you can specify custom file read/write callbacks.

     - Archive reading: Just call this function to read a single file from a disk archive:

      void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
        size_t *pSize, mz_uint zip_flags);

     For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
     directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.

     - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:

     int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);

     The locate operation can optionally check file comments too, which (as one example) can be used to identify
     multiple versions of the same file in an archive. This function uses a simple linear search through the central
     directory, so it's not very fast.

     Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
     retrieve detailed info on each file by calling mz_zip_reader_file_stat().

     - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
     to disk and builds an exact image of the central directory in memory. The central directory image is written
     all at once at the end of the archive file when the archive is finalized.

     The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
     which can be useful when the archive will be read from optical media. Also, the writer supports placing
     arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
     readable by any ZIP tool.

     - Archive appending: The simple way to add a single file to an archive is to call this function:

      mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
        const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);

     The archive will be created if it doesn't already exist, otherwise it'll be appended to.
     Note the appending is done in-place and is not an atomic operation, so if something goes wrong
     during the operation it's possible the archive could be left without a central directory (although the local
     file headers and file data will be fine, so the archive will be recoverable).

     For more complex archive modification scenarios:
     1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
     preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
     compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
     you're done. This is safe but requires a bunch of temporary disk space or heap memory.

     2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
     append new files as needed, then finalize the archive which will write an updated central directory to the
     original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
     possibility that the archive's central directory could be lost with this method if anything goes wrong, though.

     - ZIP archive support limitations:
     No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
     Requires streams capable of seeking.

   * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
     below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.

   * Important: For best perf. be sure to customize the below macros for your target platform:
     #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
     #define MINIZ_LITTLE_ENDIAN 1
     #define MINIZ_HAS_64BIT_REGISTERS 1

   * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
     uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
     (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
*/






/* Defines to completely disable specific portions of miniz.c:
   If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */

/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
#define MINIZ_NO_STDIO

/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or */
/* get/set file times, and the C run-time funcs that get/set times won't be called. */
/* The current downside is the times written to your archives will be from 1979. */
/*#define MINIZ_NO_TIME */

/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */
#define MINIZ_NO_ARCHIVE_APIS

/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */
/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */

/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */
/*#define MINIZ_NO_ZLIB_APIS */

/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES

/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
   Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
   callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
   functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */
/*#define MINIZ_NO_MALLOC */

#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */
#define MINIZ_NO_TIME
#endif

#include <stddef.h>

#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
#include <time.h>
#endif

#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */
#define MINIZ_X86_OR_X64_CPU 1
#else
#define MINIZ_X86_OR_X64_CPU 0
#endif

#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
#define MINIZ_LITTLE_ENDIAN 1
#else
#define MINIZ_LITTLE_ENDIAN 0
#endif

#if MINIZ_X86_OR_X64_CPU
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
#else
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
#endif

#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */
#define MINIZ_HAS_64BIT_REGISTERS 1
#else
#define MINIZ_HAS_64BIT_REGISTERS 0
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* ------------------- zlib-style API Definitions. */

/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */
typedef unsigned long mz_ulong;

/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */
void mz_free(void *p);

#define MZ_ADLER32_INIT (1)
/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);

#define MZ_CRC32_INIT (0)
/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */
mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);

/* Compression strategies. */
enum
{
    MZ_DEFAULT_STRATEGY = 0,
    MZ_FILTERED = 1,
    MZ_HUFFMAN_ONLY = 2,
    MZ_RLE = 3,
    MZ_FIXED = 4
};

/* Method */
#define MZ_DEFLATED 8

/* Heap allocation callbacks.
Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. */
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
typedef void (*mz_free_func)(void *opaque, void *address);
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);

/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */
enum
{
    MZ_NO_COMPRESSION = 0,
    MZ_BEST_SPEED = 1,
    MZ_BEST_COMPRESSION = 9,
    MZ_UBER_COMPRESSION = 10,
    MZ_DEFAULT_LEVEL = 6,
    MZ_DEFAULT_COMPRESSION = -1
};

#define MZ_VERSION "10.0.3"
#define MZ_VERNUM 0xA030
#define MZ_VER_MAJOR 10
#define MZ_VER_MINOR 0
#define MZ_VER_REVISION 3
#define MZ_VER_SUBREVISION 0

#ifndef MINIZ_NO_ZLIB_APIS

/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). */
enum
{
    MZ_NO_FLUSH = 0,
    MZ_PARTIAL_FLUSH = 1,
    MZ_SYNC_FLUSH = 2,
    MZ_FULL_FLUSH = 3,
    MZ_FINISH = 4,
    MZ_BLOCK = 5
};

/* Return status codes. MZ_PARAM_ERROR is non-standard. */
enum
{
    MZ_OK = 0,
    MZ_STREAM_END = 1,
    MZ_NEED_DICT = 2,
    MZ_ERRNO = -1,
    MZ_STREAM_ERROR = -2,
    MZ_DATA_ERROR = -3,
    MZ_MEM_ERROR = -4,
    MZ_BUF_ERROR = -5,
    MZ_VERSION_ERROR = -6,
    MZ_PARAM_ERROR = -10000
};

/* Window bits */
#define MZ_DEFAULT_WINDOW_BITS 15

struct mz_internal_state;

/* Compression/decompression stream struct. */
typedef struct mz_stream_s
{
    const unsigned char *next_in; /* pointer to next byte to read */
    unsigned int avail_in;        /* number of bytes available at next_in */
    mz_ulong total_in;            /* total number of bytes consumed so far */

    unsigned char *next_out; /* pointer to next byte to write */
    unsigned int avail_out;  /* number of bytes that can be written to next_out */
    mz_ulong total_out;      /* total number of bytes produced so far */

    char *msg;                       /* error msg (unused) */
    struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */

    mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */
    mz_free_func zfree;   /* optional heap free function (defaults to free) */
    void *opaque;         /* heap alloc function user pointer */

    int data_type;     /* data_type (unused) */
    mz_ulong adler;    /* adler32 of the source or uncompressed data */
    mz_ulong reserved; /* not used */
} mz_stream;

typedef mz_stream *mz_streamp;

/* Returns the version string of miniz.c. */
const char *mz_version(void);

/* mz_deflateInit() initializes a compressor with default options: */
/* Parameters: */
/*  pStream must point to an initialized mz_stream struct. */
/*  level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. */
/*  level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. */
/*  (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) */
/* Return values: */
/*  MZ_OK on success. */
/*  MZ_STREAM_ERROR if the stream is bogus. */
/*  MZ_PARAM_ERROR if the input parameters are bogus. */
/*  MZ_MEM_ERROR on out of memory. */
int mz_deflateInit(mz_streamp pStream, int level);

/* mz_deflateInit2() is like mz_deflate(), except with more control: */
/* Additional parameters: */
/*   method must be MZ_DEFLATED */
/*   window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */
/*   mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);

/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */
int mz_deflateReset(mz_streamp pStream);

/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */
/* Parameters: */
/*   pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */
/*   flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. */
/* Return values: */
/*   MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). */
/*   MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. */
/*   MZ_STREAM_ERROR if the stream is bogus. */
/*   MZ_PARAM_ERROR if one of the parameters is invalid. */
/*   MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */
int mz_deflate(mz_streamp pStream, int flush);

/* mz_deflateEnd() deinitializes a compressor: */
/* Return values: */
/*  MZ_OK on success. */
/*  MZ_STREAM_ERROR if the stream is bogus. */
int mz_deflateEnd(mz_streamp pStream);

/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);

/* Single-call compression functions mz_compress() and mz_compress2(): */
/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);

/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
mz_ulong mz_compressBound(mz_ulong source_len);

/* Initializes a decompressor. */
int mz_inflateInit(mz_streamp pStream);

/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */
int mz_inflateInit2(mz_streamp pStream, int window_bits);

/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */
/* Parameters: */
/*   pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */
/*   flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. */
/*   On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). */
/*   MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. */
/* Return values: */
/*   MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. */
/*   MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. */
/*   MZ_STREAM_ERROR if the stream is bogus. */
/*   MZ_DATA_ERROR if the deflate stream is invalid. */
/*   MZ_PARAM_ERROR if one of the parameters is invalid. */
/*   MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */
/*   with more input data, or with more room in the output buffer (except when using single call decompression, described above). */
int mz_inflate(mz_streamp pStream, int flush);

/* Deinitializes a decompressor. */
int mz_inflateEnd(mz_streamp pStream);

/* Single-call decompression. */
/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);

/* Returns a string description of the specified error code, or NULL if the error code is invalid. */
const char *mz_error(int err);

/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
typedef unsigned char Byte;
typedef unsigned int uInt;
typedef mz_ulong uLong;
typedef Byte Bytef;
typedef uInt uIntf;
typedef char charf;
typedef int intf;
typedef void *voidpf;
typedef uLong uLongf;
typedef void *voidp;
typedef void *const voidpc;
#define Z_NULL 0
#define Z_NO_FLUSH MZ_NO_FLUSH
#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
#define Z_FULL_FLUSH MZ_FULL_FLUSH
#define Z_FINISH MZ_FINISH
#define Z_BLOCK MZ_BLOCK
#define Z_OK MZ_OK
#define Z_STREAM_END MZ_STREAM_END
#define Z_NEED_DICT MZ_NEED_DICT
#define Z_ERRNO MZ_ERRNO
#define Z_STREAM_ERROR MZ_STREAM_ERROR
#define Z_DATA_ERROR MZ_DATA_ERROR
#define Z_MEM_ERROR MZ_MEM_ERROR
#define Z_BUF_ERROR MZ_BUF_ERROR
#define Z_VERSION_ERROR MZ_VERSION_ERROR
#define Z_PARAM_ERROR MZ_PARAM_ERROR
#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
#define Z_BEST_SPEED MZ_BEST_SPEED
#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
#define Z_FILTERED MZ_FILTERED
#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
#define Z_RLE MZ_RLE
#define Z_FIXED MZ_FIXED
#define Z_DEFLATED MZ_DEFLATED
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
#define alloc_func mz_alloc_func
#define free_func mz_free_func
#define internal_state mz_internal_state
#define z_stream mz_stream
#define deflateInit mz_deflateInit
#define deflateInit2 mz_deflateInit2
#define deflateReset mz_deflateReset
#define deflate mz_deflate
#define deflateEnd mz_deflateEnd
#define deflateBound mz_deflateBound
#define compress mz_compress
#define compress2 mz_compress2
#define compressBound mz_compressBound
#define inflateInit mz_inflateInit
#define inflateInit2 mz_inflateInit2
#define inflate mz_inflate
#define inflateEnd mz_inflateEnd
#define uncompress mz_uncompress
#define crc32 mz_crc32
#define adler32 mz_adler32
#define MAX_WBITS 15
#define MAX_MEM_LEVEL 9
#define zError mz_error
#define ZLIB_VERSION MZ_VERSION
#define ZLIB_VERNUM MZ_VERNUM
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
#define ZLIB_VER_MINOR MZ_VER_MINOR
#define ZLIB_VER_REVISION MZ_VER_REVISION
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
#define zlibVersion mz_version
#define zlib_version mz_version()
#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */

#endif /* MINIZ_NO_ZLIB_APIS */

#ifdef __cplusplus
}
#endif

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/* ------------------- Types and macros */
typedef unsigned char mz_uint8;
typedef signed short mz_int16;
typedef unsigned short mz_uint16;
typedef unsigned int mz_uint32;
typedef unsigned int mz_uint;
typedef int64_t mz_int64;
typedef uint64_t mz_uint64;
typedef int mz_bool;

#define MZ_FALSE (0)
#define MZ_TRUE (1)

/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */
#ifdef _MSC_VER
#define MZ_MACRO_END while (0, 0)
#else
#define MZ_MACRO_END while (0)
#endif

#ifdef MINIZ_NO_STDIO
#define MZ_FILE void *
#else
#include <stdio.h>
#define MZ_FILE FILE
#endif /* #ifdef MINIZ_NO_STDIO */

#ifdef MINIZ_NO_TIME
typedef struct mz_dummy_time_t_tag
{
    int m_dummy;
} mz_dummy_time_t;
#define MZ_TIME_T mz_dummy_time_t
#else
#define MZ_TIME_T time_t
#endif

#define MZ_ASSERT(x) assert(x)

#ifdef MINIZ_NO_MALLOC
#define MZ_MALLOC(x) NULL
#define MZ_FREE(x) (void)x, ((void)0)
#define MZ_REALLOC(p, x) NULL
#else
#define MZ_MALLOC(x) malloc(x)
#define MZ_FREE(x) free(x)
#define MZ_REALLOC(p, x) realloc(p, x)
#endif

#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))

#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
#else
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
#endif

#define MZ_READ_LE64(p) (((mz_uint64)MZ_READ_LE32(p)) | (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) << 32U))

#ifdef _MSC_VER
#define MZ_FORCEINLINE __forceinline
#elif defined(__GNUC__)
#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__))
#else
#define MZ_FORCEINLINE inline
#endif

#ifdef __cplusplus
extern "C" {
#endif

extern void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
extern void miniz_def_free_func(void *opaque, void *address);
extern void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);

#define MZ_UINT16_MAX (0xFFFFU)
#define MZ_UINT32_MAX (0xFFFFFFFFU)

#ifdef __cplusplus
}
#endif



#ifdef __cplusplus
extern "C" {
#endif
/* ------------------- Low-level Compression API Definitions */

/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */
#define TDEFL_LESS_MEMORY 0

/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */
/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */
enum
{
    TDEFL_HUFFMAN_ONLY = 0,
    TDEFL_DEFAULT_MAX_PROBES = 128,
    TDEFL_MAX_PROBES_MASK = 0xFFF
};

/* TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. */
/* TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). */
/* TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. */
/* TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). */
/* TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) */
/* TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. */
/* TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. */
/* TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. */
/* The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). */
enum
{
    TDEFL_WRITE_ZLIB_HEADER = 0x01000,
    TDEFL_COMPUTE_ADLER32 = 0x02000,
    TDEFL_GREEDY_PARSING_FLAG = 0x04000,
    TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
    TDEFL_RLE_MATCHES = 0x10000,
    TDEFL_FILTER_MATCHES = 0x20000,
    TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
    TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
};

/* High level compression functions: */
/* tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). */
/* On entry: */
/*  pSrc_buf, src_buf_len: Pointer and size of source block to compress. */
/*  flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. */
/* On return: */
/*  Function returns a pointer to the compressed data, or NULL on failure. */
/*  *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */
/*  The caller must free() the returned block when it's no longer needed. */
void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);

/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */
/* Returns 0 on failure. */
size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);

/* Compresses an image to a compressed PNG file in memory. */
/* On entry: */
/*  pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. */
/*  The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. */
/*  level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */
/*  If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). */
/* On return: */
/*  Function returns a pointer to the compressed data, or NULL on failure. */
/*  *pLen_out will be set to the size of the PNG image file. */
/*  The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);

/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);

/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */
mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);

enum
{
    TDEFL_MAX_HUFF_TABLES = 3,
    TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
    TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
    TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
    TDEFL_LZ_DICT_SIZE = 32768,
    TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
    TDEFL_MIN_MATCH_LEN = 3,
    TDEFL_MAX_MATCH_LEN = 258
};

/* TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). */
#if TDEFL_LESS_MEMORY
enum
{
    TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024,
    TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
    TDEFL_MAX_HUFF_SYMBOLS = 288,
    TDEFL_LZ_HASH_BITS = 12,
    TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
    TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
    TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
};
#else
enum
{
    TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
    TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
    TDEFL_MAX_HUFF_SYMBOLS = 288,
    TDEFL_LZ_HASH_BITS = 15,
    TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
    TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
    TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
};
#endif

/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */
typedef enum {
    TDEFL_STATUS_BAD_PARAM = -2,
    TDEFL_STATUS_PUT_BUF_FAILED = -1,
    TDEFL_STATUS_OKAY = 0,
    TDEFL_STATUS_DONE = 1
} tdefl_status;

/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
typedef enum {
    TDEFL_NO_FLUSH = 0,
    TDEFL_SYNC_FLUSH = 2,
    TDEFL_FULL_FLUSH = 3,
    TDEFL_FINISH = 4
} tdefl_flush;

/* tdefl's compression state structure. */
typedef struct
{
    tdefl_put_buf_func_ptr m_pPut_buf_func;
    void *m_pPut_buf_user;
    mz_uint m_flags, m_max_probes[2];
    int m_greedy_parsing;
    mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
    mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
    mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
    mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
    tdefl_status m_prev_return_status;
    const void *m_pIn_buf;
    void *m_pOut_buf;
    size_t *m_pIn_buf_size, *m_pOut_buf_size;
    tdefl_flush m_flush;
    const mz_uint8 *m_pSrc;
    size_t m_src_buf_left, m_out_buf_ofs;
    mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
    mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
    mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
    mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
    mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
    mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
    mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
    mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
} tdefl_compressor;

/* Initializes the compressor. */
/* There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. */
/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */
/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */
/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);

/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);

/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */
/* tdefl_compress_buffer() always consumes the entire input buffer. */
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);

tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
mz_uint32 tdefl_get_adler32(tdefl_compressor *d);

/* Create tdefl_compress() flags given zlib-style compression parameters. */
/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */
/* window_bits may be -15 (raw deflate) or 15 (zlib) */
/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);

/* Allocate the tdefl_compressor structure in C so that */
/* non-C language bindings to tdefl_ API don't need to worry about */
/* structure size and allocation mechanism. */
tdefl_compressor *tdefl_compressor_alloc();
void tdefl_compressor_free(tdefl_compressor *pComp);

#ifdef __cplusplus
}
#endif


/* ------------------- Low-level Decompression API Definitions */

#ifdef __cplusplus
extern "C" {
#endif
/* Decompression flags used by tinfl_decompress(). */
/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */
/* TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. */
/* TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). */
/* TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. */
enum
{
    TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
    TINFL_FLAG_HAS_MORE_INPUT = 2,
    TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
    TINFL_FLAG_COMPUTE_ADLER32 = 8
};

/* High level decompression functions: */
/* tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). */
/* On entry: */
/*  pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. */
/* On return: */
/*  Function returns a pointer to the decompressed data, or NULL on failure. */
/*  *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */
/*  The caller must call mz_free() on the returned block when it's no longer needed. */
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);

/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */
/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);

/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */
/* Returns 1 on success or 0 on failure. */
typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);

struct tinfl_decompressor_tag;
typedef struct tinfl_decompressor_tag tinfl_decompressor;

/* Allocate the tinfl_decompressor structure in C so that */
/* non-C language bindings to tinfl_ API don't need to worry about */
/* structure size and allocation mechanism. */

tinfl_decompressor *tinfl_decompressor_alloc();
void tinfl_decompressor_free(tinfl_decompressor *pDecomp);

/* Max size of LZ dictionary. */
#define TINFL_LZ_DICT_SIZE 32768

/* Return status. */
typedef enum {
    /* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
    /* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
    /* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
    TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,

    /* This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.) */
    TINFL_STATUS_BAD_PARAM = -3,

    /* This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE. */
    TINFL_STATUS_ADLER32_MISMATCH = -2,

    /* This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code. */
    TINFL_STATUS_FAILED = -1,

    /* Any status code less than TINFL_STATUS_DONE must indicate a failure. */

    /* This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and */
    /* if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again. */
    TINFL_STATUS_DONE = 0,

    /* This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT */
    /* flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to */
    /* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */
    TINFL_STATUS_NEEDS_MORE_INPUT = 1,

    /* This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer. */
    /* Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect */
    /* (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible */
    /* so I may need to add some code to address this. */
    TINFL_STATUS_HAS_MORE_OUTPUT = 2
} tinfl_status;

/* Initializes the decompressor to its initial state. */
#define tinfl_init(r)     \
    do                    \
    {                     \
        (r)->m_state = 0; \
    }                     \
    MZ_MACRO_END
#define tinfl_get_adler32(r) (r)->m_check_adler32

/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);

/* Internal/private bits follow. */
enum
{
    TINFL_MAX_HUFF_TABLES = 3,
    TINFL_MAX_HUFF_SYMBOLS_0 = 288,
    TINFL_MAX_HUFF_SYMBOLS_1 = 32,
    TINFL_MAX_HUFF_SYMBOLS_2 = 19,
    TINFL_FAST_LOOKUP_BITS = 10,
    TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
};

typedef struct
{
    mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
    mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;

#if MINIZ_HAS_64BIT_REGISTERS
#define TINFL_USE_64BIT_BITBUF 1
#else
#define TINFL_USE_64BIT_BITBUF 0
#endif

#if TINFL_USE_64BIT_BITBUF
typedef mz_uint64 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (64)
#else
typedef mz_uint32 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (32)
#endif

struct tinfl_decompressor_tag
{
    mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
    tinfl_bit_buf_t m_bit_buf;
    size_t m_dist_from_out_buf_start;
    tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
    mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};

#ifdef __cplusplus
}
#endif




/* ------------------- ZIP archive reading/writing */

#ifndef MINIZ_NO_ARCHIVE_APIS

#ifdef __cplusplus
extern "C" {
#endif

enum
{
    /* Note: These enums can be reduced as needed to save memory or stack space - they are pretty conservative. */
    MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
    MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512,
    MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512
};

typedef struct
{
    /* Central directory file index. */
    mz_uint32 m_file_index;

    /* Byte offset of this entry in the archive's central directory. Note we currently only support up to UINT_MAX or less bytes in the central dir. */
    mz_uint64 m_central_dir_ofs;

    /* These fields are copied directly from the zip's central dir. */
    mz_uint16 m_version_made_by;
    mz_uint16 m_version_needed;
    mz_uint16 m_bit_flag;
    mz_uint16 m_method;

#ifndef MINIZ_NO_TIME
    MZ_TIME_T m_time;
#endif

    /* CRC-32 of uncompressed data. */
    mz_uint32 m_crc32;

    /* File's compressed size. */
    mz_uint64 m_comp_size;

    /* File's uncompressed size. Note, I've seen some old archives where directory entries had 512 bytes for their uncompressed sizes, but when you try to unpack them you actually get 0 bytes. */
    mz_uint64 m_uncomp_size;

    /* Zip internal and external file attributes. */
    mz_uint16 m_internal_attr;
    mz_uint32 m_external_attr;

    /* Entry's local header file offset in bytes. */
    mz_uint64 m_local_header_ofs;

    /* Size of comment in bytes. */
    mz_uint32 m_comment_size;

    /* MZ_TRUE if the entry appears to be a directory. */
    mz_bool m_is_directory;

    /* MZ_TRUE if the entry uses encryption/strong encryption (which miniz_zip doesn't support) */
    mz_bool m_is_encrypted;

    /* MZ_TRUE if the file is not encrypted, a patch file, and if it uses a compression method we support. */
    mz_bool m_is_supported;

    /* Filename. If string ends in '/' it's a subdirectory entry. */
    /* Guaranteed to be zero terminated, may be truncated to fit. */
    char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];

    /* Comment field. */
    /* Guaranteed to be zero terminated, may be truncated to fit. */
    char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];

} mz_zip_archive_file_stat;

typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);

struct mz_zip_internal_state_tag;
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;

typedef enum {
    MZ_ZIP_MODE_INVALID = 0,
    MZ_ZIP_MODE_READING = 1,
    MZ_ZIP_MODE_WRITING = 2,
    MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
} mz_zip_mode;

typedef enum {
    MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
    MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
    MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
    MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
    MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */
    MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000,     /* validate the local headers, but don't decompress the entire file and check the crc32 */
    MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000,               /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */
    MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
    MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000
} mz_zip_flags;

typedef enum {
    MZ_ZIP_TYPE_INVALID = 0,
    MZ_ZIP_TYPE_USER,
    MZ_ZIP_TYPE_MEMORY,
    MZ_ZIP_TYPE_HEAP,
    MZ_ZIP_TYPE_FILE,
    MZ_ZIP_TYPE_CFILE,
    MZ_ZIP_TOTAL_TYPES
} mz_zip_type;

/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
typedef enum {
    MZ_ZIP_NO_ERROR = 0,
    MZ_ZIP_UNDEFINED_ERROR,
    MZ_ZIP_TOO_MANY_FILES,
    MZ_ZIP_FILE_TOO_LARGE,
    MZ_ZIP_UNSUPPORTED_METHOD,
    MZ_ZIP_UNSUPPORTED_ENCRYPTION,
    MZ_ZIP_UNSUPPORTED_FEATURE,
    MZ_ZIP_FAILED_FINDING_CENTRAL_DIR,
    MZ_ZIP_NOT_AN_ARCHIVE,
    MZ_ZIP_INVALID_HEADER_OR_CORRUPTED,
    MZ_ZIP_UNSUPPORTED_MULTIDISK,
    MZ_ZIP_DECOMPRESSION_FAILED,
    MZ_ZIP_COMPRESSION_FAILED,
    MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE,
    MZ_ZIP_CRC_CHECK_FAILED,
    MZ_ZIP_UNSUPPORTED_CDIR_SIZE,
    MZ_ZIP_ALLOC_FAILED,
    MZ_ZIP_FILE_OPEN_FAILED,
    MZ_ZIP_FILE_CREATE_FAILED,
    MZ_ZIP_FILE_WRITE_FAILED,
    MZ_ZIP_FILE_READ_FAILED,
    MZ_ZIP_FILE_CLOSE_FAILED,
    MZ_ZIP_FILE_SEEK_FAILED,
    MZ_ZIP_FILE_STAT_FAILED,
    MZ_ZIP_INVALID_PARAMETER,
    MZ_ZIP_INVALID_FILENAME,
    MZ_ZIP_BUF_TOO_SMALL,
    MZ_ZIP_INTERNAL_ERROR,
    MZ_ZIP_FILE_NOT_FOUND,
    MZ_ZIP_ARCHIVE_TOO_LARGE,
    MZ_ZIP_VALIDATION_FAILED,
    MZ_ZIP_WRITE_CALLBACK_FAILED,
    MZ_ZIP_TOTAL_ERRORS
} mz_zip_error;

typedef struct
{
    mz_uint64 m_archive_size;
    mz_uint64 m_central_directory_file_ofs;

    /* We only support up to UINT32_MAX files in zip64 mode. */
    mz_uint32 m_total_files;
    mz_zip_mode m_zip_mode;
    mz_zip_type m_zip_type;
    mz_zip_error m_last_error;

    mz_uint64 m_file_offset_alignment;

    mz_alloc_func m_pAlloc;
    mz_free_func m_pFree;
    mz_realloc_func m_pRealloc;
    void *m_pAlloc_opaque;

    mz_file_read_func m_pRead;
    mz_file_write_func m_pWrite;
    mz_file_needs_keepalive m_pNeeds_keepalive;
    void *m_pIO_opaque;

    mz_zip_internal_state *m_pState;

} mz_zip_archive;

typedef struct
{
    mz_zip_archive *pZip;
    mz_uint flags;

    int status;
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
    mz_uint file_crc32;
#endif
    mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs;
    mz_zip_archive_file_stat file_stat;
    void *pRead_buf;
    void *pWrite_buf;

    size_t out_blk_remain;

    tinfl_decompressor inflator;

} mz_zip_reader_extract_iter_state;

/* -------- ZIP reading */

/* Inits a ZIP archive reader. */
/* These functions read and validate the archive's central directory. */
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);

mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);

#ifndef MINIZ_NO_STDIO
/* Read a archive from a disk file. */
/* file_start_ofs is the file offset where the archive actually begins, or 0. */
/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);

/* Read an archive from an already opened FILE, beginning at the current file position. */
/* The archive is assumed to be archive_size bytes long. If archive_size is < 0, then the entire rest of the file is assumed to contain the archive. */
/* The FILE will NOT be closed when mz_zip_reader_end() is called. */
mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
#endif

/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */
mz_bool mz_zip_reader_end(mz_zip_archive *pZip);

/* -------- ZIP reading or writing */

/* Clears a mz_zip_archive struct to all zeros. */
/* Important: This must be done before passing the struct to any mz_zip functions. */
void mz_zip_zero_struct(mz_zip_archive *pZip);

mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);

/* Returns the total number of files in the archive. */
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);

mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);

/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);

/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
/* Note that the m_last_error functionality is not thread safe. */
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
const char *mz_zip_get_error_string(mz_zip_error mz_err);

/* MZ_TRUE if the archive file entry is a directory entry. */
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);

/* MZ_TRUE if the file is encrypted/strong encrypted. */
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);

/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */
mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);

/* Retrieves the filename of an archive file entry. */
/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);

/* Attempts to locates a file in the archive's central directory. */
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
/* Returns -1 if the file cannot be found. */
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
int mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);

/* Returns detailed information about an archive file entry. */
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);

/* MZ_TRUE if the file is in zip64 format. */
/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);

/* Returns the total central directory size in bytes. */
/* The current max supported size is <= MZ_UINT32_MAX. */
size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);

/* Extracts a archive file to a memory buffer using no memory allocation. */
/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);

/* Extracts a archive file to a memory buffer. */
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);

/* Extracts a archive file to a dynamically allocated heap buffer. */
/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */
/* Returns NULL and sets the last error on failure. */
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);

/* Extracts a archive file using a callback function to output the file's data. */
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);

/* Extract a file iteratively */
mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size);
mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState);

#ifndef MINIZ_NO_STDIO
/* Extracts a archive file to a disk file and sets its last accessed and modified times. */
/* This function only extracts files, not archive directory records. */
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);

/* Extracts a archive file starting at the current position in the destination FILE stream. */
mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
#endif

#if 0
/* TODO */
	typedef void *mz_zip_streaming_extract_state_ptr;
	mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
	uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
	uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
	mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs);
	size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
	mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
#endif

/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);

/* Validates an entire archive by calling mz_zip_validate_file() on each file. */
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);

/* Misc utils/helpers, valid for ZIP reading or writing */
mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);

/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */
mz_bool mz_zip_end(mz_zip_archive *pZip);

/* -------- ZIP writing */

#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS

/* Inits a ZIP archive writer. */
/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init or mz_zip_writer_init_v2*/
/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases only by n*/
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);

mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);

#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
#endif

/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */
/* For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. */
/* For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). */
/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */
/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */
/* the archive is finalized the file's central directory will be hosed. */
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);

/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */
/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);

/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */
/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
                                 mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);

mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
                                    mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
                                    const char *user_extra_data_central, mz_uint user_extra_data_central_len);

#ifndef MINIZ_NO_STDIO
/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);

/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add,
                                const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
                                const char *user_extra_data_central, mz_uint user_extra_data_central_len);
#endif

/* Adds a file to an archive by fully cloning the data from another archive. */
/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);

/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */
/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */
/* An archive must be manually finalized by calling this function for it to be valid. */
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);

/* Finalizes a heap archive, returning a poiner to the heap block and its size. */
/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);

/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */
/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */
mz_bool mz_zip_writer_end(mz_zip_archive *pZip);

/* -------- Misc. high-level helper functions: */

/* mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. */
/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);

/* Reads a single file from an archive into a heap block. */
/* If pComment is not NULL, only the file with the specified comment will be extracted. */
/* Returns NULL on failure. */
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);

#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */

#ifdef __cplusplus
}
#endif

#endif /* MINIZ_NO_ARCHIVE_APIS */


#include <limits>

using namespace std;
using namespace duckdb;

/*

  0      2 bytes  magic header  0x1f, 0x8b (\037 \213)
  2      1 byte   compression method
                     0: store (copied)
                     1: compress
                     2: pack
                     3: lzh
                     4..7: reserved
                     8: deflate
  3      1 byte   flags
                     bit 0 set: file probably ascii text
                     bit 1 set: continuation of multi-part gzip file, part number present
                     bit 2 set: extra field present
                     bit 3 set: original file name present
                     bit 4 set: file comment present
                     bit 5 set: file is encrypted, encryption header present
                     bit 6,7:   reserved
  4      4 bytes  file modification time in Unix format
  8      1 byte   extra flags (depend on compression method)
  9      1 byte   OS type
[
         2 bytes  optional part number (second part=1)
]?
[
         2 bytes  optional extra field length (e)
        (e)bytes  optional extra field
]?
[
           bytes  optional original file name, zero terminated
]?
[
           bytes  optional file comment, zero terminated
]?
[
        12 bytes  optional encryption header
]?
           bytes  compressed data
         4 bytes  crc32
         4 bytes  uncompressed input size modulo 2^32

 */

static idx_t consume_string(fstream &input) {
	idx_t size = 1; // terminator
	while (input.get() != '\0') {
		size++;
	}
	return size;
}

static const uint8_t GZIP_COMPRESSION_DEFLATE = 0x08;

static const uint8_t GZIP_FLAG_ASCII = 0x1;
static const uint8_t GZIP_FLAG_MULTIPART = 0x2;
static const uint8_t GZIP_FLAG_EXTRA = 0x4;
static const uint8_t GZIP_FLAG_NAME = 0x8;
static const uint8_t GZIP_FLAG_COMMENT = 0x10;
static const uint8_t GZIP_FLAG_ENCRYPT = 0x20;

static const uint8_t GZIP_HEADER_MINSIZE = 10;

static const unsigned char GZIP_FLAG_UNSUPPORTED =
    GZIP_FLAG_ASCII | GZIP_FLAG_MULTIPART | GZIP_FLAG_EXTRA | GZIP_FLAG_COMMENT | GZIP_FLAG_ENCRYPT;

void GzipStreamBuf::initialize() {
	if (is_initialized) {
		return;
	}
	assert(BUFFER_SIZE >= 3); // found to work fine with 3
	uint8_t gzip_hdr[10];
	data_start = GZIP_HEADER_MINSIZE;

	in_buff = new data_t[BUFFER_SIZE];
	in_buff_start = in_buff;
	in_buff_end = in_buff;
	out_buff = new data_t[BUFFER_SIZE];

	mz_stream_ptr = new mz_stream();
	// TODO use custom alloc/free methods in miniz to throw exceptions on OOM

	FstreamUtil::OpenFile(filename, input, ios::in | ios::binary);

	input.read((char *)gzip_hdr, GZIP_HEADER_MINSIZE);
	if (!input) {
		throw Exception("Input is not a GZIP stream");
	}
	if (gzip_hdr[0] != 0x1F || gzip_hdr[1] != 0x8B) { // magic header
		throw Exception("Input is not a GZIP stream");
	}
	if (gzip_hdr[2] != GZIP_COMPRESSION_DEFLATE) { // compression method
		throw Exception("Unsupported GZIP compression method");
	}
	if (gzip_hdr[3] & GZIP_FLAG_UNSUPPORTED) {
		throw Exception("Unsupported GZIP archive");
	}

	if (gzip_hdr[3] & GZIP_FLAG_NAME) {
		input.seekg(data_start, input.beg);
		data_start += consume_string(input);
	}
	input.seekg(data_start, input.beg);
	// stream is now set to beginning of payload data

	auto ret = mz_inflateInit2((mz_streamp)mz_stream_ptr, -MZ_DEFAULT_WINDOW_BITS);
	if (ret != MZ_OK) {
		throw Exception("Failed to initialize miniz");
	}
	// initialize eback, gptr, egptr
	setg((char *)out_buff, (char *)out_buff, (char *)out_buff);
	is_initialized = true;
}

streambuf::int_type GzipStreamBuf::underflow() {
	if (!is_initialized) {
		initialize();
	}

	// adapted from https://github.com/mateidavid/zstr
	auto zstrm_p = (mz_streamp)mz_stream_ptr;
	if (!zstrm_p) {
		return traits_type::eof();
	}

	if (gptr() == egptr()) {
		// pointers for free region in output buffer
		auto out_buff_free_start = out_buff;
		do {
			assert(in_buff_start <= in_buff_end);
			assert(in_buff_end <= in_buff_start + BUFFER_SIZE);

			// read more input if none available
			if (in_buff_start == in_buff_end) {
				// empty input buffer: refill from the start
				in_buff_start = in_buff;
				std::streamsize sz = input.rdbuf()->sgetn((char *)in_buff, BUFFER_SIZE);
				if (sz == 0) {
					break; // end of input
				}
				in_buff_end = in_buff + sz;
			}

			// actually decompress
			assert(zstrm_p);
			zstrm_p->next_in = (data_ptr_t)in_buff_start;
			assert(in_buff_end - in_buff_start < numeric_limits<int32_t>::max());
			zstrm_p->avail_in = (uint32_t)(in_buff_end - in_buff_start);
			zstrm_p->next_out = (data_ptr_t)out_buff_free_start;
			assert((out_buff + BUFFER_SIZE) - out_buff_free_start < numeric_limits<int32_t>::max());
			zstrm_p->avail_out = (uint32_t)((out_buff + BUFFER_SIZE) - out_buff_free_start);
			auto ret = mz_inflate(zstrm_p, MZ_NO_FLUSH);
			if (ret != MZ_OK && ret != MZ_STREAM_END) {
				throw Exception(mz_error(ret));
			}
			// update pointers following inflate()
			in_buff_start = (data_ptr_t)zstrm_p->next_in;
			in_buff_end = in_buff_start + zstrm_p->avail_in;
			out_buff_free_start = (data_ptr_t)zstrm_p->next_out;
			assert(out_buff_free_start + zstrm_p->avail_out == out_buff + BUFFER_SIZE);
			// if stream ended, deallocate inflator
			if (ret == MZ_STREAM_END) {
				mz_inflateEnd(zstrm_p);
				delete zstrm_p;
				mz_stream_ptr = nullptr;
				break;
			}

		} while (out_buff_free_start == out_buff);
		// 2 exit conditions:
		// - end of input: there might or might not be output available
		// - out_buff_free_start != out_buff: output available
		setg((char *)out_buff, (char *)out_buff, (char *)out_buff_free_start);
	}

	// ensure all those pointers point at something sane
	assert(out_buff);
	assert(gptr() <= egptr());
	assert(eback() == (char *)out_buff);
	assert(gptr() >= (char *)out_buff);
	assert(gptr() <= (char *)out_buff + BUFFER_SIZE);
	assert(egptr() >= (char *)out_buff);
	assert(egptr() <= (char *)out_buff + BUFFER_SIZE);
	assert(gptr() <= egptr());

	return this->gptr() == this->egptr() ? traits_type::eof() : traits_type::to_int_type(*this->gptr());
}

GzipStreamBuf::~GzipStreamBuf() {
	delete[] in_buff;
	delete[] out_buff;
	auto zstrm_p = (mz_streamp)mz_stream_ptr;
	if (zstrm_p) {
		mz_inflateEnd(zstrm_p);
	}
	delete zstrm_p;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/limits.hpp
//
//
//===----------------------------------------------------------------------===//





#include <limits>

namespace duckdb {

//! Returns the minimum value that can be stored in a given type
template <class T> int64_t MinimumValue() {
	assert(IsIntegerType<T>());
	if (std::is_same<T, int8_t>()) {
		return std::numeric_limits<int8_t>::min() + 1;
	} else if (std::is_same<T, int16_t>()) {
		return std::numeric_limits<int16_t>::min() + 1;
	} else if (std::is_same<T, int32_t>()) {
		return std::numeric_limits<int32_t>::min() + 1;
	} else if (std::is_same<T, int64_t>()) {
		return std::numeric_limits<int64_t>::min() + 1;
	} else if (std::is_same<T, uint64_t>()) {
		return std::numeric_limits<uint64_t>::min();
	} else if (std::is_same<T, uintptr_t>()) {
		return std::numeric_limits<uintptr_t>::min();
	} else {
		assert(0);
		return 0;
	}
}

//! Returns the maximum value that can be stored in a given type
template <class T> int64_t MaximumValue() {
	assert(IsIntegerType<T>());
	if (std::is_same<T, int8_t>()) {
		return std::numeric_limits<int8_t>::max();
	} else if (std::is_same<T, int16_t>()) {
		return std::numeric_limits<int16_t>::max();
	} else if (std::is_same<T, int32_t>()) {
		return std::numeric_limits<int32_t>::max();
	} else if (std::is_same<T, int64_t>()) {
		return std::numeric_limits<int64_t>::max();
	} else if (std::is_same<T, uint64_t>()) {
		return std::numeric_limits<int64_t>::max();
	} else if (std::is_same<T, uintptr_t>()) {
		return std::numeric_limits<uintptr_t>::max();
	} else {
		assert(0);
		return 0;
	}
}

//! Returns the minimum value that can be stored in a given type
int64_t MinimumValue(TypeId type);
//! Returns the maximum value that can be stored in a given type
uint64_t MaximumValue(TypeId type);
//! Returns the minimal type that guarantees an integer value from not
//! overflowing
TypeId MinimalType(int64_t value);

} // namespace duckdb




using namespace std;

namespace duckdb {

// we offset the minimum value by 1 to account for the NULL value in the
// hashtables
int64_t MinimumValue(TypeId type) {
	switch (type) {
	case TypeId::INT8:
		return MinimumValue<int8_t>();
	case TypeId::INT16:
		return MinimumValue<int16_t>();
	case TypeId::INT32:
		return MinimumValue<int32_t>();
	case TypeId::INT64:
		return MinimumValue<int64_t>();
	case TypeId::HASH:
		return MinimumValue<uint64_t>();
	case TypeId::POINTER:
		return MinimumValue<uintptr_t>();
	default:
		throw InvalidTypeException(type, "MinimumValue requires integral type");
	}
}

uint64_t MaximumValue(TypeId type) {
	switch (type) {
	case TypeId::INT8:
		return MaximumValue<int8_t>();
	case TypeId::INT16:
		return MaximumValue<int16_t>();
	case TypeId::INT32:
		return MaximumValue<int32_t>();
	case TypeId::INT64:
		return MaximumValue<int64_t>();
	case TypeId::HASH:
		return MaximumValue<uint64_t>();
	case TypeId::POINTER:
		return MaximumValue<uintptr_t>();
	default:
		throw InvalidTypeException(type, "MaximumValue requires integral type");
	}
}

TypeId MinimalType(int64_t value) {
	if (value >= MinimumValue(TypeId::INT8) && (uint64_t)value <= MaximumValue(TypeId::INT8)) {
		return TypeId::INT8;
	}
	if (value >= MinimumValue(TypeId::INT16) && (uint64_t)value <= MaximumValue(TypeId::INT16)) {
		return TypeId::INT16;
	}
	if (value >= MinimumValue(TypeId::INT32) && (uint64_t)value <= MaximumValue(TypeId::INT32)) {
		return TypeId::INT32;
	}
	return TypeId::INT64;
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/operator/cast_operators.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

struct Cast {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		return (DST)input;
	}
};

struct TryCast {
	template <class SRC, class DST> static inline bool Operation(SRC input, DST &target) {
		target = Cast::Operation(input);
		return true;
	}
};

//===--------------------------------------------------------------------===//
// Numeric -> int8_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(int16_t input, int8_t &result);
template <> bool TryCast::Operation(int32_t input, int8_t &result);
template <> bool TryCast::Operation(int64_t input, int8_t &result);
template <> bool TryCast::Operation(float input, int8_t &result);
template <> bool TryCast::Operation(double input, int8_t &result);

template <> int8_t Cast::Operation(int16_t input);
template <> int8_t Cast::Operation(int32_t input);
template <> int8_t Cast::Operation(int64_t input);
template <> int8_t Cast::Operation(float input);
template <> int8_t Cast::Operation(double input);
//===--------------------------------------------------------------------===//
// Numeric -> int16_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(int32_t input, int16_t &result);
template <> bool TryCast::Operation(int64_t input, int16_t &result);
template <> bool TryCast::Operation(float input, int16_t &result);
template <> bool TryCast::Operation(double input, int16_t &result);

template <> int16_t Cast::Operation(int32_t input);
template <> int16_t Cast::Operation(int64_t input);
template <> int16_t Cast::Operation(float input);
template <> int16_t Cast::Operation(double input);
//===--------------------------------------------------------------------===//
// Numeric -> int32_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(int64_t input, int32_t &result);
template <> bool TryCast::Operation(float input, int32_t &result);
template <> bool TryCast::Operation(double input, int32_t &result);

template <> int32_t Cast::Operation(int64_t input);
template <> int32_t Cast::Operation(float input);
template <> int32_t Cast::Operation(double input);
//===--------------------------------------------------------------------===//
// Numeric -> int64_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(float input, int64_t &result);
template <> bool TryCast::Operation(double input, int64_t &result);

template <> int64_t Cast::Operation(float input);
template <> int64_t Cast::Operation(double input);
//===--------------------------------------------------------------------===//
// String -> Numeric Casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(string_t input, bool &result);
template <> bool TryCast::Operation(string_t input, int8_t &result);
template <> bool TryCast::Operation(string_t input, int16_t &result);
template <> bool TryCast::Operation(string_t input, int32_t &result);
template <> bool TryCast::Operation(string_t input, int64_t &result);
template <> bool TryCast::Operation(string_t input, float &result);
template <> bool TryCast::Operation(string_t input, double &result);

template <> bool Cast::Operation(string_t input);
template <> int8_t Cast::Operation(string_t input);
template <> int16_t Cast::Operation(string_t input);
template <> int32_t Cast::Operation(string_t input);
template <> int64_t Cast::Operation(string_t input);
template <> float Cast::Operation(string_t input);
template <> double Cast::Operation(string_t input);
template <> string Cast::Operation(string_t input);
//===--------------------------------------------------------------------===//
// Numeric -> String Casts
//===--------------------------------------------------------------------===//
// these functions are convenience functions that cast a value to a std::string, they are very slow
// for performance sensitive casting StringCast::Operation should be used
template <> string Cast::Operation(bool input);
template <> string Cast::Operation(int8_t  input);
template <> string Cast::Operation(int16_t input);
template <> string Cast::Operation(int32_t input);
template <> string Cast::Operation(int64_t input);
template <> string Cast::Operation(float input);
template <> string Cast::Operation(double input);
template <> string Cast::Operation(string_t input);

class Vector;
struct StringCast {
	template <class SRC> static inline string_t Operation(SRC input, Vector &result) {
		throw NotImplementedException("Unimplemented type for string cast!");
	}
};

template <> duckdb::string_t StringCast::Operation(bool input, Vector &result);
template <> duckdb::string_t StringCast::Operation(int8_t input, Vector &result);
template <> duckdb::string_t StringCast::Operation(int16_t input, Vector &result);
template <> duckdb::string_t StringCast::Operation(int32_t input, Vector &result);
template <> duckdb::string_t StringCast::Operation(int64_t input, Vector &result);
template <> duckdb::string_t StringCast::Operation(uint64_t input, Vector &result);
template <> duckdb::string_t StringCast::Operation(float input, Vector &result);
template <> duckdb::string_t StringCast::Operation(double input, Vector &result);

struct CastFromDate {
	template <class SRC> static inline string_t Operation(SRC input, Vector &result) {
		throw duckdb::NotImplementedException("Cast from date could not be performed!");
	}
};

struct CastToDate {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		throw duckdb::NotImplementedException("Cast to date could not be performed!");
	}
};

struct CastDateToTimestamp {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		throw duckdb::NotImplementedException("Cast to timestamp could not be performed!");
	}
};
template <> duckdb::string_t CastFromDate::Operation(duckdb::date_t input, Vector &result);
template <> duckdb::date_t CastToDate::Operation(string_t input);
template <> duckdb::timestamp_t CastDateToTimestamp::Operation(duckdb::date_t input);

struct CastFromTime {
	template <class SRC> static inline string_t Operation(SRC input, Vector &result) {
		throw duckdb::NotImplementedException("Cast from time could not be performed!");
	}
};
struct CastToTime {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		throw duckdb::NotImplementedException("Cast to time could not be performed!");
	}
};
template <> duckdb::string_t CastFromTime::Operation(duckdb::dtime_t input, Vector &result);
template <> duckdb::dtime_t CastToTime::Operation(string_t input);

struct CastToTimestamp {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		throw duckdb::NotImplementedException("Cast to timestamp could not be performed!");
	}
};

struct CastFromTimestamp {
	template <class SRC> static inline string_t Operation(SRC input, Vector &result) {
		throw duckdb::NotImplementedException("Cast to timestamp could not be performed!");
	}
};

struct CastTimestampToDate {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		throw duckdb::NotImplementedException("Cast to timestamp could not be performed!");
	}
};

struct CastTimestampToTime {
	template <class SRC, class DST> static inline DST Operation(SRC input) {
		throw duckdb::NotImplementedException("Cast to timestamp could not be performed!");
	}
};

template <> duckdb::date_t CastTimestampToDate::Operation(duckdb::timestamp_t input);
template <> duckdb::dtime_t CastTimestampToTime::Operation(duckdb::timestamp_t input);
template <> duckdb::string_t CastFromTimestamp::Operation(duckdb::timestamp_t input, Vector &result);
template <> duckdb::timestamp_t CastToTimestamp::Operation(string_t input);

} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/types/time.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The Date class is a static class that holds helper functions for the Time
//! type.
class Time {
public:
	//! Convert a string in the format "hh:mm:ss" to a time object
	static dtime_t FromString(string str);
	static dtime_t FromCString(const char *buf);

	//! Convert a time object to a string in the format "hh:mm:ss"
	static string ToString(dtime_t time);

	static string Format(int32_t hour, int32_t minute, int32_t second, int32_t milisecond = 0);

	static dtime_t FromTime(int32_t hour, int32_t minute, int32_t second, int32_t milisecond = 0);

	static bool IsValidTime(int32_t hour, int32_t minute, int32_t second, int32_t milisecond = 0);
	//! Extract the time from a given timestamp object
	static void Convert(dtime_t time, int32_t &out_hour, int32_t &out_min, int32_t &out_sec, int32_t &out_msec);
};
} // namespace duckdb




/*
 Formatting library for C++

 Copyright (c) 2012 - present, Victor Zverovich

 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.

 --- Optional exception to the license ---

 As an exception, if, as a result of your compiling your source code, portions
 of this Software are embedded into a machine-executable object form of such
 source code, you may redistribute such embedded portions in such object form
 without including the above copyright and permission notices.
 */

#ifndef FMT_FORMAT_H_
#define FMT_FORMAT_H_


// Formatting library for C++ - the core API
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#ifndef FMT_CORE_H_
#define FMT_CORE_H_

#include <cstdio>  // std::FILE
#include <cstring>
#include <iterator>
#include <string>
#include <type_traits>

// The fmt library version in the form major * 10000 + minor * 100 + patch.
#define FMT_VERSION 60102

#ifdef __has_feature
#  define FMT_HAS_FEATURE(x) __has_feature(x)
#else
#  define FMT_HAS_FEATURE(x) 0
#endif

#if defined(__has_include) && !defined(__INTELLISENSE__) && \
    !(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600)
#  define FMT_HAS_INCLUDE(x) __has_include(x)
#else
#  define FMT_HAS_INCLUDE(x) 0
#endif

#ifdef __has_cpp_attribute
#  define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
#else
#  define FMT_HAS_CPP_ATTRIBUTE(x) 0
#endif

#if defined(__GNUC__) && !defined(__clang__)
#  define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#else
#  define FMT_GCC_VERSION 0
#endif

#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#  define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION
#else
#  define FMT_HAS_GXX_CXX11 0
#endif

#ifdef __NVCC__
#  define FMT_NVCC __NVCC__
#else
#  define FMT_NVCC 0
#endif

#ifdef _MSC_VER
#  define FMT_MSC_VER _MSC_VER
#else
#  define FMT_MSC_VER 0
#endif

// Check if relaxed C++14 constexpr is supported.
// GCC doesn't allow throw in constexpr until version 6 (bug 67371).
#ifndef FMT_USE_CONSTEXPR
#  define FMT_USE_CONSTEXPR                                           \
    (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \
     (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) &&           \
        !FMT_NVCC
#endif
#if FMT_USE_CONSTEXPR
#  define FMT_CONSTEXPR constexpr
#  define FMT_CONSTEXPR_DECL constexpr
#else
#  define FMT_CONSTEXPR inline
#  define FMT_CONSTEXPR_DECL
#endif

#ifndef FMT_OVERRIDE
#  if FMT_HAS_FEATURE(cxx_override) || \
      (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
#    define FMT_OVERRIDE override
#  else
#    define FMT_OVERRIDE
#  endif
#endif

// Check if exceptions are disabled.
#ifndef FMT_EXCEPTIONS
#  if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
      FMT_MSC_VER && !_HAS_EXCEPTIONS
#    define FMT_EXCEPTIONS 0
#  else
#    define FMT_EXCEPTIONS 1
#  endif
#endif

// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
#ifndef FMT_USE_NOEXCEPT
#  define FMT_USE_NOEXCEPT 0
#endif

#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
    (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
#  define FMT_DETECTED_NOEXCEPT noexcept
#  define FMT_HAS_CXX11_NOEXCEPT 1
#else
#  define FMT_DETECTED_NOEXCEPT throw()
#  define FMT_HAS_CXX11_NOEXCEPT 0
#endif

#ifndef FMT_NOEXCEPT
#  if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT
#    define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
#  else
#    define FMT_NOEXCEPT
#  endif
#endif

// [[noreturn]] is disabled on MSVC because of bogus unreachable code warnings.
#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER
#  define FMT_NORETURN [[noreturn]]
#else
#  define FMT_NORETURN
#endif

#ifndef FMT_DEPRECATED
#  if (FMT_HAS_CPP_ATTRIBUTE(deprecated) && __cplusplus >= 201402L) || \
      FMT_MSC_VER >= 1900
#    define FMT_DEPRECATED [[deprecated]]
#  else
#    if defined(__GNUC__) || defined(__clang__)
#      define FMT_DEPRECATED __attribute__((deprecated))
#    elif FMT_MSC_VER
#      define FMT_DEPRECATED __declspec(deprecated)
#    else
#      define FMT_DEPRECATED /* deprecated */
#    endif
#  endif
#endif

// Workaround broken [[deprecated]] in the Intel compiler and NVCC.
#if defined(__INTEL_COMPILER) || FMT_NVCC
#  define FMT_DEPRECATED_ALIAS
#else
#  define FMT_DEPRECATED_ALIAS FMT_DEPRECATED
#endif

#ifndef FMT_BEGIN_NAMESPACE
#  if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \
      FMT_MSC_VER >= 1900
#    define FMT_INLINE_NAMESPACE inline namespace
#    define FMT_END_NAMESPACE \
      }                       \
      }
#  else
#    define FMT_INLINE_NAMESPACE namespace
#    define FMT_END_NAMESPACE \
      }                       \
      using namespace v6;     \
      }
#  endif
#  define FMT_BEGIN_NAMESPACE \
    namespace fmt {           \
    FMT_INLINE_NAMESPACE v6 {
#endif

#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
#  ifdef FMT_EXPORT
#    define FMT_API __declspec(dllexport)
#  elif defined(FMT_SHARED)
#    define FMT_API __declspec(dllimport)
#    define FMT_EXTERN_TEMPLATE_API FMT_API
#  endif
#endif
#ifndef FMT_API
#  define FMT_API
#endif
#ifndef FMT_EXTERN_TEMPLATE_API
#  define FMT_EXTERN_TEMPLATE_API
#endif

#ifndef FMT_HEADER_ONLY
#  define FMT_EXTERN extern
#else
#  define FMT_EXTERN
#endif

// libc++ supports string_view in pre-c++17.
#if (FMT_HAS_INCLUDE(<string_view>) &&                       \
     (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \
    (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
#  include <string_view>
#  define FMT_USE_STRING_VIEW
#elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L
#  include <experimental/string_view>
#  define FMT_USE_EXPERIMENTAL_STRING_VIEW
#endif

FMT_BEGIN_NAMESPACE

// Implementations of enable_if_t and other types for pre-C++14 systems.
template <bool B, class T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template <bool B, class T, class F>
using conditional_t = typename std::conditional<B, T, F>::type;
template <bool B> using bool_constant = std::integral_constant<bool, B>;
template <typename T>
using remove_reference_t = typename std::remove_reference<T>::type;
template <typename T>
using remove_const_t = typename std::remove_const<T>::type;
template <typename T>
using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;

struct monostate {};

// An enable_if helper to be used in template parameters which results in much
// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
// to workaround a bug in MSVC 2019 (see #1140 and #1186).
#define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0

namespace internal {

// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
template <typename... Ts> struct void_t_impl { using type = void; };

#ifndef FMT_ASSERT
#define FMT_ASSERT(condition, message)
#endif

#if defined(FMT_USE_STRING_VIEW)
template <typename Char> using std_string_view = std::basic_string_view<Char>;
#elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
template <typename Char>
using std_string_view = std::experimental::basic_string_view<Char>;
#else
template <typename T> struct std_string_view {};
#endif

#ifdef FMT_USE_INT128
// Do nothing.
#elif defined(__SIZEOF_INT128__)
#  define FMT_USE_INT128 1
using int128_t = __int128_t;
using uint128_t = __uint128_t;
#else
#  define FMT_USE_INT128 0
#endif
#if !FMT_USE_INT128
struct int128_t {};
struct uint128_t {};
#endif

// Casts a nonnegative integer to unsigned.
template <typename Int>
FMT_CONSTEXPR typename std::make_unsigned<Int>::type to_unsigned(Int value) {
  FMT_ASSERT(value >= 0, "negative value");
  return static_cast<typename std::make_unsigned<Int>::type>(value);
}
}  // namespace internal

template <typename... Ts>
using void_t = typename internal::void_t_impl<Ts...>::type;

/**
  An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
  subset of the API. ``fmt::basic_string_view`` is used for format strings even
  if ``std::string_view`` is available to prevent issues when a library is
  compiled with a different ``-std`` option than the client code (which is not
  recommended).
 */
template <typename Char> class basic_string_view {
 private:
  const Char* data_;
  size_t size_;

 public:
  using char_type = Char;
  using iterator = const Char*;

  FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {}

  /** Constructs a string reference object from a C string and a size. */
  FMT_CONSTEXPR basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT
      : data_(s),
        size_(count) {}

  /**
    \rst
    Constructs a string reference object from a C string computing
    the size with ``std::char_traits<Char>::length``.
    \endrst
   */
  basic_string_view(const Char* s)
      : data_(s), size_(std::char_traits<Char>::length(s)) {}

  /** Constructs a string reference from a ``std::basic_string`` object. */
  template <typename Traits, typename Alloc>
  FMT_CONSTEXPR basic_string_view(
      const std::basic_string<Char, Traits, Alloc>& s) FMT_NOEXCEPT
      : data_(s.data()),
        size_(s.size()) {}

  template <
      typename S,
      FMT_ENABLE_IF(std::is_same<S, internal::std_string_view<Char>>::value)>
  FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()),
                                                      size_(s.size()) {}

  /** Returns a pointer to the string data. */
  FMT_CONSTEXPR const Char* data() const { return data_; }

  /** Returns the string size. */
  FMT_CONSTEXPR size_t size() const { return size_; }

  FMT_CONSTEXPR iterator begin() const { return data_; }
  FMT_CONSTEXPR iterator end() const { return data_ + size_; }

  FMT_CONSTEXPR const Char& operator[](size_t pos) const { return data_[pos]; }

  FMT_CONSTEXPR void remove_prefix(size_t n) {
    data_ += n;
    size_ -= n;
  }

  // Lexicographically compare this string reference to other.
  int compare(basic_string_view other) const {
    size_t str_size = size_ < other.size_ ? size_ : other.size_;
    int result = std::char_traits<Char>::compare(data_, other.data_, str_size);
    if (result == 0)
      result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
    return result;
  }

  friend bool operator==(basic_string_view lhs, basic_string_view rhs) {
    return lhs.compare(rhs) == 0;
  }
  friend bool operator!=(basic_string_view lhs, basic_string_view rhs) {
    return lhs.compare(rhs) != 0;
  }
  friend bool operator<(basic_string_view lhs, basic_string_view rhs) {
    return lhs.compare(rhs) < 0;
  }
  friend bool operator<=(basic_string_view lhs, basic_string_view rhs) {
    return lhs.compare(rhs) <= 0;
  }
  friend bool operator>(basic_string_view lhs, basic_string_view rhs) {
    return lhs.compare(rhs) > 0;
  }
  friend bool operator>=(basic_string_view lhs, basic_string_view rhs) {
    return lhs.compare(rhs) >= 0;
  }
};

using string_view = basic_string_view<char>;
using wstring_view = basic_string_view<wchar_t>;

#ifndef __cpp_char8_t
// A UTF-8 code unit type.
enum char8_t : unsigned char {};
#endif

/** Specifies if ``T`` is a character type. Can be specialized by users. */
template <typename T> struct is_char : std::false_type {};
template <> struct is_char<char> : std::true_type {};
template <> struct is_char<wchar_t> : std::true_type {};
template <> struct is_char<char8_t> : std::true_type {};
template <> struct is_char<char16_t> : std::true_type {};
template <> struct is_char<char32_t> : std::true_type {};

/**
  \rst
  Returns a string view of `s`. In order to add custom string type support to
  {fmt} provide an overload of `to_string_view` for it in the same namespace as
  the type for the argument-dependent lookup to work.

  **Example**::

    namespace my_ns {
    inline string_view to_string_view(const my_string& s) {
      return {s.data(), s.length()};
    }
    }
    std::string message = fmt::format(my_string("The answer is {}"), 42);
  \endrst
 */
template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
inline basic_string_view<Char> to_string_view(const Char* s) {
  return s;
}

template <typename Char, typename Traits, typename Alloc>
inline basic_string_view<Char> to_string_view(
    const std::basic_string<Char, Traits, Alloc>& s) {
  return s;
}

template <typename Char>
inline basic_string_view<Char> to_string_view(basic_string_view<Char> s) {
  return s;
}

template <typename Char,
          FMT_ENABLE_IF(!std::is_empty<internal::std_string_view<Char>>::value)>
inline basic_string_view<Char> to_string_view(
    internal::std_string_view<Char> s) {
  return s;
}

// A base class for compile-time strings. It is defined in the fmt namespace to
// make formatting functions visible via ADL, e.g. format(fmt("{}"), 42).
struct compile_string {};

template <typename S>
struct is_compile_string : std::is_base_of<compile_string, S> {};

template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
constexpr basic_string_view<typename S::char_type> to_string_view(const S& s) {
  return s;
}

namespace internal {
void to_string_view(...);
using fmt::v6::to_string_view;

// Specifies whether S is a string type convertible to fmt::basic_string_view.
// It should be a constexpr function but MSVC 2017 fails to compile it in
// enable_if and MSVC 2015 fails to compile it as an alias template.
template <typename S>
struct is_string : std::is_class<decltype(to_string_view(std::declval<S>()))> {
};

template <typename S, typename = void> struct char_t_impl {};
template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> {
  using result = decltype(to_string_view(std::declval<S>()));
  using type = typename result::char_type;
};

struct error_handler {
  FMT_CONSTEXPR error_handler() = default;
  FMT_CONSTEXPR error_handler(const error_handler&) = default;

  // This function is intentionally not constexpr to give a compile-time error.
  FMT_NORETURN FMT_API void on_error(const char* message);
};
}  // namespace internal

/** String's character type. */
template <typename S> using char_t = typename internal::char_t_impl<S>::type;

/**
  \rst
  Parsing context consisting of a format string range being parsed and an
  argument counter for automatic indexing.

  You can use one of the following type aliases for common character types:

  +-----------------------+-------------------------------------+
  | Type                  | Definition                          |
  +=======================+=====================================+
  | format_parse_context  | basic_format_parse_context<char>    |
  +-----------------------+-------------------------------------+
  | wformat_parse_context | basic_format_parse_context<wchar_t> |
  +-----------------------+-------------------------------------+
  \endrst
 */
template <typename Char, typename ErrorHandler = internal::error_handler>
class basic_format_parse_context : private ErrorHandler {
 private:
  basic_string_view<Char> format_str_;
  int next_arg_id_;

 public:
  using char_type = Char;
  using iterator = typename basic_string_view<Char>::iterator;

  explicit FMT_CONSTEXPR basic_format_parse_context(
      basic_string_view<Char> format_str, ErrorHandler eh = ErrorHandler())
      : ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {}

  /**
    Returns an iterator to the beginning of the format string range being
    parsed.
   */
  FMT_CONSTEXPR iterator begin() const FMT_NOEXCEPT {
    return format_str_.begin();
  }

  /**
    Returns an iterator past the end of the format string range being parsed.
   */
  FMT_CONSTEXPR iterator end() const FMT_NOEXCEPT { return format_str_.end(); }

  /** Advances the begin iterator to ``it``. */
  FMT_CONSTEXPR void advance_to(iterator it) {
    format_str_.remove_prefix(internal::to_unsigned(it - begin()));
  }

  /**
    Reports an error if using the manual argument indexing; otherwise returns
    the next argument index and switches to the automatic indexing.
   */
  FMT_CONSTEXPR int next_arg_id() {
    if (next_arg_id_ >= 0) return next_arg_id_++;
    on_error("cannot switch from manual to automatic argument indexing");
    return 0;
  }

  /**
    Reports an error if using the automatic argument indexing; otherwise
    switches to the manual indexing.
   */
  FMT_CONSTEXPR void check_arg_id(int) {
    if (next_arg_id_ > 0)
      on_error("cannot switch from automatic to manual argument indexing");
    else
      next_arg_id_ = -1;
  }

  FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {}

  FMT_CONSTEXPR void on_error(const char* message) {
    ErrorHandler::on_error(message);
  }

  FMT_CONSTEXPR ErrorHandler error_handler() const { return *this; }
};

using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;

template <typename Char, typename ErrorHandler = internal::error_handler>
using basic_parse_context FMT_DEPRECATED_ALIAS =
    basic_format_parse_context<Char, ErrorHandler>;
using parse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context<char>;
using wparse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context<wchar_t>;

template <typename Context> class basic_format_arg;
template <typename Context> class basic_format_args;

// A formatter for objects of type T.
template <typename T, typename Char = char, typename Enable = void>
struct formatter {
  // A deleted default constructor indicates a disabled formatter.
  formatter() = delete;
};

template <typename T, typename Char, typename Enable = void>
struct FMT_DEPRECATED convert_to_int
    : bool_constant<!std::is_arithmetic<T>::value &&
                    std::is_convertible<T, int>::value> {};

// Specifies if T has an enabled formatter specialization. A type can be
// formattable even if it doesn't have a formatter e.g. via a conversion.
template <typename T, typename Context>
using has_formatter =
    std::is_constructible<typename Context::template formatter_type<T>>;

namespace internal {

/** A contiguous memory buffer with an optional growing ability. */
template <typename T> class buffer {
 private:
  T* ptr_;
  std::size_t size_;
  std::size_t capacity_;

 protected:
  // Don't initialize ptr_ since it is not accessed to save a few cycles.
  buffer(std::size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {}

  buffer(T* p = nullptr, std::size_t sz = 0, std::size_t cap = 0) FMT_NOEXCEPT
      : ptr_(p),
        size_(sz),
        capacity_(cap) {}

  /** Sets the buffer data and capacity. */
  void set(T* buf_data, std::size_t buf_capacity) FMT_NOEXCEPT {
    ptr_ = buf_data;
    capacity_ = buf_capacity;
  }

  /** Increases the buffer capacity to hold at least *capacity* elements. */
  virtual void grow(std::size_t capacity) = 0;

 public:
  using value_type = T;
  using const_reference = const T&;

  buffer(const buffer&) = delete;
  void operator=(const buffer&) = delete;
  virtual ~buffer() = default;

  T* begin() FMT_NOEXCEPT { return ptr_; }
  T* end() FMT_NOEXCEPT { return ptr_ + size_; }

  /** Returns the size of this buffer. */
  std::size_t size() const FMT_NOEXCEPT { return size_; }

  /** Returns the capacity of this buffer. */
  std::size_t capacity() const FMT_NOEXCEPT { return capacity_; }

  /** Returns a pointer to the buffer data. */
  T* data() FMT_NOEXCEPT { return ptr_; }

  /** Returns a pointer to the buffer data. */
  const T* data() const FMT_NOEXCEPT { return ptr_; }

  /**
    Resizes the buffer. If T is a POD type new elements may not be initialized.
   */
  void resize(std::size_t new_size) {
    reserve(new_size);
    size_ = new_size;
  }

  /** Clears this buffer. */
  void clear() { size_ = 0; }

  /** Reserves space to store at least *capacity* elements. */
  void reserve(std::size_t new_capacity) {
    if (new_capacity > capacity_) grow(new_capacity);
  }

  void push_back(const T& value) {
    reserve(size_ + 1);
    ptr_[size_++] = value;
  }

  /** Appends data to the end of the buffer. */
  template <typename U> void append(const U* begin, const U* end);

  T& operator[](std::size_t index) { return ptr_[index]; }
  const T& operator[](std::size_t index) const { return ptr_[index]; }
};

// A container-backed buffer.
template <typename Container>
class container_buffer : public buffer<typename Container::value_type> {
 private:
  Container& container_;

 protected:
  void grow(std::size_t capacity) FMT_OVERRIDE {
    container_.resize(capacity);
    this->set(&container_[0], capacity);
  }

 public:
  explicit container_buffer(Container& c)
      : buffer<typename Container::value_type>(c.size()), container_(c) {}
};

// Extracts a reference to the container from back_insert_iterator.
template <typename Container>
inline Container& get_container(std::back_insert_iterator<Container> it) {
  using bi_iterator = std::back_insert_iterator<Container>;
  struct accessor : bi_iterator {
    accessor(bi_iterator iter) : bi_iterator(iter) {}
    using bi_iterator::container;
  };
  return *accessor(it).container;
}

template <typename T, typename Char = char, typename Enable = void>
struct fallback_formatter {
  fallback_formatter() = delete;
};

// Specifies if T has an enabled fallback_formatter specialization.
template <typename T, typename Context>
using has_fallback_formatter =
    std::is_constructible<fallback_formatter<T, typename Context::char_type>>;

template <typename Char> struct named_arg_base;
template <typename T, typename Char> struct named_arg;

enum type {
  none_type,
  named_arg_type,
  // Integer types should go first,
  int_type,
  uint_type,
  long_long_type,
  ulong_long_type,
  int128_type,
  uint128_type,
  bool_type,
  char_type,
  last_integer_type = char_type,
  // followed by floating-point types.
  float_type,
  double_type,
  long_double_type,
  last_numeric_type = long_double_type,
  cstring_type,
  string_type,
  pointer_type,
  custom_type
};

// Maps core type T to the corresponding type enum constant.
template <typename T, typename Char>
struct type_constant : std::integral_constant<type, custom_type> {};

#define FMT_TYPE_CONSTANT(Type, constant) \
  template <typename Char>                \
  struct type_constant<Type, Char> : std::integral_constant<type, constant> {}

FMT_TYPE_CONSTANT(const named_arg_base<Char>&, named_arg_type);
FMT_TYPE_CONSTANT(int, int_type);
FMT_TYPE_CONSTANT(unsigned, uint_type);
FMT_TYPE_CONSTANT(long long, long_long_type);
FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
FMT_TYPE_CONSTANT(int128_t, int128_type);
FMT_TYPE_CONSTANT(uint128_t, uint128_type);
FMT_TYPE_CONSTANT(bool, bool_type);
FMT_TYPE_CONSTANT(Char, char_type);
FMT_TYPE_CONSTANT(float, float_type);
FMT_TYPE_CONSTANT(double, double_type);
FMT_TYPE_CONSTANT(long double, long_double_type);
FMT_TYPE_CONSTANT(const Char*, cstring_type);
FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);
FMT_TYPE_CONSTANT(const void*, pointer_type);

FMT_CONSTEXPR bool is_integral_type(type t) {
  FMT_ASSERT(t != named_arg_type, "invalid argument type");
  return t > none_type && t <= last_integer_type;
}

FMT_CONSTEXPR bool is_arithmetic_type(type t) {
  FMT_ASSERT(t != named_arg_type, "invalid argument type");
  return t > none_type && t <= last_numeric_type;
}

template <typename Char> struct string_value {
  const Char* data;
  std::size_t size;
};

template <typename Context> struct custom_value {
  using parse_context = basic_format_parse_context<typename Context::char_type>;
  const void* value;
  void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx);
};

// A formatting argument value.
template <typename Context> class value {
 public:
  using char_type = typename Context::char_type;

  union {
    int int_value;
    unsigned uint_value;
    long long long_long_value;
    unsigned long long ulong_long_value;
    int128_t int128_value;
    uint128_t uint128_value;
    bool bool_value;
    char_type char_value;
    float float_value;
    double double_value;
    long double long_double_value;
    const void* pointer;
    string_value<char_type> string;
    custom_value<Context> custom;
    const named_arg_base<char_type>* named_arg;
  };

  FMT_CONSTEXPR value(int val = 0) : int_value(val) {}
  FMT_CONSTEXPR value(unsigned val) : uint_value(val) {}
  value(long long val) : long_long_value(val) {}
  value(unsigned long long val) : ulong_long_value(val) {}
  value(int128_t val) : int128_value(val) {}
  value(uint128_t val) : uint128_value(val) {}
  value(float val) : float_value(val) {}
  value(double val) : double_value(val) {}
  value(long double val) : long_double_value(val) {}
  value(bool val) : bool_value(val) {}
  value(char_type val) : char_value(val) {}
  value(const char_type* val) { string.data = val; }
  value(basic_string_view<char_type> val) {
    string.data = val.data();
    string.size = val.size();
  }
  value(const void* val) : pointer(val) {}

  template <typename T> value(const T& val) {
    custom.value = &val;
    // Get the formatter type through the context to allow different contexts
    // have different extension points, e.g. `formatter<T>` for `format` and
    // `printf_formatter<T>` for `printf`.
    custom.format = format_custom_arg<
        T, conditional_t<has_formatter<T, Context>::value,
                         typename Context::template formatter_type<T>,
                         fallback_formatter<T, char_type>>>;
  }

  value(const named_arg_base<char_type>& val) { named_arg = &val; }

 private:
  // Formats an argument of a custom type, such as a user-defined class.
  template <typename T, typename Formatter>
  static void format_custom_arg(
      const void* arg, basic_format_parse_context<char_type>& parse_ctx,
      Context& ctx) {
    Formatter f;
    parse_ctx.advance_to(f.parse(parse_ctx));
    ctx.advance_to(f.format(*static_cast<const T*>(arg), ctx));
  }
};

template <typename Context, typename T>
FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T& value);

// To minimize the number of types we need to deal with, long is translated
// either to int or to long long depending on its size.
enum { long_short = sizeof(long) == sizeof(int) };
using long_type = conditional_t<long_short, int, long long>;
using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;

// Maps formatting arguments to core types.
template <typename Context> struct arg_mapper {
  using char_type = typename Context::char_type;

  FMT_CONSTEXPR int map(signed char val) { return val; }
  FMT_CONSTEXPR unsigned map(unsigned char val) { return val; }
  FMT_CONSTEXPR int map(short val) { return val; }
  FMT_CONSTEXPR unsigned map(unsigned short val) { return val; }
  FMT_CONSTEXPR int map(int val) { return val; }
  FMT_CONSTEXPR unsigned map(unsigned val) { return val; }
  FMT_CONSTEXPR long_type map(long val) { return val; }
  FMT_CONSTEXPR ulong_type map(unsigned long val) { return val; }
  FMT_CONSTEXPR long long map(long long val) { return val; }
  FMT_CONSTEXPR unsigned long long map(unsigned long long val) { return val; }
  FMT_CONSTEXPR int128_t map(int128_t val) { return val; }
  FMT_CONSTEXPR uint128_t map(uint128_t val) { return val; }
  FMT_CONSTEXPR bool map(bool val) { return val; }

  template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
  FMT_CONSTEXPR char_type map(T val) {
    static_assert(
        std::is_same<T, char>::value || std::is_same<T, char_type>::value,
        "mixing character types is disallowed");
    return val;
  }

  FMT_CONSTEXPR float map(float val) { return val; }
  FMT_CONSTEXPR double map(double val) { return val; }
  FMT_CONSTEXPR long double map(long double val) { return val; }

  FMT_CONSTEXPR const char_type* map(char_type* val) { return val; }
  FMT_CONSTEXPR const char_type* map(const char_type* val) { return val; }
  template <typename T, FMT_ENABLE_IF(is_string<T>::value)>
  FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) {
    static_assert(std::is_same<char_type, char_t<T>>::value,
                  "mixing character types is disallowed");
    return to_string_view(val);
  }
  template <typename T,
            FMT_ENABLE_IF(
                std::is_constructible<basic_string_view<char_type>, T>::value &&
                !is_string<T>::value)>
  FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) {
    return basic_string_view<char_type>(val);
  }
  template <
      typename T,
      FMT_ENABLE_IF(
          std::is_constructible<std_string_view<char_type>, T>::value &&
          !std::is_constructible<basic_string_view<char_type>, T>::value &&
          !is_string<T>::value && !has_formatter<T, Context>::value)>
  FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) {
    return std_string_view<char_type>(val);
  }
  FMT_CONSTEXPR const char* map(const signed char* val) {
    static_assert(std::is_same<char_type, char>::value, "invalid string type");
    return reinterpret_cast<const char*>(val);
  }
  FMT_CONSTEXPR const char* map(const unsigned char* val) {
    static_assert(std::is_same<char_type, char>::value, "invalid string type");
    return reinterpret_cast<const char*>(val);
  }

  FMT_CONSTEXPR const void* map(void* val) { return val; }
  FMT_CONSTEXPR const void* map(const void* val) { return val; }
  FMT_CONSTEXPR const void* map(std::nullptr_t val) { return val; }
  template <typename T> FMT_CONSTEXPR int map(const T*) {
    // Formatting of arbitrary pointers is disallowed. If you want to output
    // a pointer cast it to "void *" or "const void *". In particular, this
    // forbids formatting of "[const] volatile char *" which is printed as bool
    // by iostreams.
    static_assert(!sizeof(T), "formatting of non-void pointers is disallowed");
    return 0;
  }

  template <typename T,
            FMT_ENABLE_IF(std::is_enum<T>::value &&
                          !has_formatter<T, Context>::value &&
                          !has_fallback_formatter<T, Context>::value)>
  FMT_CONSTEXPR auto map(const T& val) -> decltype(
      map(static_cast<typename std::underlying_type<T>::type>(val))) {
    return map(static_cast<typename std::underlying_type<T>::type>(val));
  }
  template <
      typename T,
      FMT_ENABLE_IF(
          !is_string<T>::value && !is_char<T>::value &&
          !std::is_constructible<basic_string_view<char_type>, T>::value &&
          (has_formatter<T, Context>::value ||
           (has_fallback_formatter<T, Context>::value &&
            !std::is_constructible<std_string_view<char_type>, T>::value)))>
  FMT_CONSTEXPR const T& map(const T& val) {
    return val;
  }

  template <typename T>
  FMT_CONSTEXPR const named_arg_base<char_type>& map(
      const named_arg<T, char_type>& val) {
    auto arg = make_arg<Context>(val.value);
    std::memcpy(val.data, &arg, sizeof(arg));
    return val;
  }
};

// A type constant after applying arg_mapper<Context>.
template <typename T, typename Context>
using mapped_type_constant =
    type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())),
                  typename Context::char_type>;

enum { packed_arg_bits = 5 };
// Maximum number of arguments with packed types.
enum { max_packed_args = 63 / packed_arg_bits };
enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };

template <typename Context> class arg_map;
}  // namespace internal

// A formatting argument. It is a trivially copyable/constructible type to
// allow storage in basic_memory_buffer.
template <typename Context> class basic_format_arg {
 private:
  internal::value<Context> value_;
  internal::type type_;

  template <typename ContextType, typename T>
  friend FMT_CONSTEXPR basic_format_arg<ContextType> internal::make_arg(
      const T& value);

  template <typename Visitor, typename Ctx>
  friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis,
                                             const basic_format_arg<Ctx>& arg)
      -> decltype(vis(0));

  friend class basic_format_args<Context>;
  friend class internal::arg_map<Context>;

  using char_type = typename Context::char_type;

 public:
  class handle {
   public:
    explicit handle(internal::custom_value<Context> custom) : custom_(custom) {}

    void format(basic_format_parse_context<char_type>& parse_ctx,
                Context& ctx) const {
      custom_.format(custom_.value, parse_ctx, ctx);
    }

   private:
    internal::custom_value<Context> custom_;
  };

  FMT_CONSTEXPR basic_format_arg() : type_(internal::none_type) {}

  FMT_CONSTEXPR explicit operator bool() const FMT_NOEXCEPT {
    return type_ != internal::none_type;
  }

  internal::type type() const { return type_; }

  bool is_integral() const { return internal::is_integral_type(type_); }
  bool is_arithmetic() const { return internal::is_arithmetic_type(type_); }
};

/**
  \rst
  Visits an argument dispatching to the appropriate visit method based on
  the argument type. For example, if the argument type is ``double`` then
  ``vis(value)`` will be called with the value of type ``double``.
  \endrst
 */
template <typename Visitor, typename Context>
FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis,
                                    const basic_format_arg<Context>& arg)
    -> decltype(vis(0)) {
  using char_type = typename Context::char_type;
  switch (arg.type_) {
  case internal::none_type:
    break;
  case internal::named_arg_type:
    FMT_ASSERT(false, "invalid argument type");
    break;
  case internal::int_type:
    return vis(arg.value_.int_value);
  case internal::uint_type:
    return vis(arg.value_.uint_value);
  case internal::long_long_type:
    return vis(arg.value_.long_long_value);
  case internal::ulong_long_type:
    return vis(arg.value_.ulong_long_value);
#if FMT_USE_INT128
  case internal::int128_type:
    return vis(arg.value_.int128_value);
  case internal::uint128_type:
    return vis(arg.value_.uint128_value);
#else
  case internal::int128_type:
  case internal::uint128_type:
    break;
#endif
  case internal::bool_type:
    return vis(arg.value_.bool_value);
  case internal::char_type:
    return vis(arg.value_.char_value);
  case internal::float_type:
    return vis(arg.value_.float_value);
  case internal::double_type:
    return vis(arg.value_.double_value);
  case internal::long_double_type:
    return vis(arg.value_.long_double_value);
  case internal::cstring_type:
    return vis(arg.value_.string.data);
  case internal::string_type:
    return vis(basic_string_view<char_type>(arg.value_.string.data,
                                            arg.value_.string.size));
  case internal::pointer_type:
    return vis(arg.value_.pointer);
  case internal::custom_type:
    return vis(typename basic_format_arg<Context>::handle(arg.value_.custom));
  }
  return vis(monostate());
}

namespace internal {
// A map from argument names to their values for named arguments.
template <typename Context> class arg_map {
 private:
  using char_type = typename Context::char_type;

  struct entry {
    basic_string_view<char_type> name;
    basic_format_arg<Context> arg;
  };

  entry* map_;
  unsigned size_;

  void push_back(value<Context> val) {
    const auto& named = *val.named_arg;
    map_[size_] = {named.name, named.template deserialize<Context>()};
    ++size_;
  }

 public:
  arg_map(const arg_map&) = delete;
  void operator=(const arg_map&) = delete;
  arg_map() : map_(nullptr), size_(0) {}
  void init(const basic_format_args<Context>& args);
  ~arg_map() { delete[] map_; }

  basic_format_arg<Context> find(basic_string_view<char_type> name) const {
    // The list is unsorted, so just return the first matching name.
    for (entry *it = map_, *end = map_ + size_; it != end; ++it) {
      if (it->name == name) return it->arg;
    }
    return {};
  }
};

// A type-erased reference to an std::locale to avoid heavy <locale> include.
class locale_ref {
 private:
  const void* locale_;  // A type-erased pointer to std::locale.

 public:
  locale_ref() : locale_(nullptr) {}
  template <typename Locale> explicit locale_ref(const Locale& loc);

  explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; }

  template <typename Locale> Locale get() const;
};

template <typename> constexpr unsigned long long encode_types() { return 0; }

template <typename Context, typename Arg, typename... Args>
constexpr unsigned long long encode_types() {
  return mapped_type_constant<Arg, Context>::value |
         (encode_types<Context, Args...>() << packed_arg_bits);
}

template <typename Context, typename T>
FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T& value) {
  basic_format_arg<Context> arg;
  arg.type_ = mapped_type_constant<T, Context>::value;
  arg.value_ = arg_mapper<Context>().map(value);
  return arg;
}

template <bool IS_PACKED, typename Context, typename T,
          FMT_ENABLE_IF(IS_PACKED)>
inline value<Context> make_arg(const T& val) {
  return arg_mapper<Context>().map(val);
}

template <bool IS_PACKED, typename Context, typename T,
          FMT_ENABLE_IF(!IS_PACKED)>
inline basic_format_arg<Context> make_arg(const T& value) {
  return make_arg<Context>(value);
}
}  // namespace internal

// Formatting context.
template <typename OutputIt, typename Char> class basic_format_context {
 public:
  /** The character type for the output. */
  using char_type = Char;

 private:
  OutputIt out_;
  basic_format_args<basic_format_context> args_;
  internal::arg_map<basic_format_context> map_;
  internal::locale_ref loc_;

 public:
  using iterator = OutputIt;
  using format_arg = basic_format_arg<basic_format_context>;
  template <typename T> using formatter_type = formatter<T, char_type>;

  basic_format_context(const basic_format_context&) = delete;
  void operator=(const basic_format_context&) = delete;
  /**
   Constructs a ``basic_format_context`` object. References to the arguments are
   stored in the object so make sure they have appropriate lifetimes.
   */
  basic_format_context(OutputIt out,
                       basic_format_args<basic_format_context> ctx_args,
                       internal::locale_ref loc = internal::locale_ref())
      : out_(out), args_(ctx_args), loc_(loc) {}

  format_arg arg(int id) const { return args_.get(id); }

  // Checks if manual indexing is used and returns the argument with the
  // specified name.
  format_arg arg(basic_string_view<char_type> name);

  internal::error_handler error_handler() { return {}; }
  void on_error(const char* message) { error_handler().on_error(message); }

  // Returns an iterator to the beginning of the output range.
  iterator out() { return out_; }

  // Advances the begin iterator to ``it``.
  void advance_to(iterator it) { out_ = it; }

  internal::locale_ref locale() { return loc_; }
};

template <typename Char>
using buffer_context =
    basic_format_context<std::back_insert_iterator<internal::buffer<Char>>,
                         Char>;
using format_context = buffer_context<char>;
using wformat_context = buffer_context<wchar_t>;

/**
  \rst
  An array of references to arguments. It can be implicitly converted into
  `~fmt::basic_format_args` for passing into type-erased formatting functions
  such as `~fmt::vformat`.
  \endrst
 */
template <typename Context, typename... Args> class format_arg_store {
 private:
  static const size_t num_args = sizeof...(Args);
  static const bool is_packed = num_args < internal::max_packed_args;

  using value_type = conditional_t<is_packed, internal::value<Context>,
                                   basic_format_arg<Context>>;

  // If the arguments are not packed, add one more element to mark the end.
  value_type data_[num_args + (num_args == 0 ? 1 : 0)];

  friend class basic_format_args<Context>;

 public:
  static constexpr unsigned long long types =
      is_packed ? internal::encode_types<Context, Args...>()
                : internal::is_unpacked_bit | num_args;

  format_arg_store(const Args&... args)
      : data_{internal::make_arg<is_packed, Context>(args)...} {}
};

/**
  \rst
  Constructs an `~fmt::format_arg_store` object that contains references to
  arguments and can be implicitly converted to `~fmt::format_args`. `Context`
  can be omitted in which case it defaults to `~fmt::context`.
  See `~fmt::arg` for lifetime considerations.
  \endrst
 */
template <typename Context = format_context, typename... Args>
inline format_arg_store<Context, Args...> make_format_args(
    const Args&... args) {
  return {args...};
}

/** Formatting arguments. */
template <typename Context> class basic_format_args {
 public:
  using size_type = int;
  using format_arg = basic_format_arg<Context>;

 private:
  // To reduce compiled code size per formatting function call, types of first
  // max_packed_args arguments are passed in the types_ field.
  unsigned long long types_;
  union {
    // If the number of arguments is less than max_packed_args, the argument
    // values are stored in values_, otherwise they are stored in args_.
    // This is done to reduce compiled code size as storing larger objects
    // may require more code (at least on x86-64) even if the same amount of
    // data is actually copied to stack. It saves ~10% on the bloat test.
    const internal::value<Context>* values_;
    const format_arg* args_;
  };

  bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; }

  internal::type type(int index) const {
    int shift = index * internal::packed_arg_bits;
    unsigned int mask = (1 << internal::packed_arg_bits) - 1;
    return static_cast<internal::type>((types_ >> shift) & mask);
  }

  friend class internal::arg_map<Context>;

  void set_data(const internal::value<Context>* values) { values_ = values; }
  void set_data(const format_arg* args) { args_ = args; }

  format_arg do_get(int index) const {
    format_arg arg;
    if (!is_packed()) {
      auto num_args = max_size();
      if (index < num_args) arg = args_[index];
      return arg;
    }
    if (index > internal::max_packed_args) return arg;
    arg.type_ = type(index);
    if (arg.type_ == internal::none_type) return arg;
    internal::value<Context>& val = arg.value_;
    val = values_[index];
    return arg;
  }

 public:
  basic_format_args() : types_(0) {}

  /**
   \rst
   Constructs a `basic_format_args` object from `~fmt::format_arg_store`.
   \endrst
   */
  template <typename... Args>
  basic_format_args(const format_arg_store<Context, Args...>& store)
      : types_(store.types) {
    set_data(store.data_);
  }

  /**
   \rst
   Constructs a `basic_format_args` object from a dynamic set of arguments.
   \endrst
   */
  basic_format_args(const format_arg* args, int count)
      : types_(internal::is_unpacked_bit | internal::to_unsigned(count)) {
    set_data(args);
  }

  /** Returns the argument at specified index. */
  format_arg get(int index) const {
    format_arg arg = do_get(index);
    if (arg.type_ == internal::named_arg_type)
      arg = arg.value_.named_arg->template deserialize<Context>();
    return arg;
  }

  int max_size() const {
    unsigned long long max_packed = internal::max_packed_args;
    return static_cast<int>(is_packed() ? max_packed
                                        : types_ & ~internal::is_unpacked_bit);
  }
};

/** An alias to ``basic_format_args<context>``. */
// It is a separate type rather than an alias to make symbols readable.
struct format_args : basic_format_args<format_context> {
  template <typename... Args>
  format_args(Args&&... args)
      : basic_format_args<format_context>(std::forward<Args>(args)...) {}
};
struct wformat_args : basic_format_args<wformat_context> {
  template <typename... Args>
  wformat_args(Args&&... args)
      : basic_format_args<wformat_context>(std::forward<Args>(args)...) {}
};

template <typename Container> struct is_contiguous : std::false_type {};

template <typename Char>
struct is_contiguous<std::basic_string<Char>> : std::true_type {};

template <typename Char>
struct is_contiguous<internal::buffer<Char>> : std::true_type {};

namespace internal {

template <typename OutputIt>
struct is_contiguous_back_insert_iterator : std::false_type {};
template <typename Container>
struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>>
    : is_contiguous<Container> {};

template <typename Char> struct named_arg_base {
  basic_string_view<Char> name;

  // Serialized value<context>.
  mutable char data[sizeof(basic_format_arg<buffer_context<Char>>)];

  named_arg_base(basic_string_view<Char> nm) : name(nm) {}

  template <typename Context> basic_format_arg<Context> deserialize() const {
    basic_format_arg<Context> arg;
    std::memcpy(&arg, data, sizeof(basic_format_arg<Context>));
    return arg;
  }
};

template <typename T, typename Char> struct named_arg : named_arg_base<Char> {
  const T& value;

  named_arg(basic_string_view<Char> name, const T& val)
      : named_arg_base<Char>(name), value(val) {}
};

template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)>
inline void check_format_string(const S&) {
#if defined(FMT_ENFORCE_COMPILE_STRING)
  static_assert(is_compile_string<S>::value,
                "FMT_ENFORCE_COMPILE_STRING requires all format strings to "
                "utilize FMT_STRING() or fmt().");
#endif
}
template <typename..., typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
void check_format_string(S);

struct view {};
template <bool...> struct bool_pack;
template <bool... Args>
using all_true =
    std::is_same<bool_pack<Args..., true>, bool_pack<true, Args...>>;

template <typename... Args, typename S, typename Char = char_t<S>>
inline format_arg_store<buffer_context<Char>, remove_reference_t<Args>...>
make_args_checked(const S& format_str,
                  const remove_reference_t<Args>&... args) {
  static_assert(all_true<(!std::is_base_of<view, remove_reference_t<Args>>() ||
                          !std::is_reference<Args>())...>::value,
                "passing views as lvalues is disallowed");
  check_format_string<remove_const_t<remove_reference_t<Args>>...>(format_str);
  return {args...};
}

template <typename Char>
std::basic_string<Char> vformat(basic_string_view<Char> format_str,
                                basic_format_args<buffer_context<Char>> args);

template <typename Char>
typename buffer_context<Char>::iterator vformat_to(
    buffer<Char>& buf, basic_string_view<Char> format_str,
    basic_format_args<buffer_context<Char>> args);
}  // namespace internal

/**
  \rst
  Returns a named argument to be used in a formatting function.

  The named argument holds a reference and does not extend the lifetime
  of its arguments.
  Consequently, a dangling reference can accidentally be created.
  The user should take care to only pass this function temporaries when
  the named argument is itself a temporary, as per the following example.

  **Example**::

    fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23));
  \endrst
 */
template <typename S, typename T, typename Char = char_t<S>>
inline internal::named_arg<T, Char> arg(const S& name, const T& arg) {
  static_assert(internal::is_string<S>::value, "");
  return {name, arg};
}

// Disable nested named arguments, e.g. ``arg("a", arg("b", 42))``.
template <typename S, typename T, typename Char>
void arg(S, internal::named_arg<T, Char>) = delete;

/** Formats a string and writes the output to ``out``. */
// GCC 8 and earlier cannot handle std::back_insert_iterator<Container> with
// vformat_to<ArgFormatter>(...) overload, so SFINAE on iterator type instead.
template <typename OutputIt, typename S, typename Char = char_t<S>,
          FMT_ENABLE_IF(
              internal::is_contiguous_back_insert_iterator<OutputIt>::value)>
OutputIt vformat_to(OutputIt out, const S& format_str,
                    basic_format_args<buffer_context<Char>> args) {
  using container = remove_reference_t<decltype(internal::get_container(out))>;
  internal::container_buffer<container> buf((internal::get_container(out)));
  internal::vformat_to(buf, to_string_view(format_str), args);
  return out;
}

template <typename Container, typename S, typename... Args,
          FMT_ENABLE_IF(
              is_contiguous<Container>::value&& internal::is_string<S>::value)>
inline std::back_insert_iterator<Container> format_to(
    std::back_insert_iterator<Container> out, const S& format_str,
    Args&&... args) {
  return vformat_to(
      out, to_string_view(format_str),
      {internal::make_args_checked<Args...>(format_str, args...)});
}

template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
    const S& format_str, basic_format_args<buffer_context<Char>> args) {
  return internal::vformat(to_string_view(format_str), args);
}

/**
  \rst
  Formats arguments and returns the result as a string.

  **Example**::

    #include <fmt/core.h>
    std::string message = fmt::format("The answer is {}", 42);
  \endrst
*/
// Pass char_t as a default template parameter instead of using
// std::basic_string<char_t<S>> to reduce the symbol size.
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const S& format_str, Args&&... args) {
  return internal::vformat(
      to_string_view(format_str),
      {internal::make_args_checked<Args...>(format_str, args...)});
}

FMT_END_NAMESPACE

#endif  // FMT_CORE_H_


#include <algorithm>
#include <cerrno>
#include <cmath>
#include <cstdint>
#include <limits>
#include <memory>
#include <stdexcept>

#ifdef __clang__
#  define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
#else
#  define FMT_CLANG_VERSION 0
#endif

#ifdef __INTEL_COMPILER
#  define FMT_ICC_VERSION __INTEL_COMPILER
#elif defined(__ICL)
#  define FMT_ICC_VERSION __ICL
#else
#  define FMT_ICC_VERSION 0
#endif

#ifdef __NVCC__
#  define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
#else
#  define FMT_CUDA_VERSION 0
#endif

#ifdef __has_builtin
#  define FMT_HAS_BUILTIN(x) __has_builtin(x)
#else
#  define FMT_HAS_BUILTIN(x) 0
#endif

#if FMT_HAS_CPP_ATTRIBUTE(fallthrough) && \
    (__cplusplus >= 201703 || FMT_GCC_VERSION != 0)
#  define FMT_FALLTHROUGH [[fallthrough]]
#else
#  define FMT_FALLTHROUGH
#endif

#ifndef FMT_THROW
#  if FMT_EXCEPTIONS
#    if FMT_MSC_VER
FMT_BEGIN_NAMESPACE
namespace internal {
template <typename Exception> inline void do_throw(const Exception& x) {
  // Silence unreachable code warnings in MSVC because these are nearly
  // impossible to fix in a generic code.
  volatile bool b = true;
  if (b) throw x;
}
}  // namespace internal
FMT_END_NAMESPACE
#      define FMT_THROW(x) internal::do_throw(x)
#    else
#      define FMT_THROW(x) throw x
#    endif
#  else
#    define FMT_THROW(x)              \
      do {                            \
        static_cast<void>(sizeof(x)); \
        FMT_ASSERT(false, "");        \
      } while (false)
#  endif
#endif

#ifndef FMT_USE_USER_DEFINED_LITERALS
// For Intel and NVIDIA compilers both they and the system gcc/msc support UDLs.
#  if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 ||      \
       FMT_MSC_VER >= 1900) &&                                              \
      (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || FMT_ICC_VERSION >= 1500 || \
       FMT_CUDA_VERSION >= 700)
#    define FMT_USE_USER_DEFINED_LITERALS 1
#  else
#    define FMT_USE_USER_DEFINED_LITERALS 0
#  endif
#endif

#ifndef FMT_USE_UDL_TEMPLATE
// EDG front end based compilers (icc, nvcc) do not support UDL templates yet
// and GCC 9 warns about them.
#  if FMT_USE_USER_DEFINED_LITERALS && FMT_ICC_VERSION == 0 && \
      FMT_CUDA_VERSION == 0 &&                                 \
      ((FMT_GCC_VERSION >= 600 && FMT_GCC_VERSION <= 900 &&    \
        __cplusplus >= 201402L) ||                             \
       FMT_CLANG_VERSION >= 304)
#    define FMT_USE_UDL_TEMPLATE 1
#  else
#    define FMT_USE_UDL_TEMPLATE 0
#  endif
#endif

// __builtin_clz is broken in clang with Microsoft CodeGen:
// https://github.com/fmtlib/fmt/issues/519
#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER
#  define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
#endif
#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER
#  define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
#endif

// Some compilers masquerade as both MSVC and GCC-likes or otherwise support
// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
// MSVC intrinsics if the clz and clzll builtins are not available.
#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
#  include <intrin.h>  // _BitScanReverse, _BitScanReverse64

FMT_BEGIN_NAMESPACE
namespace internal {
// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
#  ifndef __clang__
#    pragma intrinsic(_BitScanReverse)
#  endif
inline uint32_t clz(uint32_t x) {
  unsigned long r = 0;
  _BitScanReverse(&r, x);

  FMT_ASSERT(x != 0, "");
  // Static analysis complains about using uninitialized data
  // "r", but the only way that can happen is if "x" is 0,
  // which the callers guarantee to not happen.
#  pragma warning(suppress : 6102)
  return 31 - r;
}
#  define FMT_BUILTIN_CLZ(n) internal::clz(n)

#  if defined(_WIN64) && !defined(__clang__)
#    pragma intrinsic(_BitScanReverse64)
#  endif

inline uint32_t clzll(uint64_t x) {
  unsigned long r = 0;
#  ifdef _WIN64
  _BitScanReverse64(&r, x);
#  else
  // Scan the high 32 bits.
  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 - (r + 32);

  // Scan the low 32 bits.
  _BitScanReverse(&r, static_cast<uint32_t>(x));
#  endif

  FMT_ASSERT(x != 0, "");
  // Static analysis complains about using uninitialized data
  // "r", but the only way that can happen is if "x" is 0,
  // which the callers guarantee to not happen.
#  pragma warning(suppress : 6102)
  return 63 - r;
}
#  define FMT_BUILTIN_CLZLL(n) internal::clzll(n)
}  // namespace internal
FMT_END_NAMESPACE
#endif

// Enable the deprecated numeric alignment.
#ifndef FMT_NUMERIC_ALIGN
#  define FMT_NUMERIC_ALIGN 1
#endif

// Enable the deprecated percent specifier.
#ifndef FMT_DEPRECATED_PERCENT
#  define FMT_DEPRECATED_PERCENT 0
#endif

FMT_BEGIN_NAMESPACE
namespace internal {

// A helper function to suppress bogus "conditional expression is constant"
// warnings.
template <typename T> inline T const_check(T value) { return value; }

// An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't have
// undefined behavior (e.g. due to type aliasing).
// Example: uint64_t d = bit_cast<uint64_t>(2.718);
template <typename Dest, typename Source>
inline Dest bit_cast(const Source& source) {
  static_assert(sizeof(Dest) == sizeof(Source), "size mismatch");
  Dest dest;
  std::memcpy(&dest, &source, sizeof(dest));
  return dest;
}

inline bool is_big_endian() {
  auto u = 1u;
  struct bytes {
    char data[sizeof(u)];
  };
  return bit_cast<bytes>(u).data[0] == 0;
}

// A fallback implementation of uintptr_t for systems that lack it.
struct fallback_uintptr {
  unsigned char value[sizeof(void*)];

  fallback_uintptr() = default;
  explicit fallback_uintptr(const void* p) {
    *this = bit_cast<fallback_uintptr>(p);
    if (is_big_endian()) {
      for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j)
        std::swap(value[i], value[j]);
    }
  }
};
#ifdef UINTPTR_MAX
using uintptr_t = ::uintptr_t;
inline uintptr_t to_uintptr(const void* p) { return bit_cast<uintptr_t>(p); }
#else
using uintptr_t = fallback_uintptr;
inline fallback_uintptr to_uintptr(const void* p) {
  return fallback_uintptr(p);
}
#endif

// Returns the largest possible value for type T. Same as
// std::numeric_limits<T>::max() but shorter and not affected by the max macro.
template <typename T> constexpr T max_value() {
  return (std::numeric_limits<T>::max)();
}
template <typename T> constexpr int num_bits() {
  return std::numeric_limits<T>::digits;
}
template <> constexpr int num_bits<fallback_uintptr>() {
  return static_cast<int>(sizeof(void*) *
                          std::numeric_limits<unsigned char>::digits);
}

// An approximation of iterator_t for pre-C++20 systems.
template <typename T>
using iterator_t = decltype(std::begin(std::declval<T&>()));

// Detect the iterator category of *any* given type in a SFINAE-friendly way.
// Unfortunately, older implementations of std::iterator_traits are not safe
// for use in a SFINAE-context.
template <typename It, typename Enable = void>
struct iterator_category : std::false_type {};

template <typename T> struct iterator_category<T*> {
  using type = std::random_access_iterator_tag;
};

template <typename It>
struct iterator_category<It, void_t<typename It::iterator_category>> {
  using type = typename It::iterator_category;
};

// Detect if *any* given type models the OutputIterator concept.
template <typename It> class is_output_iterator {
  // Check for mutability because all iterator categories derived from
  // std::input_iterator_tag *may* also meet the requirements of an
  // OutputIterator, thereby falling into the category of 'mutable iterators'
  // [iterator.requirements.general] clause 4. The compiler reveals this
  // property only at the point of *actually dereferencing* the iterator!
  template <typename U>
  static decltype(*(std::declval<U>())) test(std::input_iterator_tag);
  template <typename U> static char& test(std::output_iterator_tag);
  template <typename U> static const char& test(...);

  using type = decltype(test<It>(typename iterator_category<It>::type{}));

 public:
  static const bool value = !std::is_const<remove_reference_t<type>>::value;
};

// A workaround for std::string not having mutable data() until C++17.
template <typename Char> inline Char* get_data(std::basic_string<Char>& s) {
  return &s[0];
}
template <typename Container>
inline typename Container::value_type* get_data(Container& c) {
  return c.data();
}

#ifdef _SECURE_SCL
// Make a checked iterator to avoid MSVC warnings.
template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
template <typename T> checked_ptr<T> make_checked(T* p, std::size_t size) {
  return {p, size};
}
#else
template <typename T> using checked_ptr = T*;
template <typename T> inline T* make_checked(T* p, std::size_t) { return p; }
#endif

template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
inline checked_ptr<typename Container::value_type> reserve(
    std::back_insert_iterator<Container>& it, std::size_t n) {
  Container& c = get_container(it);
  std::size_t size = c.size();
  c.resize(size + n);
  return make_checked(get_data(c) + size, n);
}

template <typename Iterator>
inline Iterator& reserve(Iterator& it, std::size_t) {
  return it;
}

// An output iterator that counts the number of objects written to it and
// discards them.
class counting_iterator {
 private:
  std::size_t count_;

 public:
  using iterator_category = std::output_iterator_tag;
  using difference_type = std::ptrdiff_t;
  using pointer = void;
  using reference = void;
  using _Unchecked_type = counting_iterator;  // Mark iterator as checked.

  struct value_type {
    template <typename T> void operator=(const T&) {}
  };

  counting_iterator() : count_(0) {}

  std::size_t count() const { return count_; }

  counting_iterator& operator++() {
    ++count_;
    return *this;
  }

  counting_iterator operator++(int) {
    auto it = *this;
    ++*this;
    return it;
  }

  value_type operator*() const { return {}; }
};

template <typename OutputIt> class truncating_iterator_base {
 protected:
  OutputIt out_;
  std::size_t limit_;
  std::size_t count_;

  truncating_iterator_base(OutputIt out, std::size_t limit)
      : out_(out), limit_(limit), count_(0) {}

 public:
  using iterator_category = std::output_iterator_tag;
  using difference_type = void;
  using pointer = void;
  using reference = void;
  using _Unchecked_type =
      truncating_iterator_base;  // Mark iterator as checked.

  OutputIt base() const { return out_; }
  std::size_t count() const { return count_; }
};

// An output iterator that truncates the output and counts the number of objects
// written to it.
template <typename OutputIt,
          typename Enable = typename std::is_void<
              typename std::iterator_traits<OutputIt>::value_type>::type>
class truncating_iterator;

template <typename OutputIt>
class truncating_iterator<OutputIt, std::false_type>
    : public truncating_iterator_base<OutputIt> {
  using traits = std::iterator_traits<OutputIt>;

  mutable typename traits::value_type blackhole_;

 public:
  using value_type = typename traits::value_type;

  truncating_iterator(OutputIt out, std::size_t limit)
      : truncating_iterator_base<OutputIt>(out, limit) {}

  truncating_iterator& operator++() {
    if (this->count_++ < this->limit_) ++this->out_;
    return *this;
  }

  truncating_iterator operator++(int) {
    auto it = *this;
    ++*this;
    return it;
  }

  value_type& operator*() const {
    return this->count_ < this->limit_ ? *this->out_ : blackhole_;
  }
};

template <typename OutputIt>
class truncating_iterator<OutputIt, std::true_type>
    : public truncating_iterator_base<OutputIt> {
 public:
  using value_type = typename OutputIt::container_type::value_type;

  truncating_iterator(OutputIt out, std::size_t limit)
      : truncating_iterator_base<OutputIt>(out, limit) {}

  truncating_iterator& operator=(value_type val) {
    if (this->count_++ < this->limit_) this->out_ = val;
    return *this;
  }

  truncating_iterator& operator++() { return *this; }
  truncating_iterator& operator++(int) { return *this; }
  truncating_iterator& operator*() { return *this; }
};

// A range with the specified output iterator and value type.
template <typename OutputIt, typename T = typename OutputIt::value_type>
class output_range {
 private:
  OutputIt it_;

 public:
  using value_type = T;
  using iterator = OutputIt;
  struct sentinel {};

  explicit output_range(OutputIt it) : it_(it) {}
  OutputIt begin() const { return it_; }
  sentinel end() const { return {}; }  // Sentinel is not used yet.
};

template <typename Char>
inline size_t count_code_points(basic_string_view<Char> s) {
  return s.size();
}

// Counts the number of code points in a UTF-8 string.
inline size_t count_code_points(basic_string_view<char8_t> s) {
  const char8_t* data = s.data();
  size_t num_code_points = 0;
  for (size_t i = 0, size = s.size(); i != size; ++i) {
    if ((data[i] & 0xc0) != 0x80) ++num_code_points;
  }
  return num_code_points;
}

template <typename Char>
inline size_t code_point_index(basic_string_view<Char> s, size_t n) {
  size_t size = s.size();
  return n < size ? n : size;
}

// Calculates the index of the nth code point in a UTF-8 string.
inline size_t code_point_index(basic_string_view<char8_t> s, size_t n) {
  const char8_t* data = s.data();
  size_t num_code_points = 0;
  for (size_t i = 0, size = s.size(); i != size; ++i) {
    if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) {
      return i;
    }
  }
  return s.size();
}

inline char8_t to_char8_t(char c) { return static_cast<char8_t>(c); }

template <typename InputIt, typename OutChar>
using needs_conversion = bool_constant<
    std::is_same<typename std::iterator_traits<InputIt>::value_type,
                 char>::value &&
    std::is_same<OutChar, char8_t>::value>;

template <typename OutChar, typename InputIt, typename OutputIt,
          FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
  return std::copy(begin, end, it);
}

template <typename OutChar, typename InputIt, typename OutputIt,
          FMT_ENABLE_IF(needs_conversion<InputIt, OutChar>::value)>
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
  return std::transform(begin, end, it, to_char8_t);
}

#ifndef FMT_USE_GRISU
#  define FMT_USE_GRISU 1
#endif

template <typename T> constexpr bool use_grisu() {
  return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 &&
         sizeof(T) <= sizeof(double);
}

template <typename T>
template <typename U>
void buffer<T>::append(const U* begin, const U* end) {
  std::size_t new_size = size_ + to_unsigned(end - begin);
  reserve(new_size);
  std::uninitialized_copy(begin, end, make_checked(ptr_, capacity_) + size_);
  size_ = new_size;
}
}  // namespace internal

// A range with an iterator appending to a buffer.
template <typename T>
class buffer_range : public internal::output_range<
                         std::back_insert_iterator<internal::buffer<T>>, T> {
 public:
  using iterator = std::back_insert_iterator<internal::buffer<T>>;
  using internal::output_range<iterator, T>::output_range;
  buffer_range(internal::buffer<T>& buf)
      : internal::output_range<iterator, T>(std::back_inserter(buf)) {}
};

// A UTF-8 string view.
class u8string_view : public basic_string_view<char8_t> {
 public:
  u8string_view(const char* s)
      : basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s)) {}
  u8string_view(const char* s, size_t count) FMT_NOEXCEPT
      : basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s), count) {
  }
};

#if FMT_USE_USER_DEFINED_LITERALS
inline namespace literals {
inline u8string_view operator"" _u(const char* s, std::size_t n) {
  return {s, n};
}
}  // namespace literals
#endif

// The number of characters to store in the basic_memory_buffer object itself
// to avoid dynamic memory allocation.
enum { inline_buffer_size = 500 };

/**
  \rst
  A dynamically growing memory buffer for trivially copyable/constructible types
  with the first ``SIZE`` elements stored in the object itself.

  You can use one of the following type aliases for common character types:

  +----------------+------------------------------+
  | Type           | Definition                   |
  +================+==============================+
  | memory_buffer  | basic_memory_buffer<char>    |
  +----------------+------------------------------+
  | wmemory_buffer | basic_memory_buffer<wchar_t> |
  +----------------+------------------------------+

  **Example**::

     fmt::memory_buffer out;
     format_to(out, "The answer is {}.", 42);

  This will append the following output to the ``out`` object:

  .. code-block:: none

     The answer is 42.

  The output can be converted to an ``std::string`` with ``to_string(out)``.
  \endrst
 */
template <typename T, std::size_t SIZE = inline_buffer_size,
          typename Allocator = std::allocator<T>>
class basic_memory_buffer : private Allocator, public internal::buffer<T> {
 private:
  T store_[SIZE];

  // Deallocate memory allocated by the buffer.
  void deallocate() {
    T* data = this->data();
    if (data != store_) Allocator::deallocate(data, this->capacity());
  }

 protected:
  void grow(std::size_t size) FMT_OVERRIDE;

 public:
  using value_type = T;
  using const_reference = const T&;

  explicit basic_memory_buffer(const Allocator& alloc = Allocator())
      : Allocator(alloc) {
    this->set(store_, SIZE);
  }
  ~basic_memory_buffer() FMT_OVERRIDE { deallocate(); }

 private:
  // Move data from other to this buffer.
  void move(basic_memory_buffer& other) {
    Allocator &this_alloc = *this, &other_alloc = other;
    this_alloc = std::move(other_alloc);
    T* data = other.data();
    std::size_t size = other.size(), capacity = other.capacity();
    if (data == other.store_) {
      this->set(store_, capacity);
      std::uninitialized_copy(other.store_, other.store_ + size,
                              internal::make_checked(store_, capacity));
    } else {
      this->set(data, capacity);
      // Set pointer to the inline array so that delete is not called
      // when deallocating.
      other.set(other.store_, 0);
    }
    this->resize(size);
  }

 public:
  /**
    \rst
    Constructs a :class:`fmt::basic_memory_buffer` object moving the content
    of the other object to it.
    \endrst
   */
  basic_memory_buffer(basic_memory_buffer&& other) FMT_NOEXCEPT { move(other); }

  /**
    \rst
    Moves the content of the other ``basic_memory_buffer`` object to this one.
    \endrst
   */
  basic_memory_buffer& operator=(basic_memory_buffer&& other) FMT_NOEXCEPT {
    FMT_ASSERT(this != &other, "");
    deallocate();
    move(other);
    return *this;
  }

  // Returns a copy of the allocator associated with this buffer.
  Allocator get_allocator() const { return *this; }
};

template <typename T, std::size_t SIZE, typename Allocator>
void basic_memory_buffer<T, SIZE, Allocator>::grow(std::size_t size) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  if (size > 1000) throw std::runtime_error("fuzz mode - won't grow that much");
#endif
  std::size_t old_capacity = this->capacity();
  std::size_t new_capacity = old_capacity + old_capacity / 2;
  if (size > new_capacity) new_capacity = size;
  T* old_data = this->data();
  T* new_data = std::allocator_traits<Allocator>::allocate(*this, new_capacity);
  // The following code doesn't throw, so the raw pointer above doesn't leak.
  std::uninitialized_copy(old_data, old_data + this->size(),
                          internal::make_checked(new_data, new_capacity));
  this->set(new_data, new_capacity);
  // deallocate must not throw according to the standard, but even if it does,
  // the buffer already uses the new storage and will deallocate it in
  // destructor.
  if (old_data != store_) Allocator::deallocate(old_data, old_capacity);
}

using memory_buffer = basic_memory_buffer<char>;
using wmemory_buffer = basic_memory_buffer<wchar_t>;

namespace internal {

// Returns true if value is negative, false otherwise.
// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
template <typename T, FMT_ENABLE_IF(std::numeric_limits<T>::is_signed)>
FMT_CONSTEXPR bool is_negative(T value) {
  return value < 0;
}
template <typename T, FMT_ENABLE_IF(!std::numeric_limits<T>::is_signed)>
FMT_CONSTEXPR bool is_negative(T) {
  return false;
}

// Smallest of uint32_t, uint64_t, uint128_t that is large enough to
// represent all values of T.
template <typename T>
using uint32_or_64_or_128_t = conditional_t<
    std::numeric_limits<T>::digits <= 32, uint32_t,
    conditional_t<std::numeric_limits<T>::digits <= 64, uint64_t, uint128_t>>;

// Static data is placed in this class template for the header-only config.
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
  static const uint64_t powers_of_10_64[];
  static const uint32_t zero_or_powers_of_10_32[];
  static const uint64_t zero_or_powers_of_10_64[];
  static const uint64_t pow10_significands[];
  static const int16_t pow10_exponents[];
  static const char digits[];
  static const char hex_digits[];
  static const char foreground_color[];
  static const char background_color[];
  static const char reset_color[5];
  static const wchar_t wreset_color[5];
  static const char signs[];
};

FMT_EXTERN template struct basic_data<void>;

// This is a struct rather than an alias to avoid shadowing warnings in gcc.
struct data : basic_data<> {};

#ifdef FMT_BUILTIN_CLZLL
// Returns the number of decimal digits in n. Leading zeros are not counted
// except for n == 0 in which case count_digits returns 1.
inline int count_digits(uint64_t n) {
  // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
  // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
  int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
  return t - (n < data::zero_or_powers_of_10_64[t]) + 1;
}
#else
// Fallback version of count_digits used when __builtin_clz is not available.
inline int count_digits(uint64_t n) {
  int count = 1;
  for (;;) {
    // Integer division is slow so do it for a group of four digits instead
    // of for every digit. The idea comes from the talk by Alexandrescu
    // "Three Optimization Tips for C++". See speed-test for a comparison.
    if (n < 10) return count;
    if (n < 100) return count + 1;
    if (n < 1000) return count + 2;
    if (n < 10000) return count + 3;
    n /= 10000u;
    count += 4;
  }
}
#endif

#if FMT_USE_INT128
inline int count_digits(uint128_t n) {
  int count = 1;
  for (;;) {
    // Integer division is slow so do it for a group of four digits instead
    // of for every digit. The idea comes from the talk by Alexandrescu
    // "Three Optimization Tips for C++". See speed-test for a comparison.
    if (n < 10) return count;
    if (n < 100) return count + 1;
    if (n < 1000) return count + 2;
    if (n < 10000) return count + 3;
    n /= 10000U;
    count += 4;
  }
}
#endif

// Counts the number of digits in n. BITS = log2(radix).
template <unsigned BITS, typename UInt> inline int count_digits(UInt n) {
  int num_digits = 0;
  do {
    ++num_digits;
  } while ((n >>= BITS) != 0);
  return num_digits;
}

template <> int count_digits<4>(internal::fallback_uintptr n);

#if FMT_GCC_VERSION || FMT_CLANG_VERSION
#  define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
#else
#  define FMT_ALWAYS_INLINE
#endif

#ifdef FMT_BUILTIN_CLZ
// Optional version of count_digits for better performance on 32-bit platforms.
inline int count_digits(uint32_t n) {
  int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
  return t - (n < data::zero_or_powers_of_10_32[t]) + 1;
}
#endif

template <typename Char> FMT_API std::string grouping_impl(locale_ref loc);
template <typename Char> inline std::string grouping(locale_ref loc) {
  return grouping_impl<char>(loc);
}
template <> inline std::string grouping<wchar_t>(locale_ref loc) {
  return grouping_impl<wchar_t>(loc);
}

template <typename Char> FMT_API Char thousands_sep_impl(locale_ref loc);
template <typename Char> inline Char thousands_sep(locale_ref loc) {
  return Char(thousands_sep_impl<char>(loc));
}
template <> inline wchar_t thousands_sep(locale_ref loc) {
  return thousands_sep_impl<wchar_t>(loc);
}

template <typename Char> FMT_API Char decimal_point_impl(locale_ref loc);
template <typename Char> inline Char decimal_point(locale_ref loc) {
  return Char(decimal_point_impl<char>(loc));
}
template <> inline wchar_t decimal_point(locale_ref loc) {
  return decimal_point_impl<wchar_t>(loc);
}

// Formats a decimal unsigned integer value writing into buffer.
// add_thousands_sep is called after writing each char to add a thousands
// separator if necessary.
template <typename UInt, typename Char, typename F>
inline Char* format_decimal(Char* buffer, UInt value, int num_digits,
                            F add_thousands_sep) {
  FMT_ASSERT(num_digits >= 0, "invalid digit count");
  buffer += num_digits;
  Char* end = buffer;
  while (value >= 100) {
    // Integer division is slow so do it for a group of two digits instead
    // of for every digit. The idea comes from the talk by Alexandrescu
    // "Three Optimization Tips for C++". See speed-test for a comparison.
    auto index = static_cast<unsigned>((value % 100) * 2);
    value /= 100;
    *--buffer = static_cast<Char>(data::digits[index + 1]);
    add_thousands_sep(buffer);
    *--buffer = static_cast<Char>(data::digits[index]);
    add_thousands_sep(buffer);
  }
  if (value < 10) {
    *--buffer = static_cast<Char>('0' + value);
    return end;
  }
  auto index = static_cast<unsigned>(value * 2);
  *--buffer = static_cast<Char>(data::digits[index + 1]);
  add_thousands_sep(buffer);
  *--buffer = static_cast<Char>(data::digits[index]);
  return end;
}

template <typename Int> constexpr int digits10() noexcept {
  return std::numeric_limits<Int>::digits10;
}
template <> constexpr int digits10<int128_t>() noexcept { return 38; }
template <> constexpr int digits10<uint128_t>() noexcept { return 38; }

template <typename Char, typename UInt, typename Iterator, typename F>
inline Iterator format_decimal(Iterator out, UInt value, int num_digits,
                               F add_thousands_sep) {
  FMT_ASSERT(num_digits >= 0, "invalid digit count");
  // Buffer should be large enough to hold all digits (<= digits10 + 1).
  enum { max_size = digits10<UInt>() + 1 };
  Char buffer[2 * max_size];
  auto end = format_decimal(buffer, value, num_digits, add_thousands_sep);
  return internal::copy_str<Char>(buffer, end, out);
}

template <typename Char, typename It, typename UInt>
inline It format_decimal(It out, UInt value, int num_digits) {
  return format_decimal<Char>(out, value, num_digits, [](Char*) {});
}

template <unsigned BASE_BITS, typename Char, typename UInt>
inline Char* format_uint(Char* buffer, UInt value, int num_digits,
                         bool upper = false) {
  buffer += num_digits;
  Char* end = buffer;
  do {
    const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits;
    unsigned digit = (value & ((1 << BASE_BITS) - 1));
    *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
                                                : digits[digit]);
  } while ((value >>= BASE_BITS) != 0);
  return end;
}

template <unsigned BASE_BITS, typename Char>
Char* format_uint(Char* buffer, internal::fallback_uintptr n, int num_digits,
                  bool = false) {
  auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
  int start = (num_digits + char_digits - 1) / char_digits - 1;
  if (int start_digits = num_digits % char_digits) {
    unsigned value = n.value[start--];
    buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
  }
  for (; start >= 0; --start) {
    unsigned value = n.value[start];
    buffer += char_digits;
    auto p = buffer;
    for (int i = 0; i < char_digits; ++i) {
      unsigned digit = (value & ((1 << BASE_BITS) - 1));
      *--p = static_cast<Char>(data::hex_digits[digit]);
      value >>= BASE_BITS;
    }
  }
  return buffer;
}

template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
inline It format_uint(It out, UInt value, int num_digits, bool upper = false) {
  // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
  char buffer[num_bits<UInt>() / BASE_BITS + 1];
  format_uint<BASE_BITS>(buffer, value, num_digits, upper);
  return internal::copy_str<Char>(buffer, buffer + num_digits, out);
}

template <typename T = void> struct null {};

// Workaround an array initialization issue in gcc 4.8.
template <typename Char> struct fill_t {
 private:
  Char data_[6];

 public:
  FMT_CONSTEXPR Char& operator[](size_t index) { return data_[index]; }
  FMT_CONSTEXPR const Char& operator[](size_t index) const {
    return data_[index];
  }

  static FMT_CONSTEXPR fill_t<Char> make() {
    auto fill = fill_t<Char>();
    fill[0] = Char(' ');
    return fill;
  }
};
}  // namespace internal

// We cannot use enum classes as bit fields because of a gcc bug
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
namespace align {
enum type { none, left, right, center, numeric };
}
using align_t = align::type;

namespace sign {
enum type { none, minus, plus, space };
}
using sign_t = sign::type;

// Format specifiers for built-in and string types.
template <typename Char> struct basic_format_specs {
  int width;
  int precision;
  char type;
  align_t align : 4;
  sign_t sign : 3;
  bool alt : 1;  // Alternate form ('#').
  internal::fill_t<Char> fill;

  constexpr basic_format_specs()
      : width(0),
        precision(-1),
        type(0),
        align(align::none),
        sign(sign::none),
        alt(false),
        fill(internal::fill_t<Char>::make()) {}
};

using format_specs = basic_format_specs<char>;

namespace internal {

// A floating-point presentation format.
enum class float_format : unsigned char {
  general,  // General: exponent notation or fixed point based on magnitude.
  exp,      // Exponent notation with the default precision of 6, e.g. 1.2e-3.
  fixed,    // Fixed point with the default precision of 6, e.g. 0.0012.
  hex
};

struct float_specs {
  int precision;
  float_format format : 8;
  sign_t sign : 8;
  bool upper : 1;
  bool locale : 1;
  bool percent : 1;
  bool binary32 : 1;
  bool use_grisu : 1;
  bool trailing_zeros : 1;
};

// Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
template <typename Char, typename It> It write_exponent(int exp, It it) {
  FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
  if (exp < 0) {
    *it++ = static_cast<Char>('-');
    exp = -exp;
  } else {
    *it++ = static_cast<Char>('+');
  }
  if (exp >= 100) {
    const char* top = data::digits + (exp / 100) * 2;
    if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
    *it++ = static_cast<Char>(top[1]);
    exp %= 100;
  }
  const char* d = data::digits + exp * 2;
  *it++ = static_cast<Char>(d[0]);
  *it++ = static_cast<Char>(d[1]);
  return it;
}

template <typename Char> class float_writer {
 private:
  // The number is given as v = digits_ * pow(10, exp_).
  const char* digits_;
  int num_digits_;
  int exp_;
  size_t size_;
  float_specs specs_;
  Char decimal_point_;

  template <typename It> It prettify(It it) const {
    // pow(10, full_exp - 1) <= v <= pow(10, full_exp).
    int full_exp = num_digits_ + exp_;
    if (specs_.format == float_format::exp) {
      // Insert a decimal point after the first digit and add an exponent.
      *it++ = static_cast<Char>(*digits_);
      int num_zeros = specs_.precision - num_digits_;
      bool trailing_zeros = num_zeros > 0 && specs_.trailing_zeros;
      if (num_digits_ > 1 || trailing_zeros) *it++ = decimal_point_;
      it = copy_str<Char>(digits_ + 1, digits_ + num_digits_, it);
      if (trailing_zeros)
        it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
      *it++ = static_cast<Char>(specs_.upper ? 'E' : 'e');
      return write_exponent<Char>(full_exp - 1, it);
    }
    if (num_digits_ <= full_exp) {
      // 1234e7 -> 12340000000[.0+]
      it = copy_str<Char>(digits_, digits_ + num_digits_, it);
      it = std::fill_n(it, full_exp - num_digits_, static_cast<Char>('0'));
      if (specs_.trailing_zeros) {
        *it++ = decimal_point_;
        int num_zeros = specs_.precision - full_exp;
        if (num_zeros <= 0) {
          if (specs_.format != float_format::fixed)
            *it++ = static_cast<Char>('0');
          return it;
        }
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        if (num_zeros > 1000)
          throw std::runtime_error("fuzz mode - avoiding excessive cpu use");
#endif
        it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
      }
    } else if (full_exp > 0) {
      // 1234e-2 -> 12.34[0+]
      it = copy_str<Char>(digits_, digits_ + full_exp, it);
      if (!specs_.trailing_zeros) {
        // Remove trailing zeros.
        int num_digits = num_digits_;
        while (num_digits > full_exp && digits_[num_digits - 1] == '0')
          --num_digits;
        if (num_digits != full_exp) *it++ = decimal_point_;
        return copy_str<Char>(digits_ + full_exp, digits_ + num_digits, it);
      }
      *it++ = decimal_point_;
      it = copy_str<Char>(digits_ + full_exp, digits_ + num_digits_, it);
      if (specs_.precision > num_digits_) {
        // Add trailing zeros.
        int num_zeros = specs_.precision - num_digits_;
        it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
      }
    } else {
      // 1234e-6 -> 0.001234
      *it++ = static_cast<Char>('0');
      int num_zeros = -full_exp;
      if (specs_.precision >= 0 && specs_.precision < num_zeros)
        num_zeros = specs_.precision;
      int num_digits = num_digits_;
      if (!specs_.trailing_zeros)
        while (num_digits > 0 && digits_[num_digits - 1] == '0') --num_digits;
      if (num_zeros != 0 || num_digits != 0) {
        *it++ = decimal_point_;
        it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
        it = copy_str<Char>(digits_, digits_ + num_digits, it);
      }
    }
    return it;
  }

 public:
  float_writer(const char* digits, int num_digits, int exp, float_specs specs,
               Char decimal_point)
      : digits_(digits),
        num_digits_(num_digits),
        exp_(exp),
        specs_(specs),
        decimal_point_(decimal_point) {
    int full_exp = num_digits + exp - 1;
    int precision = specs.precision > 0 ? specs.precision : 16;
    if (specs_.format == float_format::general &&
        !(full_exp >= -4 && full_exp < precision)) {
      specs_.format = float_format::exp;
    }
    size_ = prettify(counting_iterator()).count();
    size_ += specs.sign ? 1 : 0;
  }

  size_t size() const { return size_; }
  size_t width() const { return size(); }

  template <typename It> void operator()(It&& it) {
    if (specs_.sign) *it++ = static_cast<Char>(data::signs[specs_.sign]);
    it = prettify(it);
  }
};

template <typename T>
int format_float(T value, int precision, float_specs specs, buffer<char>& buf);

// Formats a floating-point number with snprintf.
template <typename T>
int snprintf_float(T value, int precision, float_specs specs,
                   buffer<char>& buf);

template <typename T> T promote_float(T value) { return value; }
inline double promote_float(float value) { return value; }

template <typename Handler>
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) {
  switch (spec) {
  case 0:
  case 'd':
    handler.on_dec();
    break;
  case 'x':
  case 'X':
    handler.on_hex();
    break;
  case 'b':
  case 'B':
    handler.on_bin();
    break;
  case 'o':
    handler.on_oct();
    break;
  case 'n':
    handler.on_num();
    break;
  default:
    handler.on_error();
  }
}

template <typename ErrorHandler = error_handler, typename Char>
FMT_CONSTEXPR float_specs parse_float_type_spec(
    const basic_format_specs<Char>& specs, ErrorHandler&& eh = {}) {
  auto result = float_specs();
  result.trailing_zeros = specs.alt;
  switch (specs.type) {
  case 0:
    result.format = float_format::general;
    result.trailing_zeros |= specs.precision != 0;
    break;
  case 'G':
    result.upper = true;
    FMT_FALLTHROUGH;
  case 'g':
    result.format = float_format::general;
    break;
  case 'E':
    result.upper = true;
    FMT_FALLTHROUGH;
  case 'e':
    result.format = float_format::exp;
    result.trailing_zeros |= specs.precision != 0;
    break;
  case 'F':
    result.upper = true;
    FMT_FALLTHROUGH;
  case 'f':
    result.format = float_format::fixed;
    result.trailing_zeros |= specs.precision != 0;
    break;
#if FMT_DEPRECATED_PERCENT
  case '%':
    result.format = float_format::fixed;
    result.percent = true;
    break;
#endif
  case 'A':
    result.upper = true;
    FMT_FALLTHROUGH;
  case 'a':
    result.format = float_format::hex;
    break;
  case 'n':
    result.locale = true;
    break;
  default:
    eh.on_error("invalid type specifier");
    break;
  }
  return result;
}

template <typename Char, typename Handler>
FMT_CONSTEXPR void handle_char_specs(const basic_format_specs<Char>* specs,
                                     Handler&& handler) {
  if (!specs) return handler.on_char();
  if (specs->type && specs->type != 'c') return handler.on_int();
  if (specs->align == align::numeric || specs->sign != sign::none || specs->alt)
    handler.on_error("invalid format specifier for char");
  handler.on_char();
}

template <typename Char, typename Handler>
FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler&& handler) {
  if (spec == 0 || spec == 's')
    handler.on_string();
  else if (spec == 'p')
    handler.on_pointer();
  else
    handler.on_error("invalid type specifier");
}

template <typename Char, typename ErrorHandler>
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler&& eh) {
  if (spec != 0 && spec != 's') eh.on_error("invalid type specifier");
}

template <typename Char, typename ErrorHandler>
FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) {
  if (spec != 0 && spec != 'p') eh.on_error("invalid type specifier");
}

template <typename ErrorHandler> class int_type_checker : private ErrorHandler {
 public:
  FMT_CONSTEXPR explicit int_type_checker(ErrorHandler eh) : ErrorHandler(eh) {}

  FMT_CONSTEXPR void on_dec() {}
  FMT_CONSTEXPR void on_hex() {}
  FMT_CONSTEXPR void on_bin() {}
  FMT_CONSTEXPR void on_oct() {}
  FMT_CONSTEXPR void on_num() {}

  FMT_CONSTEXPR void on_error() {
    ErrorHandler::on_error("invalid type specifier");
  }
};

template <typename ErrorHandler>
class char_specs_checker : public ErrorHandler {
 private:
  char type_;

 public:
  FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
      : ErrorHandler(eh), type_(type) {}

  FMT_CONSTEXPR void on_int() {
    handle_int_type_spec(type_, int_type_checker<ErrorHandler>(*this));
  }
  FMT_CONSTEXPR void on_char() {}
};

template <typename ErrorHandler>
class cstring_type_checker : public ErrorHandler {
 public:
  FMT_CONSTEXPR explicit cstring_type_checker(ErrorHandler eh)
      : ErrorHandler(eh) {}

  FMT_CONSTEXPR void on_string() {}
  FMT_CONSTEXPR void on_pointer() {}
};

template <typename Context>
void arg_map<Context>::init(const basic_format_args<Context>& args) {
  if (map_) return;
  map_ = new entry[internal::to_unsigned(args.max_size())];
  if (args.is_packed()) {
    for (int i = 0;; ++i) {
      internal::type arg_type = args.type(i);
      if (arg_type == internal::none_type) return;
      if (arg_type == internal::named_arg_type) push_back(args.values_[i]);
    }
  }
  for (int i = 0, n = args.max_size(); i < n; ++i) {
    auto type = args.args_[i].type_;
    if (type == internal::named_arg_type) push_back(args.args_[i].value_);
  }
}

template <typename Char> struct nonfinite_writer {
  sign_t sign;
  const char* str;
  static constexpr size_t str_size = 3;

  size_t size() const { return str_size + (sign ? 1 : 0); }
  size_t width() const { return size(); }

  template <typename It> void operator()(It&& it) const {
    if (sign) *it++ = static_cast<Char>(data::signs[sign]);
    it = copy_str<Char>(str, str + str_size, it);
  }
};

// This template provides operations for formatting and writing data into a
// character range.
template <typename Range> class basic_writer {
 public:
  using char_type = typename Range::value_type;
  using iterator = typename Range::iterator;
  using format_specs = basic_format_specs<char_type>;

 private:
  iterator out_;  // Output iterator.
  locale_ref locale_;

  // Attempts to reserve space for n extra characters in the output range.
  // Returns a pointer to the reserved range or a reference to out_.
  auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) {
    return internal::reserve(out_, n);
  }

  template <typename F> struct padded_int_writer {
    size_t size_;
    string_view prefix;
    char_type fill;
    std::size_t padding;
    F f;

    size_t size() const { return size_; }
    size_t width() const { return size_; }

    template <typename It> void operator()(It&& it) const {
      if (prefix.size() != 0)
        it = copy_str<char_type>(prefix.begin(), prefix.end(), it);
      it = std::fill_n(it, padding, fill);
      f(it);
    }
  };

  // Writes an integer in the format
  //   <left-padding><prefix><numeric-padding><digits><right-padding>
  // where <digits> are written by f(it).
  template <typename F>
  void write_int(int num_digits, string_view prefix, format_specs specs, F f) {
    std::size_t size = prefix.size() + to_unsigned(num_digits);
    char_type fill = specs.fill[0];
    std::size_t padding = 0;
    if (specs.align == align::numeric) {
      auto unsiged_width = to_unsigned(specs.width);
      if (unsiged_width > size) {
        padding = unsiged_width - size;
        size = unsiged_width;
      }
    } else if (specs.precision > num_digits) {
      size = prefix.size() + to_unsigned(specs.precision);
      padding = to_unsigned(specs.precision - num_digits);
      fill = static_cast<char_type>('0');
    }
    if (specs.align == align::none) specs.align = align::right;
    write_padded(specs, padded_int_writer<F>{size, prefix, fill, padding, f});
  }

  // Writes a decimal integer.
  template <typename Int> void write_decimal(Int value) {
    auto abs_value = static_cast<uint32_or_64_or_128_t<Int>>(value);
    bool negative = is_negative(value);
    // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
    if (negative) abs_value = ~abs_value + 1;
    int num_digits = count_digits(abs_value);
    auto&& it = reserve((negative ? 1 : 0) + static_cast<size_t>(num_digits));
    if (negative) *it++ = static_cast<char_type>('-');
    it = format_decimal<char_type>(it, abs_value, num_digits);
  }

  // The handle_int_type_spec handler that writes an integer.
  template <typename Int, typename Specs> struct int_writer {
    using unsigned_type = uint32_or_64_or_128_t<Int>;

    basic_writer<Range>& writer;
    const Specs& specs;
    unsigned_type abs_value;
    char prefix[4];
    unsigned prefix_size;

    string_view get_prefix() const { return string_view(prefix, prefix_size); }

    int_writer(basic_writer<Range>& w, Int value, const Specs& s)
        : writer(w),
          specs(s),
          abs_value(static_cast<unsigned_type>(value)),
          prefix_size(0) {
      if (is_negative(value)) {
        prefix[0] = '-';
        ++prefix_size;
        abs_value = 0 - abs_value;
      } else if (specs.sign != sign::none && specs.sign != sign::minus) {
        prefix[0] = specs.sign == sign::plus ? '+' : ' ';
        ++prefix_size;
      }
    }

    struct dec_writer {
      unsigned_type abs_value;
      int num_digits;

      template <typename It> void operator()(It&& it) const {
        it = internal::format_decimal<char_type>(it, abs_value, num_digits);
      }
    };

    void on_dec() {
      int num_digits = count_digits(abs_value);
      writer.write_int(num_digits, get_prefix(), specs,
                       dec_writer{abs_value, num_digits});
    }

    struct hex_writer {
      int_writer& self;
      int num_digits;

      template <typename It> void operator()(It&& it) const {
        it = format_uint<4, char_type>(it, self.abs_value, num_digits,
                                       self.specs.type != 'x');
      }
    };

    void on_hex() {
      if (specs.alt) {
        prefix[prefix_size++] = '0';
        prefix[prefix_size++] = specs.type;
      }
      int num_digits = count_digits<4>(abs_value);
      writer.write_int(num_digits, get_prefix(), specs,
                       hex_writer{*this, num_digits});
    }

    template <int BITS> struct bin_writer {
      unsigned_type abs_value;
      int num_digits;

      template <typename It> void operator()(It&& it) const {
        it = format_uint<BITS, char_type>(it, abs_value, num_digits);
      }
    };

    void on_bin() {
      if (specs.alt) {
        prefix[prefix_size++] = '0';
        prefix[prefix_size++] = static_cast<char>(specs.type);
      }
      int num_digits = count_digits<1>(abs_value);
      writer.write_int(num_digits, get_prefix(), specs,
                       bin_writer<1>{abs_value, num_digits});
    }

    void on_oct() {
      int num_digits = count_digits<3>(abs_value);
      if (specs.alt && specs.precision <= num_digits && abs_value != 0) {
        // Octal prefix '0' is counted as a digit, so only add it if precision
        // is not greater than the number of digits.
        prefix[prefix_size++] = '0';
      }
      writer.write_int(num_digits, get_prefix(), specs,
                       bin_writer<3>{abs_value, num_digits});
    }

    enum { sep_size = 1 };

    struct num_writer {
      unsigned_type abs_value;
      int size;
      const std::string& groups;
      char_type sep;

      template <typename It> void operator()(It&& it) const {
        basic_string_view<char_type> s(&sep, sep_size);
        // Index of a decimal digit with the least significant digit having
        // index 0.
        int digit_index = 0;
        std::string::const_iterator group = groups.cbegin();
        it = format_decimal<char_type>(
            it, abs_value, size,
            [this, s, &group, &digit_index](char_type*& buffer) {
              if (*group <= 0 || ++digit_index % *group != 0 ||
                  *group == max_value<char>())
                return;
              if (group + 1 != groups.cend()) {
                digit_index = 0;
                ++group;
              }
              buffer -= s.size();
              std::uninitialized_copy(s.data(), s.data() + s.size(),
                                      make_checked(buffer, s.size()));
            });
      }
    };

    void on_num() {
      std::string groups = grouping<char_type>(writer.locale_);
      if (groups.empty()) return on_dec();
      auto sep = thousands_sep<char_type>(writer.locale_);
      if (!sep) return on_dec();
      int num_digits = count_digits(abs_value);
      int size = num_digits;
      std::string::const_iterator group = groups.cbegin();
      while (group != groups.cend() && num_digits > *group && *group > 0 &&
             *group != max_value<char>()) {
        size += sep_size;
        num_digits -= *group;
        ++group;
      }
      if (group == groups.cend())
        size += sep_size * ((num_digits - 1) / groups.back());
      writer.write_int(size, get_prefix(), specs,
                       num_writer{abs_value, size, groups, sep});
    }

    FMT_NORETURN void on_error() {
      FMT_THROW(duckdb::Exception("invalid type specifier"));
    }
  };

  template <typename Char> struct str_writer {
    const Char* s;
    size_t size_;

    size_t size() const { return size_; }
    size_t width() const {
      return count_code_points(basic_string_view<Char>(s, size_));
    }

    template <typename It> void operator()(It&& it) const {
      it = copy_str<char_type>(s, s + size_, it);
    }
  };

  template <typename UIntPtr> struct pointer_writer {
    UIntPtr value;
    int num_digits;

    size_t size() const { return to_unsigned(num_digits) + 2; }
    size_t width() const { return size(); }

    template <typename It> void operator()(It&& it) const {
      *it++ = static_cast<char_type>('0');
      *it++ = static_cast<char_type>('x');
      it = format_uint<4, char_type>(it, value, num_digits);
    }
  };

 public:
  explicit basic_writer(Range out, locale_ref loc = locale_ref())
      : out_(out.begin()), locale_(loc) {}

  iterator out() const { return out_; }

  // Writes a value in the format
  //   <left-padding><value><right-padding>
  // where <value> is written by f(it).
  template <typename F> void write_padded(const format_specs& specs, F&& f) {
    // User-perceived width (in code points).
    unsigned width = to_unsigned(specs.width);
    size_t size = f.size();  // The number of code units.
    size_t num_code_points = width != 0 ? f.width() : size;
    if (width <= num_code_points) return f(reserve(size));
    auto&& it = reserve(width + (size - num_code_points));
    char_type fill = specs.fill[0];
    std::size_t padding = width - num_code_points;
    if (specs.align == align::right) {
      it = std::fill_n(it, padding, fill);
      f(it);
    } else if (specs.align == align::center) {
      std::size_t left_padding = padding / 2;
      it = std::fill_n(it, left_padding, fill);
      f(it);
      it = std::fill_n(it, padding - left_padding, fill);
    } else {
      f(it);
      it = std::fill_n(it, padding, fill);
    }
  }

  void write(int value) { write_decimal(value); }
  void write(long value) { write_decimal(value); }
  void write(long long value) { write_decimal(value); }

  void write(unsigned value) { write_decimal(value); }
  void write(unsigned long value) { write_decimal(value); }
  void write(unsigned long long value) { write_decimal(value); }

#if FMT_USE_INT128
  void write(int128_t value) { write_decimal(value); }
  void write(uint128_t value) { write_decimal(value); }
#endif

  template <typename T, typename Spec>
  void write_int(T value, const Spec& spec) {
    handle_int_type_spec(spec.type, int_writer<T, Spec>(*this, value, spec));
  }

  template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
  void write(T value, format_specs specs = {}) {
    float_specs fspecs = parse_float_type_spec(specs);
    fspecs.sign = specs.sign;
    if (std::signbit(value)) {  // value < 0 is false for NaN so use signbit.
      fspecs.sign = sign::minus;
      value = -value;
    } else if (fspecs.sign == sign::minus) {
      fspecs.sign = sign::none;
    }

    if (!std::isfinite(value)) {
      auto str = std::isinf(value) ? (fspecs.upper ? "INF" : "inf")
                                   : (fspecs.upper ? "NAN" : "nan");
      return write_padded(specs, nonfinite_writer<char_type>{fspecs.sign, str});
    }

    if (specs.align == align::none) {
      specs.align = align::right;
    } else if (specs.align == align::numeric) {
      if (fspecs.sign) {
        auto&& it = reserve(1);
        *it++ = static_cast<char_type>(data::signs[fspecs.sign]);
        fspecs.sign = sign::none;
        if (specs.width != 0) --specs.width;
      }
      specs.align = align::right;
    }

    memory_buffer buffer;
    if (fspecs.format == float_format::hex) {
      if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]);
      snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
      write_padded(specs, str_writer<char>{buffer.data(), buffer.size()});
      return;
    }
    int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
    if (fspecs.format == float_format::exp) ++precision;
    if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
    fspecs.use_grisu = use_grisu<T>();
    if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) value *= 100;
    int exp = format_float(promote_float(value), precision, fspecs, buffer);
    if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) {
      buffer.push_back('%');
      --exp;  // Adjust decimal place position.
    }
    fspecs.precision = precision;
    char_type point = fspecs.locale ? decimal_point<char_type>(locale_)
                                    : static_cast<char_type>('.');
    write_padded(specs, float_writer<char_type>(buffer.data(),
                                                static_cast<int>(buffer.size()),
                                                exp, fspecs, point));
  }

  void write(char value) {
    auto&& it = reserve(1);
    *it++ = value;
  }

  template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char_type>::value)>
  void write(Char value) {
    auto&& it = reserve(1);
    *it++ = value;
  }

  void write(string_view value) {
    auto&& it = reserve(value.size());
    it = copy_str<char_type>(value.begin(), value.end(), it);
  }
  void write(wstring_view value) {
    static_assert(std::is_same<char_type, wchar_t>::value, "");
    auto&& it = reserve(value.size());
    it = std::copy(value.begin(), value.end(), it);
  }

  template <typename Char>
  void write(const Char* s, std::size_t size, const format_specs& specs) {
    write_padded(specs, str_writer<Char>{s, size});
  }

  template <typename Char>
  void write(basic_string_view<Char> s, const format_specs& specs = {}) {
    const Char* data = s.data();
    std::size_t size = s.size();
    if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
      size = code_point_index(s, to_unsigned(specs.precision));
    write(data, size, specs);
  }

  template <typename UIntPtr>
  void write_pointer(UIntPtr value, const format_specs* specs) {
    int num_digits = count_digits<4>(value);
    auto pw = pointer_writer<UIntPtr>{value, num_digits};
    if (!specs) return pw(reserve(to_unsigned(num_digits) + 2));
    format_specs specs_copy = *specs;
    if (specs_copy.align == align::none) specs_copy.align = align::right;
    write_padded(specs_copy, pw);
  }
};

using writer = basic_writer<buffer_range<char>>;

template <typename T> struct is_integral : std::is_integral<T> {};
template <> struct is_integral<int128_t> : std::true_type {};
template <> struct is_integral<uint128_t> : std::true_type {};

template <typename Range, typename ErrorHandler = internal::error_handler>
class arg_formatter_base {
 public:
  using char_type = typename Range::value_type;
  using iterator = typename Range::iterator;
  using format_specs = basic_format_specs<char_type>;

 private:
  using writer_type = basic_writer<Range>;
  writer_type writer_;
  format_specs* specs_;

  struct char_writer {
    char_type value;

    size_t size() const { return 1; }
    size_t width() const { return 1; }

    template <typename It> void operator()(It&& it) const { *it++ = value; }
  };

  void write_char(char_type value) {
    if (specs_)
      writer_.write_padded(*specs_, char_writer{value});
    else
      writer_.write(value);
  }

  void write_pointer(const void* p) {
    writer_.write_pointer(internal::to_uintptr(p), specs_);
  }

 protected:
  writer_type& writer() { return writer_; }
  FMT_DEPRECATED format_specs* spec() { return specs_; }
  format_specs* specs() { return specs_; }
  iterator out() { return writer_.out(); }

  void write(bool value) {
    string_view sv(value ? "true" : "false");
    specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
  }

  void write(const char_type* value) {
    if (!value) {
      FMT_THROW(duckdb::Exception("string pointer is null"));
    } else {
      auto length = std::char_traits<char_type>::length(value);
      basic_string_view<char_type> sv(value, length);
      specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
    }
  }

 public:
  arg_formatter_base(Range r, format_specs* s, locale_ref loc)
      : writer_(r, loc), specs_(s) {}

  iterator operator()(monostate) {
    FMT_ASSERT(false, "invalid argument type");
    return out();
  }

  template <typename T, FMT_ENABLE_IF(is_integral<T>::value)>
  iterator operator()(T value) {
    if (specs_)
      writer_.write_int(value, *specs_);
    else
      writer_.write(value);
    return out();
  }

  iterator operator()(char_type value) {
    internal::handle_char_specs(
        specs_, char_spec_handler(*this, static_cast<char_type>(value)));
    return out();
  }

  iterator operator()(bool value) {
    if (specs_ && specs_->type) return (*this)(value ? 1 : 0);
    write(value != 0);
    return out();
  }

  template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
  iterator operator()(T value) {
    writer_.write(value, specs_ ? *specs_ : format_specs());
    return out();
  }

  struct char_spec_handler : ErrorHandler {
    arg_formatter_base& formatter;
    char_type value;

    char_spec_handler(arg_formatter_base& f, char_type val)
        : formatter(f), value(val) {}

    void on_int() {
      if (formatter.specs_)
        formatter.writer_.write_int(value, *formatter.specs_);
      else
        formatter.writer_.write(value);
    }
    void on_char() { formatter.write_char(value); }
  };

  struct cstring_spec_handler : internal::error_handler {
    arg_formatter_base& formatter;
    const char_type* value;

    cstring_spec_handler(arg_formatter_base& f, const char_type* val)
        : formatter(f), value(val) {}

    void on_string() { formatter.write(value); }
    void on_pointer() { formatter.write_pointer(value); }
  };

  iterator operator()(const char_type* value) {
    if (!specs_) return write(value), out();
    internal::handle_cstring_type_spec(specs_->type,
                                       cstring_spec_handler(*this, value));
    return out();
  }

  iterator operator()(basic_string_view<char_type> value) {
    if (specs_) {
      internal::check_string_type_spec(specs_->type, internal::error_handler());
      writer_.write(value, *specs_);
    } else {
      writer_.write(value);
    }
    return out();
  }

  iterator operator()(const void* value) {
    if (specs_)
      check_pointer_type_spec(specs_->type, internal::error_handler());
    write_pointer(value);
    return out();
  }
};

template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) {
  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
}

// Parses the range [begin, end) as an unsigned integer. This function assumes
// that the range is non-empty and the first character is a digit.
template <typename Char, typename ErrorHandler>
FMT_CONSTEXPR int parse_nonnegative_int(const Char*& begin, const Char* end,
                                        ErrorHandler&& eh) {
  FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
  if (*begin == '0') {
    ++begin;
    return 0;
  }
  unsigned value = 0;
  // Convert to unsigned to prevent a warning.
  constexpr unsigned max_int = max_value<int>();
  unsigned big = max_int / 10;
  do {
    // Check for overflow.
    if (value > big) {
      value = max_int + 1;
      break;
    }
    value = value * 10 + unsigned(*begin - '0');
    ++begin;
  } while (begin != end && '0' <= *begin && *begin <= '9');
  if (value > max_int) eh.on_error("number is too big");
  return static_cast<int>(value);
}

template <typename Context> class custom_formatter {
 private:
  using char_type = typename Context::char_type;

  basic_format_parse_context<char_type>& parse_ctx_;
  Context& ctx_;

 public:
  explicit custom_formatter(basic_format_parse_context<char_type>& parse_ctx,
                            Context& ctx)
      : parse_ctx_(parse_ctx), ctx_(ctx) {}

  bool operator()(typename basic_format_arg<Context>::handle h) const {
    h.format(parse_ctx_, ctx_);
    return true;
  }

  template <typename T> bool operator()(T) const { return false; }
};

template <typename T>
using is_integer =
    bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
                  !std::is_same<T, char>::value &&
                  !std::is_same<T, wchar_t>::value>;

template <typename ErrorHandler> class width_checker {
 public:
  explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}

  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
  FMT_CONSTEXPR unsigned long long operator()(T value) {
    if (is_negative(value)) handler_.on_error("negative width");
    return static_cast<unsigned long long>(value);
  }

  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
  FMT_CONSTEXPR unsigned long long operator()(T) {
    handler_.on_error("width is not integer");
    return 0;
  }

 private:
  ErrorHandler& handler_;
};

template <typename ErrorHandler> class precision_checker {
 public:
  explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}

  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
  FMT_CONSTEXPR unsigned long long operator()(T value) {
    if (is_negative(value)) handler_.on_error("negative precision");
    return static_cast<unsigned long long>(value);
  }

  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
  FMT_CONSTEXPR unsigned long long operator()(T) {
    handler_.on_error("precision is not integer");
    return 0;
  }

 private:
  ErrorHandler& handler_;
};

// A format specifier handler that sets fields in basic_format_specs.
template <typename Char> class specs_setter {
 public:
  explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs)
      : specs_(specs) {}

  FMT_CONSTEXPR specs_setter(const specs_setter& other)
      : specs_(other.specs_) {}

  FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; }
  FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill[0] = fill; }
  FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; }
  FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; }
  FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; }
  FMT_CONSTEXPR void on_hash() { specs_.alt = true; }

  FMT_CONSTEXPR void on_zero() {
    specs_.align = align::numeric;
    specs_.fill[0] = Char('0');
  }

  FMT_CONSTEXPR void on_width(int width) { specs_.width = width; }
  FMT_CONSTEXPR void on_precision(int precision) {
    specs_.precision = precision;
  }
  FMT_CONSTEXPR void end_precision() {}

  FMT_CONSTEXPR void on_type(Char type) {
    specs_.type = static_cast<char>(type);
  }

 protected:
  basic_format_specs<Char>& specs_;
};

template <typename ErrorHandler> class numeric_specs_checker {
 public:
  FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, internal::type arg_type)
      : error_handler_(eh), arg_type_(arg_type) {}

  FMT_CONSTEXPR void require_numeric_argument() {
    if (!is_arithmetic_type(arg_type_))
      error_handler_.on_error("format specifier requires numeric argument");
  }

  FMT_CONSTEXPR void check_sign() {
    require_numeric_argument();
    if (is_integral_type(arg_type_) && arg_type_ != int_type &&
        arg_type_ != long_long_type && arg_type_ != internal::char_type) {
      error_handler_.on_error("format specifier requires signed argument");
    }
  }

  FMT_CONSTEXPR void check_precision() {
    if (is_integral_type(arg_type_) || arg_type_ == internal::pointer_type)
      error_handler_.on_error("precision not allowed for this argument type");
  }

 private:
  ErrorHandler& error_handler_;
  internal::type arg_type_;
};

// A format specifier handler that checks if specifiers are consistent with the
// argument type.
template <typename Handler> class specs_checker : public Handler {
 public:
  FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type)
      : Handler(handler), checker_(*this, arg_type) {}

  FMT_CONSTEXPR specs_checker(const specs_checker& other)
      : Handler(other), checker_(*this, other.arg_type_) {}

  FMT_CONSTEXPR void on_align(align_t align) {
    if (align == align::numeric) checker_.require_numeric_argument();
    Handler::on_align(align);
  }

  FMT_CONSTEXPR void on_plus() {
    checker_.check_sign();
    Handler::on_plus();
  }

  FMT_CONSTEXPR void on_minus() {
    checker_.check_sign();
    Handler::on_minus();
  }

  FMT_CONSTEXPR void on_space() {
    checker_.check_sign();
    Handler::on_space();
  }

  FMT_CONSTEXPR void on_hash() {
    checker_.require_numeric_argument();
    Handler::on_hash();
  }

  FMT_CONSTEXPR void on_zero() {
    checker_.require_numeric_argument();
    Handler::on_zero();
  }

  FMT_CONSTEXPR void end_precision() { checker_.check_precision(); }

 private:
  numeric_specs_checker<Handler> checker_;
};

template <template <typename> class Handler, typename FormatArg,
          typename ErrorHandler>
FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh) {
  unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg);
  if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big");
  return static_cast<int>(value);
}

struct auto_id {};

template <typename Context>
FMT_CONSTEXPR typename Context::format_arg get_arg(Context& ctx, int id) {
  auto arg = ctx.arg(id);
  if (!arg) ctx.on_error("argument index out of range");
  return arg;
}

// The standard format specifier handler with checking.
template <typename ParseContext, typename Context>
class specs_handler : public specs_setter<typename Context::char_type> {
 public:
  using char_type = typename Context::char_type;

  FMT_CONSTEXPR specs_handler(basic_format_specs<char_type>& specs,
                              ParseContext& parse_ctx, Context& ctx)
      : specs_setter<char_type>(specs),
        parse_context_(parse_ctx),
        context_(ctx) {}

  template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
    this->specs_.width = get_dynamic_spec<width_checker>(
        get_arg(arg_id), context_.error_handler());
  }

  template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
    this->specs_.precision = get_dynamic_spec<precision_checker>(
        get_arg(arg_id), context_.error_handler());
  }

  void on_error(const char* message) { context_.on_error(message); }

 private:
  // This is only needed for compatibility with gcc 4.4.
  using format_arg = typename Context::format_arg;

  FMT_CONSTEXPR format_arg get_arg(auto_id) {
    return internal::get_arg(context_, parse_context_.next_arg_id());
  }

  FMT_CONSTEXPR format_arg get_arg(int arg_id) {
    parse_context_.check_arg_id(arg_id);
    return internal::get_arg(context_, arg_id);
  }

  FMT_CONSTEXPR format_arg get_arg(basic_string_view<char_type> arg_id) {
    parse_context_.check_arg_id(arg_id);
    return context_.arg(arg_id);
  }

  ParseContext& parse_context_;
  Context& context_;
};

enum class arg_id_kind { none, index, name };

// An argument reference.
template <typename Char> struct arg_ref {
  FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {}
  FMT_CONSTEXPR explicit arg_ref(int index)
      : kind(arg_id_kind::index), val(index) {}
  FMT_CONSTEXPR explicit arg_ref(basic_string_view<Char> name)
      : kind(arg_id_kind::name), val(name) {}

  FMT_CONSTEXPR arg_ref& operator=(int idx) {
    kind = arg_id_kind::index;
    val.index = idx;
    return *this;
  }

  arg_id_kind kind;
  union value {
    FMT_CONSTEXPR value(int id = 0) : index{id} {}
    FMT_CONSTEXPR value(basic_string_view<Char> n) : name(n) {}

    int index;
    basic_string_view<Char> name;
  } val;
};

// Format specifiers with width and precision resolved at formatting rather
// than parsing time to allow re-using the same parsed specifiers with
// different sets of arguments (precompilation of format strings).
template <typename Char>
struct dynamic_format_specs : basic_format_specs<Char> {
  arg_ref<Char> width_ref;
  arg_ref<Char> precision_ref;
};

// Format spec handler that saves references to arguments representing dynamic
// width and precision to be resolved at formatting time.
template <typename ParseContext>
class dynamic_specs_handler
    : public specs_setter<typename ParseContext::char_type> {
 public:
  using char_type = typename ParseContext::char_type;

  FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs<char_type>& specs,
                                      ParseContext& ctx)
      : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}

  FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler& other)
      : specs_setter<char_type>(other),
        specs_(other.specs_),
        context_(other.context_) {}

  template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
    specs_.width_ref = make_arg_ref(arg_id);
  }

  template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
    specs_.precision_ref = make_arg_ref(arg_id);
  }

  FMT_CONSTEXPR void on_error(const char* message) {
    context_.on_error(message);
  }

 private:
  using arg_ref_type = arg_ref<char_type>;

  FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id) {
    context_.check_arg_id(arg_id);
    return arg_ref_type(arg_id);
  }

  FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id) {
    return arg_ref_type(context_.next_arg_id());
  }

  FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view<char_type> arg_id) {
    context_.check_arg_id(arg_id);
    basic_string_view<char_type> format_str(
        context_.begin(), to_unsigned(context_.end() - context_.begin()));
    return arg_ref_type(arg_id);
  }

  dynamic_format_specs<char_type>& specs_;
  ParseContext& context_;
};

template <typename Char, typename IDHandler>
FMT_CONSTEXPR const Char* parse_arg_id(const Char* begin, const Char* end,
                                       IDHandler&& handler) {
  FMT_ASSERT(begin != end, "");
  Char c = *begin;
  if (c == '}' || c == ':') {
    handler();
    return begin;
  }
  if (c >= '0' && c <= '9') {
    int index = parse_nonnegative_int(begin, end, handler);
    if (begin == end || (*begin != '}' && *begin != ':'))
      handler.on_error("invalid format string");
    else
      handler(index);
    return begin;
  }
  if (!is_name_start(c)) {
    handler.on_error("invalid format string");
    return begin;
  }
  auto it = begin;
  do {
    ++it;
  } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
  handler(basic_string_view<Char>(begin, to_unsigned(it - begin)));
  return it;
}

// Adapts SpecHandler to IDHandler API for dynamic width.
template <typename SpecHandler, typename Char> struct width_adapter {
  explicit FMT_CONSTEXPR width_adapter(SpecHandler& h) : handler(h) {}

  FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
  FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); }
  FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
    handler.on_dynamic_width(id);
  }

  FMT_CONSTEXPR void on_error(const char* message) {
    handler.on_error(message);
  }

  SpecHandler& handler;
};

// Adapts SpecHandler to IDHandler API for dynamic precision.
template <typename SpecHandler, typename Char> struct precision_adapter {
  explicit FMT_CONSTEXPR precision_adapter(SpecHandler& h) : handler(h) {}

  FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
  FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); }
  FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
    handler.on_dynamic_precision(id);
  }

  FMT_CONSTEXPR void on_error(const char* message) {
    handler.on_error(message);
  }

  SpecHandler& handler;
};

// Parses fill and alignment.
template <typename Char, typename Handler>
FMT_CONSTEXPR const Char* parse_align(const Char* begin, const Char* end,
                                      Handler&& handler) {
  FMT_ASSERT(begin != end, "");
  auto align = align::none;
  int i = 0;
  if (begin + 1 != end) ++i;
  do {
    switch (static_cast<char>(begin[i])) {
    case '<':
      align = align::left;
      break;
    case '>':
      align = align::right;
      break;
#if FMT_NUMERIC_ALIGN
    case '=':
      align = align::numeric;
      break;
#endif
    case '^':
      align = align::center;
      break;
    }
    if (align != align::none) {
      if (i > 0) {
        auto c = *begin;
        if (c == '{')
          return handler.on_error("invalid fill character '{'"), begin;
        begin += 2;
        handler.on_fill(c);
      } else
        ++begin;
      handler.on_align(align);
      break;
    }
  } while (i-- > 0);
  return begin;
}

template <typename Char, typename Handler>
FMT_CONSTEXPR const Char* parse_width(const Char* begin, const Char* end,
                                      Handler&& handler) {
  FMT_ASSERT(begin != end, "");
  if ('0' <= *begin && *begin <= '9') {
    handler.on_width(parse_nonnegative_int(begin, end, handler));
  } else if (*begin == '{') {
    ++begin;
    if (begin != end)
      begin = parse_arg_id(begin, end, width_adapter<Handler, Char>(handler));
    if (begin == end || *begin != '}')
      return handler.on_error("invalid format string"), begin;
    ++begin;
  }
  return begin;
}

template <typename Char, typename Handler>
FMT_CONSTEXPR const Char* parse_precision(const Char* begin, const Char* end,
                                          Handler&& handler) {
  ++begin;
  auto c = begin != end ? *begin : Char();
  if ('0' <= c && c <= '9') {
    handler.on_precision(parse_nonnegative_int(begin, end, handler));
  } else if (c == '{') {
    ++begin;
    if (begin != end) {
      begin =
          parse_arg_id(begin, end, precision_adapter<Handler, Char>(handler));
    }
    if (begin == end || *begin++ != '}')
      return handler.on_error("invalid format string"), begin;
  } else {
    return handler.on_error("missing precision specifier"), begin;
  }
  handler.end_precision();
  return begin;
}

// Parses standard format specifiers and sends notifications about parsed
// components to handler.
template <typename Char, typename SpecHandler>
FMT_CONSTEXPR const Char* parse_format_specs(const Char* begin, const Char* end,
                                             SpecHandler&& handler) {
  if (begin == end || *begin == '}') return begin;

  begin = parse_align(begin, end, handler);
  if (begin == end) return begin;

  // Parse sign.
  switch (static_cast<char>(*begin)) {
  case '+':
    handler.on_plus();
    ++begin;
    break;
  case '-':
    handler.on_minus();
    ++begin;
    break;
  case ' ':
    handler.on_space();
    ++begin;
    break;
  }
  if (begin == end) return begin;

  if (*begin == '#') {
    handler.on_hash();
    if (++begin == end) return begin;
  }

  // Parse zero flag.
  if (*begin == '0') {
    handler.on_zero();
    if (++begin == end) return begin;
  }

  begin = parse_width(begin, end, handler);
  if (begin == end) return begin;

  // Parse precision.
  if (*begin == '.') {
    begin = parse_precision(begin, end, handler);
  }

  // Parse type.
  if (begin != end && *begin != '}') handler.on_type(*begin++);
  return begin;
}

// Return the result via the out param to workaround gcc bug 77539.
template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr& out) {
  for (out = first; out != last; ++out) {
    if (*out == value) return true;
  }
  return false;
}

template <>
inline bool find<false, char>(const char* first, const char* last, char value,
                              const char*& out) {
  out = static_cast<const char*>(
      std::memchr(first, value, internal::to_unsigned(last - first)));
  return out != nullptr;
}

template <typename Handler, typename Char> struct id_adapter {
  FMT_CONSTEXPR void operator()() { handler.on_arg_id(); }
  FMT_CONSTEXPR void operator()(int id) { handler.on_arg_id(id); }
  FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
    handler.on_arg_id(id);
  }
  FMT_CONSTEXPR void on_error(const char* message) {
    handler.on_error(message);
  }
  Handler& handler;
};

template <bool IS_CONSTEXPR, typename Char, typename Handler>
FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> format_str,
                                       Handler&& handler) {
  struct pfs_writer {
    FMT_CONSTEXPR void operator()(const Char* begin, const Char* end) {
      if (begin == end) return;
      for (;;) {
        const Char* p = nullptr;
        if (!find<IS_CONSTEXPR>(begin, end, '}', p))
          return handler_.on_text(begin, end);
        ++p;
        if (p == end || *p != '}')
          return handler_.on_error("unmatched '}' in format string");
        handler_.on_text(begin, p);
        begin = p + 1;
      }
    }
    Handler& handler_;
  } write{handler};
  auto begin = format_str.data();
  auto end = begin + format_str.size();
  while (begin != end) {
    // Doing two passes with memchr (one for '{' and another for '}') is up to
    // 2.5x faster than the naive one-pass implementation on big format strings.
    const Char* p = begin;
    if (*begin != '{' && !find<IS_CONSTEXPR>(begin, end, '{', p))
      return write(begin, end);
    write(begin, p);
    ++p;
    if (p == end) return handler.on_error("invalid format string");
    if (static_cast<char>(*p) == '}') {
      handler.on_arg_id();
      handler.on_replacement_field(p);
    } else if (*p == '{') {
      handler.on_text(p, p + 1);
    } else {
      p = parse_arg_id(p, end, id_adapter<Handler, Char>{handler});
      Char c = p != end ? *p : Char();
      if (c == '}') {
        handler.on_replacement_field(p);
      } else if (c == ':') {
        p = handler.on_format_specs(p + 1, end);
        if (p == end || *p != '}')
          return handler.on_error("unknown format specifier");
      } else {
        return handler.on_error("missing '}' in format string");
      }
    }
    begin = p + 1;
  }
}

template <typename T, typename ParseContext>
FMT_CONSTEXPR const typename ParseContext::char_type* parse_format_specs(
    ParseContext& ctx) {
  using char_type = typename ParseContext::char_type;
  using context = buffer_context<char_type>;
  using mapped_type =
      conditional_t<internal::mapped_type_constant<T, context>::value !=
                        internal::custom_type,
                    decltype(arg_mapper<context>().map(std::declval<T>())), T>;
  auto f = conditional_t<has_formatter<mapped_type, context>::value,
                         formatter<mapped_type, char_type>,
                         internal::fallback_formatter<T, char_type>>();
  return f.parse(ctx);
}

template <typename Char, typename ErrorHandler, typename... Args>
class format_string_checker {
 public:
  explicit FMT_CONSTEXPR format_string_checker(
      basic_string_view<Char> format_str, ErrorHandler eh)
      : arg_id_(-1),
        context_(format_str, eh),
        parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}

  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}

  FMT_CONSTEXPR void on_arg_id() {
    arg_id_ = context_.next_arg_id();
    check_arg_id();
  }
  FMT_CONSTEXPR void on_arg_id(int id) {
    arg_id_ = id;
    context_.check_arg_id(id);
    check_arg_id();
  }
  FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) {
    on_error("compile-time checks don't support named arguments");
  }

  FMT_CONSTEXPR void on_replacement_field(const Char*) {}

  FMT_CONSTEXPR const Char* on_format_specs(const Char* begin, const Char*) {
    advance_to(context_, begin);
    return arg_id_ < num_args ? parse_funcs_[arg_id_](context_) : begin;
  }

  FMT_CONSTEXPR void on_error(const char* message) {
    context_.on_error(message);
  }

 private:
  using parse_context_type = basic_format_parse_context<Char, ErrorHandler>;
  enum { num_args = sizeof...(Args) };

  FMT_CONSTEXPR void check_arg_id() {
    if (arg_id_ >= num_args) context_.on_error("argument index out of range");
  }

  // Format specifier parsing function.
  using parse_func = const Char* (*)(parse_context_type&);

  int arg_id_;
  parse_context_type context_;
  parse_func parse_funcs_[num_args > 0 ? num_args : 1];
};

template <typename Char, typename ErrorHandler, typename... Args>
FMT_CONSTEXPR bool do_check_format_string(basic_string_view<Char> s,
                                          ErrorHandler eh = ErrorHandler()) {
  format_string_checker<Char, ErrorHandler, Args...> checker(s, eh);
  parse_format_string<true>(s, checker);
  return true;
}

template <typename... Args, typename S,
          enable_if_t<(is_compile_string<S>::value), int>>
void check_format_string(S format_str) {
  FMT_CONSTEXPR_DECL bool invalid_format =
      internal::do_check_format_string<typename S::char_type,
                                       internal::error_handler, Args...>(
          to_string_view(format_str));
  (void)invalid_format;
}

template <template <typename> class Handler, typename Context>
void handle_dynamic_spec(int& value, arg_ref<typename Context::char_type> ref,
                         Context& ctx) {
  switch (ref.kind) {
  case arg_id_kind::none:
    break;
  case arg_id_kind::index:
    value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
                                                ctx.error_handler());
    break;
  case arg_id_kind::name:
    value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
                                                ctx.error_handler());
    break;
  }
}
}  // namespace internal

template <typename Range>
using basic_writer FMT_DEPRECATED_ALIAS = internal::basic_writer<Range>;
using writer FMT_DEPRECATED_ALIAS = internal::writer;
using wwriter FMT_DEPRECATED_ALIAS =
    internal::basic_writer<buffer_range<wchar_t>>;

/** The default argument formatter. */
template <typename Range>
class arg_formatter : public internal::arg_formatter_base<Range> {
 private:
  using char_type = typename Range::value_type;
  using base = internal::arg_formatter_base<Range>;
  using context_type = basic_format_context<typename base::iterator, char_type>;

  context_type& ctx_;
  basic_format_parse_context<char_type>* parse_ctx_;

 public:
  using range = Range;
  using iterator = typename base::iterator;
  using format_specs = typename base::format_specs;

  /**
    \rst
    Constructs an argument formatter object.
    *ctx* is a reference to the formatting context,
    *specs* contains format specifier information for standard argument types.
    \endrst
   */
  explicit arg_formatter(
      context_type& ctx,
      basic_format_parse_context<char_type>* parse_ctx = nullptr,
      format_specs* specs = nullptr)
      : base(Range(ctx.out()), specs, ctx.locale()),
        ctx_(ctx),
        parse_ctx_(parse_ctx) {}

  using base::operator();

  /** Formats an argument of a user-defined type. */
  iterator operator()(typename basic_format_arg<context_type>::handle handle) {
    handle.format(*parse_ctx_, ctx_);
    return ctx_.out();
  }
};

/** Fast integer formatter. */
class format_int {
 private:
  // Buffer should be large enough to hold all digits (digits10 + 1),
  // a sign and a null character.
  enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
  mutable char buffer_[buffer_size];
  char* str_;

  // Formats value in reverse and returns a pointer to the beginning.
  char* format_decimal(unsigned long long value) {
    char* ptr = buffer_ + (buffer_size - 1);  // Parens to workaround MSVC bug.
    while (value >= 100) {
      // Integer division is slow so do it for a group of two digits instead
      // of for every digit. The idea comes from the talk by Alexandrescu
      // "Three Optimization Tips for C++". See speed-test for a comparison.
      auto index = static_cast<unsigned>((value % 100) * 2);
      value /= 100;
      *--ptr = internal::data::digits[index + 1];
      *--ptr = internal::data::digits[index];
    }
    if (value < 10) {
      *--ptr = static_cast<char>('0' + value);
      return ptr;
    }
    auto index = static_cast<unsigned>(value * 2);
    *--ptr = internal::data::digits[index + 1];
    *--ptr = internal::data::digits[index];
    return ptr;
  }

  void format_signed(long long value) {
    auto abs_value = static_cast<unsigned long long>(value);
    bool negative = value < 0;
    if (negative) abs_value = 0 - abs_value;
    str_ = format_decimal(abs_value);
    if (negative) *--str_ = '-';
  }

 public:
  explicit format_int(int value) { format_signed(value); }
  explicit format_int(long value) { format_signed(value); }
  explicit format_int(long long value) { format_signed(value); }
  explicit format_int(unsigned value) : str_(format_decimal(value)) {}
  explicit format_int(unsigned long value) : str_(format_decimal(value)) {}
  explicit format_int(unsigned long long value) : str_(format_decimal(value)) {}

  /** Returns the number of characters written to the output buffer. */
  std::size_t size() const {
    return internal::to_unsigned(buffer_ - str_ + buffer_size - 1);
  }

  /**
    Returns a pointer to the output buffer content. No terminating null
    character is appended.
   */
  const char* data() const { return str_; }

  /**
    Returns a pointer to the output buffer content with terminating null
    character appended.
   */
  const char* c_str() const {
    buffer_[buffer_size - 1] = '\0';
    return str_;
  }

  /**
    \rst
    Returns the content of the output buffer as an ``std::string``.
    \endrst
   */
  std::string str() const { return std::string(str_, size()); }
};

// A formatter specialization for the core types corresponding to internal::type
// constants.
template <typename T, typename Char>
struct formatter<T, Char,
                 enable_if_t<internal::type_constant<T, Char>::value !=
                             internal::custom_type>> {
  FMT_CONSTEXPR formatter() = default;

  // Parses format specifiers stopping either at the end of the range or at the
  // terminating '}'.
  template <typename ParseContext>
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    using handler_type = internal::dynamic_specs_handler<ParseContext>;
    auto type = internal::type_constant<T, Char>::value;
    internal::specs_checker<handler_type> handler(handler_type(specs_, ctx),
                                                  type);
    auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
    auto eh = ctx.error_handler();
    switch (type) {
    case internal::none_type:
    case internal::named_arg_type:
      FMT_ASSERT(false, "invalid argument type");
      break;
    case internal::int_type:
    case internal::uint_type:
    case internal::long_long_type:
    case internal::ulong_long_type:
    case internal::int128_type:
    case internal::uint128_type:
    case internal::bool_type:
      handle_int_type_spec(specs_.type,
                           internal::int_type_checker<decltype(eh)>(eh));
      break;
    case internal::char_type:
      handle_char_specs(
          &specs_, internal::char_specs_checker<decltype(eh)>(specs_.type, eh));
      break;
    case internal::float_type:
    case internal::double_type:
    case internal::long_double_type:
      internal::parse_float_type_spec(specs_, eh);
      break;
    case internal::cstring_type:
      internal::handle_cstring_type_spec(
          specs_.type, internal::cstring_type_checker<decltype(eh)>(eh));
      break;
    case internal::string_type:
      internal::check_string_type_spec(specs_.type, eh);
      break;
    case internal::pointer_type:
      internal::check_pointer_type_spec(specs_.type, eh);
      break;
    case internal::custom_type:
      // Custom format specifiers should be checked in parse functions of
      // formatter specializations.
      break;
    }
    return it;
  }

  template <typename FormatContext>
  auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
    internal::handle_dynamic_spec<internal::width_checker>(
        specs_.width, specs_.width_ref, ctx);
    internal::handle_dynamic_spec<internal::precision_checker>(
        specs_.precision, specs_.precision_ref, ctx);
    using range_type =
        internal::output_range<typename FormatContext::iterator,
                               typename FormatContext::char_type>;
    return visit_format_arg(arg_formatter<range_type>(ctx, nullptr, &specs_),
                            internal::make_arg<FormatContext>(val));
  }

 private:
  internal::dynamic_format_specs<Char> specs_;
};

#define FMT_FORMAT_AS(Type, Base)                                             \
  template <typename Char>                                                    \
  struct formatter<Type, Char> : formatter<Base, Char> {                      \
    template <typename FormatContext>                                         \
    auto format(const Type& val, FormatContext& ctx) -> decltype(ctx.out()) { \
      return formatter<Base, Char>::format(val, ctx);                         \
    }                                                                         \
  }

FMT_FORMAT_AS(signed char, int);
FMT_FORMAT_AS(unsigned char, unsigned);
FMT_FORMAT_AS(short, int);
FMT_FORMAT_AS(unsigned short, unsigned);
FMT_FORMAT_AS(long, long long);
FMT_FORMAT_AS(unsigned long, unsigned long long);
FMT_FORMAT_AS(Char*, const Char*);
FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
FMT_FORMAT_AS(std::nullptr_t, const void*);
FMT_FORMAT_AS(internal::std_string_view<Char>, basic_string_view<Char>);

template <typename Char>
struct formatter<void*, Char> : formatter<const void*, Char> {
  template <typename FormatContext>
  auto format(void* val, FormatContext& ctx) -> decltype(ctx.out()) {
    return formatter<const void*, Char>::format(val, ctx);
  }
};

template <typename Char, size_t N>
struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
  template <typename FormatContext>
  auto format(const Char* val, FormatContext& ctx) -> decltype(ctx.out()) {
    return formatter<basic_string_view<Char>, Char>::format(val, ctx);
  }
};

// A formatter for types known only at run time such as variant alternatives.
//
// Usage:
//   using variant = std::variant<int, std::string>;
//   template <>
//   struct formatter<variant>: dynamic_formatter<> {
//     void format(buffer &buf, const variant &v, context &ctx) {
//       visit([&](const auto &val) { format(buf, val, ctx); }, v);
//     }
//   };
template <typename Char = char> class dynamic_formatter {
 private:
  struct null_handler : internal::error_handler {
    void on_align(align_t) {}
    void on_plus() {}
    void on_minus() {}
    void on_space() {}
    void on_hash() {}
  };

 public:
  template <typename ParseContext>
  auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    format_str_ = ctx.begin();
    // Checks are deferred to formatting time when the argument type is known.
    internal::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
    return parse_format_specs(ctx.begin(), ctx.end(), handler);
  }

  template <typename T, typename FormatContext>
  auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
    handle_specs(ctx);
    internal::specs_checker<null_handler> checker(
        null_handler(),
        internal::mapped_type_constant<T, FormatContext>::value);
    checker.on_align(specs_.align);
    switch (specs_.sign) {
    case sign::none:
      break;
    case sign::plus:
      checker.on_plus();
      break;
    case sign::minus:
      checker.on_minus();
      break;
    case sign::space:
      checker.on_space();
      break;
    }
    if (specs_.alt) checker.on_hash();
    if (specs_.precision >= 0) checker.end_precision();
    using range = internal::output_range<typename FormatContext::iterator,
                                         typename FormatContext::char_type>;
    visit_format_arg(arg_formatter<range>(ctx, nullptr, &specs_),
                     internal::make_arg<FormatContext>(val));
    return ctx.out();
  }

 private:
  template <typename Context> void handle_specs(Context& ctx) {
    internal::handle_dynamic_spec<internal::width_checker>(
        specs_.width, specs_.width_ref, ctx);
    internal::handle_dynamic_spec<internal::precision_checker>(
        specs_.precision, specs_.precision_ref, ctx);
  }

  internal::dynamic_format_specs<Char> specs_;
  const Char* format_str_;
};

template <typename Range, typename Char>
typename basic_format_context<Range, Char>::format_arg
basic_format_context<Range, Char>::arg(basic_string_view<char_type> name) {
  map_.init(args_);
  format_arg arg = map_.find(name);
  if (arg.type() == internal::none_type) this->on_error("argument not found");
  return arg;
}

template <typename Char, typename ErrorHandler>
FMT_CONSTEXPR void advance_to(
    basic_format_parse_context<Char, ErrorHandler>& ctx, const Char* p) {
  ctx.advance_to(ctx.begin() + (p - &*ctx.begin()));
}

template <typename ArgFormatter, typename Char, typename Context>
struct format_handler : internal::error_handler {
  using range = typename ArgFormatter::range;

  format_handler(range r, basic_string_view<Char> str,
                 basic_format_args<Context> format_args,
                 internal::locale_ref loc)
      : parse_context(str), context(r.begin(), format_args, loc) {}

  void on_text(const Char* begin, const Char* end) {
    auto size = internal::to_unsigned(end - begin);
    auto out = context.out();
    auto&& it = internal::reserve(out, size);
    it = std::copy_n(begin, size, it);
    context.advance_to(out);
  }

  void get_arg(int id) { arg = internal::get_arg(context, id); }

  void on_arg_id() { get_arg(parse_context.next_arg_id()); }
  void on_arg_id(int id) {
    parse_context.check_arg_id(id);
    get_arg(id);
  }
  void on_arg_id(basic_string_view<Char> id) { arg = context.arg(id); }

  void on_replacement_field(const Char* p) {
    advance_to(parse_context, p);
    context.advance_to(
        visit_format_arg(ArgFormatter(context, &parse_context), arg));
  }

  const Char* on_format_specs(const Char* begin, const Char* end) {
    advance_to(parse_context, begin);
    internal::custom_formatter<Context> f(parse_context, context);
    if (visit_format_arg(f, arg)) return parse_context.begin();
    basic_format_specs<Char> specs;
    using internal::specs_handler;
    using parse_context_t = basic_format_parse_context<Char>;
    internal::specs_checker<specs_handler<parse_context_t, Context>> handler(
        specs_handler<parse_context_t, Context>(specs, parse_context, context),
        arg.type());
    begin = parse_format_specs(begin, end, handler);
    if (begin == end || *begin != '}') on_error("missing '}' in format string");
    advance_to(parse_context, begin);
    context.advance_to(
        visit_format_arg(ArgFormatter(context, &parse_context, &specs), arg));
    return begin;
  }

  basic_format_parse_context<Char> parse_context;
  Context context;
  basic_format_arg<Context> arg;
};

/** Formats arguments and writes the output to the range. */
template <typename ArgFormatter, typename Char, typename Context>
typename Context::iterator vformat_to(
    typename ArgFormatter::range out, basic_string_view<Char> format_str,
    basic_format_args<Context> args,
    internal::locale_ref loc = internal::locale_ref()) {
  format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc);
  internal::parse_format_string<false>(format_str, h);
  return h.context.out();
}

// Casts ``p`` to ``const void*`` for pointer formatting.
// Example:
//   auto s = format("{}", ptr(p));
template <typename T> inline const void* ptr(const T* p) { return p; }
template <typename T> inline const void* ptr(const std::unique_ptr<T>& p) {
  return p.get();
}
template <typename T> inline const void* ptr(const std::shared_ptr<T>& p) {
  return p.get();
}

template <typename It, typename Char> struct arg_join : internal::view {
  It begin;
  It end;
  basic_string_view<Char> sep;

  arg_join(It b, It e, basic_string_view<Char> s) : begin(b), end(e), sep(s) {}
};

template <typename It, typename Char>
struct formatter<arg_join<It, Char>, Char>
    : formatter<typename std::iterator_traits<It>::value_type, Char> {
  template <typename FormatContext>
  auto format(const arg_join<It, Char>& value, FormatContext& ctx)
      -> decltype(ctx.out()) {
    using base = formatter<typename std::iterator_traits<It>::value_type, Char>;
    auto it = value.begin;
    auto out = ctx.out();
    if (it != value.end) {
      out = base::format(*it++, ctx);
      while (it != value.end) {
        out = std::copy(value.sep.begin(), value.sep.end(), out);
        ctx.advance_to(out);
        out = base::format(*it++, ctx);
      }
    }
    return out;
  }
};

/**
  Returns an object that formats the iterator range `[begin, end)` with elements
  separated by `sep`.
 */
template <typename It>
arg_join<It, char> join(It begin, It end, string_view sep) {
  return {begin, end, sep};
}

template <typename It>
arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
  return {begin, end, sep};
}

/**
  \rst
  Returns an object that formats `range` with elements separated by `sep`.

  **Example**::

    std::vector<int> v = {1, 2, 3};
    fmt::print("{}", fmt::join(v, ", "));
    // Output: "1, 2, 3"
  \endrst
 */
template <typename Range>
arg_join<internal::iterator_t<const Range>, char> join(const Range& range,
                                                       string_view sep) {
  return join(std::begin(range), std::end(range), sep);
}

template <typename Range>
arg_join<internal::iterator_t<const Range>, wchar_t> join(const Range& range,
                                                          wstring_view sep) {
  return join(std::begin(range), std::end(range), sep);
}

/**
  \rst
  Converts *value* to ``std::string`` using the default format for type *T*.
  It doesn't support user-defined types with custom formatters.

  **Example**::

    #include <fmt/format.h>

    std::string answer = fmt::to_string(42);
  \endrst
 */
template <typename T> inline std::string to_string(const T& value) {
  return format("{}", value);
}

/**
  Converts *value* to ``std::wstring`` using the default format for type *T*.
 */
template <typename T> inline std::wstring to_wstring(const T& value) {
  return format(L"{}", value);
}

template <typename Char, std::size_t SIZE>
std::basic_string<Char> to_string(const basic_memory_buffer<Char, SIZE>& buf) {
  return std::basic_string<Char>(buf.data(), buf.size());
}

template <typename Char>
typename buffer_context<Char>::iterator internal::vformat_to(
    internal::buffer<Char>& buf, basic_string_view<Char> format_str,
    basic_format_args<buffer_context<Char>> args) {
  using range = buffer_range<Char>;
  return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str),
                                          args);
}

template <typename S, typename Char = char_t<S>,
          FMT_ENABLE_IF(internal::is_string<S>::value)>
inline typename buffer_context<Char>::iterator vformat_to(
    internal::buffer<Char>& buf, const S& format_str,
    basic_format_args<buffer_context<Char>> args) {
  return internal::vformat_to(buf, to_string_view(format_str), args);
}

template <typename S, typename... Args, std::size_t SIZE = inline_buffer_size,
          typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
inline typename buffer_context<Char>::iterator format_to(
    basic_memory_buffer<Char, SIZE>& buf, const S& format_str, Args&&... args) {
  internal::check_format_string<Args...>(format_str);
  using context = buffer_context<Char>;
  return internal::vformat_to(buf, to_string_view(format_str),
                              {make_format_args<context>(args...)});
}

template <typename OutputIt, typename Char = char>
using format_context_t = basic_format_context<OutputIt, Char>;

template <typename OutputIt, typename Char = char>
using format_args_t = basic_format_args<format_context_t<OutputIt, Char>>;

template <typename S, typename OutputIt, typename... Args,
          FMT_ENABLE_IF(
              internal::is_output_iterator<OutputIt>::value &&
              !internal::is_contiguous_back_insert_iterator<OutputIt>::value)>
inline OutputIt vformat_to(OutputIt out, const S& format_str,
                           format_args_t<OutputIt, char_t<S>> args) {
  using range = internal::output_range<OutputIt, char_t<S>>;
  return vformat_to<arg_formatter<range>>(range(out),
                                          to_string_view(format_str), args);
}

/**
 \rst
 Formats arguments, writes the result to the output iterator ``out`` and returns
 the iterator past the end of the output range.

 **Example**::

   std::vector<char> out;
   fmt::format_to(std::back_inserter(out), "{}", 42);
 \endrst
 */
template <typename OutputIt, typename S, typename... Args,
          FMT_ENABLE_IF(
              internal::is_output_iterator<OutputIt>::value &&
              !internal::is_contiguous_back_insert_iterator<OutputIt>::value &&
              internal::is_string<S>::value)>
inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) {
  internal::check_format_string<Args...>(format_str);
  using context = format_context_t<OutputIt, char_t<S>>;
  return vformat_to(out, to_string_view(format_str),
                    {make_format_args<context>(args...)});
}

template <typename OutputIt> struct format_to_n_result {
  /** Iterator past the end of the output range. */
  OutputIt out;
  /** Total (not truncated) output size. */
  std::size_t size;
};

template <typename OutputIt, typename Char = typename OutputIt::value_type>
using format_to_n_context =
    format_context_t<internal::truncating_iterator<OutputIt>, Char>;

template <typename OutputIt, typename Char = typename OutputIt::value_type>
using format_to_n_args = basic_format_args<format_to_n_context<OutputIt, Char>>;

template <typename OutputIt, typename Char, typename... Args>
inline format_arg_store<format_to_n_context<OutputIt, Char>, Args...>
make_format_to_n_args(const Args&... args) {
  return format_arg_store<format_to_n_context<OutputIt, Char>, Args...>(
      args...);
}

template <typename OutputIt, typename Char, typename... Args,
          FMT_ENABLE_IF(internal::is_output_iterator<OutputIt>::value)>
inline format_to_n_result<OutputIt> vformat_to_n(
    OutputIt out, std::size_t n, basic_string_view<Char> format_str,
    format_to_n_args<OutputIt, Char> args) {
  auto it = vformat_to(internal::truncating_iterator<OutputIt>(out, n),
                       format_str, args);
  return {it.base(), it.count()};
}

/**
 \rst
 Formats arguments, writes up to ``n`` characters of the result to the output
 iterator ``out`` and returns the total output size and the iterator past the
 end of the output range.
 \endrst
 */
template <typename OutputIt, typename S, typename... Args,
          FMT_ENABLE_IF(internal::is_string<S>::value&&
                            internal::is_output_iterator<OutputIt>::value)>
inline format_to_n_result<OutputIt> format_to_n(OutputIt out, std::size_t n,
                                                const S& format_str,
                                                const Args&... args) {
  internal::check_format_string<Args...>(format_str);
  using context = format_to_n_context<OutputIt, char_t<S>>;
  return vformat_to_n(out, n, to_string_view(format_str),
                      {make_format_args<context>(args...)});
}

template <typename Char>
inline std::basic_string<Char> internal::vformat(
    basic_string_view<Char> format_str,
    basic_format_args<buffer_context<Char>> args) {
  basic_memory_buffer<Char> buffer;
  internal::vformat_to(buffer, format_str, args);
  return to_string(buffer);
}

/**
  Returns the number of characters in the output of
  ``format(format_str, args...)``.
 */
template <typename... Args>
inline std::size_t formatted_size(string_view format_str, const Args&... args) {
  return format_to(internal::counting_iterator(), format_str, args...).count();
}

#if FMT_USE_USER_DEFINED_LITERALS
namespace internal {

#  if FMT_USE_UDL_TEMPLATE
template <typename Char, Char... CHARS> class udl_formatter {
 public:
  template <typename... Args>
  std::basic_string<Char> operator()(Args&&... args) const {
    FMT_CONSTEXPR_DECL Char s[] = {CHARS..., '\0'};
    FMT_CONSTEXPR_DECL bool invalid_format =
        do_check_format_string<Char, error_handler, remove_cvref_t<Args>...>(
            basic_string_view<Char>(s, sizeof...(CHARS)));
    (void)invalid_format;
    return format(s, std::forward<Args>(args)...);
  }
};
#  else
template <typename Char> struct udl_formatter {
  basic_string_view<Char> str;

  template <typename... Args>
  std::basic_string<Char> operator()(Args&&... args) const {
    return format(str, std::forward<Args>(args)...);
  }
};
#  endif  // FMT_USE_UDL_TEMPLATE

template <typename Char> struct udl_arg {
  basic_string_view<Char> str;

  template <typename T> named_arg<T, Char> operator=(T&& value) const {
    return {str, std::forward<T>(value)};
  }
};

}  // namespace internal

inline namespace literals {
#  if FMT_USE_UDL_TEMPLATE
#    pragma GCC diagnostic push
#    if FMT_CLANG_VERSION
#      pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template"
#    endif
template <typename Char, Char... CHARS>
FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...> operator""_format() {
  return {};
}
#    pragma GCC diagnostic pop
#  else
/**
  \rst
  User-defined literal equivalent of :func:`fmt::format`.

  **Example**::

    using namespace fmt::literals;
    std::string message = "The answer is {}"_format(42);
  \endrst
 */
FMT_CONSTEXPR internal::udl_formatter<char> operator"" _format(const char* s,
                                                               std::size_t n) {
  return {{s, n}};
}
FMT_CONSTEXPR internal::udl_formatter<wchar_t> operator"" _format(
    const wchar_t* s, std::size_t n) {
  return {{s, n}};
}
#  endif  // FMT_USE_UDL_TEMPLATE

/**
  \rst
  User-defined literal equivalent of :func:`fmt::arg`.

  **Example**::

    using namespace fmt::literals;
    fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
  \endrst
 */
FMT_CONSTEXPR internal::udl_arg<char> operator"" _a(const char* s,
                                                    std::size_t n) {
  return {{s, n}};
}
FMT_CONSTEXPR internal::udl_arg<wchar_t> operator"" _a(const wchar_t* s,
                                                       std::size_t n) {
  return {{s, n}};
}
}  // namespace literals
#endif  // FMT_USE_USER_DEFINED_LITERALS
FMT_END_NAMESPACE

#define FMT_STRING_IMPL(s, ...)                                         \
  [] {                                                                  \
    struct str : fmt::compile_string {                                  \
      using char_type = typename std::remove_cv<std::remove_pointer<    \
          typename std::decay<decltype(s)>::type>::type>::type;         \
      __VA_ARGS__ FMT_CONSTEXPR                                         \
      operator fmt::basic_string_view<char_type>() const {              \
        return {s, sizeof(s) / sizeof(char_type) - 1};                  \
      }                                                                 \
    } result;                                                           \
    /* Suppress Qt Creator warning about unused operator. */            \
    (void)static_cast<fmt::basic_string_view<typename str::char_type>>( \
        result);                                                        \
    return result;                                                      \
  }()

/**
  \rst
  Constructs a compile-time format string.

  **Example**::

    // A compile-time error because 'd' is an invalid specifier for strings.
    std::string s = format(FMT_STRING("{:d}"), "foo");
  \endrst
 */
#define FMT_STRING(s) FMT_STRING_IMPL(s, )

#if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS
#  define fmt(s) FMT_STRING_IMPL(s, [[deprecated]])
#endif

#ifdef FMT_HEADER_ONLY
#  define FMT_FUNC inline
#  include "format-inl.h"
#else
#  define FMT_FUNC
#endif

#endif  // FMT_FORMAT_H_


#include <cstdlib>
#include <cctype>
#include <cmath>

using namespace std;

namespace duckdb {

template <class SRC, class DST> static bool try_cast_with_overflow_check(SRC value, DST &result) {
	if (value < MinimumValue<DST>() || value > MaximumValue<DST>()) {
		return false;
	}
	result = (DST)value;
	return true;
}

template <class SRC, class DST> static DST cast_with_overflow_check(SRC value) {
	DST result;
	if (!try_cast_with_overflow_check<SRC, DST>(value, result)) {
		throw ValueOutOfRangeException((int64_t)value, GetTypeId<SRC>(), GetTypeId<DST>());
	}
	return result;
}

//===--------------------------------------------------------------------===//
// Numeric -> int8_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(int16_t input, int8_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(int32_t input, int8_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(int64_t input, int8_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(float input, int8_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(double input, int8_t &result) {
	return try_cast_with_overflow_check(input, result);
}

template <> int8_t Cast::Operation(int16_t input) {
	return cast_with_overflow_check<int16_t, int8_t>(input);
}
template <> int8_t Cast::Operation(int32_t input) {
	return cast_with_overflow_check<int32_t, int8_t>(input);
}
template <> int8_t Cast::Operation(int64_t input) {
	return cast_with_overflow_check<int64_t, int8_t>(input);
}
template <> int8_t Cast::Operation(float input) {
	return cast_with_overflow_check<float, int8_t>(input);
}
template <> int8_t Cast::Operation(double input) {
	return cast_with_overflow_check<double, int8_t>(input);
}
//===--------------------------------------------------------------------===//
// Numeric -> int16_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(int32_t input, int16_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(int64_t input, int16_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(float input, int16_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(double input, int16_t &result) {
	return try_cast_with_overflow_check(input, result);
}

template <> int16_t Cast::Operation(int32_t input) {
	return cast_with_overflow_check<int32_t, int16_t>(input);
}
template <> int16_t Cast::Operation(int64_t input) {
	return cast_with_overflow_check<int64_t, int16_t>(input);
}
template <> int16_t Cast::Operation(float input) {
	return cast_with_overflow_check<float, int16_t>(input);
}
template <> int16_t Cast::Operation(double input) {
	return cast_with_overflow_check<double, int16_t>(input);
}
//===--------------------------------------------------------------------===//
// Numeric -> int32_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(int64_t input, int32_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(float input, int32_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(double input, int32_t &result) {
	return try_cast_with_overflow_check(input, result);
}

template <> int32_t Cast::Operation(int64_t input) {
	return cast_with_overflow_check<int64_t, int32_t>(input);
}
template <> int32_t Cast::Operation(float input) {
	return cast_with_overflow_check<float, int32_t>(input);
}
template <> int32_t Cast::Operation(double input) {
	return cast_with_overflow_check<double, int32_t>(input);
}
//===--------------------------------------------------------------------===//
// Numeric -> int64_t casts
//===--------------------------------------------------------------------===//
template <> bool TryCast::Operation(float input, int64_t &result) {
	return try_cast_with_overflow_check(input, result);
}
template <> bool TryCast::Operation(double input, int64_t &result) {
	return try_cast_with_overflow_check(input, result);
}

template <> int64_t Cast::Operation(float input) {
	return cast_with_overflow_check<float, int64_t>(input);
}
template <> int64_t Cast::Operation(double input) {
	return cast_with_overflow_check<double, int64_t>(input);
}

//===--------------------------------------------------------------------===//
// Cast String -> Numeric
//===--------------------------------------------------------------------===//
template <class T> static T try_cast_string(string_t input) {
	T result;
	if (!TryCast::Operation<string_t, T>(input, result)) {
		throw ConversionException("Could not convert string '%s' to numeric", input.GetData());
	}
	return result;
}

template <class T, bool NEGATIVE, bool ALLOW_EXPONENT> static bool IntegerCastLoop(const char *buf, T &result) {
	idx_t pos = NEGATIVE ? 1 : 0;
	while (buf[pos]) {
		if (!std::isdigit(buf[pos])) {
			// not a digit!
			if (buf[pos] == '.') {
				// decimal point: we accept decimal values for integers as well
				// we just truncate them
				// make sure everything after the period is a number
				pos++;
				while (buf[pos]) {
					if (!std::isdigit(buf[pos++])) {
						return false;
					}
				}
				return true;
			}
			if (std::isspace(buf[pos])) {
				// skip any trailing spaces
				while (buf[++pos]) {
					if (!std::isspace(buf[pos])) {
						return false;
					}
				}
				return true;
			}
			if (ALLOW_EXPONENT) {
				if (buf[pos] == 'e' || buf[pos] == 'E') {
					pos++;
					int64_t exponent = 0;
					int negative = buf[pos] == '-';
					if (negative) {
						if (!IntegerCastLoop<int64_t, true, false>(buf + pos, exponent)) {
							return false;
						}
					} else {
						if (!IntegerCastLoop<int64_t, false, false>(buf + pos, exponent)) {
							return false;
						}
					}
					double dbl_res = result * pow(10, exponent);
					if (dbl_res < MinimumValue<T>() || dbl_res > MaximumValue<T>()) {
						return false;
					}
					result = (T)dbl_res;
					return true;
				}
			}
			return false;
		}
		T digit = buf[pos++] - '0';
		if (NEGATIVE) {
			if (result < (MinimumValue<T>() + digit) / 10) {
				return false;
			}
			result = result * 10 - digit;
		} else {
			if (result > (MaximumValue<T>() - digit) / 10) {
				return false;
			}
			result = result * 10 + digit;
		}
	}
	return pos > (NEGATIVE ? 1 : 0);
}

template <class T, bool ALLOW_EXPONENT = true> static bool TryIntegerCast(const char *buf, T &result) {
	if (!*buf) {
		return false;
	}
	// skip any spaces at the start
	while (std::isspace(*buf)) {
		buf++;
	}
	int negative = *buf == '-';

	result = 0;
	if (!negative) {
		return IntegerCastLoop<T, false, ALLOW_EXPONENT>(buf, result);
	} else {
		return IntegerCastLoop<T, true, ALLOW_EXPONENT>(buf, result);
	}
}

template <> bool TryCast::Operation(string_t input, bool &result) {
	auto input_data = input.GetData();
	if (input_data[0] == 't' || input_data[0] == 'T') {
		result = true;
	} else if (input_data[0] == 'f' || input_data[0] == 'F') {
		result = false;
	} else {
		return false;
	}
	return true;
}
template <> bool TryCast::Operation(string_t input, int8_t &result) {
	return TryIntegerCast<int8_t>(input.GetData(), result);
}
template <> bool TryCast::Operation(string_t input, int16_t &result) {
	return TryIntegerCast<int16_t>(input.GetData(), result);
}
template <> bool TryCast::Operation(string_t input, int32_t &result) {
	return TryIntegerCast<int32_t>(input.GetData(), result);
}
template <> bool TryCast::Operation(string_t input, int64_t &result) {
	return TryIntegerCast<int64_t>(input.GetData(), result);
}

template <class T, bool NEGATIVE> static void ComputeDoubleResult(T &result, idx_t decimal, idx_t decimal_factor) {
	if (decimal_factor > 1) {
		if (NEGATIVE) {
			result -= (T)decimal / (T)decimal_factor;
		} else {
			result += (T)decimal / (T)decimal_factor;
		}
	}
}

template <class T, bool NEGATIVE> static bool DoubleCastLoop(const char *buf, T &result) {
	idx_t pos = NEGATIVE ? 1 : 0;
	idx_t decimal = 0;
	idx_t decimal_factor = 0;
	while (buf[pos]) {
		if (!std::isdigit(buf[pos])) {
			// not a digit!
			if (buf[pos] == '.') {
				// decimal point
				if (decimal_factor != 0) {
					// nested periods
					return false;
				}
				decimal_factor = 1;
				pos++;
				continue;
			} else if (std::isspace(buf[pos])) {
				// skip any trailing spaces
				while (buf[++pos]) {
					if (!std::isspace(buf[pos])) {
						return false;
					}
				}
				ComputeDoubleResult<T, NEGATIVE>(result, decimal, decimal_factor);
				return true;
			} else if (buf[pos] == 'e' || buf[pos] == 'E') {
				// E power
				// parse an integer, this time not allowing another exponent
				pos++;
				int64_t exponent;
				if (!TryIntegerCast<int64_t, false>(buf + pos, exponent)) {
					return false;
				}
				ComputeDoubleResult<T, NEGATIVE>(result, decimal, decimal_factor);
				result = result * pow(10, exponent);
				return true;
			} else {
				return false;
			}
		}
		T digit = buf[pos++] - '0';
		if (decimal_factor == 0) {
			result = result * 10 + (NEGATIVE ? -digit : digit);
		} else {
			if (decimal_factor >= 1000000000000000000) {
				// decimal value will overflow if we parse more, ignore any subsequent numbers
				continue;
			}
			decimal = decimal * 10 + digit;
			decimal_factor *= 10;
		}
	}
	ComputeDoubleResult<T, NEGATIVE>(result, decimal, decimal_factor);
	return pos > (NEGATIVE ? 1 : 0);
}

template <class T> static bool TryDoubleCast(const char *buf, T &result) {
	if (!*buf) {
		return false;
	}
	// skip any spaces at the start
	while (std::isspace(*buf)) {
		buf++;
	}
	int negative = *buf == '-';

	result = 0;
	if (!negative) {
		return DoubleCastLoop<T, false>(buf, result);
	} else {
		return DoubleCastLoop<T, true>(buf, result);
	}
}

template <> bool TryCast::Operation(string_t input, float &result) {
	return TryDoubleCast<float>(input.GetData(), result);
}
template <> bool TryCast::Operation(string_t input, double &result) {
	return TryDoubleCast<double>(input.GetData(), result);
}

template <> bool Cast::Operation(string_t input) {
	return try_cast_string<bool>(input);
}
template <> int8_t Cast::Operation(string_t input) {
	return try_cast_string<int8_t>(input);
}
template <> int16_t Cast::Operation(string_t input) {
	return try_cast_string<int16_t>(input);
}
template <> int32_t Cast::Operation(string_t input) {
	return try_cast_string<int32_t>(input);
}
template <> int64_t Cast::Operation(string_t input) {
	return try_cast_string<int64_t>(input);
}
template <> float Cast::Operation(string_t input) {
	return try_cast_string<float>(input);
}
template <> double Cast::Operation(string_t input) {
	return try_cast_string<double>(input);
}

//===--------------------------------------------------------------------===//
// Cast Numeric -> String
//===--------------------------------------------------------------------===//
template <class T> string CastToStandardString(T input) {
	Vector v(TypeId::VARCHAR);
	return StringCast::Operation(input, v).GetString();
}

template <> string Cast::Operation(bool input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(int8_t input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(int16_t input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(int32_t input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(int64_t input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(float input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(double input) {
	return CastToStandardString(input);
}
template <> string Cast::Operation(string_t input) {
	return input.GetString();
}

template <> string_t StringCast::Operation(bool input, Vector &vector) {
	if (input) {
		return StringVector::AddString(vector, "true", 4);
	} else {
		return StringVector::AddString(vector, "false", 5);
	}
}

struct StringToIntegerCast {
	template <class T> static int UnsignedLength(T value);

	// Formats value in reverse and returns a pointer to the beginning.
	template <class T> static char *FormatUnsigned(T value, char *ptr) {
		while (value >= 100) {
			// Integer division is slow so do it for a group of two digits instead
			// of for every digit. The idea comes from the talk by Alexandrescu
			// "Three Optimization Tips for C++". See speed-test for a comparison.
			auto index = static_cast<unsigned>((value % 100) * 2);
			value /= 100;
			*--ptr = fmt::internal::data::digits[index + 1];
			*--ptr = fmt::internal::data::digits[index];
		}
		if (value < 10) {
			*--ptr = static_cast<char>('0' + value);
			return ptr;
		}
		auto index = static_cast<unsigned>(value * 2);
		*--ptr = fmt::internal::data::digits[index + 1];
		*--ptr = fmt::internal::data::digits[index];
		return ptr;
	}

	template <class SIGNED, class UNSIGNED> static string_t FormatSigned(SIGNED value, Vector &vector) {
		int sign = -(value < 0);
		UNSIGNED unsigned_value = (value ^ sign) - sign;
		int length = UnsignedLength<UNSIGNED>(unsigned_value) - sign;
		string_t result = StringVector::EmptyString(vector, length);
		auto dataptr = result.GetData();
		auto endptr = dataptr + length;
		endptr = FormatUnsigned(unsigned_value, endptr);
		if (sign) {
			*--endptr = '-';
		}
		result.Finalize();
		return result;
	}
};

template <> int StringToIntegerCast::UnsignedLength(uint8_t value) {
	int length = 1;
	length += value >= 10;
	length += value >= 100;
	return length;
}

template <> int StringToIntegerCast::UnsignedLength(uint16_t value) {
	int length = 1;
	length += value >= 10;
	length += value >= 100;
	length += value >= 1000;
	length += value >= 10000;
	return length;
}

template <> int StringToIntegerCast::UnsignedLength(uint32_t value) {
	if (value >= 10000) {
		int length = 5;
		length += value >= 100000;
		length += value >= 1000000;
		length += value >= 10000000;
		length += value >= 100000000;
		length += value >= 1000000000;
		return length;
	} else {
		int length = 1;
		length += value >= 10;
		length += value >= 100;
		length += value >= 1000;
		return length;
	}
}

template <> int StringToIntegerCast::UnsignedLength(uint64_t value) {
	if (value >= 10000000000ULL) {
		if (value >= 1000000000000000ULL) {
			int length = 16;
			length += value >= 10000000000000000ULL;
			length += value >= 100000000000000000ULL;
			length += value >= 1000000000000000000ULL;
			length += value >= 10000000000000000000ULL;
			return length;
		} else {
			int length = 11;
			length += value >= 100000000000ULL;
			length += value >= 1000000000000ULL;
			length += value >= 10000000000000ULL;
			length += value >= 100000000000000ULL;
			return length;
		}
	} else {
		if (value >= 100000ULL) {
			int length = 6;
			length += value >= 1000000ULL;
			length += value >= 10000000ULL;
			length += value >= 100000000ULL;
			length += value >= 1000000000ULL;
			return length;
		} else {
			int length = 1;
			length += value >= 10ULL;
			length += value >= 100ULL;
			length += value >= 1000ULL;
			length += value >= 10000ULL;
			return length;
		}
	}
}

template <> string_t StringCast::Operation(int8_t input, Vector &vector) {
	return StringToIntegerCast::FormatSigned<int8_t, uint8_t>(input, vector);
}

template <> string_t StringCast::Operation(int16_t input, Vector &vector) {
	return StringToIntegerCast::FormatSigned<int16_t, uint16_t>(input, vector);
}
template <> string_t StringCast::Operation(int32_t input, Vector &vector) {
	return StringToIntegerCast::FormatSigned<int32_t, uint32_t>(input, vector);
}

template <> string_t StringCast::Operation(int64_t input, Vector &vector) {
	return StringToIntegerCast::FormatSigned<int64_t, uint64_t>(input, vector);
}

template <> string_t StringCast::Operation(float input, Vector &vector) {
	std::string s = fmt::format("{}", input);
	return StringVector::AddString(vector, s);
}

template <> string_t StringCast::Operation(double input, Vector &vector) {
	std::string s = fmt::format("{}", input);
	return StringVector::AddString(vector, s);
}

//===--------------------------------------------------------------------===//
// Cast From Date
//===--------------------------------------------------------------------===//
struct DateToStringCast {
	static idx_t Length(int32_t date[], idx_t &year_length, bool &add_bc) {
		// format is YYYY-MM-DD with optional (BC) at the end
		// regular length is 10
		idx_t length = 6;
		year_length = 4;
		add_bc = false;
		if (date[0] <= 0) {
			// add (BC) suffix
			length += 5;
			date[0] = -date[0];
			add_bc = true;
		} else {
			// potentially add extra characters depending on length of year
			year_length += date[0] >= 10000;
			year_length += date[0] >= 100000;
			year_length += date[0] >= 1000000;
			year_length += date[0] >= 10000000;
		}
		length += year_length;
		return length;
	}

	static void Format(char *data, int32_t date[], idx_t year_length, bool add_bc) {
		// now we write the string, first write the year
		auto endptr = data + year_length;
		endptr = StringToIntegerCast::FormatUnsigned(date[0], endptr);
		// add optional leading zeros
		while (endptr > data) {
			*--endptr = '0';
		}
		// now write the month and day
		auto ptr = data + year_length;
		for (int i = 1; i <= 2; i++) {
			ptr[0] = '-';
			if (date[i] < 10) {
				ptr[1] = '0';
				ptr[2] = '0' + date[i];
			} else {
				auto index = static_cast<unsigned>(date[i] * 2);
				ptr[1] = fmt::internal::data::digits[index];
				ptr[2] = fmt::internal::data::digits[index + 1];
			}
			ptr += 3;
		}
		// optionally add BC to the end of the date
		if (add_bc) {
			memcpy(ptr, " (BC)", 5);
		}
	}
};

template <> string_t CastFromDate::Operation(date_t input, Vector &vector) {
	int32_t date[3];
	Date::Convert(input, date[0], date[1], date[2]);

	idx_t year_length;
	bool add_bc;
	idx_t length = DateToStringCast::Length(date, year_length, add_bc);

	string_t result = StringVector::EmptyString(vector, length);
	auto data = result.GetData();

	DateToStringCast::Format(data, date, year_length, add_bc);

	result.Finalize();
	return result;
}

//===--------------------------------------------------------------------===//
// Cast To Date
//===--------------------------------------------------------------------===//
template <> date_t CastToDate::Operation(string_t input) {
	return Date::FromCString(input.GetData());
}

//===--------------------------------------------------------------------===//
// Cast From Time
//===--------------------------------------------------------------------===//
struct TimeToStringCast {
	static idx_t Length(int32_t time[]) {
		// format is HH:MM:DD
		// regular length is 8
		idx_t length = 8;
		if (time[3] > 0) {
			// if there are msecs, we add the miliseconds after the time with a period separator
			// i.e. the format becomes HH:MM:DD.msec
			length += 4;
		}
		return length;
	}

	static void Format(char *data, idx_t length, int32_t time[]) {
		// first write hour, month and day
		auto ptr = data;
		for (int i = 0; i <= 2; i++) {
			if (time[i] < 10) {
				ptr[0] = '0';
				ptr[1] = '0' + time[i];
			} else {
				auto index = static_cast<unsigned>(time[i] * 2);
				ptr[0] = fmt::internal::data::digits[index];
				ptr[1] = fmt::internal::data::digits[index + 1];
			}
			ptr[2] = ':';
			ptr += 3;
		}
		// now optionally write ms at the end
		if (time[3] > 0) {
			auto start = ptr;
			ptr = StringToIntegerCast::FormatUnsigned(time[3], data + length);
			while (ptr > start) {
				*--ptr = '0';
			}
			*--ptr = '.';
		}
	}
};

template <> string_t CastFromTime::Operation(dtime_t input, Vector &vector) {
	int32_t time[4];
	Time::Convert(input, time[0], time[1], time[2], time[3]);

	idx_t length = TimeToStringCast::Length(time);

	string_t result = StringVector::EmptyString(vector, length);
	auto data = result.GetData();

	TimeToStringCast::Format(data, length, time);

	result.Finalize();
	return result;
}

//===--------------------------------------------------------------------===//
// Cast To Time
//===--------------------------------------------------------------------===//
template <> dtime_t CastToTime::Operation(string_t input) {
	return Time::FromCString(input.GetData());
}

template <> timestamp_t CastDateToTimestamp::Operation(date_t input) {
	return Timestamp::FromDatetime(input, Time::FromTime(0, 0, 0, 0));
}

//===--------------------------------------------------------------------===//
// Cast From Timestamps
//===--------------------------------------------------------------------===//
template <> string_t CastFromTimestamp::Operation(timestamp_t input, Vector &vector) {
	date_t date_entry;
	dtime_t time_entry;
	Timestamp::Convert(input, date_entry, time_entry);

	int32_t date[3], time[4];
	Date::Convert(date_entry, date[0], date[1], date[2]);
	Time::Convert(time_entry, time[0], time[1], time[2], time[3]);

	// format for timestamp is DATE TIME (separated by space)
	idx_t year_length;
	bool add_bc;
	idx_t date_length = DateToStringCast::Length(date, year_length, add_bc);
	idx_t time_length = TimeToStringCast::Length(time);
	idx_t length = date_length + time_length + 1;

	string_t result = StringVector::EmptyString(vector, length);
	auto data = result.GetData();

	DateToStringCast::Format(data, date, year_length, add_bc);
	data[date_length] = ' ';
	TimeToStringCast::Format(data + date_length + 1, time_length, time);

	result.Finalize();
	return result;
}

template <> date_t CastTimestampToDate::Operation(timestamp_t input) {
	return Timestamp::GetDate(input);
}

template <> dtime_t CastTimestampToTime::Operation(timestamp_t input) {
	return Timestamp::GetTime(input);
}

//===--------------------------------------------------------------------===//
// Cast To Timestamp
//===--------------------------------------------------------------------===//
template <> timestamp_t CastToTimestamp::Operation(string_t input) {
	return Timestamp::FromString(input.GetData());
}

} // namespace duckdb


#include <stdio.h>

using namespace duckdb;

void Printer::Print(string str) {
	fprintf(stderr, "%s\n", str.c_str());
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/serializer/buffered_deserializer.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class BufferedDeserializer : public Deserializer {
public:
	BufferedDeserializer(data_ptr_t ptr, idx_t data_size);
	BufferedDeserializer(BufferedSerializer &serializer);

	data_ptr_t ptr;
	data_ptr_t endptr;

public:
	void ReadData(data_ptr_t buffer, uint64_t read_size) override;
};

} // namespace duckdb


#include <cstring>

using namespace duckdb;
using namespace std;

BufferedDeserializer::BufferedDeserializer(data_ptr_t ptr, idx_t data_size) : ptr(ptr), endptr(ptr + data_size) {
}

BufferedDeserializer::BufferedDeserializer(BufferedSerializer &serializer)
    : BufferedDeserializer(serializer.data, serializer.maximum_size) {
}

void BufferedDeserializer::ReadData(data_ptr_t buffer, idx_t read_size) {
	if (ptr + read_size > endptr) {
		throw SerializationException("Failed to deserialize: not enough data in buffer to fulfill read request");
	}
	memcpy(buffer, ptr, read_size);
	ptr += read_size;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/serializer/buffered_file_reader.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BufferedFileReader : public Deserializer {
public:
	BufferedFileReader(FileSystem &fs, const char *path);

	FileSystem &fs;
	unique_ptr<data_t[]> data;
	idx_t offset;
	idx_t read_data;
	unique_ptr<FileHandle> handle;

public:
	void ReadData(data_ptr_t buffer, uint64_t read_size) override;
	//! Returns true if the reader has finished reading the entire file
	bool Finished();

	idx_t FileSize() {
		return file_size;
	}

private:
	idx_t file_size;
	idx_t total_read;
};

} // namespace duckdb




#include <cstring>

using namespace duckdb;
using namespace std;

BufferedFileReader::BufferedFileReader(FileSystem &fs, const char *path)
    : fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0), read_data(0), total_read(0) {
	handle = fs.OpenFile(path, FileFlags::READ, FileLockType::READ_LOCK);
	file_size = fs.GetFileSize(*handle);
}

void BufferedFileReader::ReadData(data_ptr_t target_buffer, uint64_t read_size) {
	// first copy anything we can from the buffer
	data_ptr_t end_ptr = target_buffer + read_size;
	while (true) {
		idx_t to_read = std::min((idx_t)(end_ptr - target_buffer), read_data - offset);
		if (to_read > 0) {
			memcpy(target_buffer, data.get() + offset, to_read);
			offset += to_read;
			target_buffer += to_read;
		}
		if (target_buffer < end_ptr) {
			assert(offset == read_data);
			total_read += read_data;
			// did not finish reading yet but exhausted buffer
			// read data into buffer
			offset = 0;
			read_data = fs.Read(*handle, data.get(), FILE_BUFFER_SIZE);
			if (read_data == 0) {
				throw SerializationException("not enough data in file to deserialize result");
			}
		} else {
			return;
		}
	}
}

bool BufferedFileReader::Finished() {
	return total_read + offset == file_size;
}



#include <cstring>

using namespace duckdb;
using namespace std;

BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const char *path, bool append)
    : fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0) {
	uint8_t flags = FileFlags::WRITE | FileFlags::CREATE;
	if (append) {
		flags |= FileFlags::APPEND;
	}
	handle = fs.OpenFile(path, flags, FileLockType::WRITE_LOCK);
}

int64_t BufferedFileWriter::GetFileSize() {
	return fs.GetFileSize(*handle);
}

void BufferedFileWriter::WriteData(const_data_ptr_t buffer, uint64_t write_size) {
	// first copy anything we can from the buffer
	const_data_ptr_t end_ptr = buffer + write_size;
	while (buffer < end_ptr) {
		idx_t to_write = std::min((idx_t)(end_ptr - buffer), FILE_BUFFER_SIZE - offset);
		assert(to_write > 0);
		memcpy(data.get() + offset, buffer, to_write);
		offset += to_write;
		buffer += to_write;
		if (offset == FILE_BUFFER_SIZE) {
			Flush();
		}
	}
}

void BufferedFileWriter::Flush() {
	if (offset == 0) {
		return;
	}
	fs.Write(*handle, data.get(), offset);
	offset = 0;
}

void BufferedFileWriter::Sync() {
	Flush();
	handle->Sync();
}

void BufferedFileWriter::Truncate(int64_t size) {
	// truncate the physical file on disk
	handle->Truncate(size);
	// reset anything written in the buffer
	offset = 0;
}


#include <cstring>

using namespace duckdb;
using namespace std;

BufferedSerializer::BufferedSerializer(idx_t maximum_size)
    : BufferedSerializer(unique_ptr<data_t[]>(new data_t[maximum_size]), maximum_size) {
}

BufferedSerializer::BufferedSerializer(unique_ptr<data_t[]> data, idx_t size) : maximum_size(size), data(data.get()) {
	blob.size = 0;
	blob.data = move(data);
}

void BufferedSerializer::WriteData(const_data_ptr_t buffer, idx_t write_size) {
	if (blob.size + write_size >= maximum_size) {
		do {
			maximum_size *= 2;
		} while (blob.size + write_size > maximum_size);
		auto new_data = new data_t[maximum_size];
		memcpy(new_data, data, blob.size);
		data = new_data;
		blob.data = unique_ptr<data_t[]>(new_data);
	}

	memcpy(blob.data.get() + blob.size, buffer, write_size);
	blob.size += write_size;
}


using namespace duckdb;
using namespace std;

template <> string Deserializer::Read() {
	uint32_t size = Read<uint32_t>();
	auto buffer = unique_ptr<data_t[]>(new data_t[size]);
	ReadData(buffer.get(), size);
	return string((char *)buffer.get(), size);
}


#include <algorithm>
#include <cctype>
#include <iomanip>
#include <memory>
#include <sstream>
#include <stdarg.h>
#include <string.h>
#include <string>

using namespace duckdb;
using namespace std;

bool StringUtil::Contains(const string &haystack, const string &needle) {
	return (haystack.find(needle) != string::npos);
}

void StringUtil::LTrim(string &str) {
	auto it = str.begin();
	while (isspace(*it)) {
		it++;
	}
	str.erase(str.begin(), it);
}

// Remove trailing ' ', '\f', '\n', '\r', '\t', '\v'
void StringUtil::RTrim(string &str) {
	str.erase(find_if(str.rbegin(), str.rend(), [](int ch) { return ch > 0 && !isspace(ch); }).base(), str.end());
}

void StringUtil::Trim(string &str) {
	StringUtil::LTrim(str);
	StringUtil::RTrim(str);
}

bool StringUtil::StartsWith(const string &str, const string &prefix) {
	if (prefix.size() > str.size()) {
		return false;
	}
	return equal(prefix.begin(), prefix.end(), str.begin());
}

bool StringUtil::EndsWith(const string &str, const string &suffix) {
	if (suffix.size() > str.size())
		return false;
	return equal(suffix.rbegin(), suffix.rend(), str.rbegin());
}

string StringUtil::Repeat(const string &str, idx_t n) {
	ostringstream os;
	if (n == 0 || str.empty()) {
		return (os.str());
	}
	for (int i = 0; i < static_cast<int>(n); i++) {
		os << str;
	}
	return (os.str());
}

vector<string> StringUtil::Split(const string &str, char delimiter) {
	stringstream ss(str);
	vector<string> lines;
	string temp;
	while (getline(ss, temp, delimiter)) {
		lines.push_back(temp);
	} // WHILE
	return (lines);
}

string StringUtil::Join(const vector<string> &input, const string &separator) {
	return StringUtil::Join(input, input.size(), separator, [](const string &s) { return s; });
}

string StringUtil::Prefix(const string &str, const string &prefix) {
	vector<string> lines = StringUtil::Split(str, '\n');
	if (lines.empty())
		return ("");

	ostringstream os;
	for (idx_t i = 0, cnt = lines.size(); i < cnt; i++) {
		if (i > 0)
			os << endl;
		os << prefix << lines[i];
	} // FOR
	return (os.str());
}

// http://ubuntuforums.org/showpost.php?p=10215516&postcount=5
string StringUtil::FormatSize(idx_t bytes) {
	double BASE = 1024;
	double KB = BASE;
	double MB = KB * BASE;
	double GB = MB * BASE;

	ostringstream os;

	if (bytes >= GB) {
		os << fixed << setprecision(2) << (bytes / GB) << " GB";
	} else if (bytes >= MB) {
		os << fixed << setprecision(2) << (bytes / MB) << " MB";
	} else if (bytes >= KB) {
		os << fixed << setprecision(2) << (bytes / KB) << " KB";
	} else {
		os << to_string(bytes) + " bytes";
	}
	return (os.str());
}

string StringUtil::Upper(const string &str) {
	string copy(str);
	transform(copy.begin(), copy.end(), copy.begin(), [](unsigned char c) { return toupper(c); });
	return (copy);
}

string StringUtil::Lower(const string &str) {
	string copy(str);
	transform(copy.begin(), copy.end(), copy.begin(), [](unsigned char c) { return tolower(c); });
	return (copy);
}

// http://stackoverflow.com/a/8098080
string StringUtil::Format(const string fmt_str, ...) {
	// Reserve two times as much as the length of the fmt_str
	int final_n, n = ((int)fmt_str.size()) * 2;
	string str;
	unique_ptr<char[]> formatted;
	va_list ap;

	while (1) {
		// Wrap the plain char array into the unique_ptr
		formatted.reset(new char[n + 1]);
		strcpy(&formatted[0], fmt_str.c_str());
		va_start(ap, fmt_str);
		final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap);
		va_end(ap);
		if (final_n < 0 || final_n >= n)
			n += abs(final_n - n + 1);
		else
			break;
	}
	return string(formatted.get());
}

string StringUtil::VFormat(const string fmt_str, va_list args) {
	va_list args_copy;

	unique_ptr<char[]> formatted;
	// make a copy of the args as we can only use it once
	va_copy(args_copy, args);

	// first get the amount of characters we need
	const auto n = vsnprintf(nullptr, 0, fmt_str.c_str(), args) + 1;

	// now allocate the string and do the actual printing
	formatted.reset(new char[n]);
	(void)vsnprintf(&formatted[0], n, fmt_str.c_str(), args_copy);
	return string(formatted.get());
}

vector<string> StringUtil::Split(const string &input, const string &split) {
	vector<string> splits;

	idx_t last = 0;
	idx_t input_len = input.size();
	idx_t split_len = split.size();
	while (last <= input_len) {
		idx_t next = input.find(split, last);
		if (next == string::npos) {
			next = input_len;
		}

		// Push the substring [last, next) on to splits
		string substr = input.substr(last, next - last);
		if (substr.empty() == false) {
			splits.push_back(substr);
		}
		last = next + split_len;
	}
	return splits;
}

string StringUtil::Replace(string source, const string &from, const string &to) {
	if (from.empty())
		return source;
	;
	idx_t start_pos = 0;
	while ((start_pos = source.find(from, start_pos)) != string::npos) {
		source.replace(start_pos, from.length(), to);
		start_pos += to.length(); // In case 'to' contains 'from', like
		                          // replacing 'x' with 'yx'
	}
	return source;
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/value_operations/value_operations.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct ValueOperations {
	//===--------------------------------------------------------------------===//
	// Numeric Operations
	//===--------------------------------------------------------------------===//
	// A + B
	static Value Add(const Value &left, const Value &right);
	// A - B
	static Value Subtract(const Value &left, const Value &right);
	// A * B
	static Value Multiply(const Value &left, const Value &right);
	// A / B
	static Value Divide(const Value &left, const Value &right);
	// A % B
	static Value Modulo(const Value &left, const Value &right);
	// // MIN(A, B)
	// static Value Min(const Value &left, const Value &right);
	// // MAX(A, B)
	// static Value Max(const Value &left, const Value &right);
	//===--------------------------------------------------------------------===//
	// Comparison Operations
	//===--------------------------------------------------------------------===//
	// A == B
	static bool Equals(const Value &left, const Value &right);
	// A != B
	static bool NotEquals(const Value &left, const Value &right);
	// A > B
	static bool GreaterThan(const Value &left, const Value &right);
	// A >= B
	static bool GreaterThanEquals(const Value &left, const Value &right);
	// A < B
	static bool LessThan(const Value &left, const Value &right);
	// A <= B
	static bool LessThanEquals(const Value &left, const Value &right);
	//===--------------------------------------------------------------------===//
	// Hash functions
	//===--------------------------------------------------------------------===//
	// result = HASH(A)
	static hash_t Hash(const Value &left);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/operator/comparison_operators.hpp
//
//
//===----------------------------------------------------------------------===//





#include <cstring>

namespace duckdb {

//===--------------------------------------------------------------------===//
// Comparison Operations
//===--------------------------------------------------------------------===//
struct Equals {
	template <class T> static inline bool Operation(T left, T right) {
		return left == right;
	}
};
struct NotEquals {
	template <class T> static inline bool Operation(T left, T right) {
		return left != right;
	}
};
struct GreaterThan {
	template <class T> static inline bool Operation(T left, T right) {
		return left > right;
	}
};
struct GreaterThanEquals {
	template <class T> static inline bool Operation(T left, T right) {
		return left >= right;
	}
};
struct LessThan {
	template <class T> static inline bool Operation(T left, T right) {
		return left < right;
	}
};
struct LessThanEquals {
	template <class T> static inline bool Operation(T left, T right) {
		return left <= right;
	}
};
//===--------------------------------------------------------------------===//
// Specialized Boolean Comparison Operators
//===--------------------------------------------------------------------===//
template <> inline bool GreaterThan::Operation(bool left, bool right) {
	return !right && left;
}
template <> inline bool LessThan::Operation(bool left, bool right) {
	return !left && right;
}
//===--------------------------------------------------------------------===//
// Specialized String Comparison Operations
//===--------------------------------------------------------------------===//
struct StringComparisonOperators {
	template <bool INVERSE> static inline bool EqualsOrNot(const string_t a, const string_t b) {
		if (memcmp(&a, &b, sizeof(uint32_t) + string_t::PREFIX_LENGTH) == 0) {
			// prefix and length are equal
			if (a.IsInlined()) {
				// small string: compare entire inlined string
				if (memcmp(a.prefix, b.prefix, a.length) == 0) {
					// entire string is equal
					return INVERSE ? false : true;
				}
			} else {
				// large string: check main data source
				if (memcmp(a.value_.data, b.value_.data, a.length) == 0) {
					// entire string is equal
					return INVERSE ? false : true;
				}
			}
		}
		// not equal
		return INVERSE ? true : false;
	}
};
template <> inline bool Equals::Operation(string_t left, string_t right) {
	return StringComparisonOperators::EqualsOrNot<false>(left, right);
}
template <> inline bool NotEquals::Operation(string_t left, string_t right) {
	return StringComparisonOperators::EqualsOrNot<true>(left, right);
}
template <> inline bool GreaterThan::Operation(string_t left, string_t right) {
	return strcmp(left.GetData(), right.GetData()) > 0;
}
template <> inline bool GreaterThanEquals::Operation(string_t left, string_t right) {
	return strcmp(left.GetData(), right.GetData()) >= 0;
}
template <> inline bool LessThan::Operation(string_t left, string_t right) {
	return strcmp(left.GetData(), right.GetData()) < 0;
}
template <> inline bool LessThanEquals::Operation(string_t left, string_t right) {
	return strcmp(left.GetData(), right.GetData()) <= 0;
}

} // namespace duckdb



#include <algorithm>
#include <cstring>

using namespace duckdb;
using namespace std;

void ChunkCollection::Verify() {
#ifdef DEBUG
	for (auto &chunk : chunks) {
		chunk->Verify();
	}
#endif
}

void ChunkCollection::Append(ChunkCollection &other) {
	for (auto &chunk : other.chunks) {
		Append(*chunk.get());
	}
}

void ChunkCollection::Append(DataChunk &new_chunk) {
	if (new_chunk.size() == 0) {
		return;
	}
	new_chunk.Verify();

	// we have to ensure that every chunk in the ChunkCollection is completely
	// filled, otherwise our O(1) lookup in GetValue and SetValue does not work
	// first fill the latest chunk, if it exists
	count += new_chunk.size();

	idx_t remaining_data = new_chunk.size();
	idx_t offset = 0;
	if (chunks.size() == 0) {
		// first chunk
		types = new_chunk.GetTypes();
	} else {
		// the types of the new chunk should match the types of the previous one
		assert(types.size() == new_chunk.column_count());
		auto new_types = new_chunk.GetTypes();
		for (idx_t i = 0; i < types.size(); i++) {
			if (new_types[i] != types[i]) {
				throw TypeMismatchException(new_types[i], types[i], "Type mismatch when combining rows");
			}
			if (types[i] == TypeId::LIST) {
				for (auto &chunk :
				     chunks) { // need to check all the chunks because they can have only-null list entries
					auto &chunk_vec = chunk->data[i];
					auto &new_vec = new_chunk.data[i];
					if (ListVector::HasEntry(chunk_vec) && ListVector::HasEntry(new_vec)) {
						auto &chunk_types = ListVector::GetEntry(chunk_vec).types;
						auto &new_types = ListVector::GetEntry(new_vec).types;
						if (chunk_types.size() > 0 && new_types.size() > 0 && chunk_types != new_types) {
							throw TypeMismatchException(chunk_types[0], new_types[i],
							                            "Type mismatch when combining lists");
						}
					}
				}
			}
			// TODO check structs, too
		}

		// first append data to the current chunk
		DataChunk &last_chunk = *chunks.back();
		idx_t added_data = std::min(remaining_data, (idx_t)(STANDARD_VECTOR_SIZE - last_chunk.size()));
		if (added_data > 0) {
			// copy <added_data> elements to the last chunk
			idx_t old_count = new_chunk.size();
			new_chunk.SetCardinality(added_data);

			last_chunk.Append(new_chunk);
			remaining_data -= added_data;
			// reset the chunk to the old data
			new_chunk.SetCardinality(old_count);
			offset = added_data;
		}
	}

	if (remaining_data > 0) {
		// create a new chunk and fill it with the remainder
		auto chunk = make_unique<DataChunk>();
		chunk->Initialize(types);
		new_chunk.Copy(*chunk, offset);
		chunks.push_back(move(chunk));
	}
}

// returns an int similar to a C comparator:
// -1 if left < right
// 0 if left == right
// 1 if left > right

template <class TYPE>
static int8_t templated_compare_value(Vector &left_vec, Vector &right_vec, idx_t left_idx, idx_t right_idx) {
	assert(left_vec.type == right_vec.type);
	auto left_val = FlatVector::GetData<TYPE>(left_vec)[left_idx];
	auto right_val = FlatVector::GetData<TYPE>(right_vec)[right_idx];
	if (Equals::Operation<TYPE>(left_val, right_val)) {
		return 0;
	}
	if (LessThan::Operation<TYPE>(left_val, right_val)) {
		return -1;
	}
	return 1;
}

// return type here is int32 because strcmp() on some platforms returns rather large values
static int32_t compare_value(Vector &left_vec, Vector &right_vec, idx_t vector_idx_left, idx_t vector_idx_right) {
	auto left_null = FlatVector::Nullmask(left_vec)[vector_idx_left];
	auto right_null = FlatVector::Nullmask(right_vec)[vector_idx_right];

	if (left_null && right_null) {
		return 0;
	} else if (right_null) {
		return 1;
	} else if (left_null) {
		return -1;
	}

	switch (left_vec.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return templated_compare_value<int8_t>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	case TypeId::INT16:
		return templated_compare_value<int16_t>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	case TypeId::INT32:
		return templated_compare_value<int32_t>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	case TypeId::INT64:
		return templated_compare_value<int64_t>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	case TypeId::FLOAT:
		return templated_compare_value<float>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	case TypeId::DOUBLE:
		return templated_compare_value<double>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	case TypeId::VARCHAR:
		return templated_compare_value<string_t>(left_vec, right_vec, vector_idx_left, vector_idx_right);
	default:
		throw NotImplementedException("Type for comparison");
	}
	return false;
}

static int compare_tuple(ChunkCollection *sort_by, vector<OrderType> &desc, idx_t left, idx_t right) {
	assert(sort_by);

	idx_t chunk_idx_left = left / STANDARD_VECTOR_SIZE;
	idx_t chunk_idx_right = right / STANDARD_VECTOR_SIZE;
	idx_t vector_idx_left = left % STANDARD_VECTOR_SIZE;
	idx_t vector_idx_right = right % STANDARD_VECTOR_SIZE;

	auto &left_chunk = sort_by->chunks[chunk_idx_left];
	auto &right_chunk = sort_by->chunks[chunk_idx_right];

	for (idx_t col_idx = 0; col_idx < desc.size(); col_idx++) {
		auto order_type = desc[col_idx];

		Vector &left_vec = left_chunk->data[col_idx];
		Vector &right_vec = right_chunk->data[col_idx];

		assert(left_vec.vector_type == VectorType::FLAT_VECTOR);
		assert(right_vec.vector_type == VectorType::FLAT_VECTOR);
		assert(left_vec.type == right_vec.type);

		auto comp_res = compare_value(left_vec, right_vec, vector_idx_left, vector_idx_right);

		if (comp_res == 0) {
			continue;
		}
		return comp_res < 0 ? (order_type == OrderType::ASCENDING ? -1 : 1)
		                    : (order_type == OrderType::ASCENDING ? 1 : -1);
	}
	return 0;
}

static int64_t _quicksort_initial(ChunkCollection *sort_by, vector<OrderType> &desc, idx_t *result) {
	// select pivot
	int64_t pivot = 0;
	int64_t low = 0, high = sort_by->count - 1;
	// now insert elements
	for (idx_t i = 1; i < sort_by->count; i++) {
		if (compare_tuple(sort_by, desc, i, pivot) <= 0) {
			result[low++] = i;
		} else {
			result[high--] = i;
		}
	}
	assert(low == high);
	result[low] = pivot;
	return low;
}

static void _quicksort_inplace(ChunkCollection *sort_by, vector<OrderType> &desc, idx_t *result, int64_t left,
                               int64_t right) {
	if (left >= right) {
		return;
	}

	int64_t middle = left + (right - left) / 2;
	int64_t pivot = result[middle];
	// move the mid point value to the front.
	int64_t i = left + 1;
	int64_t j = right;

	std::swap(result[middle], result[left]);
	while (i <= j) {
		while (i <= j && compare_tuple(sort_by, desc, result[i], pivot) <= 0) {
			i++;
		}

		while (i <= j && compare_tuple(sort_by, desc, result[j], pivot) > 0) {
			j--;
		}

		if (i < j) {
			std::swap(result[i], result[j]);
		}
	}
	std::swap(result[i - 1], result[left]);
	int64_t part = i - 1;

	_quicksort_inplace(sort_by, desc, result, left, part - 1);
	_quicksort_inplace(sort_by, desc, result, part + 1, right);
}

void ChunkCollection::Sort(vector<OrderType> &desc, idx_t result[]) {
	assert(result);
	if (count == 0)
		return;
	// quicksort
	int64_t part = _quicksort_initial(this, desc, result);
	_quicksort_inplace(this, desc, result, 0, part);
	_quicksort_inplace(this, desc, result, part + 1, count - 1);
}

// FIXME make this more efficient by not using the Value API
// just use memcpy in the vectors
// assert that there is no selection list
void ChunkCollection::Reorder(idx_t order_org[]) {
	auto order = unique_ptr<idx_t[]>(new idx_t[count]);
	memcpy(order.get(), order_org, sizeof(idx_t) * count);

	// adapted from https://stackoverflow.com/a/7366196/2652376

	auto val_buf = vector<Value>();
	val_buf.resize(column_count());

	idx_t j, k;
	for (idx_t i = 0; i < count; i++) {
		for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
			val_buf[col_idx] = GetValue(col_idx, i);
		}
		j = i;
		while (true) {
			k = order[j];
			order[j] = j;
			if (k == i) {
				break;
			}
			for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
				SetValue(col_idx, j, GetValue(col_idx, k));
			}
			j = k;
		}
		for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
			SetValue(col_idx, j, val_buf[col_idx]);
		}
	}
}

template <class TYPE>
static void templated_set_values(ChunkCollection *src_coll, Vector &tgt_vec, idx_t order[], idx_t col_idx,
                                 idx_t start_offset, idx_t remaining_data) {
	assert(src_coll);

	for (idx_t row_idx = 0; row_idx < remaining_data; row_idx++) {
		idx_t chunk_idx_src = order[start_offset + row_idx] / STANDARD_VECTOR_SIZE;
		idx_t vector_idx_src = order[start_offset + row_idx] % STANDARD_VECTOR_SIZE;

		auto &src_chunk = src_coll->chunks[chunk_idx_src];
		Vector &src_vec = src_chunk->data[col_idx];
		auto source_data = FlatVector::GetData<TYPE>(src_vec);
		auto target_data = FlatVector::GetData<TYPE>(tgt_vec);

		if (FlatVector::IsNull(src_vec, vector_idx_src)) {
			FlatVector::SetNull(tgt_vec, row_idx, true);
		} else {
			target_data[row_idx] = source_data[vector_idx_src];
		}
	}
}

// TODO: reorder functionality is similar, perhaps merge
void ChunkCollection::MaterializeSortedChunk(DataChunk &target, idx_t order[], idx_t start_offset) {
	idx_t remaining_data = min((idx_t)STANDARD_VECTOR_SIZE, count - start_offset);
	assert(target.GetTypes() == types);

	target.SetCardinality(remaining_data);
	for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
		switch (types[col_idx]) {
		case TypeId::BOOL:
		case TypeId::INT8:
			templated_set_values<int8_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::INT16:
			templated_set_values<int16_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::INT32:
			templated_set_values<int32_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::INT64:
			templated_set_values<int64_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::FLOAT:
			templated_set_values<float>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::DOUBLE:
			templated_set_values<double>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::VARCHAR:
			templated_set_values<string_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;

		case TypeId::LIST:
		case TypeId::STRUCT: {
			for (idx_t row_idx = 0; row_idx < remaining_data; row_idx++) {
				idx_t chunk_idx_src = order[start_offset + row_idx] / STANDARD_VECTOR_SIZE;
				idx_t vector_idx_src = order[start_offset + row_idx] % STANDARD_VECTOR_SIZE;

				auto &src_chunk = chunks[chunk_idx_src];
				Vector &src_vec = src_chunk->data[col_idx];
				auto &tgt_vec = target.data[col_idx];
				if (FlatVector::IsNull(src_vec, vector_idx_src)) {
					FlatVector::SetNull(tgt_vec, row_idx, true);
				} else {
					tgt_vec.SetValue(row_idx, src_vec.GetValue(vector_idx_src));
				}
			}
		} break;
		default:
			throw NotImplementedException("Type is unsupported in MaterializeSortedChunk()");
		}
	}
	target.Verify();
}

Value ChunkCollection::GetValue(idx_t column, idx_t index) {
	return chunks[LocateChunk(index)]->GetValue(column, index % STANDARD_VECTOR_SIZE);
}

vector<Value> ChunkCollection::GetRow(idx_t index) {
	vector<Value> values;
	values.resize(column_count());

	for (idx_t p_idx = 0; p_idx < column_count(); p_idx++) {
		values[p_idx] = GetValue(p_idx, index);
	}
	return values;
}

void ChunkCollection::SetValue(idx_t column, idx_t index, Value value) {
	chunks[LocateChunk(index)]->SetValue(column, index % STANDARD_VECTOR_SIZE, value);
}

void ChunkCollection::Print() {
	Printer::Print(ToString());
}

bool ChunkCollection::Equals(ChunkCollection &other) {
	if (count != other.count) {
		return false;
	}
	if (column_count() != other.column_count()) {
		return false;
	}
	if (types != other.types) {
		return false;
	}
	// if count is equal amount of chunks should be equal
	for (idx_t row_idx = 0; row_idx < count; row_idx++) {
		for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
			auto lvalue = GetValue(col_idx, row_idx);
			auto rvalue = other.GetValue(col_idx, row_idx);
			if (!Value::ValuesAreEqual(lvalue, rvalue)) {
				return false;
			}
		}
	}
	return true;
}
static void _heapify(ChunkCollection *input, vector<OrderType> &desc, idx_t *heap, idx_t heap_size,
                     idx_t current_index) {
	if (current_index >= heap_size) {
		return;
	}
	idx_t left_child_index = current_index * 2 + 1;
	idx_t right_child_index = current_index * 2 + 2;
	idx_t swap_index = current_index;

	if (left_child_index < heap_size) {
		swap_index =
		    compare_tuple(input, desc, heap[swap_index], heap[left_child_index]) <= 0 ? left_child_index : swap_index;
	}

	if (right_child_index < heap_size) {
		swap_index =
		    compare_tuple(input, desc, heap[swap_index], heap[right_child_index]) <= 0 ? right_child_index : swap_index;
	}

	if (swap_index != current_index) {
		std::swap(heap[current_index], heap[swap_index]);
		_heapify(input, desc, heap, heap_size, swap_index);
	}
}

static void _heap_create(ChunkCollection *input, vector<OrderType> &desc, idx_t *heap, idx_t heap_size) {
	for (idx_t i = 0; i < heap_size; i++) {
		heap[i] = i;
	}

	// build heap
	for (int64_t i = heap_size / 2 - 1; i >= 0; i--) {
		_heapify(input, desc, heap, heap_size, i);
	}

	// Run through all the rows.
	for (idx_t i = heap_size; i < input->count; i++) {
		if (compare_tuple(input, desc, i, heap[0]) <= 0) {
			heap[0] = i;
			_heapify(input, desc, heap, heap_size, 0);
		}
	}
}

void ChunkCollection::Heap(vector<OrderType> &desc, idx_t heap[], idx_t heap_size) {
	assert(heap);
	if (count == 0)
		return;

	_heap_create(this, desc, heap, heap_size);

	// Heap is ready. Now do a heapsort
	for (int64_t i = heap_size - 1; i >= 0; i--) {
		std::swap(heap[i], heap[0]);
		_heapify(this, desc, heap, i, 0);
	}
}

idx_t ChunkCollection::MaterializeHeapChunk(DataChunk &target, idx_t order[], idx_t start_offset, idx_t heap_size) {
	idx_t remaining_data = min((idx_t)STANDARD_VECTOR_SIZE, heap_size - start_offset);
	assert(target.GetTypes() == types);

	target.SetCardinality(remaining_data);
	for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
		switch (types[col_idx]) {
		case TypeId::BOOL:
		case TypeId::INT8:
			templated_set_values<int8_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::INT16:
			templated_set_values<int16_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::INT32:
			templated_set_values<int32_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::INT64:
			templated_set_values<int64_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::FLOAT:
			templated_set_values<float>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::DOUBLE:
			templated_set_values<double>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
		case TypeId::VARCHAR:
			templated_set_values<string_t>(this, target.data[col_idx], order, col_idx, start_offset, remaining_data);
			break;
			// TODO this is ugly and sloooow!
		case TypeId::STRUCT:
		case TypeId::LIST: {
			for (idx_t row_idx = 0; row_idx < remaining_data; row_idx++) {
				idx_t chunk_idx_src = order[start_offset + row_idx] / STANDARD_VECTOR_SIZE;
				idx_t vector_idx_src = order[start_offset + row_idx] % STANDARD_VECTOR_SIZE;

				auto &src_chunk = chunks[chunk_idx_src];
				Vector &src_vec = src_chunk->data[col_idx];
				auto &tgt_vec = target.data[col_idx];
				if (FlatVector::IsNull(src_vec, vector_idx_src)) {
					FlatVector::SetNull(tgt_vec, row_idx, true);
				} else {
					tgt_vec.SetValue(row_idx, src_vec.GetValue(vector_idx_src));
				}
			}
		} break;

		default:
			throw NotImplementedException("Type is unsupported in MaterializeHeapChunk()");
		}
	}
	target.Verify();
	return remaining_data;
}






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/types/null_value.hpp
//
//
//===----------------------------------------------------------------------===//






#include <cstring>

namespace duckdb {

//! This is no longer used in regular vectors, however, hash tables use this
//! value to store a NULL
template <class T> inline T NullValue() {
	return std::numeric_limits<T>::min();
}

constexpr const char str_nil[2] = {'\200', '\0'};

template <> inline const char *NullValue() {
	assert(str_nil[0] == '\200' && str_nil[1] == '\0');
	return str_nil;
}

template <> inline string_t NullValue() {
	return string_t(NullValue<const char *>());
}

template <> inline char *NullValue() {
	return (char *)NullValue<const char *>();
}

template <class T> inline bool IsNullValue(T value) {
	return value == NullValue<T>();
}

template <> inline bool IsNullValue(const char *value) {
	return *value == str_nil[0];
}

template <> inline bool IsNullValue(string_t value) {
	return value.GetData()[0] == str_nil[0];
}

template <> inline bool IsNullValue(char *value) {
	return IsNullValue<const char *>(value);
}

//! Compares a specific memory region against the types NULL value
bool IsNullValue(data_ptr_t ptr, TypeId type);

//! Writes NullValue<T> value of a specific type to a memory address
void SetNullValue(data_ptr_t ptr, TypeId type);

} // namespace duckdb




using namespace duckdb;
using namespace std;

DataChunk::DataChunk() : count(0) {
}

void DataChunk::InitializeEmpty(vector<TypeId> &types) {
	assert(types.size() > 0);
	for (idx_t i = 0; i < types.size(); i++) {
		data.emplace_back(Vector(types[i], nullptr));
	}
}

void DataChunk::Initialize(vector<TypeId> &types) {
	assert(types.size() > 0);
	InitializeEmpty(types);
	for (idx_t i = 0; i < types.size(); i++) {
		data[i].Initialize();
	}
}

void DataChunk::Reset() {
	for (idx_t i = 0; i < column_count(); i++) {
		data[i].Initialize();
	}
	SetCardinality(0);
}

void DataChunk::Destroy() {
	data.clear();
	SetCardinality(0);
}

Value DataChunk::GetValue(idx_t col_idx, idx_t index) const {
	assert(index < size());
	return data[col_idx].GetValue(index);
}

void DataChunk::SetValue(idx_t col_idx, idx_t index, Value val) {
	data[col_idx].SetValue(index, move(val));
}

void DataChunk::Reference(DataChunk &chunk) {
	assert(chunk.column_count() <= column_count());
	SetCardinality(chunk);
	for (idx_t i = 0; i < chunk.column_count(); i++) {
		data[i].Reference(chunk.data[i]);
	}
}

void DataChunk::Copy(DataChunk &other, idx_t offset) {
	assert(column_count() == other.column_count());
	assert(other.size() == 0);

	for (idx_t i = 0; i < column_count(); i++) {
		assert(other.data[i].vector_type == VectorType::FLAT_VECTOR);
		VectorOperations::Copy(data[i], other.data[i], size(), offset, 0);
	}
	other.SetCardinality(size() - offset);
}

void DataChunk::Append(DataChunk &other) {
	if (other.size() == 0) {
		return;
	}
	if (column_count() != other.column_count()) {
		throw OutOfRangeException("Column counts of appending chunk doesn't match!");
	}
	for (idx_t i = 0; i < column_count(); i++) {
		assert(data[i].vector_type == VectorType::FLAT_VECTOR);
		VectorOperations::Copy(other.data[i], data[i], other.size(), 0, size());
	}
	SetCardinality(size() + other.size());
}

void DataChunk::Normalify() {
	for (idx_t i = 0; i < column_count(); i++) {
		data[i].Normalify(size());
	}
}

vector<TypeId> DataChunk::GetTypes() {
	vector<TypeId> types;
	for (idx_t i = 0; i < column_count(); i++) {
		types.push_back(data[i].type);
	}
	return types;
}

string DataChunk::ToString() const {
	string retval = "Chunk - [" + to_string(column_count()) + " Columns]\n";
	for (idx_t i = 0; i < column_count(); i++) {
		retval += "- " + data[i].ToString(size()) + "\n";
	}
	return retval;
}

void DataChunk::Serialize(Serializer &serializer) {
	// write the count
	serializer.Write<sel_t>(size());
	serializer.Write<idx_t>(column_count());
	for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
		// write the types
		serializer.Write<int>((int)data[col_idx].type);
	}
	// write the data
	for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
		data[col_idx].Serialize(size(), serializer);
	}
}

void DataChunk::Deserialize(Deserializer &source) {
	auto rows = source.Read<sel_t>();
	idx_t column_count = source.Read<idx_t>();

	vector<TypeId> types;
	for (idx_t i = 0; i < column_count; i++) {
		types.push_back((TypeId)source.Read<int>());
	}
	Initialize(types);
	// now load the column data
	SetCardinality(rows);
	for (idx_t i = 0; i < column_count; i++) {
		data[i].Deserialize(rows, source);
	}
	Verify();
}

void DataChunk::Slice(const SelectionVector &sel_vector, idx_t count) {
	this->count = count;
	sel_cache_t merge_cache;
	for (idx_t c = 0; c < column_count(); c++) {
		data[c].Slice(sel_vector, count, merge_cache);
	}
}

void DataChunk::Slice(DataChunk &other, const SelectionVector &sel, idx_t count, idx_t col_offset) {
	assert(other.column_count() <= col_offset + column_count());
	this->count = count;
	sel_cache_t merge_cache;
	for (idx_t c = 0; c < other.column_count(); c++) {
		if (other.data[c].vector_type == VectorType::DICTIONARY_VECTOR) {
			// already a dictionary! merge the dictionaries
			data[col_offset + c].Reference(other.data[c]);
			data[col_offset + c].Slice(sel, count, merge_cache);
		} else {
			data[col_offset + c].Slice(other.data[c], sel, count);
		}
	}
}

unique_ptr<VectorData[]> DataChunk::Orrify() {
	auto orrified_data = unique_ptr<VectorData[]>(new VectorData[column_count()]);
	for (idx_t col_idx = 0; col_idx < column_count(); col_idx++) {
		data[col_idx].Orrify(size(), orrified_data[col_idx]);
	}
	return orrified_data;
}

void DataChunk::Hash(Vector &result) {
	assert(result.type == TypeId::HASH);
	VectorOperations::Hash(data[0], result, size());
	for (idx_t i = 1; i < column_count(); i++) {
		VectorOperations::CombineHash(result, data[i], size());
	}
}

void DataChunk::Verify() {
#ifdef DEBUG
	assert(size() <= STANDARD_VECTOR_SIZE);
	// verify that all vectors in this chunk have the chunk selection vector
	for (idx_t i = 0; i < column_count(); i++) {
		data[i].Verify(size());
	}
#endif
}

void DataChunk::Print() {
	Printer::Print(ToString());
}





#include <cctype>
#include <iomanip>
#include <iostream>
#include <sstream>

using namespace duckdb;
using namespace std;

// Taken from MonetDB mtime.c

static int NORMALDAYS[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int LEAPDAYS[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int CUMDAYS[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
static int CUMLEAPDAYS[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};

#define YEAR_MAX 5867411
#define YEAR_MIN (-YEAR_MAX)
#define MONTHDAYS(m, y) ((m) != 2 ? LEAPDAYS[m] : leapyear(y) ? 29 : 28)
#define YEARDAYS(y) (leapyear(y) ? 366 : 365)
#define DD_DATE(d, m, y)                                                                                               \
	((m) > 0 && (m) <= 12 && (d) > 0 && (y) != 0 && (y) >= YEAR_MIN && (y) <= YEAR_MAX && (d) <= MONTHDAYS(m, y))
#define LOWER(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))
// 1970-01-01 in date_t format
#define EPOCH_DATE 719528
// 1970-01-01 was a Thursday
#define EPOCH_DAY_OF_THE_WEEK 4
#define SECONDS_PER_DAY (60 * 60 * 24)

#define leapyear(y) ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))

static inline int leapyears(int year) {
	/* count the 4-fold years that passed since jan-1-0 */
	int y4 = year / 4;

	/* count the 100-fold years */
	int y100 = year / 100;

	/* count the 400-fold years */
	int y400 = year / 400;

	return y4 + y400 - y100 + (year >= 0); /* may be negative */
}

static inline void number_to_date(int32_t n, int32_t &year, int32_t &month, int32_t &day) {
	year = n / 365;
	day = (n - year * 365) - leapyears(year >= 0 ? year - 1 : year);
	if (n < 0) {
		year--;
		while (day >= 0) {
			year++;
			day -= YEARDAYS(year);
		}
		day = YEARDAYS(year) + day;
	} else {
		while (day < 0) {
			year--;
			day += YEARDAYS(year);
		}
	}

	day++;
	if (leapyear(year)) {
		for (month = day / 31 == 0 ? 1 : day / 31; month <= 12; month++)
			if (day > CUMLEAPDAYS[month - 1] && day <= CUMLEAPDAYS[month]) {
				break;
			}
		day -= CUMLEAPDAYS[month - 1];
	} else {
		for (month = day / 31 == 0 ? 1 : day / 31; month <= 12; month++)
			if (day > CUMDAYS[month - 1] && day <= CUMDAYS[month]) {
				break;
			}
		day -= CUMDAYS[month - 1];
	}
	year = (year <= 0) ? year - 1 : year;
}

static inline int32_t date_to_number(int32_t year, int32_t month, int32_t day) {
	int32_t n = 0;
	if (!(DD_DATE(day, month, year))) {
		throw ConversionException("Date out of range: %d-%d-%d", year, month, day);
	}

	if (year < 0)
		year++;
	n = (int32_t)(day - 1);
	if (month > 2 && leapyear(year)) {
		n++;
	}
	n += CUMDAYS[month - 1];
	/* current year does not count as leapyear */
	n += 365 * year + leapyears(year >= 0 ? year - 1 : year);

	return n;
}

static bool ParseDoubleDigit(const char *buf, idx_t &pos, int32_t &result) {
	if (std::isdigit(buf[pos])) {
		result = buf[pos++] - '0';
		if (std::isdigit(buf[pos])) {
			result = (buf[pos++] - '0') + result * 10;
		}
		return true;
	}
	return false;
}

static bool TryConvertDate(const char *buf, date_t &result) {
	int32_t day = 0, month = -1;
	int32_t year = 0, yearneg = (buf[0] == '-');
	idx_t pos = 0;
	int sep;

	if (yearneg == 0 && !std::isdigit(buf[0])) {
		return false;
	}

	// first parse the year
	for (pos = yearneg; std::isdigit(buf[pos]); pos++) {
		year = (buf[pos] - '0') + year * 10;
		if (year > YEAR_MAX) {
			break;
		}
	}

	// fetch the separator
	sep = buf[pos++];
	if (sep != ' ' && sep != '-' && sep != '/' && sep != '\\') {
		// invalid separator
		return false;
	}

	// parse the month
	if (!ParseDoubleDigit(buf, pos, month)) {
		return false;
	}

	if (buf[pos++] != sep) {
		return false;
	}

	// now parse the day
	if (!ParseDoubleDigit(buf, pos, day)) {
		return false;
	}

	if (std::isdigit(buf[pos])) {
		return false;
	}

	result = Date::FromDate(yearneg ? -year : year, month, day);
	return true;
}

date_t Date::FromCString(const char *buf) {
	date_t result;
	if (!TryConvertDate(buf, result)) {
		throw ConversionException("date/time field value out of range: \"%s\", "
		                          "expected format is (YYYY-MM-DD)",
		                          buf);
	}
	return result;
}

date_t Date::FromString(string str) {
	return Date::FromCString(str.c_str());
}

string Date::ToString(int32_t date) {
	int32_t year, month, day;
	number_to_date(date, year, month, day);
	if (year < 0) {
		return StringUtil::Format("%04d-%02d-%02d (BC)", -year, month, day);
	} else {
		return StringUtil::Format("%04d-%02d-%02d", year, month, day);
	}
}

string Date::Format(int32_t year, int32_t month, int32_t day) {
	return ToString(Date::FromDate(year, month, day));
}

void Date::Convert(int32_t date, int32_t &out_year, int32_t &out_month, int32_t &out_day) {
	number_to_date(date, out_year, out_month, out_day);
}

int32_t Date::FromDate(int32_t year, int32_t month, int32_t day) {
	return date_to_number(year, month, day);
}

bool Date::IsLeapYear(int32_t year) {
	return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

bool Date::IsValidDay(int32_t year, int32_t month, int32_t day) {
	if (month < 1 || month > 12)
		return false;
	if (day < 1)
		return false;
	if (year < YEAR_MIN || year > YEAR_MAX)
		return false;

	return IsLeapYear(year) ? day <= LEAPDAYS[month] : day <= NORMALDAYS[month];
}

date_t Date::EpochToDate(int64_t epoch) {
	assert((epoch / SECONDS_PER_DAY) + EPOCH_DATE <= numeric_limits<int32_t>::max());
	return (date_t)((epoch / SECONDS_PER_DAY) + EPOCH_DATE);
}

int64_t Date::Epoch(date_t date) {
	return ((int64_t)date - EPOCH_DATE) * SECONDS_PER_DAY;
}
int32_t Date::ExtractYear(date_t date) {
	int32_t out_year, out_month, out_day;
	Date::Convert(date, out_year, out_month, out_day);
	return out_year;
}

int32_t Date::ExtractMonth(date_t date) {
	int32_t out_year, out_month, out_day;
	Date::Convert(date, out_year, out_month, out_day);
	return out_month;
}

int32_t Date::ExtractDay(date_t date) {
	int32_t out_year, out_month, out_day;
	Date::Convert(date, out_year, out_month, out_day);
	return out_day;
}

int32_t Date::ExtractDayOfTheYear(date_t date) {
	int32_t out_year, out_month, out_day;
	Date::Convert(date, out_year, out_month, out_day);
	if (out_month >= 1) {
		out_day += Date::IsLeapYear(out_year) ? CUMLEAPDAYS[out_month - 1] : CUMDAYS[out_month - 1];
	}
	return out_day;
}

int32_t Date::ExtractISODayOfTheWeek(date_t date) {
	// -1 = 5
	// 0 = 6
	// 1 = 7
	// 2 = 1
	// 3 = 2
	// 4 = 3
	// 5 = 4
	// 6 = 5
	// 0 = 6
	// 1 = 7
	if (date < 2) {
		return ((date - 1) % 7) + 7;
	} else {
		return ((date - 2) % 7) + 1;
	}
}

static int32_t GetWeek(int32_t year, int32_t month, int32_t day) {
	auto day_of_the_year = (leapyear(year) ? CUMLEAPDAYS[month] : CUMDAYS[month]) + day;
	// get the first day of the first week of the year
	// the first week is the week that has the 4th of January in it
	auto day_of_the_fourth = Date::ExtractISODayOfTheWeek(Date::FromDate(year, 1, 4));
	// if fourth is monday, then fourth is the first day
	// if fourth is tuesday, third is the first day
	// if fourth is wednesday, second is the first day
	// if fourth is thursday - sunday, first is the first day
	auto first_day_of_the_first_week = day_of_the_fourth >= 4 ? 0 : 5 - day_of_the_fourth;
	if (day_of_the_year < first_day_of_the_first_week) {
		// day is part of last year
		return GetWeek(year - 1, 12, day);
	} else {
		return ((day_of_the_year - first_day_of_the_first_week) / 7) + 1;
	}
}

int32_t Date::ExtractWeekNumber(date_t date) {
	int32_t year, month, day;
	Date::Convert(date, year, month, day);
	return GetWeek(year, month - 1, day - 1);
}

// Returns the date of the monday of the current week.
date_t Date::GetMondayOfCurrentWeek(date_t date) {
	int32_t dotw = Date::ExtractISODayOfTheWeek(date);

	int32_t days = date_to_number(Date::ExtractYear(date), Date::ExtractMonth(date), Date::ExtractDay(date));

	days -= dotw - 1;

	int32_t year, month, day;
	number_to_date(days, year, month, day);

	return (Date::FromDate(year, month, day));
}





#include <functional>

using namespace std;

namespace duckdb {

template <> hash_t Hash(uint64_t val) {
	return murmurhash64(val);
}

template <> hash_t Hash(int64_t val) {
	return murmurhash64((uint64_t)val);
}

template <> hash_t Hash(float val) {
	return std::hash<float>{}(val);
}

template <> hash_t Hash(double val) {
	return std::hash<double>{}(val);
}

template <> hash_t Hash(const char *str) {
	hash_t hash = 5381;
	hash_t c;

	while ((c = *str++)) {
		hash = ((hash << 5) + hash) + c;
	}

	return hash;
}

template <> hash_t Hash(string_t val) {
	return Hash(val.GetData(), val.GetSize());
}

template <> hash_t Hash(char *val) {
	return Hash<const char *>(val);
}

hash_t Hash(const char *val, size_t size) {
	hash_t hash = 5381;

	for (size_t i = 0; i < size; i++) {
		hash = ((hash << 5) + hash) + val[i];
	}

	return hash;
}

hash_t Hash(char *val, size_t size) {
	return Hash((const char *)val, size);
}

hash_t Hash(uint8_t *val, size_t size) {
	return Hash((const char *)val, size);
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/types/hyperloglog.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The HyperLogLog class holds a HyperLogLog counter for approximate cardinality counting
class HyperLogLog {
public:
	HyperLogLog();
	~HyperLogLog();
	// implicit copying of HyperLogLog is not allowed
	HyperLogLog(const HyperLogLog &) = delete;

	//! Adds an element of the specified size to the HyperLogLog counter
	void Add(data_ptr_t element, idx_t size);
	//! Return the count of this HyperLogLog counter
	idx_t Count();
	//! Merge this HyperLogLog counter with another counter to create a new one
	unique_ptr<HyperLogLog> Merge(HyperLogLog &other);
	//! Merge a set of HyperLogLogs to create one big one
	static unique_ptr<HyperLogLog> Merge(HyperLogLog logs[], idx_t count);

private:
	HyperLogLog(void *hll);

	void *hll;
};
} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// third_party/hyperloglog/hyperloglog.h
//
//
//===----------------------------------------------------------------------===//



#ifdef __cplusplus
extern "C" {
#endif

#include <string.h>

/* Error codes */
#define C_OK                    0
#define C_ERR                   -1

typedef struct {
    void *ptr;
} robj;

//! Create a new empty HyperLogLog object
robj *hll_create(void);
//! Destroy the specified HyperLogLog object
void hll_destroy(robj *obj);
//! Add an element with the specified amount of bytes to the HyperLogLog. Returns C_ERR on failure, otherwise returns 0 if the cardinality did not change, and 1 otherwise.
int hll_add(robj *o, unsigned char *ele, size_t elesize);
//! Returns the estimated amount of unique elements seen by the HyperLogLog. Returns C_OK on success, or C_ERR on failure.
int hll_count(robj *o, size_t *result);
//! Merge hll_count HyperLogLog objects into a single one. Returns NULL on failure, or the new HLL object on success.
robj *hll_merge(robj **hlls, size_t hll_count);

#ifdef __cplusplus
}
#endif


using namespace duckdb;
using namespace std;

HyperLogLog::HyperLogLog() : hll(nullptr) {
	hll = hll_create();
}

HyperLogLog::HyperLogLog(void *hll) : hll(hll) {
}

HyperLogLog::~HyperLogLog() {
	hll_destroy((robj *)hll);
}

void HyperLogLog::Add(data_ptr_t element, idx_t size) {
	if (hll_add((robj *)hll, element, size) == C_ERR) {
		throw Exception("Could not add to HLL?");
	}
}

idx_t HyperLogLog::Count() {
	size_t result; // exception from size_t ban
	if (hll_count((robj *)hll, &result) != C_OK) {
		throw Exception("Could not count HLL?");
	}
	return result;
}

unique_ptr<HyperLogLog> HyperLogLog::Merge(HyperLogLog &other) {
	robj *hlls[2];
	hlls[0] = (robj *)hll;
	hlls[1] = (robj *)other.hll;
	auto new_hll = hll_merge(hlls, 2);
	if (!new_hll) {
		throw Exception("Could not merge HLLs");
	}
	return unique_ptr<HyperLogLog>(new HyperLogLog((void *)new_hll));
}

unique_ptr<HyperLogLog> HyperLogLog::Merge(HyperLogLog logs[], idx_t count) {
	auto hlls_uptr = unique_ptr<robj *[]> { new robj *[count] };
	auto hlls = hlls_uptr.get();
	for (idx_t i = 0; i < count; i++) {
		hlls[i] = (robj *)logs[i].hll;
	}
	auto new_hll = hll_merge(hlls, count);
	if (!new_hll) {
		throw Exception("Could not merge HLLs");
	}
	return unique_ptr<HyperLogLog>(new HyperLogLog((void *)new_hll));
}





#include <cstring>

using namespace std;

namespace duckdb {

bool IsNullValue(data_ptr_t ptr, TypeId type) {
	data_t data[100];
	SetNullValue(data, type);
	return memcmp(ptr, data, GetTypeIdSize(type)) == 0;
}

//! Writes NullValue<T> value of a specific type to a memory address
void SetNullValue(data_ptr_t ptr, TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		*((int8_t *)ptr) = NullValue<int8_t>();
		break;
	case TypeId::INT16:
		*((int16_t *)ptr) = NullValue<int16_t>();
		break;
	case TypeId::INT32:
		*((int32_t *)ptr) = NullValue<int32_t>();
		break;
	case TypeId::INT64:
		*((int64_t *)ptr) = NullValue<int64_t>();
		break;
	case TypeId::FLOAT:
		*((float *)ptr) = NullValue<float>();
		break;
	case TypeId::DOUBLE:
		*((double *)ptr) = NullValue<double>();
		break;
	case TypeId::VARCHAR:
		*((string_t *)ptr) = string_t(NullValue<const char *>());
		break;
	default:
		throw InvalidTypeException(type, "Unsupported type for SetNullValue!");
	}
}

} // namespace duckdb



namespace duckdb {

string SelectionVector::ToString(idx_t count) const {
	string result = "Selection Vector (" + std::to_string(count) + ") [";
	for (idx_t i = 0; i < count; i++) {
		if (i != 0) {
			result += ", ";
		}
		result += std::to_string(get_index(i));
	}
	result += "]";
	return result;
}

void SelectionVector::Print(idx_t count) const {
	Printer::Print(ToString(count));
}

buffer_ptr<SelectionData> SelectionVector::Slice(const SelectionVector &sel, idx_t count) {
	auto data = make_buffer<SelectionData>(count);
	auto result_ptr = data->owned_data.get();
	// for every element, we perform result[i] = target[new[i]]
	for (idx_t i = 0; i < count; i++) {
		auto new_idx = sel.get_index(i);
		auto idx = this->get_index(new_idx);
		result_ptr[i] = idx;
	}
	return data;
}

} // namespace duckdb






#include <string>
#include <cassert>
#include <cstring>

namespace duckdb {

enum class UnicodeType {INVALID, ASCII, UNICODE};


class Utf8Proc {
public:

	static UnicodeType Analyze(const char* s) {
		return Analyze(s, std::strlen(s));
	}

	static UnicodeType Analyze(std::string s) {
		return Analyze(s.c_str(), s.size());
	}

	static UnicodeType Analyze(const char *s, size_t len);


	static std::string Normalize(std::string s);

	static char* Normalize(const char* s);

};
}


#include <cstring>

using namespace duckdb;
using namespace std;

#define MINIMUM_HEAP_SIZE 4096

StringHeap::StringHeap() : tail(nullptr) {
}

string_t StringHeap::AddString(const char *data, idx_t len) {
	assert(Utf8Proc::Analyze(data, len) != UnicodeType::INVALID);

	auto insert_string = EmptyString(len);
	auto insert_pos = insert_string.GetData();
	memcpy(insert_pos, data, len);
	insert_string.Finalize();
	return insert_string;
}

string_t StringHeap::AddString(const char *data) {
	return AddString(data, strlen(data));
}

string_t StringHeap::AddString(const string &data) {
	return AddString(data.c_str(), data.size());
}

string_t StringHeap::AddString(const string_t &data) {
	return AddString(data.GetData(), data.GetSize());
}

string_t StringHeap::EmptyString(idx_t len) {
	assert(len >= string_t::INLINE_LENGTH);
	if (!chunk || chunk->current_position + len >= chunk->maximum_size) {
		// have to make a new entry
		auto new_chunk = make_unique<StringChunk>(std::max(len + 1, (idx_t)MINIMUM_HEAP_SIZE));
		new_chunk->prev = move(chunk);
		chunk = move(new_chunk);
		if (!tail) {
			tail = chunk.get();
		}
	}
	auto insert_pos = chunk->data.get() + chunk->current_position;
	chunk->current_position += len + 1;
	return string_t(insert_pos, len);
}

void StringHeap::MergeHeap(StringHeap &other) {
	if (!other.tail) {
		return;
	}
	other.tail->prev = move(chunk);
	this->chunk = move(other.chunk);
	if (!tail) {
		tail = this->chunk.get();
	}
	other.tail = nullptr;
}




namespace duckdb {

void string_t::Verify() {
	auto dataptr = GetData();
	(void)dataptr;
	assert(dataptr);

#ifdef DEBUG
	auto utf_type = Utf8Proc::Analyze(dataptr, length);
	assert(utf_type != UnicodeType::INVALID);
	if (utf_type == UnicodeType::UNICODE) {
		// check that the data is a valid NFC UTF8 string
		auto normalized = Utf8Proc::Normalize(dataptr);
		assert(strcmp(dataptr, normalized) == 0);
		free(normalized);
	}
#endif

	// verify that the string is null-terminated and that the length is correct
	assert(strlen(dataptr) == length);
	// verify that the prefix contains the first four characters of the string
	for (idx_t i = 0; i < std::min((uint32_t)PREFIX_LENGTH, length); i++) {
		assert(prefix[i] == dataptr[i]);
	}
	// verify that for strings with length < PREFIX_LENGTH, the rest of the prefix is zero
	for (idx_t i = length; i < PREFIX_LENGTH; i++) {
		assert(prefix[i] == '\0');
	}
}

} // namespace duckdb






#include <iomanip>
#include <cstring>
#include <iostream>
#include <sstream>
#include <cctype>

using namespace duckdb;
using namespace std;

// string format is hh:mm:ssZ
// Z is optional
// ISO 8601

// Taken from MonetDB mtime.c
#define DD_TIME(h, m, s, x)                                                                                            \
	((h) >= 0 && (h) < 24 && (m) >= 0 && (m) < 60 && (s) >= 0 && (s) <= 60 && (x) >= 0 && (x) < 1000)

static dtime_t time_to_number(int hour, int min, int sec, int msec) {
	if (!DD_TIME(hour, min, sec, msec)) {
		throw Exception("Invalid time");
	}
	return (dtime_t)(((((hour * 60) + min) * 60) + sec) * 1000 + msec);
}

static void number_to_time(dtime_t n, int32_t &hour, int32_t &min, int32_t &sec, int32_t &msec) {
	int h, m, s, ms;

	h = n / 3600000;
	n -= h * 3600000;
	m = n / 60000;
	n -= m * 60000;
	s = n / 1000;
	n -= s * 1000;
	ms = n;

	hour = h;
	min = m;
	sec = s;
	msec = ms;
}

// TODO this is duplicated in date.cpp
static bool ParseDoubleDigit2(const char *buf, idx_t &pos, int32_t &result) {
	if (std::isdigit(buf[pos])) {
		result = buf[pos++] - '0';
		if (std::isdigit(buf[pos])) {
			result = (buf[pos++] - '0') + result * 10;
		}
		return true;
	}
	return false;
}

static bool TryConvertTime(const char *buf, dtime_t &result) {
	int32_t hour = -1, min = -1, sec = -1, msec = -1;
	idx_t pos = 0;
	int sep;

	// skip leading spaces
	while (std::isspace(buf[pos])) {
		pos++;
	}

	if (!std::isdigit(buf[pos])) {
		return false;
	}

	if (!ParseDoubleDigit2(buf, pos, hour)) {
		return false;
	}
	if (hour < 0 || hour > 24) {
		return false;
	}

	// fetch the separator
	sep = buf[pos++];
	if (sep != ':') {
		// invalid separator
		return false;
	}

	if (!ParseDoubleDigit2(buf, pos, min)) {
		return false;
	}
	if (min < 0 || min > 60) {
		return false;
	}

	if (buf[pos++] != sep) {
		return false;
	}

	if (!ParseDoubleDigit2(buf, pos, sec)) {
		return false;
	}
	if (sec < 0 || sec > 60) {
		return false;
	}

	msec = 0;
	sep = buf[pos++];
	if (sep == '.') { // we expect some milliseconds
		uint8_t mult = 100;
		for (; std::isdigit(buf[pos]) && mult > 0; pos++, mult /= 10) {
			msec += (buf[pos] - '0') * mult;
		}
	}

	result = Time::FromTime(hour, min, sec, msec);
	return true;
}

dtime_t Time::FromCString(const char *buf) {
	dtime_t result;
	if (!TryConvertTime(buf, result)) {
		// last chance, check if we can parse as timestamp
		if (strlen(buf) > 10) {
			return Timestamp::GetTime(Timestamp::FromString(buf));
		}
		throw ConversionException("time field value out of range: \"%s\", "
		                          "expected format is ([YYY-MM-DD ]HH:MM:SS[.MS])",
		                          buf);
	}
	return result;
}

dtime_t Time::FromString(string str) {
	return Time::FromCString(str.c_str());
}

string Time::ToString(dtime_t time) {
	int32_t hour, min, sec, msec;
	number_to_time(time, hour, min, sec, msec);

	if (msec > 0) {
		return StringUtil::Format("%02d:%02d:%02d.%03d", hour, min, sec, msec);
	} else {
		return StringUtil::Format("%02d:%02d:%02d", hour, min, sec);
	}
}

string Time::Format(int32_t hour, int32_t minute, int32_t second, int32_t milisecond) {
	return ToString(Time::FromTime(hour, minute, second, milisecond));
}

dtime_t Time::FromTime(int32_t hour, int32_t minute, int32_t second, int32_t milisecond) {
	return time_to_number(hour, minute, second, milisecond);
}

bool Time::IsValidTime(int32_t hour, int32_t minute, int32_t second, int32_t milisecond) {
	return DD_TIME(hour, minute, second, milisecond);
}

void Time::Convert(dtime_t time, int32_t &out_hour, int32_t &out_min, int32_t &out_sec, int32_t &out_msec) {
	number_to_time(time, out_hour, out_min, out_sec, out_msec);
}






#include <iomanip>
#include <iostream>
#include <sstream>

using namespace duckdb;
using namespace std;

constexpr const int32_t MONTHS_PER_YEAR = 12;
constexpr const int32_t HOURS_PER_DAY = 24; //! assume no daylight savings time changes
constexpr const int32_t STD_TIMESTAMP_LENGTH = 19;
constexpr const int32_t START_YEAR = 1900;

constexpr const int32_t SECS_PER_MINUTE = 60;
constexpr const int32_t MINS_PER_HOUR = 60;
constexpr const int64_t MSECS_PER_HOUR = 360000;
constexpr const int64_t MSECS_PER_MINUTE = 60000;
constexpr const int64_t MSECS_PER_SEC = 1000;

// Used to check amount of days per month in common year and leap year
constexpr int days_per_month[2][13] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
                                       {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}};
constexpr bool isleap(int16_t year) {
	return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0));
}

// timestamp/datetime uses 64 bits, high 32 bits for date and low 32 bits for time
// string format is YYYY-MM-DDThh:mm:ssZ
// T may be a space
// Z is optional
// ISO 8601

timestamp_t Timestamp::FromString(string str) {
	assert(sizeof(timestamp_t) == 8);
	assert(sizeof(date_t) == 4);
	assert(sizeof(dtime_t) == 4);

	// In case we have only date we add a default time
	if (str.size() == 10) {
		str += " 00:00:00";
	}
	// Character length	19 positions minimum to 23 maximum
	if (str.size() < STD_TIMESTAMP_LENGTH) {
		throw ConversionException("timestamp field value out of range: \"%s\", "
		                          "expected format is (YYYY-MM-DD HH:MM:SS[.MS])",
		                          str.c_str());
	}

	date_t date = Date::FromString(str.substr(0, 10));
	dtime_t time = Time::FromString(str.substr(10));

	return ((int64_t)date << 32 | (int32_t)time);
}

string Timestamp::ToString(timestamp_t timestamp) {
	assert(sizeof(timestamp_t) == 8);
	assert(sizeof(date_t) == 4);
	assert(sizeof(dtime_t) == 4);

	return Date::ToString(GetDate(timestamp)) + " " + Time::ToString(GetTime(timestamp));
}

date_t Timestamp::GetDate(timestamp_t timestamp) {
	return (date_t)(((int64_t)timestamp) >> 32);
}

dtime_t Timestamp::GetTime(timestamp_t timestamp) {
	return (dtime_t)(timestamp & 0xFFFFFFFF);
}

timestamp_t Timestamp::FromDatetime(date_t date, dtime_t time) {
	return ((int64_t)date << 32 | (int64_t)time);
}

void Timestamp::Convert(timestamp_t date, date_t &out_date, dtime_t &out_time) {
	out_date = GetDate(date);
	out_time = GetTime(date);
}

timestamp_t Timestamp::GetCurrentTimestamp() {
	auto in_time_t = std::time(nullptr);
	auto utc = std::gmtime(&in_time_t);

	// tm_year[0...] considers the amount of years since 1900 and tm_mon considers the amount of months since january
	// tm_mon[0-11]
	auto date = Date::FromDate(utc->tm_year + START_YEAR, utc->tm_mon + 1, utc->tm_mday);
	auto time = Time::FromTime(utc->tm_hour, utc->tm_min, utc->tm_sec);

	return Timestamp::FromDatetime(date, time);
}

Interval Timestamp::GetDifference(timestamp_t timestamp_1, timestamp_t timestamp_2) {
	// First extract the dates
	auto date1 = GetDate(timestamp_1);
	auto date2 = GetDate(timestamp_2);
	// and from date extract the years, months and days
	int32_t year1, month1, day1;
	int32_t year2, month2, day2;
	Date::Convert(date1, year1, month1, day1);
	Date::Convert(date2, year2, month2, day2);
	// finally perform the differences
	auto year_diff = year1 - year2;
	auto month_diff = month1 - month2;
	auto day_diff = day1 - day2;

	// Now we extract the time
	auto time1 = GetTime(timestamp_1);
	auto time2 = GetTime(timestamp_2);

	// In case time is not specified we do not show it in the output
	if (time1 == 0) {
		time2 = time1;
	}

	// and from time extract hours, minutes, seconds and miliseconds
	int32_t hour1, min1, sec1, msec1;
	int32_t hour2, min2, sec2, msec2;
	Time::Convert(time1, hour1, min1, sec1, msec1);
	Time::Convert(time2, hour2, min2, sec2, msec2);
	// finally perform the differences
	auto hour_diff = hour1 - hour2;
	auto min_diff = min1 - min2;
	auto sec_diff = sec1 - sec2;
	auto msec_diff = msec1 - msec2;

	// flip sign if necessary
	if (timestamp_1 < timestamp_2) {
		year_diff = -year_diff;
		month_diff = -month_diff;
		day_diff = -day_diff;
		hour_diff = -hour_diff;
		min_diff = -min_diff;
		sec_diff = -sec_diff;
		msec_diff = -msec_diff;
	}
	// now propagate any negative field into the next higher field
	while (msec_diff < 0) {
		msec_diff += MSECS_PER_SEC;
		sec_diff--;
	}
	while (sec_diff < 0) {
		sec_diff += SECS_PER_MINUTE;
		min_diff--;
	}
	while (min_diff < 0) {
		min_diff += MINS_PER_HOUR;
		hour_diff--;
	}
	while (hour_diff < 0) {
		hour_diff += HOURS_PER_DAY;
		day_diff--;
	}
	while (day_diff < 0) {
		if (timestamp_1 < timestamp_2) {
			day_diff += days_per_month[isleap(year1)][month1 - 1];
			month_diff--;
		} else {
			day_diff += days_per_month[isleap(year2)][month2 - 1];
			month_diff--;
		}
	}
	while (month_diff < 0) {
		month_diff += MONTHS_PER_YEAR;
		year_diff--;
	}

	// recover sign if necessary
	if (timestamp_1 < timestamp_2 && (month_diff != 0 || day_diff != 0)) {
		year_diff = -year_diff;
		month_diff = -month_diff;
		day_diff = -day_diff;
		hour_diff = -hour_diff;
		min_diff = -min_diff;
		sec_diff = -sec_diff;
		msec_diff = -msec_diff;
	}
	Interval interval;
	interval.months = year_diff * MONTHS_PER_YEAR + month_diff;
	interval.days = day_diff;
	interval.time =
	    ((((((hour_diff * MINS_PER_HOUR) + min_diff) * SECS_PER_MINUTE) + sec_diff) * MSECS_PER_SEC) + msec_diff);

	return interval;
}

timestamp_struct Timestamp::IntervalToTimestamp(Interval &interval) {
	timestamp_struct timestamp;

	if (interval.months != 0) {
		timestamp.year = interval.months / MONTHS_PER_YEAR;
		timestamp.month = interval.months % MONTHS_PER_YEAR;

	} else {
		timestamp.year = 0;
		timestamp.month = 0;
	}
	timestamp.day = interval.days;
	auto time = interval.time;

	timestamp.hour = time / MSECS_PER_HOUR;
	time -= timestamp.hour * MSECS_PER_HOUR;
	timestamp.min = time / MSECS_PER_MINUTE;
	time -= timestamp.min * MSECS_PER_MINUTE;
	timestamp.sec = time / MSECS_PER_SEC;
	timestamp.msec = time - (timestamp.sec * MSECS_PER_SEC);
	return timestamp;
}

Interval TimestampToInterval(timestamp_struct *timestamp) {
	Interval interval;

	interval.months = timestamp->year * MONTHS_PER_YEAR + timestamp->month;
	interval.days = timestamp->day;
	interval.time =
	    ((((((timestamp->hour * MINS_PER_HOUR) + timestamp->min) * SECS_PER_MINUTE) + timestamp->sec) * MSECS_PER_SEC) +
	     timestamp->msec);

	return interval;
}

int64_t Timestamp::GetEpoch(timestamp_t timestamp) {
	return Date::Epoch(Timestamp::GetDate(timestamp)) + (int64_t)(Timestamp::GetTime(timestamp) / 1000);
}

int64_t Timestamp::GetMilliseconds(timestamp_t timestamp) {
	int n = Timestamp::GetTime(timestamp);
	int m = n / 60000;
	return n - m * 60000;
}

int64_t Timestamp::GetSeconds(timestamp_t timestamp) {
	int n = Timestamp::GetTime(timestamp);
	int m = n / 60000;
	return (n - m * 60000) / 1000;
}

int64_t Timestamp::GetMinutes(timestamp_t timestamp) {
	int n = Timestamp::GetTime(timestamp);
	int h = n / 3600000;
	return (n - h * 3600000) / 60000;
}

int64_t Timestamp::GetHours(timestamp_t timestamp) {
	return Timestamp::GetTime(timestamp) / 3600000;
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/operator/aggregate_operators.hpp
//
//
//===----------------------------------------------------------------------===//



#include <algorithm>
#include <cstdint>
#include <cstring>


namespace duckdb {

struct Min {
	template <class T> static inline T Operation(T left, T right) {
		return LessThan::Operation(left, right) ? left : right;
	}
};

struct Max {
	template <class T> static inline T Operation(T left, T right) {
		return GreaterThan::Operation(left, right) ? left : right;
	}
};

} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/operator/numeric_binary_operators.hpp
//
//
//===----------------------------------------------------------------------===//




#include <cmath>

namespace duckdb {

struct AddOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left + right;
	}
};

struct SubtractOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left - right;
	}
};

struct NegateOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return -input;
	}
};

struct MultiplyOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left * right;
	}
};

struct DivideOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		assert(right != 0); // this should be checked before!
		return left / right;
	}
};

struct ModuloOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		assert(right != 0);
		return left % right;
	}
};

template <> float ModuloOperator::Operation(float left, float right);
template <> double ModuloOperator::Operation(double left, double right);

} // namespace duckdb












using namespace duckdb;
using namespace std;

Value::Value(string_t val) : Value(string(val.GetData(), val.GetSize())) {
}

Value::Value(string val) : type(TypeId::VARCHAR), is_null(false) {
	auto utf_type = Utf8Proc::Analyze(val);
	switch (utf_type) {
	case UnicodeType::INVALID:
		throw Exception("String value is not valid UTF8");
	case UnicodeType::ASCII:
		str_value = val;
		break;
	case UnicodeType::UNICODE:
		str_value = Utf8Proc::Normalize(val);
		break;
	}
}

Value Value::MinimumValue(TypeId type) {
	Value result;
	result.type = type;
	result.is_null = false;
	switch (type) {
	case TypeId::BOOL:
		result.value_.boolean = false;
		break;
	case TypeId::INT8:
		result.value_.tinyint = std::numeric_limits<int8_t>::min();
		break;
	case TypeId::INT16:
		result.value_.smallint = std::numeric_limits<int16_t>::min();
		break;
	case TypeId::INT32:
		result.value_.integer = std::numeric_limits<int32_t>::min();
		break;
	case TypeId::INT64:
		result.value_.bigint = std::numeric_limits<int64_t>::min();
		break;
	case TypeId::FLOAT:
		result.value_.float_ = std::numeric_limits<float>::min();
		break;
	case TypeId::DOUBLE:
		result.value_.double_ = std::numeric_limits<double>::min();
		break;
	case TypeId::POINTER:
		result.value_.pointer = std::numeric_limits<uintptr_t>::min();
		break;
	default:
		throw InvalidTypeException(type, "MinimumValue requires numeric type");
	}
	return result;
}

Value Value::MaximumValue(TypeId type) {
	Value result;
	result.type = type;
	result.is_null = false;
	switch (type) {
	case TypeId::BOOL:
		result.value_.boolean = true;
		break;
	case TypeId::INT8:
		result.value_.tinyint = std::numeric_limits<int8_t>::max();
		break;
	case TypeId::INT16:
		result.value_.smallint = std::numeric_limits<int16_t>::max();
		break;
	case TypeId::INT32:
		result.value_.integer = std::numeric_limits<int32_t>::max();
		break;
	case TypeId::INT64:
		result.value_.bigint = std::numeric_limits<int64_t>::max();
		break;
	case TypeId::FLOAT:
		result.value_.float_ = std::numeric_limits<float>::max();
		break;
	case TypeId::DOUBLE:
		result.value_.double_ = std::numeric_limits<double>::max();
		break;
	case TypeId::POINTER:
		result.value_.pointer = std::numeric_limits<uintptr_t>::max();
		break;
	default:
		throw InvalidTypeException(type, "MaximumValue requires numeric type");
	}
	return result;
}

Value Value::BOOLEAN(int8_t value) {
	Value result(TypeId::BOOL);
	result.value_.boolean = value ? true : false;
	result.is_null = false;
	return result;
}

Value Value::TINYINT(int8_t value) {
	Value result(TypeId::INT8);
	result.value_.tinyint = value;
	result.is_null = false;
	return result;
}

Value Value::SMALLINT(int16_t value) {
	Value result(TypeId::INT16);
	result.value_.smallint = value;
	result.is_null = false;
	return result;
}

Value Value::INTEGER(int32_t value) {
	Value result(TypeId::INT32);
	result.value_.integer = value;
	result.is_null = false;
	return result;
}

Value Value::BIGINT(int64_t value) {
	Value result(TypeId::INT64);
	result.value_.bigint = value;
	result.is_null = false;
	return result;
}

Value Value::FLOAT(float value) {
	Value result(TypeId::FLOAT);
	result.value_.float_ = value;
	result.is_null = false;
	return result;
}

Value Value::DOUBLE(double value) {
	Value result(TypeId::DOUBLE);
	result.value_.double_ = value;
	result.is_null = false;
	return result;
}

Value Value::HASH(hash_t value) {
	Value result(TypeId::HASH);
	result.value_.hash = value;
	result.is_null = false;
	return result;
}

Value Value::POINTER(uintptr_t value) {
	Value result(TypeId::POINTER);
	result.value_.pointer = value;
	result.is_null = false;
	return result;
}

Value Value::DATE(int32_t year, int32_t month, int32_t day) {
	return Value::INTEGER(Date::FromDate(year, month, day));
}

Value Value::TIME(int32_t hour, int32_t min, int32_t sec, int32_t msec) {
	return Value::INTEGER(Time::FromTime(hour, min, sec, msec));
}

Value Value::TIMESTAMP(timestamp_t timestamp) {
	return Value::BIGINT(timestamp);
}

Value Value::TIMESTAMP(date_t date, dtime_t time) {
	return Value::BIGINT(Timestamp::FromDatetime(date, time));
}

Value Value::TIMESTAMP(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec, int32_t msec) {
	return Value::TIMESTAMP(Date::FromDate(year, month, day), Time::FromTime(hour, min, sec, msec));
}

Value Value::STRUCT(child_list_t<Value> values) {
	Value result(TypeId::STRUCT);
	result.struct_value = move(values);
	result.is_null = false;
	return result;
}

Value Value::LIST(vector<Value> values) {
	Value result(TypeId::LIST);
	result.list_value = move(values);
	result.is_null = false;
	return result;
}

//===--------------------------------------------------------------------===//
// CreateValue
//===--------------------------------------------------------------------===//
template <> Value Value::CreateValue(bool value) {
	return Value::BOOLEAN(value);
}

template <> Value Value::CreateValue(int8_t value) {
	return Value::TINYINT(value);
}

template <> Value Value::CreateValue(int16_t value) {
	return Value::SMALLINT(value);
}

template <> Value Value::CreateValue(int32_t value) {
	return Value::INTEGER(value);
}

template <> Value Value::CreateValue(int64_t value) {
	return Value::BIGINT(value);
}

template <> Value Value::CreateValue(const char *value) {
	return Value(string(value));
}

template <> Value Value::CreateValue(string value) {
	return Value(value);
}

template <> Value Value::CreateValue(string_t value) {
	return Value(value);
}

template <> Value Value::CreateValue(float value) {
	return Value::FLOAT(value);
}

template <> Value Value::CreateValue(double value) {
	return Value::DOUBLE(value);
}

//===--------------------------------------------------------------------===//
// GetValue
//===--------------------------------------------------------------------===//
template <class T> T Value::GetValueInternal() {
	if (is_null) {
		return NullValue<T>();
	}
	switch (type) {
	case TypeId::BOOL:
		return Cast::Operation<bool, T>(value_.boolean);
	case TypeId::INT8:
		return Cast::Operation<int8_t, T>(value_.tinyint);
	case TypeId::INT16:
		return Cast::Operation<int16_t, T>(value_.smallint);
	case TypeId::INT32:
		return Cast::Operation<int32_t, T>(value_.integer);
	case TypeId::INT64:
		return Cast::Operation<int64_t, T>(value_.bigint);
	case TypeId::FLOAT:
		return Cast::Operation<float, T>(value_.float_);
	case TypeId::DOUBLE:
		return Cast::Operation<double, T>(value_.double_);
	case TypeId::VARCHAR:
		return Cast::Operation<string_t, T>(str_value.c_str());
	default:
		throw NotImplementedException("Unimplemented type for GetValue()");
	}
}

template <> bool Value::GetValue() {
	return GetValueInternal<bool>();
}
template <> int8_t Value::GetValue() {
	return GetValueInternal<int8_t>();
}
template <> int16_t Value::GetValue() {
	return GetValueInternal<int16_t>();
}
template <> int32_t Value::GetValue() {
	return GetValueInternal<int32_t>();
}
template <> int64_t Value::GetValue() {
	return GetValueInternal<int64_t>();
}
template <> string Value::GetValue() {
	return GetValueInternal<string>();
}
template <> float Value::GetValue() {
	return GetValueInternal<float>();
}
template <> double Value::GetValue() {
	return GetValueInternal<double>();
}

Value Value::Numeric(TypeId type, int64_t value) {
	assert(!TypeIsIntegral(type) ||
	       (value >= duckdb::MinimumValue(type) && (value < 0 || (uint64_t)value <= duckdb::MaximumValue(type))));
	Value val(type);
	val.is_null = false;
	switch (type) {
	case TypeId::INT8:
		assert(value <= std::numeric_limits<int8_t>::max());
		return Value::TINYINT((int8_t)value);
	case TypeId::INT16:
		assert(value <= std::numeric_limits<int16_t>::max());
		return Value::SMALLINT((int16_t)value);
	case TypeId::INT32:
		assert(value <= std::numeric_limits<int32_t>::max());
		return Value::INTEGER((int32_t)value);
	case TypeId::INT64:
		return Value::BIGINT(value);
	case TypeId::FLOAT:
		return Value((float)value);
	case TypeId::DOUBLE:
		return Value((double)value);
	case TypeId::HASH:
		return Value::HASH(value);
	case TypeId::POINTER:
		return Value::POINTER(value);
	default:
		throw InvalidTypeException(type, "Numeric requires numeric type");
	}
	return val;
}

string Value::ToString(SQLType sql_type) const {
	if (is_null) {
		return "NULL";
	}
	switch (sql_type.id) {
	case SQLTypeId::BOOLEAN:
		return value_.boolean ? "True" : "False";
	case SQLTypeId::TINYINT:
		return to_string(value_.tinyint);
	case SQLTypeId::SMALLINT:
		return to_string(value_.smallint);
	case SQLTypeId::INTEGER:
		return to_string(value_.integer);
	case SQLTypeId::BIGINT:
		return to_string(value_.bigint);
	case SQLTypeId::FLOAT:
		return to_string(value_.float_);
	case SQLTypeId::DOUBLE:
		return to_string(value_.double_);
	case SQLTypeId::DATE:
		return Date::ToString(value_.integer);
	case SQLTypeId::TIME:
		return Time::ToString(value_.integer);
	case SQLTypeId::TIMESTAMP:
		return Timestamp::ToString(value_.bigint);
	case SQLTypeId::VARCHAR:
		return str_value;
	case SQLTypeId::STRUCT: {
		string ret = "<";
		for (size_t i = 0; i < struct_value.size(); i++) {
			auto &child = struct_value[i];
			ret += child.first + ": " + child.second.ToString();
			if (i < struct_value.size() - 1) {
				ret += ", ";
			}
		}
		ret += ">";
		return ret;
	}
	case SQLTypeId::LIST: {
		string ret = "[";
		for (size_t i = 0; i < list_value.size(); i++) {
			auto &child = list_value[i];
			ret += child.ToString();
			if (i < list_value.size() - 1) {
				ret += ", ";
			}
		}
		ret += "]";
		return ret;
	}
	default:
		throw NotImplementedException("Unimplemented type for printing");
	}
}

string Value::ToString() const {
	switch (type) {
	case TypeId::POINTER:
		return to_string(value_.pointer);
	case TypeId::HASH:
		return to_string(value_.hash);
	default:
		return ToString(SQLTypeFromInternalType(type));
	}
}

//===--------------------------------------------------------------------===//
// Numeric Operators
//===--------------------------------------------------------------------===//
Value Value::operator+(const Value &rhs) const {
	return ValueOperations::Add(*this, rhs);
}

Value Value::operator-(const Value &rhs) const {
	return ValueOperations::Subtract(*this, rhs);
}

Value Value::operator*(const Value &rhs) const {
	return ValueOperations::Multiply(*this, rhs);
}

Value Value::operator/(const Value &rhs) const {
	return ValueOperations::Divide(*this, rhs);
}

Value Value::operator%(const Value &rhs) const {
	throw NotImplementedException("value modulo");
	// return ValueOperations::Modulo(*this, rhs);
}

//===--------------------------------------------------------------------===//
// Comparison Operators
//===--------------------------------------------------------------------===//
bool Value::operator==(const Value &rhs) const {
	return ValueOperations::Equals(*this, rhs);
}

bool Value::operator!=(const Value &rhs) const {
	return ValueOperations::NotEquals(*this, rhs);
}

bool Value::operator<(const Value &rhs) const {
	return ValueOperations::LessThan(*this, rhs);
}

bool Value::operator>(const Value &rhs) const {
	return ValueOperations::GreaterThan(*this, rhs);
}

bool Value::operator<=(const Value &rhs) const {
	return ValueOperations::LessThanEquals(*this, rhs);
}

bool Value::operator>=(const Value &rhs) const {
	return ValueOperations::GreaterThanEquals(*this, rhs);
}

bool Value::operator==(const int64_t &rhs) const {
	return *this == Value::Numeric(type, rhs);
}

bool Value::operator!=(const int64_t &rhs) const {
	return *this != Value::Numeric(type, rhs);
}

bool Value::operator<(const int64_t &rhs) const {
	return *this < Value::Numeric(type, rhs);
}

bool Value::operator>(const int64_t &rhs) const {
	return *this > Value::Numeric(type, rhs);
}

bool Value::operator<=(const int64_t &rhs) const {
	return *this <= Value::Numeric(type, rhs);
}

bool Value::operator>=(const int64_t &rhs) const {
	return *this >= Value::Numeric(type, rhs);
}

Value Value::CastAs(SQLType source_type, SQLType target_type) {
	if (source_type == target_type) {
		return Copy();
	}
	Vector input, result;
	input.Reference(*this);
	result.Initialize(GetInternalType(target_type));
	VectorOperations::Cast(input, result, source_type, target_type, 1);
	return result.GetValue(0);
}

Value Value::CastAs(TypeId target_type) const {
	if (target_type == type) {
		return Copy(); // in case of types that have no SQLType equivalent such as POINTER
	}
	return Copy().CastAs(SQLTypeFromInternalType(type), SQLTypeFromInternalType(target_type));
}

void Value::Serialize(Serializer &serializer) {
	serializer.Write<TypeId>(type);
	serializer.Write<bool>(is_null);
	if (!is_null) {
		switch (type) {
		case TypeId::BOOL:
			serializer.Write<int8_t>(value_.boolean);
			break;
		case TypeId::INT8:
			serializer.Write<int8_t>(value_.tinyint);
			break;
		case TypeId::INT16:
			serializer.Write<int16_t>(value_.smallint);
			break;
		case TypeId::INT32:
			serializer.Write<int32_t>(value_.integer);
			break;
		case TypeId::INT64:
			serializer.Write<int64_t>(value_.bigint);
			break;
		case TypeId::FLOAT:
			serializer.Write<double>(value_.float_);
			break;
		case TypeId::DOUBLE:
			serializer.Write<double>(value_.double_);
			break;
		case TypeId::POINTER:
			serializer.Write<uintptr_t>(value_.pointer);
			break;
		case TypeId::VARCHAR:
			serializer.WriteString(str_value);
			break;
		default:
			throw NotImplementedException("Value type not implemented for serialization!");
		}
	}
}

Value Value::Deserialize(Deserializer &source) {
	auto type = source.Read<TypeId>();
	auto is_null = source.Read<bool>();
	Value new_value = Value(type);
	if (is_null) {
		return new_value;
	}
	new_value.is_null = false;
	switch (type) {
	case TypeId::BOOL:
		new_value.value_.boolean = source.Read<int8_t>();
		break;
	case TypeId::INT8:
		new_value.value_.tinyint = source.Read<int8_t>();
		break;
	case TypeId::INT16:
		new_value.value_.smallint = source.Read<int16_t>();
		break;
	case TypeId::INT32:
		new_value.value_.integer = source.Read<int32_t>();
		break;
	case TypeId::INT64:
		new_value.value_.bigint = source.Read<int64_t>();
		break;
	case TypeId::FLOAT:
		new_value.value_.float_ = source.Read<float>();
		break;
	case TypeId::DOUBLE:
		new_value.value_.double_ = source.Read<double>();
		break;
	case TypeId::POINTER:
		new_value.value_.pointer = source.Read<uint64_t>();
		break;
	case TypeId::VARCHAR:
		new_value.str_value = source.Read<string>();
		break;
	default:
		throw NotImplementedException("Value type not implemented for deserialization");
	}
	return new_value;
}

void Value::Print() {
	Printer::Print(ToString());
}

bool Value::ValuesAreEqual(Value result_value, Value value) {
	if (result_value.is_null && value.is_null) {
		// NULL = NULL in checking code
		return true;
	}
	switch (value.type) {
	case TypeId::FLOAT: {
		auto other = result_value.CastAs(TypeId::FLOAT);
		float ldecimal = value.value_.float_;
		float rdecimal = other.value_.float_;
		return ApproxEqual(ldecimal, rdecimal);
	}
	case TypeId::DOUBLE: {
		auto other = result_value.CastAs(TypeId::DOUBLE);
		double ldecimal = value.value_.double_;
		double rdecimal = other.value_.double_;
		return ApproxEqual(ldecimal, rdecimal);
	}
	case TypeId::VARCHAR: {
		auto other = result_value.CastAs(TypeId::VARCHAR);
		// some results might contain padding spaces, e.g. when rendering
		// VARCHAR(10) and the string only has 6 characters, they will be padded
		// with spaces to 10 in the rendering. We don't do that here yet as we
		// are looking at internal structures. So just ignore any extra spaces
		// on the right
		string left = other.str_value;
		string right = value.str_value;
		StringUtil::RTrim(left);
		StringUtil::RTrim(right);
		return left == right;
	}
	default:
		return value == result_value;
	}
}
#include <cstring> // strlen() on Solaris











using namespace std;

namespace duckdb {

Vector::Vector(TypeId type, bool create_data, bool zero_data)
    : vector_type(VectorType::FLAT_VECTOR), type(type), data(nullptr) {
	if (create_data) {
		Initialize(type, zero_data);
	}
}

Vector::Vector(TypeId type) : Vector(type, true, false) {
}

Vector::Vector(TypeId type, data_ptr_t dataptr) : vector_type(VectorType::FLAT_VECTOR), type(type), data(dataptr) {
	if (dataptr && type == TypeId::INVALID) {
		throw InvalidTypeException(type, "Cannot create a vector of type INVALID!");
	}
}

Vector::Vector(Value value) : vector_type(VectorType::CONSTANT_VECTOR) {
	Reference(value);
}

Vector::Vector() : vector_type(VectorType::FLAT_VECTOR), type(TypeId::INVALID), data(nullptr) {
}

Vector::Vector(Vector &&other) noexcept
    : vector_type(other.vector_type), type(other.type), data(other.data), nullmask(other.nullmask),
      buffer(move(other.buffer)), auxiliary(move(other.auxiliary)) {
}

void Vector::Reference(Value &value) {
	vector_type = VectorType::CONSTANT_VECTOR;
	type = value.type;
	buffer = VectorBuffer::CreateConstantVector(type);
	auxiliary.reset();
	data = buffer->GetData();
	SetValue(0, value);
}

void Vector::Reference(Vector &other) {
	vector_type = other.vector_type;
	buffer = other.buffer;
	auxiliary = other.auxiliary;
	data = other.data;
	type = other.type;
	nullmask = other.nullmask;
}

void Vector::Slice(Vector &other, idx_t offset) {
	if (other.vector_type == VectorType::CONSTANT_VECTOR) {
		Reference(other);
		return;
	}
	assert(other.vector_type == VectorType::FLAT_VECTOR);

	// create a reference to the other vector
	Reference(other);
	if (offset > 0) {
		data = data + GetTypeIdSize(type) * offset;
		nullmask <<= offset;
	}
}

void Vector::Slice(Vector &other, const SelectionVector &sel, idx_t count) {
	Reference(other);
	Slice(sel, count);
}

void Vector::Slice(const SelectionVector &sel, idx_t count) {
	if (vector_type == VectorType::CONSTANT_VECTOR) {
		// dictionary on a constant is just a constant
		return;
	}
	if (vector_type == VectorType::DICTIONARY_VECTOR) {
		// already a dictionary, slice the current dictionary
		auto &current_sel = DictionaryVector::SelVector(*this);
		auto sliced_dictionary = current_sel.Slice(sel, count);
		buffer = make_unique<DictionaryBuffer>(move(sliced_dictionary));
		return;
	}
	auto child_ref = make_buffer<VectorChildBuffer>();
	child_ref->data.Reference(*this);

	auto dict_buffer = make_unique<DictionaryBuffer>(sel);
	buffer = move(dict_buffer);
	auxiliary = move(child_ref);
	vector_type = VectorType::DICTIONARY_VECTOR;
}

void Vector::Slice(const SelectionVector &sel, idx_t count, sel_cache_t &cache) {
	if (vector_type == VectorType::DICTIONARY_VECTOR) {
		// dictionary vector: need to merge dictionaries
		// check if we have a cached entry
		auto &current_sel = DictionaryVector::SelVector(*this);
		auto target_data = current_sel.data();
		auto entry = cache.find(target_data);
		if (entry != cache.end()) {
			// cached entry exists: use that
			this->buffer = entry->second;
		} else {
			Slice(sel, count);
			cache[target_data] = this->buffer;
		}
	} else {
		Slice(sel, count);
	}
}

void Vector::Initialize(TypeId new_type, bool zero_data) {
	if (new_type != TypeId::INVALID) {
		type = new_type;
	}
	vector_type = VectorType::FLAT_VECTOR;
	buffer.reset();
	auxiliary.reset();
	nullmask.reset();
	if (GetTypeIdSize(type) > 0) {
		buffer = VectorBuffer::CreateStandardVector(type);
		data = buffer->GetData();
		if (zero_data) {
			memset(data, 0, STANDARD_VECTOR_SIZE * GetTypeIdSize(type));
		}
	}
}

void Vector::SetValue(idx_t index, Value val) {
	if (vector_type == VectorType::DICTIONARY_VECTOR) {
		// dictionary: apply dictionary and forward to child
		auto &sel_vector = DictionaryVector::SelVector(*this);
		auto &child = DictionaryVector::Child(*this);
		return child.SetValue(sel_vector.get_index(index), move(val));
	}
	Value newVal = val.CastAs(type);

	nullmask[index] = newVal.is_null;
	if (newVal.is_null) {
		return;
	}
	switch (type) {
	case TypeId::BOOL:
		((int8_t *)data)[index] = newVal.value_.boolean;
		break;
	case TypeId::INT8:
		((int8_t *)data)[index] = newVal.value_.tinyint;
		break;
	case TypeId::INT16:
		((int16_t *)data)[index] = newVal.value_.smallint;
		break;
	case TypeId::INT32:
		((int32_t *)data)[index] = newVal.value_.integer;
		break;
	case TypeId::INT64:
		((int64_t *)data)[index] = newVal.value_.bigint;
		break;
	case TypeId::FLOAT:
		((float *)data)[index] = newVal.value_.float_;
		break;
	case TypeId::DOUBLE:
		((double *)data)[index] = newVal.value_.double_;
		break;
	case TypeId::POINTER:
		((uintptr_t *)data)[index] = newVal.value_.pointer;
		break;
	case TypeId::VARCHAR: {
		((string_t *)data)[index] = StringVector::AddString(*this, newVal.str_value);
		break;
	}
	case TypeId::STRUCT: {
		if (!auxiliary || StructVector::GetEntries(*this).size() == 0) {
			for (size_t i = 0; i < val.struct_value.size(); i++) {
				auto &struct_child = val.struct_value[i];
				auto cv = make_unique<Vector>(struct_child.second.type);
				cv->vector_type = vector_type;
				StructVector::AddEntry(*this, struct_child.first, move(cv));
			}
		}

		auto &children = StructVector::GetEntries(*this);
		assert(children.size() == val.struct_value.size());

		for (size_t i = 0; i < val.struct_value.size(); i++) {
			auto &struct_child = val.struct_value[i];
			assert(vector_type == VectorType::CONSTANT_VECTOR || vector_type == VectorType::FLAT_VECTOR);
			auto &vec_child = children[i];
			assert(vec_child.first == struct_child.first);
			vec_child.second->SetValue(index, struct_child.second);
		}
	} break;

	case TypeId::LIST: {
		if (!auxiliary) {
			auto cc = make_unique<ChunkCollection>();
			ListVector::SetEntry(*this, move(cc));
		}
		auto &child_cc = ListVector::GetEntry(*this);
		// TODO optimization: in-place update if fits
		auto offset = child_cc.count;
		if (val.list_value.size() > 0) {
			idx_t append_idx = 0;
			while (append_idx < val.list_value.size()) {
				idx_t this_append_len = min((idx_t)STANDARD_VECTOR_SIZE, val.list_value.size() - append_idx);

				DataChunk child_append_chunk;
				child_append_chunk.SetCardinality(this_append_len);
				vector<TypeId> types;
				types.push_back(val.list_value[0].type);
				child_append_chunk.Initialize(types);
				for (idx_t i = 0; i < this_append_len; i++) {
					child_append_chunk.data[0].SetValue(i, val.list_value[i + append_idx]);
				}
				child_cc.Append(child_append_chunk);
				append_idx += this_append_len;
			}
		}
		// now set the pointer
		auto &entry = ((list_entry_t *)data)[index];
		entry.length = val.list_value.size();
		entry.offset = offset;
	} break;
	default:
		throw NotImplementedException("Unimplemented type for Vector::SetValue");
	}
}

Value Vector::GetValue(idx_t index) const {
	if (vector_type == VectorType::CONSTANT_VECTOR) {
		index = 0;
	} else if (vector_type == VectorType::DICTIONARY_VECTOR) {
		// dictionary: apply dictionary and forward to child
		auto &sel_vector = DictionaryVector::SelVector(*this);
		auto &child = DictionaryVector::Child(*this);
		return child.GetValue(sel_vector.get_index(index));
	} else {
		assert(vector_type == VectorType::FLAT_VECTOR);
	}

	if (nullmask[index]) {
		return Value(type);
	}
	switch (type) {
	case TypeId::BOOL:
		return Value::BOOLEAN(((int8_t *)data)[index]);
	case TypeId::INT8:
		return Value::TINYINT(((int8_t *)data)[index]);
	case TypeId::INT16:
		return Value::SMALLINT(((int16_t *)data)[index]);
	case TypeId::INT32:
		return Value::INTEGER(((int32_t *)data)[index]);
	case TypeId::INT64:
		return Value::BIGINT(((int64_t *)data)[index]);
	case TypeId::HASH:
		return Value::HASH(((hash_t *)data)[index]);
	case TypeId::POINTER:
		return Value::POINTER(((uintptr_t *)data)[index]);
	case TypeId::FLOAT:
		return Value::FLOAT(((float *)data)[index]);
	case TypeId::DOUBLE:
		return Value::DOUBLE(((double *)data)[index]);
	case TypeId::VARCHAR: {
		auto str = ((string_t *)data)[index];
		return Value(str.GetString());
	}
	case TypeId::STRUCT: {
		Value ret(TypeId::STRUCT);
		ret.is_null = false;
		// we can derive the value schema from the vector schema
		for (auto &struct_child : StructVector::GetEntries(*this)) {
			ret.struct_value.push_back(pair<string, Value>(struct_child.first, struct_child.second->GetValue(index)));
		}
		return ret;
	}
	case TypeId::LIST: {
		Value ret(TypeId::LIST);
		ret.is_null = false;
		auto offlen = ((list_entry_t *)data)[index];
		auto &child_cc = ListVector::GetEntry(*this);
		for (idx_t i = offlen.offset; i < offlen.offset + offlen.length; i++) {
			ret.list_value.push_back(child_cc.GetValue(0, i));
		}
		return ret;
	}
	default:
		throw NotImplementedException("Unimplemented type for value access");
	}
}

string VectorTypeToString(VectorType type) {
	switch (type) {
	case VectorType::FLAT_VECTOR:
		return "FLAT";
	case VectorType::SEQUENCE_VECTOR:
		return "SEQUENCE";
	case VectorType::DICTIONARY_VECTOR:
		return "DICTIONARY";
	case VectorType::CONSTANT_VECTOR:
		return "CONSTANT";
	default:
		return "UNKNOWN";
	}
}

string Vector::ToString(idx_t count) const {
	string retval = VectorTypeToString(vector_type) + " " + TypeIdToString(type) + ": " + to_string(count) + " = [ ";
	switch (vector_type) {
	case VectorType::FLAT_VECTOR:
	case VectorType::DICTIONARY_VECTOR:
		for (idx_t i = 0; i < count; i++) {
			retval += GetValue(i).ToString() + (i == count - 1 ? "" : ", ");
		}
		break;
	case VectorType::CONSTANT_VECTOR:
		retval += GetValue(0).ToString();
		break;
	case VectorType::SEQUENCE_VECTOR: {
		int64_t start, increment;
		SequenceVector::GetSequence(*this, start, increment);
		for (idx_t i = 0; i < count; i++) {
			retval += to_string(start + increment * i) + (i == count - 1 ? "" : ", ");
		}
		break;
	}
	default:
		retval += "UNKNOWN VECTOR TYPE";
		break;
	}
	retval += "]";
	return retval;
}

void Vector::Print(idx_t count) {
	Printer::Print(ToString(count));
}

string Vector::ToString() const {
	string retval = VectorTypeToString(vector_type) + " " + TypeIdToString(type) + ": (UNKNOWN COUNT) [ ";
	switch (vector_type) {
	case VectorType::FLAT_VECTOR:
	case VectorType::DICTIONARY_VECTOR:
		break;
	case VectorType::CONSTANT_VECTOR:
		retval += GetValue(0).ToString();
		break;
	case VectorType::SEQUENCE_VECTOR: {
		break;
	}
	default:
		retval += "UNKNOWN VECTOR TYPE";
		break;
	}
	retval += "]";
	return retval;
}

void Vector::Print() {
	Printer::Print(ToString());
}

template <class T> static void flatten_constant_vector_loop(data_ptr_t data, data_ptr_t old_data, idx_t count) {
	auto constant = *((T *)old_data);
	auto output = (T *)data;
	for (idx_t i = 0; i < count; i++) {
		output[i] = constant;
	}
}

void Vector::Normalify(idx_t count) {
	switch (vector_type) {
	case VectorType::FLAT_VECTOR:
		// already a flat vector
		break;
	case VectorType::DICTIONARY_VECTOR: {
		// create a new flat vector of this type
		Vector other(type);
		// now copy the data of this vector to the other vector, removing the selection vector in the process
		VectorOperations::Copy(*this, other, count, 0, 0);
		// create a reference to the data in the other vector
		this->Reference(other);
		break;
	}
	case VectorType::CONSTANT_VECTOR: {
		vector_type = VectorType::FLAT_VECTOR;
		// allocate a new buffer for the vector
		auto old_buffer = move(buffer);
		auto old_data = data;
		buffer = VectorBuffer::CreateStandardVector(type);
		data = buffer->GetData();
		if (nullmask[0]) {
			// constant NULL, set nullmask
			nullmask.set();
			return;
		}
		// non-null constant: have to repeat the constant
		switch (type) {
		case TypeId::BOOL:
		case TypeId::INT8:
			flatten_constant_vector_loop<int8_t>(data, old_data, count);
			break;
		case TypeId::INT16:
			flatten_constant_vector_loop<int16_t>(data, old_data, count);
			break;
		case TypeId::INT32:
			flatten_constant_vector_loop<int32_t>(data, old_data, count);
			break;
		case TypeId::INT64:
			flatten_constant_vector_loop<int64_t>(data, old_data, count);
			break;
		case TypeId::FLOAT:
			flatten_constant_vector_loop<float>(data, old_data, count);
			break;
		case TypeId::DOUBLE:
			flatten_constant_vector_loop<double>(data, old_data, count);
			break;
		case TypeId::HASH:
			flatten_constant_vector_loop<hash_t>(data, old_data, count);
			break;
		case TypeId::POINTER:
			flatten_constant_vector_loop<uintptr_t>(data, old_data, count);
			break;
		case TypeId::VARCHAR:
			flatten_constant_vector_loop<string_t>(data, old_data, count);
			break;
		case TypeId::LIST: {
			flatten_constant_vector_loop<list_entry_t>(data, old_data, count);
			break;
		}
		case TypeId::STRUCT: {
			for (auto &child : StructVector::GetEntries(*this)) {
				assert(child.second->vector_type == VectorType::CONSTANT_VECTOR);
				child.second->Normalify(count);
			}
		} break;
		default:
			throw NotImplementedException("Unimplemented type for VectorOperations::Normalify");
		}
		break;
	}
	case VectorType::SEQUENCE_VECTOR: {
		int64_t start, increment;
		SequenceVector::GetSequence(*this, start, increment);

		vector_type = VectorType::FLAT_VECTOR;
		buffer = VectorBuffer::CreateStandardVector(type);
		data = buffer->GetData();
		VectorOperations::GenerateSequence(*this, count, start, increment);
		break;
	}
	default:
		throw NotImplementedException("FIXME: unimplemented type for normalify");
	}
}

void Vector::Normalify(const SelectionVector &sel, idx_t count) {
	switch (vector_type) {
	case VectorType::FLAT_VECTOR:
		// already a flat vector
		break;
	case VectorType::SEQUENCE_VECTOR: {
		int64_t start, increment;
		SequenceVector::GetSequence(*this, start, increment);

		vector_type = VectorType::FLAT_VECTOR;
		buffer = VectorBuffer::CreateStandardVector(type);
		data = buffer->GetData();
		VectorOperations::GenerateSequence(*this, count, sel, start, increment);
		break;
	}
	default:
		throw NotImplementedException("Unimplemented type for normalify with selection vector");
	}
}

void Vector::Orrify(idx_t count, VectorData &data) {
	switch (vector_type) {
	case VectorType::DICTIONARY_VECTOR: {
		auto &sel = DictionaryVector::SelVector(*this);
		auto &child = DictionaryVector::Child(*this);
		child.Normalify(sel, count);

		data.sel = &sel;
		data.data = FlatVector::GetData(child);
		data.nullmask = &FlatVector::Nullmask(child);
		break;
	}
	case VectorType::CONSTANT_VECTOR:
		data.sel = &ConstantVector::ZeroSelectionVector;
		data.data = ConstantVector::GetData(*this);
		data.nullmask = &nullmask;
		break;
	default:
		Normalify(count);
		data.sel = &FlatVector::IncrementalSelectionVector;
		data.data = FlatVector::GetData(*this);
		data.nullmask = &nullmask;
		break;
	}
}

void Vector::Sequence(int64_t start, int64_t increment) {
	vector_type = VectorType::SEQUENCE_VECTOR;
	this->buffer = make_buffer<VectorBuffer>(sizeof(int64_t) * 2);
	auto data = (int64_t *)buffer->GetData();
	data[0] = start;
	data[1] = increment;
	nullmask.reset();
	auxiliary.reset();
}

void Vector::Serialize(idx_t count, Serializer &serializer) {
	if (TypeIsConstantSize(type)) {
		// constant size type: simple copy
		idx_t write_size = GetTypeIdSize(type) * count;
		auto ptr = unique_ptr<data_t[]>(new data_t[write_size]);
		VectorOperations::WriteToStorage(*this, count, ptr.get());
		serializer.WriteData(ptr.get(), write_size);
	} else {
		VectorData vdata;
		Orrify(count, vdata);

		switch (type) {
		case TypeId::VARCHAR: {
			auto strings = (string_t *)vdata.data;
			for (idx_t i = 0; i < count; i++) {
				auto idx = vdata.sel->get_index(i);
				auto source = (*vdata.nullmask)[idx] ? NullValue<const char *>() : strings[idx].GetData();
				serializer.WriteString(source);
			}
			break;
		}
		default:
			throw NotImplementedException("Unimplemented type for Vector::Serialize!");
		}
	}
}

void Vector::Deserialize(idx_t count, Deserializer &source) {
	if (TypeIsConstantSize(type)) {
		// constant size type: read fixed amount of data from
		auto column_size = GetTypeIdSize(type) * count;
		auto ptr = unique_ptr<data_t[]>(new data_t[column_size]);
		source.ReadData(ptr.get(), column_size);

		VectorOperations::ReadFromStorage(ptr.get(), count, *this);
	} else {
		auto strings = FlatVector::GetData<string_t>(*this);
		auto &nullmask = FlatVector::Nullmask(*this);
		for (idx_t i = 0; i < count; i++) {
			// read the strings
			auto str = source.Read<string>();
			// now add the string to the StringHeap of the vector
			// and write the pointer into the vector
			if (IsNullValue<const char *>((const char *)str.c_str())) {
				nullmask[i] = true;
			} else {
				strings[i] = StringVector::AddString(*this, str);
			}
		}
	}
}

void Vector::Verify(const SelectionVector &sel, idx_t count) {
#ifdef DEBUG
	if (count == 0) {
		return;
	}
	if (vector_type == VectorType::DICTIONARY_VECTOR) {
		auto &child = DictionaryVector::Child(*this);
		auto &dict_sel = DictionaryVector::SelVector(*this);
		for (idx_t i = 0; i < count; i++) {
			auto oidx = sel.get_index(i);
			auto idx = dict_sel.get_index(oidx);
			assert(idx < STANDARD_VECTOR_SIZE);
		}
		// merge the selection vectors and verify the child
		auto new_buffer = dict_sel.Slice(sel, count);
		SelectionVector new_sel(new_buffer);
		child.Verify(new_sel, count);
		return;
	}
	if (type == TypeId::VARCHAR) {
		// we just touch all the strings and let the sanitizer figure out if any
		// of them are deallocated/corrupt
		switch (vector_type) {
		case VectorType::CONSTANT_VECTOR: {
			auto string = ConstantVector::GetData<string_t>(*this);
			if (!ConstantVector::IsNull(*this)) {
				string->Verify();
			}
			break;
		}
		case VectorType::FLAT_VECTOR: {
			auto strings = FlatVector::GetData<string_t>(*this);
			for (idx_t i = 0; i < count; i++) {
				auto oidx = sel.get_index(i);
				if (!nullmask[oidx]) {
					strings[oidx].Verify();
				}
			}
			break;
		}
		default:
			break;
		}
	}

	if (type == TypeId::STRUCT) {
		if (vector_type == VectorType::FLAT_VECTOR || vector_type == VectorType::CONSTANT_VECTOR) {
			auto &children = StructVector::GetEntries(*this);
			assert(children.size() > 0);
			for (auto &child : children) {
				child.second->Verify(sel, count);
			}
		}
	}

	if (type == TypeId::LIST) {
		if (vector_type == VectorType::CONSTANT_VECTOR) {
			if (!ConstantVector::IsNull(*this)) {
				ListVector::GetEntry(*this).Verify();
				auto le = ConstantVector::GetData<list_entry_t>(*this);
				assert(le->offset + le->length <= ListVector::GetEntry(*this).count);
			}
		} else if (vector_type == VectorType::FLAT_VECTOR) {
			if (ListVector::HasEntry(*this)) {
				ListVector::GetEntry(*this).Verify();
			}
			auto list_data = FlatVector::GetData<list_entry_t>(*this);
			for (idx_t i = 0; i < count; i++) {
				auto idx = sel.get_index(i);
				auto &le = list_data[idx];
				if (!nullmask[idx]) {
					assert(le.offset + le.length <= ListVector::GetEntry(*this).count);
				}
			}
		}
	}
// TODO verify list and struct
#endif
}

void Vector::Verify(idx_t count) {
	Verify(FlatVector::IncrementalSelectionVector, count);
}

string_t StringVector::AddString(Vector &vector, const char *data, idx_t len) {
	return StringVector::AddString(vector, string_t(data, len));
}

string_t StringVector::AddString(Vector &vector, const char *data) {
	return StringVector::AddString(vector, string_t(data, strlen(data)));
}

string_t StringVector::AddString(Vector &vector, const string &data) {
	return StringVector::AddString(vector, string_t(data.c_str(), data.size()));
}

string_t StringVector::AddString(Vector &vector, string_t data) {
	assert(vector.type == TypeId::VARCHAR);
	if (data.IsInlined()) {
		// string will be inlined: no need to store in string heap
		return data;
	}
	if (!vector.auxiliary) {
		vector.auxiliary = make_buffer<VectorStringBuffer>();
	}
	assert(vector.auxiliary->type == VectorBufferType::STRING_BUFFER);
	auto &string_buffer = (VectorStringBuffer &)*vector.auxiliary;
	return string_buffer.AddString(data);
}

string_t StringVector::EmptyString(Vector &vector, idx_t len) {
	assert(vector.type == TypeId::VARCHAR);
	if (len < string_t::INLINE_LENGTH) {
		return string_t(len);
	}
	if (!vector.auxiliary) {
		vector.auxiliary = make_buffer<VectorStringBuffer>();
	}
	assert(vector.auxiliary->type == VectorBufferType::STRING_BUFFER);
	auto &string_buffer = (VectorStringBuffer &)*vector.auxiliary;
	return string_buffer.EmptyString(len);
}

void StringVector::AddHeapReference(Vector &vector, Vector &other) {
	assert(vector.type == TypeId::VARCHAR);
	assert(other.type == TypeId::VARCHAR);

	if (!other.auxiliary) {
		return;
	}
	if (!vector.auxiliary) {
		vector.auxiliary = make_buffer<VectorStringBuffer>();
	}
	assert(vector.auxiliary->type == VectorBufferType::STRING_BUFFER);
	assert(other.auxiliary->type == VectorBufferType::STRING_BUFFER);
	auto &string_buffer = (VectorStringBuffer &)*vector.auxiliary;
	string_buffer.AddHeapReference(other.auxiliary);
}

bool StructVector::HasEntries(const Vector &vector) {
	assert(vector.type == TypeId::STRUCT);
	assert(vector.vector_type == VectorType::FLAT_VECTOR || vector.vector_type == VectorType::CONSTANT_VECTOR);
	assert(vector.auxiliary == nullptr || vector.auxiliary->type == VectorBufferType::STRUCT_BUFFER);
	return vector.auxiliary != nullptr;
}

child_list_t<unique_ptr<Vector>> &StructVector::GetEntries(const Vector &vector) {
	assert(vector.type == TypeId::STRUCT);
	assert(vector.vector_type == VectorType::FLAT_VECTOR || vector.vector_type == VectorType::CONSTANT_VECTOR);
	assert(vector.auxiliary);
	assert(vector.auxiliary->type == VectorBufferType::STRUCT_BUFFER);
	return ((VectorStructBuffer *)vector.auxiliary.get())->GetChildren();
}

void StructVector::AddEntry(Vector &vector, string name, unique_ptr<Vector> entry) {
	// TODO asser that an entry with this name does not already exist
	assert(vector.type == TypeId::STRUCT);
	assert(vector.vector_type == VectorType::FLAT_VECTOR || vector.vector_type == VectorType::CONSTANT_VECTOR);
	if (!vector.auxiliary) {
		vector.auxiliary = make_buffer<VectorStructBuffer>();
	}
	assert(vector.auxiliary);
	assert(vector.auxiliary->type == VectorBufferType::STRUCT_BUFFER);
	((VectorStructBuffer *)vector.auxiliary.get())->AddChild(name, move(entry));
}

bool ListVector::HasEntry(const Vector &vector) {
	assert(vector.type == TypeId::LIST);
	if (vector.vector_type == VectorType::DICTIONARY_VECTOR) {
		auto &child = DictionaryVector::Child(vector);
		return ListVector::HasEntry(child);
	}
	assert(vector.vector_type == VectorType::FLAT_VECTOR || vector.vector_type == VectorType::CONSTANT_VECTOR);
	return vector.auxiliary != nullptr;
}

ChunkCollection &ListVector::GetEntry(const Vector &vector) {
	assert(vector.type == TypeId::LIST);
	if (vector.vector_type == VectorType::DICTIONARY_VECTOR) {
		auto &child = DictionaryVector::Child(vector);
		return ListVector::GetEntry(child);
	}
	assert(vector.vector_type == VectorType::FLAT_VECTOR || vector.vector_type == VectorType::CONSTANT_VECTOR);
	assert(vector.auxiliary);
	assert(vector.auxiliary->type == VectorBufferType::LIST_BUFFER);
	return ((VectorListBuffer *)vector.auxiliary.get())->GetChild();
}

void ListVector::SetEntry(Vector &vector, unique_ptr<ChunkCollection> cc) {
	assert(vector.type == TypeId::LIST);
	assert(vector.vector_type == VectorType::FLAT_VECTOR || vector.vector_type == VectorType::CONSTANT_VECTOR);
	if (!vector.auxiliary) {
		vector.auxiliary = make_buffer<VectorListBuffer>();
	}
	assert(vector.auxiliary);
	assert(vector.auxiliary->type == VectorBufferType::LIST_BUFFER);
	((VectorListBuffer *)vector.auxiliary.get())->SetChild(move(cc));
}

} // namespace duckdb






using namespace duckdb;
using namespace std;

VectorBuffer::VectorBuffer(idx_t data_size) : type(VectorBufferType::STANDARD_BUFFER) {
	if (data_size > 0) {
		data = unique_ptr<data_t[]>(new data_t[data_size]);
	}
}

buffer_ptr<VectorBuffer> VectorBuffer::CreateStandardVector(TypeId type) {
	return make_buffer<VectorBuffer>(STANDARD_VECTOR_SIZE * GetTypeIdSize(type));
}

buffer_ptr<VectorBuffer> VectorBuffer::CreateConstantVector(TypeId type) {
	return make_buffer<VectorBuffer>(GetTypeIdSize(type));
}

VectorStringBuffer::VectorStringBuffer() : VectorBuffer(VectorBufferType::STRING_BUFFER) {
}

VectorStructBuffer::VectorStructBuffer() : VectorBuffer(VectorBufferType::STRUCT_BUFFER) {
}

VectorStructBuffer::~VectorStructBuffer() {
}

VectorListBuffer::VectorListBuffer() : VectorBuffer(VectorBufferType::LIST_BUFFER) {
}

void VectorListBuffer::SetChild(unique_ptr<ChunkCollection> new_child) {
	child = move(new_child);
}

VectorListBuffer::~VectorListBuffer() {
}


namespace duckdb {

nullmask_t ZERO_MASK = nullmask_t(0);
const SelectionVector ConstantVector::ZeroSelectionVector = SelectionVector((sel_t *)ConstantVector::zero_vector);
const SelectionVector FlatVector::IncrementalSelectionVector = SelectionVector((sel_t *)FlatVector::incremental_vector);
const sel_t ConstantVector::zero_vector[STANDARD_VECTOR_SIZE] = {0};

#if STANDARD_VECTOR_SIZE == 2
const sel_t FlatVector::incremental_vector[] = {0, 1};
#elif STANDARD_VECTOR_SIZE == 4
const sel_t FlatVector::incremental_vector[] = {0, 1, 2, 3};
#elif STANDARD_VECTOR_SIZE == 8
const sel_t FlatVector::incremental_vector[] = {0, 1, 2, 3, 4, 5, 6, 7};
#elif STANDARD_VECTOR_SIZE == 16
const sel_t FlatVector::incremental_vector[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
#elif STANDARD_VECTOR_SIZE == 32
const sel_t FlatVector::incremental_vector[] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
                                                    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
#elif STANDARD_VECTOR_SIZE == 64
const sel_t FlatVector::incremental_vector[] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
                                                    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
                                                    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
                                                    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
#elif STANDARD_VECTOR_SIZE == 128
const sel_t FlatVector::incremental_vector[] = {
    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,
    22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
    44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
    66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
    88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
    110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
#elif STANDARD_VECTOR_SIZE == 256
const sel_t FlatVector::incremental_vector[] = {
    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,
    22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
    44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
    66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
    88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
    110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
    132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
    154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
    198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
    220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
    242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};
#elif STANDARD_VECTOR_SIZE == 512
const sel_t FlatVector::incremental_vector[] = {
    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,
    23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,
    46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
    69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,
    92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
    115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
    138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
    161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
    184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
    207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
    230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
    253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
    276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
    299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321,
    322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
    345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367,
    368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390,
    391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413,
    414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,
    437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459,
    460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482,
    483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505,
    506, 507, 508, 509, 510, 511};
#elif STANDARD_VECTOR_SIZE == 1024
const sel_t FlatVector::incremental_vector[] = {
    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,   14,   15,   16,   17,   18,
    19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
    38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
    57,   58,   59,   60,   61,   62,   63,   64,   65,   66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
    95,   96,   97,   98,   99,   100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,  111,  112,  113,
    114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,  127,  128,  129,  130,  131,  132,
    133,  134,  135,  136,  137,  138,  139,  140,  141,  142,  143,  144,  145,  146,  147,  148,  149,  150,  151,
    152,  153,  154,  155,  156,  157,  158,  159,  160,  161,  162,  163,  164,  165,  166,  167,  168,  169,  170,
    171,  172,  173,  174,  175,  176,  177,  178,  179,  180,  181,  182,  183,  184,  185,  186,  187,  188,  189,
    190,  191,  192,  193,  194,  195,  196,  197,  198,  199,  200,  201,  202,  203,  204,  205,  206,  207,  208,
    209,  210,  211,  212,  213,  214,  215,  216,  217,  218,  219,  220,  221,  222,  223,  224,  225,  226,  227,
    228,  229,  230,  231,  232,  233,  234,  235,  236,  237,  238,  239,  240,  241,  242,  243,  244,  245,  246,
    247,  248,  249,  250,  251,  252,  253,  254,  255,  256,  257,  258,  259,  260,  261,  262,  263,  264,  265,
    266,  267,  268,  269,  270,  271,  272,  273,  274,  275,  276,  277,  278,  279,  280,  281,  282,  283,  284,
    285,  286,  287,  288,  289,  290,  291,  292,  293,  294,  295,  296,  297,  298,  299,  300,  301,  302,  303,
    304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  314,  315,  316,  317,  318,  319,  320,  321,  322,
    323,  324,  325,  326,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,  340,  341,
    342,  343,  344,  345,  346,  347,  348,  349,  350,  351,  352,  353,  354,  355,  356,  357,  358,  359,  360,
    361,  362,  363,  364,  365,  366,  367,  368,  369,  370,  371,  372,  373,  374,  375,  376,  377,  378,  379,
    380,  381,  382,  383,  384,  385,  386,  387,  388,  389,  390,  391,  392,  393,  394,  395,  396,  397,  398,
    399,  400,  401,  402,  403,  404,  405,  406,  407,  408,  409,  410,  411,  412,  413,  414,  415,  416,  417,
    418,  419,  420,  421,  422,  423,  424,  425,  426,  427,  428,  429,  430,  431,  432,  433,  434,  435,  436,
    437,  438,  439,  440,  441,  442,  443,  444,  445,  446,  447,  448,  449,  450,  451,  452,  453,  454,  455,
    456,  457,  458,  459,  460,  461,  462,  463,  464,  465,  466,  467,  468,  469,  470,  471,  472,  473,  474,
    475,  476,  477,  478,  479,  480,  481,  482,  483,  484,  485,  486,  487,  488,  489,  490,  491,  492,  493,
    494,  495,  496,  497,  498,  499,  500,  501,  502,  503,  504,  505,  506,  507,  508,  509,  510,  511,  512,
    513,  514,  515,  516,  517,  518,  519,  520,  521,  522,  523,  524,  525,  526,  527,  528,  529,  530,  531,
    532,  533,  534,  535,  536,  537,  538,  539,  540,  541,  542,  543,  544,  545,  546,  547,  548,  549,  550,
    551,  552,  553,  554,  555,  556,  557,  558,  559,  560,  561,  562,  563,  564,  565,  566,  567,  568,  569,
    570,  571,  572,  573,  574,  575,  576,  577,  578,  579,  580,  581,  582,  583,  584,  585,  586,  587,  588,
    589,  590,  591,  592,  593,  594,  595,  596,  597,  598,  599,  600,  601,  602,  603,  604,  605,  606,  607,
    608,  609,  610,  611,  612,  613,  614,  615,  616,  617,  618,  619,  620,  621,  622,  623,  624,  625,  626,
    627,  628,  629,  630,  631,  632,  633,  634,  635,  636,  637,  638,  639,  640,  641,  642,  643,  644,  645,
    646,  647,  648,  649,  650,  651,  652,  653,  654,  655,  656,  657,  658,  659,  660,  661,  662,  663,  664,
    665,  666,  667,  668,  669,  670,  671,  672,  673,  674,  675,  676,  677,  678,  679,  680,  681,  682,  683,
    684,  685,  686,  687,  688,  689,  690,  691,  692,  693,  694,  695,  696,  697,  698,  699,  700,  701,  702,
    703,  704,  705,  706,  707,  708,  709,  710,  711,  712,  713,  714,  715,  716,  717,  718,  719,  720,  721,
    722,  723,  724,  725,  726,  727,  728,  729,  730,  731,  732,  733,  734,  735,  736,  737,  738,  739,  740,
    741,  742,  743,  744,  745,  746,  747,  748,  749,  750,  751,  752,  753,  754,  755,  756,  757,  758,  759,
    760,  761,  762,  763,  764,  765,  766,  767,  768,  769,  770,  771,  772,  773,  774,  775,  776,  777,  778,
    779,  780,  781,  782,  783,  784,  785,  786,  787,  788,  789,  790,  791,  792,  793,  794,  795,  796,  797,
    798,  799,  800,  801,  802,  803,  804,  805,  806,  807,  808,  809,  810,  811,  812,  813,  814,  815,  816,
    817,  818,  819,  820,  821,  822,  823,  824,  825,  826,  827,  828,  829,  830,  831,  832,  833,  834,  835,
    836,  837,  838,  839,  840,  841,  842,  843,  844,  845,  846,  847,  848,  849,  850,  851,  852,  853,  854,
    855,  856,  857,  858,  859,  860,  861,  862,  863,  864,  865,  866,  867,  868,  869,  870,  871,  872,  873,
    874,  875,  876,  877,  878,  879,  880,  881,  882,  883,  884,  885,  886,  887,  888,  889,  890,  891,  892,
    893,  894,  895,  896,  897,  898,  899,  900,  901,  902,  903,  904,  905,  906,  907,  908,  909,  910,  911,
    912,  913,  914,  915,  916,  917,  918,  919,  920,  921,  922,  923,  924,  925,  926,  927,  928,  929,  930,
    931,  932,  933,  934,  935,  936,  937,  938,  939,  940,  941,  942,  943,  944,  945,  946,  947,  948,  949,
    950,  951,  952,  953,  954,  955,  956,  957,  958,  959,  960,  961,  962,  963,  964,  965,  966,  967,  968,
    969,  970,  971,  972,  973,  974,  975,  976,  977,  978,  979,  980,  981,  982,  983,  984,  985,  986,  987,
    988,  989,  990,  991,  992,  993,  994,  995,  996,  997,  998,  999,  1000, 1001, 1002, 1003, 1004, 1005, 1006,
    1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023};
#elif STANDARD_VECTOR_SIZE == 2048
const sel_t FlatVector::incremental_vector[] = {
    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,   14,   15,   16,   17,   18,
    19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
    38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
    57,   58,   59,   60,   61,   62,   63,   64,   65,   66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
    95,   96,   97,   98,   99,   100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,  111,  112,  113,
    114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,  127,  128,  129,  130,  131,  132,
    133,  134,  135,  136,  137,  138,  139,  140,  141,  142,  143,  144,  145,  146,  147,  148,  149,  150,  151,
    152,  153,  154,  155,  156,  157,  158,  159,  160,  161,  162,  163,  164,  165,  166,  167,  168,  169,  170,
    171,  172,  173,  174,  175,  176,  177,  178,  179,  180,  181,  182,  183,  184,  185,  186,  187,  188,  189,
    190,  191,  192,  193,  194,  195,  196,  197,  198,  199,  200,  201,  202,  203,  204,  205,  206,  207,  208,
    209,  210,  211,  212,  213,  214,  215,  216,  217,  218,  219,  220,  221,  222,  223,  224,  225,  226,  227,
    228,  229,  230,  231,  232,  233,  234,  235,  236,  237,  238,  239,  240,  241,  242,  243,  244,  245,  246,
    247,  248,  249,  250,  251,  252,  253,  254,  255,  256,  257,  258,  259,  260,  261,  262,  263,  264,  265,
    266,  267,  268,  269,  270,  271,  272,  273,  274,  275,  276,  277,  278,  279,  280,  281,  282,  283,  284,
    285,  286,  287,  288,  289,  290,  291,  292,  293,  294,  295,  296,  297,  298,  299,  300,  301,  302,  303,
    304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  314,  315,  316,  317,  318,  319,  320,  321,  322,
    323,  324,  325,  326,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,  340,  341,
    342,  343,  344,  345,  346,  347,  348,  349,  350,  351,  352,  353,  354,  355,  356,  357,  358,  359,  360,
    361,  362,  363,  364,  365,  366,  367,  368,  369,  370,  371,  372,  373,  374,  375,  376,  377,  378,  379,
    380,  381,  382,  383,  384,  385,  386,  387,  388,  389,  390,  391,  392,  393,  394,  395,  396,  397,  398,
    399,  400,  401,  402,  403,  404,  405,  406,  407,  408,  409,  410,  411,  412,  413,  414,  415,  416,  417,
    418,  419,  420,  421,  422,  423,  424,  425,  426,  427,  428,  429,  430,  431,  432,  433,  434,  435,  436,
    437,  438,  439,  440,  441,  442,  443,  444,  445,  446,  447,  448,  449,  450,  451,  452,  453,  454,  455,
    456,  457,  458,  459,  460,  461,  462,  463,  464,  465,  466,  467,  468,  469,  470,  471,  472,  473,  474,
    475,  476,  477,  478,  479,  480,  481,  482,  483,  484,  485,  486,  487,  488,  489,  490,  491,  492,  493,
    494,  495,  496,  497,  498,  499,  500,  501,  502,  503,  504,  505,  506,  507,  508,  509,  510,  511,  512,
    513,  514,  515,  516,  517,  518,  519,  520,  521,  522,  523,  524,  525,  526,  527,  528,  529,  530,  531,
    532,  533,  534,  535,  536,  537,  538,  539,  540,  541,  542,  543,  544,  545,  546,  547,  548,  549,  550,
    551,  552,  553,  554,  555,  556,  557,  558,  559,  560,  561,  562,  563,  564,  565,  566,  567,  568,  569,
    570,  571,  572,  573,  574,  575,  576,  577,  578,  579,  580,  581,  582,  583,  584,  585,  586,  587,  588,
    589,  590,  591,  592,  593,  594,  595,  596,  597,  598,  599,  600,  601,  602,  603,  604,  605,  606,  607,
    608,  609,  610,  611,  612,  613,  614,  615,  616,  617,  618,  619,  620,  621,  622,  623,  624,  625,  626,
    627,  628,  629,  630,  631,  632,  633,  634,  635,  636,  637,  638,  639,  640,  641,  642,  643,  644,  645,
    646,  647,  648,  649,  650,  651,  652,  653,  654,  655,  656,  657,  658,  659,  660,  661,  662,  663,  664,
    665,  666,  667,  668,  669,  670,  671,  672,  673,  674,  675,  676,  677,  678,  679,  680,  681,  682,  683,
    684,  685,  686,  687,  688,  689,  690,  691,  692,  693,  694,  695,  696,  697,  698,  699,  700,  701,  702,
    703,  704,  705,  706,  707,  708,  709,  710,  711,  712,  713,  714,  715,  716,  717,  718,  719,  720,  721,
    722,  723,  724,  725,  726,  727,  728,  729,  730,  731,  732,  733,  734,  735,  736,  737,  738,  739,  740,
    741,  742,  743,  744,  745,  746,  747,  748,  749,  750,  751,  752,  753,  754,  755,  756,  757,  758,  759,
    760,  761,  762,  763,  764,  765,  766,  767,  768,  769,  770,  771,  772,  773,  774,  775,  776,  777,  778,
    779,  780,  781,  782,  783,  784,  785,  786,  787,  788,  789,  790,  791,  792,  793,  794,  795,  796,  797,
    798,  799,  800,  801,  802,  803,  804,  805,  806,  807,  808,  809,  810,  811,  812,  813,  814,  815,  816,
    817,  818,  819,  820,  821,  822,  823,  824,  825,  826,  827,  828,  829,  830,  831,  832,  833,  834,  835,
    836,  837,  838,  839,  840,  841,  842,  843,  844,  845,  846,  847,  848,  849,  850,  851,  852,  853,  854,
    855,  856,  857,  858,  859,  860,  861,  862,  863,  864,  865,  866,  867,  868,  869,  870,  871,  872,  873,
    874,  875,  876,  877,  878,  879,  880,  881,  882,  883,  884,  885,  886,  887,  888,  889,  890,  891,  892,
    893,  894,  895,  896,  897,  898,  899,  900,  901,  902,  903,  904,  905,  906,  907,  908,  909,  910,  911,
    912,  913,  914,  915,  916,  917,  918,  919,  920,  921,  922,  923,  924,  925,  926,  927,  928,  929,  930,
    931,  932,  933,  934,  935,  936,  937,  938,  939,  940,  941,  942,  943,  944,  945,  946,  947,  948,  949,
    950,  951,  952,  953,  954,  955,  956,  957,  958,  959,  960,  961,  962,  963,  964,  965,  966,  967,  968,
    969,  970,  971,  972,  973,  974,  975,  976,  977,  978,  979,  980,  981,  982,  983,  984,  985,  986,  987,
    988,  989,  990,  991,  992,  993,  994,  995,  996,  997,  998,  999,  1000, 1001, 1002, 1003, 1004, 1005, 1006,
    1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025,
    1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044,
    1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
    1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082,
    1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101,
    1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120,
    1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139,
    1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158,
    1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177,
    1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196,
    1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215,
    1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234,
    1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253,
    1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272,
    1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291,
    1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310,
    1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329,
    1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348,
    1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367,
    1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386,
    1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,
    1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424,
    1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443,
    1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462,
    1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481,
    1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500,
    1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519,
    1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538,
    1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557,
    1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576,
    1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595,
    1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614,
    1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633,
    1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652,
    1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671,
    1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690,
    1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709,
    1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728,
    1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747,
    1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766,
    1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785,
    1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804,
    1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823,
    1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842,
    1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861,
    1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880,
    1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899,
    1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918,
    1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937,
    1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956,
    1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975,
    1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
    2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032,
    2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047};
#elif STANDARD_VECTOR_SIZE == 4096
const sel_t FlatVector::incremental_vector[] = {
    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,   14,   15,   16,   17,   18,
    19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
    38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
    57,   58,   59,   60,   61,   62,   63,   64,   65,   66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
    95,   96,   97,   98,   99,   100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,  111,  112,  113,
    114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,  127,  128,  129,  130,  131,  132,
    133,  134,  135,  136,  137,  138,  139,  140,  141,  142,  143,  144,  145,  146,  147,  148,  149,  150,  151,
    152,  153,  154,  155,  156,  157,  158,  159,  160,  161,  162,  163,  164,  165,  166,  167,  168,  169,  170,
    171,  172,  173,  174,  175,  176,  177,  178,  179,  180,  181,  182,  183,  184,  185,  186,  187,  188,  189,
    190,  191,  192,  193,  194,  195,  196,  197,  198,  199,  200,  201,  202,  203,  204,  205,  206,  207,  208,
    209,  210,  211,  212,  213,  214,  215,  216,  217,  218,  219,  220,  221,  222,  223,  224,  225,  226,  227,
    228,  229,  230,  231,  232,  233,  234,  235,  236,  237,  238,  239,  240,  241,  242,  243,  244,  245,  246,
    247,  248,  249,  250,  251,  252,  253,  254,  255,  256,  257,  258,  259,  260,  261,  262,  263,  264,  265,
    266,  267,  268,  269,  270,  271,  272,  273,  274,  275,  276,  277,  278,  279,  280,  281,  282,  283,  284,
    285,  286,  287,  288,  289,  290,  291,  292,  293,  294,  295,  296,  297,  298,  299,  300,  301,  302,  303,
    304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  314,  315,  316,  317,  318,  319,  320,  321,  322,
    323,  324,  325,  326,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,  340,  341,
    342,  343,  344,  345,  346,  347,  348,  349,  350,  351,  352,  353,  354,  355,  356,  357,  358,  359,  360,
    361,  362,  363,  364,  365,  366,  367,  368,  369,  370,  371,  372,  373,  374,  375,  376,  377,  378,  379,
    380,  381,  382,  383,  384,  385,  386,  387,  388,  389,  390,  391,  392,  393,  394,  395,  396,  397,  398,
    399,  400,  401,  402,  403,  404,  405,  406,  407,  408,  409,  410,  411,  412,  413,  414,  415,  416,  417,
    418,  419,  420,  421,  422,  423,  424,  425,  426,  427,  428,  429,  430,  431,  432,  433,  434,  435,  436,
    437,  438,  439,  440,  441,  442,  443,  444,  445,  446,  447,  448,  449,  450,  451,  452,  453,  454,  455,
    456,  457,  458,  459,  460,  461,  462,  463,  464,  465,  466,  467,  468,  469,  470,  471,  472,  473,  474,
    475,  476,  477,  478,  479,  480,  481,  482,  483,  484,  485,  486,  487,  488,  489,  490,  491,  492,  493,
    494,  495,  496,  497,  498,  499,  500,  501,  502,  503,  504,  505,  506,  507,  508,  509,  510,  511,  512,
    513,  514,  515,  516,  517,  518,  519,  520,  521,  522,  523,  524,  525,  526,  527,  528,  529,  530,  531,
    532,  533,  534,  535,  536,  537,  538,  539,  540,  541,  542,  543,  544,  545,  546,  547,  548,  549,  550,
    551,  552,  553,  554,  555,  556,  557,  558,  559,  560,  561,  562,  563,  564,  565,  566,  567,  568,  569,
    570,  571,  572,  573,  574,  575,  576,  577,  578,  579,  580,  581,  582,  583,  584,  585,  586,  587,  588,
    589,  590,  591,  592,  593,  594,  595,  596,  597,  598,  599,  600,  601,  602,  603,  604,  605,  606,  607,
    608,  609,  610,  611,  612,  613,  614,  615,  616,  617,  618,  619,  620,  621,  622,  623,  624,  625,  626,
    627,  628,  629,  630,  631,  632,  633,  634,  635,  636,  637,  638,  639,  640,  641,  642,  643,  644,  645,
    646,  647,  648,  649,  650,  651,  652,  653,  654,  655,  656,  657,  658,  659,  660,  661,  662,  663,  664,
    665,  666,  667,  668,  669,  670,  671,  672,  673,  674,  675,  676,  677,  678,  679,  680,  681,  682,  683,
    684,  685,  686,  687,  688,  689,  690,  691,  692,  693,  694,  695,  696,  697,  698,  699,  700,  701,  702,
    703,  704,  705,  706,  707,  708,  709,  710,  711,  712,  713,  714,  715,  716,  717,  718,  719,  720,  721,
    722,  723,  724,  725,  726,  727,  728,  729,  730,  731,  732,  733,  734,  735,  736,  737,  738,  739,  740,
    741,  742,  743,  744,  745,  746,  747,  748,  749,  750,  751,  752,  753,  754,  755,  756,  757,  758,  759,
    760,  761,  762,  763,  764,  765,  766,  767,  768,  769,  770,  771,  772,  773,  774,  775,  776,  777,  778,
    779,  780,  781,  782,  783,  784,  785,  786,  787,  788,  789,  790,  791,  792,  793,  794,  795,  796,  797,
    798,  799,  800,  801,  802,  803,  804,  805,  806,  807,  808,  809,  810,  811,  812,  813,  814,  815,  816,
    817,  818,  819,  820,  821,  822,  823,  824,  825,  826,  827,  828,  829,  830,  831,  832,  833,  834,  835,
    836,  837,  838,  839,  840,  841,  842,  843,  844,  845,  846,  847,  848,  849,  850,  851,  852,  853,  854,
    855,  856,  857,  858,  859,  860,  861,  862,  863,  864,  865,  866,  867,  868,  869,  870,  871,  872,  873,
    874,  875,  876,  877,  878,  879,  880,  881,  882,  883,  884,  885,  886,  887,  888,  889,  890,  891,  892,
    893,  894,  895,  896,  897,  898,  899,  900,  901,  902,  903,  904,  905,  906,  907,  908,  909,  910,  911,
    912,  913,  914,  915,  916,  917,  918,  919,  920,  921,  922,  923,  924,  925,  926,  927,  928,  929,  930,
    931,  932,  933,  934,  935,  936,  937,  938,  939,  940,  941,  942,  943,  944,  945,  946,  947,  948,  949,
    950,  951,  952,  953,  954,  955,  956,  957,  958,  959,  960,  961,  962,  963,  964,  965,  966,  967,  968,
    969,  970,  971,  972,  973,  974,  975,  976,  977,  978,  979,  980,  981,  982,  983,  984,  985,  986,  987,
    988,  989,  990,  991,  992,  993,  994,  995,  996,  997,  998,  999,  1000, 1001, 1002, 1003, 1004, 1005, 1006,
    1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025,
    1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044,
    1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
    1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082,
    1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101,
    1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120,
    1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139,
    1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158,
    1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177,
    1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196,
    1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215,
    1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234,
    1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253,
    1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272,
    1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291,
    1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310,
    1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329,
    1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348,
    1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367,
    1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386,
    1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,
    1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424,
    1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443,
    1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462,
    1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481,
    1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500,
    1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519,
    1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538,
    1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557,
    1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576,
    1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595,
    1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614,
    1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633,
    1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652,
    1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671,
    1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690,
    1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709,
    1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728,
    1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747,
    1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766,
    1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785,
    1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804,
    1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823,
    1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842,
    1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861,
    1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880,
    1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899,
    1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918,
    1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937,
    1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956,
    1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975,
    1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
    2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032,
    2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051,
    2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070,
    2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089,
    2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108,
    2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127,
    2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146,
    2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165,
    2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184,
    2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203,
    2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222,
    2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241,
    2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260,
    2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279,
    2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298,
    2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317,
    2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336,
    2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355,
    2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374,
    2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393,
    2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412,
    2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431,
    2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450,
    2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469,
    2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488,
    2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507,
    2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526,
    2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545,
    2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564,
    2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583,
    2584, 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602,
    2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621,
    2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640,
    2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659,
    2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678,
    2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697,
    2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716,
    2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735,
    2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754,
    2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773,
    2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792,
    2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811,
    2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830,
    2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849,
    2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868,
    2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887,
    2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906,
    2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925,
    2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944,
    2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963,
    2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982,
    2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001,
    3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020,
    3021, 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039,
    3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058,
    3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077,
    3078, 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096,
    3097, 3098, 3099, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, 3114, 3115,
    3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134,
    3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153,
    3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172,
    3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191,
    3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210,
    3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229,
    3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248,
    3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267,
    3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286,
    3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305,
    3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324,
    3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343,
    3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362,
    3363, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381,
    3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400,
    3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419,
    3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438,
    3439, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457,
    3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, 3475, 3476,
    3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3495,
    3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514,
    3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533,
    3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552,
    3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571,
    3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590,
    3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609,
    3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628,
    3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647,
    3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666,
    3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 3684, 3685,
    3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704,
    3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723,
    3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742,
    3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761,
    3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780,
    3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799,
    3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818,
    3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837,
    3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856,
    3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875,
    3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894,
    3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913,
    3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932,
    3933, 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951,
    3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970,
    3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989,
    3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008,
    4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027,
    4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046,
    4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065,
    4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084,
    4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095};
#else
#error Unsupported VECTOR_SIZE!
#endif

} // namespace duckdb







#include <cmath>

using namespace std;

namespace duckdb {

const SQLType SQLType::SQLNULL = SQLType(SQLTypeId::SQLNULL);
const SQLType SQLType::BOOLEAN = SQLType(SQLTypeId::BOOLEAN);
const SQLType SQLType::TINYINT = SQLType(SQLTypeId::TINYINT);
const SQLType SQLType::SMALLINT = SQLType(SQLTypeId::SMALLINT);
const SQLType SQLType::INTEGER = SQLType(SQLTypeId::INTEGER);
const SQLType SQLType::BIGINT = SQLType(SQLTypeId::BIGINT);
const SQLType SQLType::FLOAT = SQLType(SQLTypeId::FLOAT);
const SQLType SQLType::DOUBLE = SQLType(SQLTypeId::DOUBLE);
const SQLType SQLType::DATE = SQLType(SQLTypeId::DATE);
const SQLType SQLType::TIMESTAMP = SQLType(SQLTypeId::TIMESTAMP);
const SQLType SQLType::TIME = SQLType(SQLTypeId::TIME);

const SQLType SQLType::VARCHAR = SQLType(SQLTypeId::VARCHAR);

// TODO these are incomplete and should maybe not exist as such
const SQLType SQLType::STRUCT = SQLType(SQLTypeId::STRUCT);
const SQLType SQLType::LIST = SQLType(SQLTypeId::LIST);

const SQLType SQLType::ANY = SQLType(SQLTypeId::ANY);

const vector<SQLType> SQLType::NUMERIC = {
    SQLType::TINYINT, SQLType::SMALLINT, SQLType::INTEGER,           SQLType::BIGINT,
    SQLType::FLOAT,   SQLType::DOUBLE,   SQLType(SQLTypeId::DECIMAL)};

const vector<SQLType> SQLType::INTEGRAL = {SQLType::TINYINT, SQLType::SMALLINT, SQLType::INTEGER, SQLType::BIGINT};

const vector<SQLType> SQLType::ALL_TYPES = {
    SQLType::BOOLEAN, SQLType::TINYINT,   SQLType::SMALLINT, SQLType::INTEGER, SQLType::BIGINT,
    SQLType::DATE,    SQLType::TIMESTAMP, SQLType::DOUBLE,   SQLType::FLOAT,   SQLType(SQLTypeId::DECIMAL),
    SQLType::VARCHAR};
// TODO add LIST/STRUCT here

const TypeId ROW_TYPE = TypeId::INT64;

string TypeIdToString(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
		return "BOOL";
	case TypeId::INT8:
		return "INT8";
	case TypeId::INT16:
		return "INT16";
	case TypeId::INT32:
		return "INT32";
	case TypeId::INT64:
		return "INT64";
	case TypeId::HASH:
		return "HASH";
	case TypeId::POINTER:
		return "POINTER";
	case TypeId::FLOAT:
		return "FLOAT";
	case TypeId::DOUBLE:
		return "DOUBLE";
	case TypeId::VARCHAR:
		return "VARCHAR";
	case TypeId::VARBINARY:
		return "VARBINARY";
	case TypeId::STRUCT:
		return "STRUCT<?>";
	case TypeId::LIST:
		return "LIST<?>";
	default:
		throw ConversionException("Invalid TypeId %d", type);
	}
}

idx_t GetTypeIdSize(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
		return sizeof(bool);
	case TypeId::INT8:
		return sizeof(int8_t);
	case TypeId::INT16:
		return sizeof(int16_t);
	case TypeId::INT32:
		return sizeof(int32_t);
	case TypeId::INT64:
		return sizeof(int64_t);
	case TypeId::FLOAT:
		return sizeof(float);
	case TypeId::DOUBLE:
		return sizeof(double);
	case TypeId::HASH:
		return sizeof(hash_t);
	case TypeId::POINTER:
		return sizeof(uintptr_t);
	case TypeId::VARCHAR:
		return sizeof(string_t);
	case TypeId::STRUCT:
		return 0; // no own payload
	case TypeId::LIST:
		return 16; // offset + len
	case TypeId::VARBINARY:
		return sizeof(blob_t);
	default:
		throw ConversionException("Invalid TypeId %d", type);
	}
}

SQLType SQLTypeFromInternalType(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
		return SQLType(SQLTypeId::BOOLEAN);
	case TypeId::INT8:
		return SQLType::TINYINT;
	case TypeId::INT16:
		return SQLType::SMALLINT;
	case TypeId::INT32:
		return SQLType::INTEGER;
	case TypeId::INT64:
		return SQLType::BIGINT;
	case TypeId::FLOAT:
		return SQLType::FLOAT;
	case TypeId::DOUBLE:
		return SQLType::DOUBLE;
	case TypeId::VARCHAR:
		return SQLType::VARCHAR;
	case TypeId::VARBINARY:
		return SQLType(SQLTypeId::VARBINARY);
	case TypeId::STRUCT:
		return SQLType(SQLTypeId::STRUCT); // TODO we do not know the child types here
	case TypeId::LIST:
		return SQLType(SQLTypeId::LIST);
	default:
		throw ConversionException("Invalid TypeId %d", type);
	}
}

bool TypeIsConstantSize(TypeId type) {
	return (type >= TypeId::BOOL && type <= TypeId::DOUBLE) ||
	       (type >= TypeId::FIXED_SIZE_BINARY && type <= TypeId::DECIMAL) || type == TypeId::HASH ||
	       type == TypeId::POINTER;
}
bool TypeIsIntegral(TypeId type) {
	return (type >= TypeId::UINT8 && type <= TypeId::INT64) || type == TypeId::HASH || type == TypeId::POINTER;
}
bool TypeIsNumeric(TypeId type) {
	return type >= TypeId::UINT8 && type <= TypeId::DOUBLE;
}
bool TypeIsInteger(TypeId type) {
	return type >= TypeId::UINT8 && type <= TypeId::INT64;
}

void SQLType::Serialize(Serializer &serializer) {
	serializer.Write(id);
	serializer.Write(width);
	serializer.Write(scale);
}

SQLType SQLType::Deserialize(Deserializer &source) {
	auto id = source.Read<SQLTypeId>();
	auto width = source.Read<uint16_t>();
	auto scale = source.Read<uint8_t>();
	return SQLType(id, width, scale);
}

string SQLTypeIdToString(SQLTypeId id) {
	switch (id) {
	case SQLTypeId::BOOLEAN:
		return "BOOLEAN";
	case SQLTypeId::TINYINT:
		return "TINYINT";
	case SQLTypeId::SMALLINT:
		return "SMALLINT";
	case SQLTypeId::INTEGER:
		return "INTEGER";
	case SQLTypeId::BIGINT:
		return "BIGINT";
	case SQLTypeId::DATE:
		return "DATE";
	case SQLTypeId::TIME:
		return "TIME";
	case SQLTypeId::TIMESTAMP:
		return "TIMESTAMP";
	case SQLTypeId::FLOAT:
		return "FLOAT";
	case SQLTypeId::DOUBLE:
		return "DOUBLE";
	case SQLTypeId::DECIMAL:
		return "DECIMAL";
	case SQLTypeId::VARCHAR:
		return "VARCHAR";
	case SQLTypeId::VARBINARY:
		return "VARBINARY";
	case SQLTypeId::CHAR:
		return "CHAR";
	case SQLTypeId::SQLNULL:
		return "NULL";
	case SQLTypeId::ANY:
		return "ANY";
	case SQLTypeId::STRUCT:
		return "STRUCT<?>";
	case SQLTypeId::LIST:
		return "LIST<?>";
	default:
		return "INVALID";
	}
}

string SQLTypeToString(SQLType type) {
	// FIXME: display width/scale
	switch (type.id) {
	case SQLTypeId::STRUCT: {
		string ret = "STRUCT<";
		for (size_t i = 0; i < type.child_type.size(); i++) {
			ret += type.child_type[i].first + ": " + SQLTypeToString(type.child_type[i].second);
			if (i < type.child_type.size() - 1) {
				ret += ", ";
			}
		}
		ret += ">";
		return ret;
	}
	case SQLTypeId::LIST: {
		if (type.child_type.size() == 0) {
			return "LIST<?>";
		}
		if (type.child_type.size() != 1) {
			throw Exception("List needs a single child element");
		}
		return "LIST<" + SQLTypeToString(type.child_type[0].second) + ">";
	}
	default:
		return SQLTypeIdToString(type.id);
	}
}

SQLType TransformStringToSQLType(string str) {
	auto lower_str = StringUtil::Lower(str);
	// Transform column type
	if (lower_str == "int" || lower_str == "int4" || lower_str == "signed" || lower_str == "integer" ||
	    lower_str == "integral" || lower_str == "int32") {
		return SQLType::INTEGER;
	} else if (lower_str == "varchar" || lower_str == "bpchar" || lower_str == "text" || lower_str == "string" ||
	           lower_str == "char") {
		return SQLType::VARCHAR;
	} else if (lower_str == "int8" || lower_str == "bigint" || lower_str == "int64" || lower_str == "long") {
		return SQLType::BIGINT;
	} else if (lower_str == "int2" || lower_str == "smallint" || lower_str == "short" || lower_str == "int16") {
		return SQLType::SMALLINT;
	} else if (lower_str == "timestamp" || lower_str == "datetime") {
		return SQLType::TIMESTAMP;
	} else if (lower_str == "bool" || lower_str == "boolean" || lower_str == "logical") {
		return SQLType(SQLTypeId::BOOLEAN);
	} else if (lower_str == "real" || lower_str == "float4" || lower_str == "float") {
		return SQLType::FLOAT;
	} else if (lower_str == "double" || lower_str == "numeric" || lower_str == "float8") {
		return SQLType::DOUBLE;
	} else if (lower_str == "tinyint" || lower_str == "int1") {
		return SQLType::TINYINT;
	} else if (lower_str == "varbinary") {
		return SQLType(SQLTypeId::VARBINARY);
	} else if (lower_str == "date") {
		return SQLType::DATE;
	} else if (lower_str == "time") {
		return SQLType::TIME;
	} else {
		throw NotImplementedException("DataType %s not supported yet...\n", str.c_str());
	}
}

bool SQLType::IsIntegral() const {
	switch (id) {
	case SQLTypeId::TINYINT:
	case SQLTypeId::SMALLINT:
	case SQLTypeId::INTEGER:
	case SQLTypeId::BIGINT:
		return true;
	default:
		return false;
	}
}

bool SQLType::IsNumeric() const {
	switch (id) {
	case SQLTypeId::TINYINT:
	case SQLTypeId::SMALLINT:
	case SQLTypeId::INTEGER:
	case SQLTypeId::BIGINT:
	case SQLTypeId::FLOAT:
	case SQLTypeId::DOUBLE:
	case SQLTypeId::DECIMAL:
		return true;
	default:
		return false;
	}
}

TypeId GetInternalType(SQLType type) {
	switch (type.id) {
	case SQLTypeId::BOOLEAN:
		return TypeId::BOOL;
	case SQLTypeId::TINYINT:
		return TypeId::INT8;
	case SQLTypeId::SMALLINT:
		return TypeId::INT16;
	case SQLTypeId::SQLNULL:
	case SQLTypeId::DATE:
	case SQLTypeId::TIME:
	case SQLTypeId::INTEGER:
		return TypeId::INT32;
	case SQLTypeId::BIGINT:
	case SQLTypeId::TIMESTAMP:
		return TypeId::INT64;
	case SQLTypeId::FLOAT:
		return TypeId::FLOAT;
	case SQLTypeId::DOUBLE:
		return TypeId::DOUBLE;
	case SQLTypeId::DECIMAL:
		// FIXME: for now
		return TypeId::DOUBLE;
	case SQLTypeId::VARCHAR:
	case SQLTypeId::CHAR:
		return TypeId::VARCHAR;
	case SQLTypeId::VARBINARY:
		return TypeId::VARBINARY;
	case SQLTypeId::STRUCT:
		return TypeId::STRUCT;
	case SQLTypeId::LIST:
		return TypeId::LIST;
	case SQLTypeId::ANY:
		return TypeId::INVALID;
	default:
		throw ConversionException("Invalid SQLType %s", SQLTypeToString(type).c_str());
	}
}

SQLType MaxSQLType(SQLType left, SQLType right) {
	if (left.id < right.id) {
		return right;
	} else if (right.id < left.id) {
		return left;
	} else if (left.width > right.width) {
		return left;
	} else {
		return right;
	}
}

bool ApproxEqual(float ldecimal, float rdecimal) {
	float epsilon = fabs(rdecimal) * 0.01;
	return fabs(ldecimal - rdecimal) <= epsilon;
}

bool ApproxEqual(double ldecimal, double rdecimal) {
	double epsilon = fabs(rdecimal) * 0.01;
	return fabs(ldecimal - rdecimal) <= epsilon;
}

} // namespace duckdb




using namespace duckdb;
using namespace std;

//===--------------------------------------------------------------------===//
// Comparison Operations
//===--------------------------------------------------------------------===//
template <class OP> static bool templated_boolean_operation(const Value &left, const Value &right) {
	if (left.type != right.type) {
		TypeId left_cast = TypeId::INVALID, right_cast = TypeId::INVALID;
		if (TypeIsNumeric(left.type) && TypeIsNumeric(right.type)) {
			if (left.type < right.type) {
				left_cast = right.type;
			} else {
				right_cast = left.type;
			}
		} else if (left.type == TypeId::BOOL) {
			right_cast = TypeId::BOOL;
		} else if (right.type == TypeId::BOOL) {
			left_cast = TypeId::BOOL;
		}
		if (left_cast != TypeId::INVALID) {
			return templated_boolean_operation<OP>(left.CastAs(left_cast), right);
		} else if (right_cast != TypeId::INVALID) {
			return templated_boolean_operation<OP>(left, right.CastAs(right_cast));
		}
		return false;
	}
	switch (left.type) {
	case TypeId::BOOL:
		return OP::Operation(left.value_.boolean, right.value_.boolean);
	case TypeId::INT8:
		return OP::Operation(left.value_.tinyint, right.value_.tinyint);
	case TypeId::INT16:
		return OP::Operation(left.value_.smallint, right.value_.smallint);
	case TypeId::INT32:
		return OP::Operation(left.value_.integer, right.value_.integer);
	case TypeId::INT64:
		return OP::Operation(left.value_.bigint, right.value_.bigint);
	case TypeId::POINTER:
		return OP::Operation(left.value_.pointer, right.value_.pointer);
	case TypeId::HASH:
		return OP::Operation(left.value_.hash, right.value_.hash);
	case TypeId::FLOAT:
		return OP::Operation(left.value_.float_, right.value_.float_);
	case TypeId::DOUBLE:
		return OP::Operation(left.value_.double_, right.value_.double_);
	case TypeId::VARCHAR:
		return OP::Operation(left.str_value, right.str_value);
	case TypeId::STRUCT: {
		for (idx_t i = 0; i < left.struct_value.size(); i++) {
			if (i >= right.struct_value.size() || left.struct_value[i].first != right.struct_value[i].first ||
			    left.struct_value[i].second != left.struct_value[i].second) {
				return false;
			}
		}
		return true;
	}
	case TypeId::LIST: {
		return left.list_value == right.list_value;
	}
	default:
		throw NotImplementedException("Unimplemented type");
	}
}

bool ValueOperations::Equals(const Value &left, const Value &right) {
	if (left.is_null && right.is_null) {
		return true;
	}
	if (left.is_null != right.is_null) {
		return false;
	}
	return templated_boolean_operation<duckdb::Equals>(left, right);
}

bool ValueOperations::NotEquals(const Value &left, const Value &right) {
	return !ValueOperations::Equals(left, right);
}

bool ValueOperations::GreaterThan(const Value &left, const Value &right) {
	if (left.is_null && right.is_null) {
		return false;
	} else if (right.is_null) {
		return true;
	} else if (left.is_null) {
		return false;
	}
	return templated_boolean_operation<duckdb::GreaterThan>(left, right);
}

bool ValueOperations::GreaterThanEquals(const Value &left, const Value &right) {
	if (left.is_null && right.is_null) {
		return true;
	} else if (right.is_null) {
		return true;
	} else if (left.is_null) {
		return false;
	}
	return templated_boolean_operation<duckdb::GreaterThanEquals>(left, right);
}

bool ValueOperations::LessThan(const Value &left, const Value &right) {
	return ValueOperations::GreaterThan(right, left);
}

bool ValueOperations::LessThanEquals(const Value &left, const Value &right) {
	return ValueOperations::GreaterThanEquals(right, left);
}





using namespace duckdb;
using namespace std;

hash_t ValueOperations::Hash(const Value &op) {
	if (op.is_null) {
		return 0;
	}
	switch (op.type) {
	case TypeId::BOOL:
		return duckdb::Hash(op.value_.boolean);
	case TypeId::INT8:
		return duckdb::Hash(op.value_.tinyint);
	case TypeId::INT16:
		return duckdb::Hash(op.value_.smallint);
	case TypeId::INT32:
		return duckdb::Hash(op.value_.integer);
	case TypeId::INT64:
		return duckdb::Hash(op.value_.bigint);
	case TypeId::FLOAT:
		return duckdb::Hash(op.value_.float_);
	case TypeId::DOUBLE:
		return duckdb::Hash(op.value_.double_);
	case TypeId::POINTER:
		return duckdb::Hash(op.value_.pointer);
	case TypeId::VARCHAR:
		return duckdb::Hash(op.str_value.c_str());
	default:
		throw NotImplementedException("Unimplemented type for hash");
	}
}






using namespace duckdb;
using namespace std;

template <class OP, bool IGNORE_NULL> static Value templated_binary_operation(const Value &left, const Value &right) {
	Value result;
	if (left.is_null || right.is_null) {
		if (IGNORE_NULL) {
			if (!right.is_null) {
				result = right;
			} else {
				result = left;
			}
		} else {
			result.type = max(left.type, right.type);
			result.is_null = true;
		}
		return result;
	}
	result.is_null = false;
	if (left.type != right.type) {
		if (TypeIsIntegral(left.type) && TypeIsIntegral(right.type) &&
		    (left.type < TypeId::INT64 || right.type < TypeId::INT64)) {
			// upcast integer types if necessary
			Value left_cast = left.CastAs(TypeId::INT64);
			Value right_cast = right.CastAs(TypeId::INT64);
			result = templated_binary_operation<OP, IGNORE_NULL>(left_cast, right_cast);
			if (result.is_null) {
				result.type = max(left.type, right.type);
			} else {
				auto type = max(MinimalType(result.GetValue<int64_t>()), max(left.type, right.type));
				result = result.CastAs(type);
			}
			return result;
		}
		if (TypeIsIntegral(left.type) && TypeIsNumeric(right.type)) {
			Value left_cast = left.CastAs(right.type);
			return templated_binary_operation<OP, IGNORE_NULL>(left_cast, right);
		}
		if (TypeIsNumeric(left.type) && TypeIsIntegral(right.type)) {
			Value right_cast = right.CastAs(left.type);
			return templated_binary_operation<OP, IGNORE_NULL>(left, right_cast);
		}
		throw TypeMismatchException(left.type, right.type, "Cannot perform binary operation on these two types");
	}
	result.type = left.type;
	switch (left.type) {
	case TypeId::INT8:
		result.value_.tinyint =
		    OP::template Operation<int8_t, int8_t, int8_t>(left.value_.tinyint, right.value_.tinyint);
		break;
	case TypeId::INT16:
		result.value_.smallint =
		    OP::template Operation<int16_t, int16_t, int16_t>(left.value_.smallint, right.value_.smallint);
		break;
	case TypeId::INT32:
		result.value_.integer =
		    OP::template Operation<int32_t, int32_t, int32_t>(left.value_.integer, right.value_.integer);
		break;
	case TypeId::INT64:
		result.value_.bigint =
		    OP::template Operation<int64_t, int64_t, int64_t>(left.value_.bigint, right.value_.bigint);
		break;
	case TypeId::FLOAT:
		result.value_.float_ = OP::template Operation<float, float, float>(left.value_.float_, right.value_.float_);
		break;
	case TypeId::DOUBLE:
		result.value_.double_ =
		    OP::template Operation<double, double, double>(left.value_.double_, right.value_.double_);
		break;
	case TypeId::POINTER:
		result.value_.pointer =
		    OP::template Operation<uint64_t, uint64_t, uint64_t>(left.value_.pointer, right.value_.pointer);
		break;
	default:
		throw NotImplementedException("Unimplemented type");
	}
	return result;
}

//===--------------------------------------------------------------------===//
// Numeric Operations
//===--------------------------------------------------------------------===//
Value ValueOperations::Add(const Value &left, const Value &right) {
	return templated_binary_operation<duckdb::AddOperator, false>(left, right);
}

Value ValueOperations::Subtract(const Value &left, const Value &right) {
	return templated_binary_operation<duckdb::SubtractOperator, false>(left, right);
}

Value ValueOperations::Multiply(const Value &left, const Value &right) {
	return templated_binary_operation<duckdb::MultiplyOperator, false>(left, right);
}

Value ValueOperations::Modulo(const Value &left, const Value &right) {
	if (!TypeIsIntegral(left.type) || !TypeIsIntegral(right.type)) {
		throw InvalidTypeException(left.type, "Arguments to modulo must be integral");
	}
	if (left.type != right.type) {
		if (left.type < right.type) {
			return Modulo(left.CastAs(right.type), right);
		} else {
			return Modulo(left, right.CastAs(left.type));
		}
	}
	if (left.is_null || right.is_null) {
		return Value(left.type);
	}
	Value result;
	result.is_null = false;
	result.type = left.type;
	switch (left.type) {
	case TypeId::INT8:
		return Value::TINYINT(left.value_.tinyint % right.value_.tinyint);
		break;
	case TypeId::INT16:
		return Value::SMALLINT(left.value_.smallint % right.value_.smallint);
		break;
	case TypeId::INT32:
		return Value::INTEGER(left.value_.integer % right.value_.integer);
		break;
	case TypeId::INT64:
		result.value_.bigint = left.value_.bigint % right.value_.bigint;
		break;
	default:
		throw NotImplementedException("Unimplemented type for modulo");
	}
	return result;
}

Value ValueOperations::Divide(const Value &left, const Value &right) {
	Value zero = Value::Numeric(right.type, 0);
	if (right == 0) {
		// special case: divide by zero
		Value result;
		result.type = max(left.type, right.type);
		result.is_null = true;
		return result;
	} else {
		return templated_binary_operation<duckdb::DivideOperator, false>(left, right);
	}
}

// Value ValueOperations::Min(const Value &left, const Value &right) {
// 	return templated_binary_operation<duckdb::Min, true>(left, right);
// }

// Value ValueOperations::Max(const Value &left, const Value &right) {
// 	return templated_binary_operation<duckdb::Max, true>(left, right);
// }
//===--------------------------------------------------------------------===//
// boolean_operators.cpp
// Description: This file contains the implementation of the boolean
// operations AND OR !
//===--------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/operator/boolean_operators.hpp
//
//
//===----------------------------------------------------------------------===//



namespace duckdb {

/*
SQL AND Rules:

TRUE  AND TRUE   = TRUE
TRUE  AND FALSE  = FALSE
TRUE  AND NULL   = NULL
FALSE AND TRUE   = FALSE
FALSE AND FALSE  = FALSE
FALSE AND NULL   = FALSE
NULL  AND TRUE   = NULL
NULL  AND FALSE  = FALSE
NULL  AND NULL   = NULL

Basically:
- Only true if both are true
- False if either is false (regardless of NULLs)
- NULL otherwise
*/
struct And {
	static inline bool Operation(bool left, bool right) {
		return left && right;
	}
};

struct AndMask {
	static inline bool Operation(bool left, bool right, bool left_null, bool right_null) {
		return (left_null && (right_null || right)) || (right_null && left);
	}
};

/*
SQL OR Rules:

OR
TRUE  OR TRUE  = TRUE
TRUE  OR FALSE = TRUE
TRUE  OR NULL  = TRUE
FALSE OR TRUE  = TRUE
FALSE OR FALSE = FALSE
FALSE OR NULL  = NULL
NULL  OR TRUE  = TRUE
NULL  OR FALSE = NULL
NULL  OR NULL  = NULL

Basically:
- Only false if both are false
- True if either is true (regardless of NULLs)
- NULL otherwise
*/
struct Or {
	static inline bool Operation(bool left, bool right) {
		return left || right;
	}
};

struct OrMask {
	static inline bool Operation(bool left, bool right, bool left_null, bool right_null) {
		return (left_null && (right_null || !right)) || (right_null && !left);
	}
};
} // namespace duckdb






using namespace duckdb;
using namespace std;

//===--------------------------------------------------------------------===//
// AND/OR
//===--------------------------------------------------------------------===//
template <class OP, class NULLOP>
static void templated_boolean_nullmask(Vector &left, Vector &right, Vector &result, idx_t count) {
	assert(left.type == TypeId::BOOL && right.type == TypeId::BOOL && result.type == TypeId::BOOL);

	if (left.vector_type == VectorType::CONSTANT_VECTOR && right.vector_type == VectorType::CONSTANT_VECTOR) {
		// operation on two constants, result is constant vector
		result.vector_type = VectorType::CONSTANT_VECTOR;
		auto ldata = ConstantVector::GetData<bool>(left);
		auto rdata = ConstantVector::GetData<bool>(right);
		auto result_data = ConstantVector::GetData<bool>(result);
		*result_data = OP::Operation(*ldata, *rdata);
		ConstantVector::SetNull(
		    result, NULLOP::Operation(*ldata, *rdata, ConstantVector::IsNull(left), ConstantVector::IsNull(right)));
	} else {
		// perform generic loop
		VectorData ldata, rdata;
		left.Orrify(count, ldata);
		right.Orrify(count, rdata);

		result.vector_type = VectorType::FLAT_VECTOR;
		auto left_data = (bool *)ldata.data;
		auto right_data = (bool *)rdata.data;
		auto result_data = FlatVector::GetData<bool>(result);
		auto &result_mask = FlatVector::Nullmask(result);
		if (ldata.nullmask->any() || rdata.nullmask->any()) {
			for (idx_t i = 0; i < count; i++) {
				auto lidx = ldata.sel->get_index(i);
				auto ridx = rdata.sel->get_index(i);
				result_data[i] = OP::Operation(left_data[lidx], right_data[ridx]);
				result_mask[i] = NULLOP::Operation(left_data[lidx], right_data[ridx], (*ldata.nullmask)[lidx],
				                                   (*rdata.nullmask)[ridx]);
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				auto lidx = ldata.sel->get_index(i);
				auto ridx = rdata.sel->get_index(i);
				result_data[i] = OP::Operation(left_data[lidx], right_data[ridx]);
			}
		}
	}
}

void VectorOperations::And(Vector &left, Vector &right, Vector &result, idx_t count) {
	templated_boolean_nullmask<duckdb::And, duckdb::AndMask>(left, right, result, count);
}

void VectorOperations::Or(Vector &left, Vector &right, Vector &result, idx_t count) {
	templated_boolean_nullmask<duckdb::Or, duckdb::OrMask>(left, right, result, count);
}

struct NotOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return !left;
	}
};

void VectorOperations::Not(Vector &input, Vector &result, idx_t count) {
	assert(input.type == TypeId::BOOL && result.type == TypeId::BOOL);
	UnaryExecutor::Execute<bool, bool, NotOperator>(input, result, count);
}
//===--------------------------------------------------------------------===//
// comparison_operators.cpp
// Description: This file contains the implementation of the comparison
// operations == != >= <= > <
//===--------------------------------------------------------------------===//






using namespace duckdb;
using namespace std;

struct ComparisonExecutor {
private:
	template <class T, class OP, bool IGNORE_NULL = false>
	static inline void TemplatedExecute(Vector &left, Vector &right, Vector &result, idx_t count) {
		BinaryExecutor::Execute<T, T, bool, OP, IGNORE_NULL>(left, right, result, count);
	}

public:
	template <class OP> static inline void Execute(Vector &left, Vector &right, Vector &result, idx_t count) {
		assert(left.type == right.type && result.type == TypeId::BOOL);
		// the inplace loops take the result as the last parameter
		switch (left.type) {
		case TypeId::BOOL:
		case TypeId::INT8:
			TemplatedExecute<int8_t, OP>(left, right, result, count);
			break;
		case TypeId::INT16:
			TemplatedExecute<int16_t, OP>(left, right, result, count);
			break;
		case TypeId::INT32:
			TemplatedExecute<int32_t, OP>(left, right, result, count);
			break;
		case TypeId::INT64:
			TemplatedExecute<int64_t, OP>(left, right, result, count);
			break;
		case TypeId::POINTER:
			TemplatedExecute<uintptr_t, OP>(left, right, result, count);
			break;
		case TypeId::FLOAT:
			TemplatedExecute<float, OP>(left, right, result, count);
			break;
		case TypeId::DOUBLE:
			TemplatedExecute<double, OP>(left, right, result, count);
			break;
		case TypeId::VARCHAR:
			TemplatedExecute<string_t, OP, true>(left, right, result, count);
			break;
		default:
			throw InvalidTypeException(left.type, "Invalid type for comparison");
		}
	}
};

void VectorOperations::Equals(Vector &left, Vector &right, Vector &result, idx_t count) {
	ComparisonExecutor::Execute<duckdb::Equals>(left, right, result, count);
}

void VectorOperations::NotEquals(Vector &left, Vector &right, Vector &result, idx_t count) {
	ComparisonExecutor::Execute<duckdb::NotEquals>(left, right, result, count);
}

void VectorOperations::GreaterThanEquals(Vector &left, Vector &right, Vector &result, idx_t count) {
	ComparisonExecutor::Execute<duckdb::GreaterThanEquals>(left, right, result, count);
}

void VectorOperations::LessThanEquals(Vector &left, Vector &right, Vector &result, idx_t count) {
	ComparisonExecutor::Execute<duckdb::LessThanEquals>(left, right, result, count);
}

void VectorOperations::GreaterThan(Vector &left, Vector &right, Vector &result, idx_t count) {
	ComparisonExecutor::Execute<duckdb::GreaterThan>(left, right, result, count);
}

void VectorOperations::LessThan(Vector &left, Vector &right, Vector &result, idx_t count) {
	ComparisonExecutor::Execute<duckdb::LessThan>(left, right, result, count);
}
//===--------------------------------------------------------------------===//
// gather.cpp
// Description: This file contains the implementation of the gather operators
//===--------------------------------------------------------------------===//


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/operator/constant_operators.hpp
//
//
//===----------------------------------------------------------------------===//



namespace duckdb {

struct PickLeft {
	template <class T> static inline T Operation(T left, T right) {
		return left;
	}
};

struct PickRight {
	template <class T> static inline T Operation(T left, T right) {
		return right;
	}
};

struct NOP {
	template <class T> static inline T Operation(T left) {
		return left;
	}
};

struct ConstantZero {
	template <class T> static inline T Operation(T left, T right) {
		return 0;
	}
};

struct ConstantOne {
	template <class T> static inline T Operation(T left, T right) {
		return 1;
	}
};

struct AddOne {
	template <class T> static inline T Operation(T left, T right) {
		return right + 1;
	}
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

template <class T> static void templated_gather_loop(Vector &source, Vector &dest, idx_t count) {
	auto addresses = FlatVector::GetData<uintptr_t>(source);
	auto data = FlatVector::GetData<T>(dest);
	auto &nullmask = FlatVector::Nullmask(dest);

	for (idx_t i = 0; i < count; i++) {
		auto dataptr = (T *)addresses[i];
		if (IsNullValue<T>(*dataptr)) {
			nullmask[i] = true;
		} else {
			data[i] = *dataptr;
		}
		addresses[i] += sizeof(T);
	}
}

void VectorOperations::Gather::Set(Vector &source, Vector &dest, idx_t count) {
	assert(source.vector_type == VectorType::FLAT_VECTOR);
	assert(source.type == TypeId::POINTER); // "Cannot gather from non-pointer type!"

	dest.vector_type = VectorType::FLAT_VECTOR;
	switch (dest.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		templated_gather_loop<int8_t>(source, dest, count);
		break;
	case TypeId::INT16:
		templated_gather_loop<int16_t>(source, dest, count);
		break;
	case TypeId::INT32:
		templated_gather_loop<int32_t>(source, dest, count);
		break;
	case TypeId::INT64:
		templated_gather_loop<int64_t>(source, dest, count);
		break;
	case TypeId::FLOAT:
		templated_gather_loop<float>(source, dest, count);
		break;
	case TypeId::DOUBLE:
		templated_gather_loop<double>(source, dest, count);
		break;
	case TypeId::POINTER:
		templated_gather_loop<uintptr_t>(source, dest, count);
		break;
	case TypeId::VARCHAR:
		templated_gather_loop<string_t>(source, dest, count);
		break;
	default:
		throw NotImplementedException("Unimplemented type for gather");
	}
}
//===--------------------------------------------------------------------===//
// generators.cpp
// Description: This file contains the implementation of different generators
//===--------------------------------------------------------------------===//




using namespace duckdb;
using namespace std;

template <class T> void templated_generate_sequence(Vector &result, idx_t count, int64_t start, int64_t increment) {
	assert(TypeIsNumeric(result.type));
	if (start > numeric_limits<T>::max() || increment > numeric_limits<T>::max()) {
		throw Exception("Sequence start or increment out of type range");
	}
	result.vector_type = VectorType::FLAT_VECTOR;
	auto result_data = FlatVector::GetData<T>(result);
	auto value = (T)start;
	for (idx_t i = 0; i < count; i++) {
		result_data[i] = value;
		value += increment;
	}
}

void VectorOperations::GenerateSequence(Vector &result, idx_t count, int64_t start, int64_t increment) {
	if (!TypeIsNumeric(result.type)) {
		throw InvalidTypeException(result.type, "Can only generate sequences for numeric values!");
	}
	switch (result.type) {
	case TypeId::INT8:
		templated_generate_sequence<int8_t>(result, count, start, increment);
		break;
	case TypeId::INT16:
		templated_generate_sequence<int16_t>(result, count, start, increment);
		break;
	case TypeId::INT32:
		templated_generate_sequence<int32_t>(result, count, start, increment);
		break;
	case TypeId::INT64:
		templated_generate_sequence<int64_t>(result, count, start, increment);
		break;
	case TypeId::FLOAT:
		templated_generate_sequence<float>(result, count, start, increment);
		break;
	case TypeId::DOUBLE:
		templated_generate_sequence<double>(result, count, start, increment);
		break;
	default:
		throw NotImplementedException("Unimplemented type for generate sequence");
	}
}

template <class T>
void templated_generate_sequence(Vector &result, idx_t count, const SelectionVector &sel, int64_t start,
                                 int64_t increment) {
	assert(TypeIsNumeric(result.type));
	if (start > numeric_limits<T>::max() || increment > numeric_limits<T>::max()) {
		throw Exception("Sequence start or increment out of type range");
	}
	result.vector_type = VectorType::FLAT_VECTOR;
	auto result_data = FlatVector::GetData<T>(result);
	auto value = (T)start;
	for (idx_t i = 0; i < count; i++) {
		auto idx = sel.get_index(i);
		result_data[idx] = value + increment * idx;
	}
}

void VectorOperations::GenerateSequence(Vector &result, idx_t count, const SelectionVector &sel, int64_t start,
                                        int64_t increment) {
	if (!TypeIsNumeric(result.type)) {
		throw InvalidTypeException(result.type, "Can only generate sequences for numeric values!");
	}
	switch (result.type) {
	case TypeId::INT8:
		templated_generate_sequence<int8_t>(result, count, sel, start, increment);
		break;
	case TypeId::INT16:
		templated_generate_sequence<int16_t>(result, count, sel, start, increment);
		break;
	case TypeId::INT32:
		templated_generate_sequence<int32_t>(result, count, sel, start, increment);
		break;
	case TypeId::INT64:
		templated_generate_sequence<int64_t>(result, count, sel, start, increment);
		break;
	case TypeId::FLOAT:
		templated_generate_sequence<float>(result, count, sel, start, increment);
		break;
	case TypeId::DOUBLE:
		templated_generate_sequence<double>(result, count, sel, start, increment);
		break;
	default:
		throw NotImplementedException("Unimplemented type for generate sequence");
	}
}
//===--------------------------------------------------------------------===//
// null_operators.cpp
// Description: This file contains the implementation of the
// IS NULL/NOT IS NULL operators
//===--------------------------------------------------------------------===//




using namespace duckdb;
using namespace std;

template <bool INVERSE> void is_null_loop(Vector &input, Vector &result, idx_t count) {
	assert(result.type == TypeId::BOOL);

	if (input.vector_type == VectorType::CONSTANT_VECTOR) {
		result.vector_type = VectorType::CONSTANT_VECTOR;
		auto result_data = ConstantVector::GetData<bool>(result);
		*result_data = INVERSE ? !ConstantVector::IsNull(input) : ConstantVector::IsNull(input);
	} else {
		VectorData data;
		input.Orrify(count, data);

		result.vector_type = VectorType::FLAT_VECTOR;
		auto result_data = FlatVector::GetData<bool>(result);
		auto &nullmask = *data.nullmask;
		for (idx_t i = 0; i < count; i++) {
			auto idx = data.sel->get_index(i);
			result_data[i] = INVERSE ? !nullmask[idx] : nullmask[idx];
		}
	}
}

void VectorOperations::IsNotNull(Vector &input, Vector &result, idx_t count) {
	is_null_loop<true>(input, result, count);
}

void VectorOperations::IsNull(Vector &input, Vector &result, idx_t count) {
	is_null_loop<false>(input, result, count);
}

bool VectorOperations::HasNotNull(Vector &input, idx_t count) {
	if (count == 0) {
		return false;
	}
	if (input.vector_type == VectorType::CONSTANT_VECTOR) {
		return !ConstantVector::IsNull(input);
	} else {
		VectorData data;
		input.Orrify(count, data);

		if (data.nullmask->none()) {
			return true;
		}
		for (idx_t i = 0; i < count; i++) {
			auto idx = data.sel->get_index(i);
			if (!(*data.nullmask)[idx]) {
				return true;
			}
		}
		return false;
	}
}

bool VectorOperations::HasNull(Vector &input, idx_t count) {
	if (count == 0) {
		return false;
	}
	if (input.vector_type == VectorType::CONSTANT_VECTOR) {
		return ConstantVector::IsNull(input);
	} else {
		VectorData data;
		input.Orrify(count, data);

		if (data.nullmask->none()) {
			return false;
		}
		for (idx_t i = 0; i < count; i++) {
			auto idx = data.sel->get_index(i);
			if ((*data.nullmask)[idx]) {
				return true;
			}
		}
		return false;
	}
}
//===--------------------------------------------------------------------===//
// numeric_inplace_operators.cpp
// Description: This file contains the implementation of numeric inplace ops
// += *= /= -= %=
//===--------------------------------------------------------------------===//



#include <algorithm>

using namespace duckdb;
using namespace std;

//===--------------------------------------------------------------------===//
// In-Place Addition
//===--------------------------------------------------------------------===//

void VectorOperations::AddInPlace(Vector &input, int64_t right, idx_t count) {
	assert(input.type == TypeId::POINTER);
	switch (input.vector_type) {
	case VectorType::CONSTANT_VECTOR: {
		assert(!ConstantVector::IsNull(input));
		auto data = ConstantVector::GetData<uintptr_t>(input);
		*data += right;
		break;
	}
	default: {
		assert(input.vector_type == VectorType::FLAT_VECTOR);
		auto data = FlatVector::GetData<uintptr_t>(input);
		for (idx_t i = 0; i < count; i++) {
			data[i] += right;
		}
		break;
	}
	}
}
//===--------------------------------------------------------------------===//
// cast_operators.cpp
// Description: This file contains the implementation of the different casts
//===--------------------------------------------------------------------===//






using namespace duckdb;
using namespace std;

template <class SRC, class OP> static void string_cast(Vector &source, Vector &result, idx_t count) {
	assert(result.type == TypeId::VARCHAR);
	UnaryExecutor::Execute<SRC, string_t, true>(source, result, count,
	                                            [&](SRC input) { return OP::template Operation<SRC>(input, result); });
}

static NotImplementedException UnimplementedCast(SQLType source_type, SQLType target_type) {
	return NotImplementedException("Unimplemented type for cast (%s -> %s)", SQLTypeToString(source_type).c_str(),
	                               SQLTypeToString(target_type).c_str());
}

// NULL cast only works if all values in source are NULL, otherwise an unimplemented cast exception is thrown
static void null_cast(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count) {
	if (VectorOperations::HasNotNull(source, count)) {
		throw UnimplementedCast(source_type, target_type);
	}
	if (source.vector_type == VectorType::CONSTANT_VECTOR) {
		result.vector_type = VectorType::CONSTANT_VECTOR;
		ConstantVector::SetNull(result, true);
	} else {
		result.vector_type = VectorType::FLAT_VECTOR;
		FlatVector::Nullmask(result).set();
	}
}

template <class SRC>
static void numeric_cast_switch(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count) {
	// now switch on the result type
	switch (target_type.id) {
	case SQLTypeId::BOOLEAN:
		assert(result.type == TypeId::BOOL);
		UnaryExecutor::Execute<SRC, bool, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::TINYINT:
		assert(result.type == TypeId::INT8);
		UnaryExecutor::Execute<SRC, int8_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::SMALLINT:
		assert(result.type == TypeId::INT16);
		UnaryExecutor::Execute<SRC, int16_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::INTEGER:
		assert(result.type == TypeId::INT32);
		UnaryExecutor::Execute<SRC, int32_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::BIGINT:
		assert(result.type == TypeId::INT64);
		UnaryExecutor::Execute<SRC, int64_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::FLOAT:
		assert(result.type == TypeId::FLOAT);
		UnaryExecutor::Execute<SRC, float, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::DECIMAL:
	case SQLTypeId::DOUBLE:
		assert(result.type == TypeId::DOUBLE);
		UnaryExecutor::Execute<SRC, double, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::VARCHAR: {
		string_cast<SRC, duckdb::StringCast>(source, result, count);
		break;
	}
	case SQLTypeId::LIST: {
		assert(result.type == TypeId::LIST);
		auto list_child = make_unique<ChunkCollection>();
		ListVector::SetEntry(result, move(list_child));
		null_cast(source, result, source_type, target_type, count);
		break;
	}
	default:
		null_cast(source, result, source_type, target_type, count);
		break;
	}
}

static void string_cast_switch(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count) {
	// now switch on the result type
	switch (target_type.id) {
	case SQLTypeId::BOOLEAN:
		assert(result.type == TypeId::BOOL);
		UnaryExecutor::Execute<string_t, bool, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::TINYINT:
		assert(result.type == TypeId::INT8);
		UnaryExecutor::Execute<string_t, int8_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::SMALLINT:
		assert(result.type == TypeId::INT16);
		UnaryExecutor::Execute<string_t, int16_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::INTEGER:
		assert(result.type == TypeId::INT32);
		UnaryExecutor::Execute<string_t, int32_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::BIGINT:
		assert(result.type == TypeId::INT64);
		UnaryExecutor::Execute<string_t, int64_t, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::FLOAT:
		assert(result.type == TypeId::FLOAT);
		UnaryExecutor::Execute<string_t, float, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::DECIMAL:
	case SQLTypeId::DOUBLE:
		assert(result.type == TypeId::DOUBLE);
		UnaryExecutor::Execute<string_t, double, duckdb::Cast, true>(source, result, count);
		break;
	case SQLTypeId::DATE:
		assert(result.type == TypeId::INT32);
		UnaryExecutor::Execute<string_t, date_t, duckdb::CastToDate, true>(source, result, count);
		break;
	case SQLTypeId::TIME:
		assert(result.type == TypeId::INT32);
		UnaryExecutor::Execute<string_t, dtime_t, duckdb::CastToTime, true>(source, result, count);
		break;
	case SQLTypeId::TIMESTAMP:
		assert(result.type == TypeId::INT64);
		UnaryExecutor::Execute<string_t, timestamp_t, duckdb::CastToTimestamp, true>(source, result, count);
		break;
	default:
		null_cast(source, result, source_type, target_type, count);
		break;
	}
}

static void date_cast_switch(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count) {
	// now switch on the result type
	switch (target_type.id) {
	case SQLTypeId::VARCHAR:
		// date to varchar
		string_cast<date_t, duckdb::CastFromDate>(source, result, count);
		break;
	case SQLTypeId::TIMESTAMP:
		// date to timestamp
		UnaryExecutor::Execute<date_t, timestamp_t, duckdb::CastDateToTimestamp, true>(source, result, count);
		break;
	default:
		null_cast(source, result, source_type, target_type, count);
		break;
	}
}

static void time_cast_switch(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count) {
	// now switch on the result type
	switch (target_type.id) {
	case SQLTypeId::VARCHAR:
		// time to varchar
		string_cast<dtime_t, duckdb::CastFromTime>(source, result, count);
		break;
	default:
		null_cast(source, result, source_type, target_type, count);
		break;
	}
}

static void timestamp_cast_switch(Vector &source, Vector &result, SQLType source_type, SQLType target_type,
                                  idx_t count) {
	// now switch on the result type
	switch (target_type.id) {
	case SQLTypeId::VARCHAR:
		// timestamp to varchar
		string_cast<timestamp_t, duckdb::CastFromTimestamp>(source, result, count);
		break;
	case SQLTypeId::DATE:
		// timestamp to date
		UnaryExecutor::Execute<timestamp_t, date_t, duckdb::CastTimestampToDate, true>(source, result, count);
		break;
	case SQLTypeId::TIME:
		// timestamp to time
		UnaryExecutor::Execute<timestamp_t, dtime_t, duckdb::CastTimestampToTime, true>(source, result, count);
		break;
	default:
		null_cast(source, result, source_type, target_type, count);
		break;
	}
}

void VectorOperations::Cast(Vector &source, Vector &result, SQLType source_type, SQLType target_type, idx_t count) {
	assert(source_type != target_type);
	// first switch on source type
	switch (source_type.id) {
	case SQLTypeId::BOOLEAN:
		assert(source.type == TypeId::BOOL);
		numeric_cast_switch<bool>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::TINYINT:
		assert(source.type == TypeId::INT8);
		numeric_cast_switch<int8_t>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::SMALLINT:
		assert(source.type == TypeId::INT16);
		numeric_cast_switch<int16_t>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::INTEGER:
		assert(source.type == TypeId::INT32);
		numeric_cast_switch<int32_t>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::BIGINT:
		assert(source.type == TypeId::INT64);
		numeric_cast_switch<int64_t>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::FLOAT:
		assert(source.type == TypeId::FLOAT);
		numeric_cast_switch<float>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::DECIMAL:
	case SQLTypeId::DOUBLE:
		assert(source.type == TypeId::DOUBLE);
		numeric_cast_switch<double>(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::DATE:
		assert(source.type == TypeId::INT32);
		date_cast_switch(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::TIME:
		assert(source.type == TypeId::INT32);
		time_cast_switch(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::TIMESTAMP:
		assert(source.type == TypeId::INT64);
		timestamp_cast_switch(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::VARCHAR:
		assert(source.type == TypeId::VARCHAR);
		string_cast_switch(source, result, source_type, target_type, count);
		break;
	case SQLTypeId::SQLNULL: {
		// cast a NULL to another type, just copy the properties and change the type
		result.vector_type = VectorType::CONSTANT_VECTOR;
		ConstantVector::SetNull(result, true);
		break;
	}
	default:
		throw UnimplementedCast(source_type, target_type);
	}
}

void VectorOperations::Cast(Vector &source, Vector &result, idx_t count) {
	return VectorOperations::Cast(source, result, SQLTypeFromInternalType(source.type),
	                              SQLTypeFromInternalType(result.type), count);
}
//===--------------------------------------------------------------------===//
// copy.cpp
// Description: This file contains the implementation of the different copy
// functions
//===--------------------------------------------------------------------===//







using namespace duckdb;
using namespace std;

template <class T>
static void TemplatedCopy(Vector &source, const SelectionVector &sel, Vector &target, idx_t source_offset,
                          idx_t target_offset, idx_t copy_count) {
	auto ldata = FlatVector::GetData<T>(source);
	auto tdata = FlatVector::GetData<T>(target);
	for (idx_t i = 0; i < copy_count; i++) {
		auto source_idx = sel.get_index(source_offset + i);
		tdata[target_offset + i] = ldata[source_idx];
	}
}

void VectorOperations::Copy(Vector &source, Vector &target, const SelectionVector &sel, idx_t source_count,
                            idx_t source_offset, idx_t target_offset) {
	assert(source_offset <= source_count);
	assert(target.vector_type == VectorType::FLAT_VECTOR);
	assert(source.type == target.type);
	switch (source.vector_type) {
	case VectorType::DICTIONARY_VECTOR: {
		// dictionary vector: merge selection vectors
		auto &child = DictionaryVector::Child(source);
		auto &dict_sel = DictionaryVector::SelVector(source);
		// merge the selection vectors and verify the child
		auto new_buffer = dict_sel.Slice(sel, source_count);
		SelectionVector merged_sel(new_buffer);
		VectorOperations::Copy(child, target, merged_sel, source_count, source_offset, target_offset);
		return;
	}
	case VectorType::SEQUENCE_VECTOR: {
		int64_t start, increment;
		Vector seq(source.type);
		SequenceVector::GetSequence(source, start, increment);
		VectorOperations::GenerateSequence(seq, source_count, sel, start, increment);
		VectorOperations::Copy(seq, target, sel, source_count, source_offset, target_offset);
		return;
	}
	case VectorType::CONSTANT_VECTOR:
	case VectorType::FLAT_VECTOR:
		break;
	default:
		throw NotImplementedException("FIXME unimplemented vector type for VectorOperations::Copy");
	}

	idx_t copy_count = source_count - source_offset;
	assert(target_offset + copy_count <= STANDARD_VECTOR_SIZE);
	if (copy_count == 0) {
		return;
	}

	// first copy the nullmask
	auto &tmask = FlatVector::Nullmask(target);
	if (source.vector_type == VectorType::CONSTANT_VECTOR) {
		if (ConstantVector::IsNull(source)) {
			for (idx_t i = 0; i < copy_count; i++) {
				tmask[target_offset + i] = true;
			}
		}
	} else {
		auto &smask = FlatVector::Nullmask(source);
		for (idx_t i = 0; i < copy_count; i++) {
			auto idx = sel.get_index(source_offset + i);
			tmask[target_offset + i] = smask[idx];
		}
	}

	// now copy over the data
	switch (source.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		TemplatedCopy<int8_t>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::INT16:
		TemplatedCopy<int16_t>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::INT32:
		TemplatedCopy<int32_t>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::INT64:
		TemplatedCopy<int64_t>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::POINTER:
		TemplatedCopy<uintptr_t>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::FLOAT:
		TemplatedCopy<float>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::DOUBLE:
		TemplatedCopy<double>(source, sel, target, source_offset, target_offset, copy_count);
		break;
	case TypeId::VARCHAR: {
		auto ldata = FlatVector::GetData<string_t>(source);
		auto tdata = FlatVector::GetData<string_t>(target);
		for (idx_t i = 0; i < copy_count; i++) {
			auto source_idx = sel.get_index(source_offset + i);
			auto target_idx = target_offset + i;
			if (!tmask[target_idx]) {
				tdata[target_idx] = StringVector::AddString(target, ldata[source_idx]);
			}
		}
		break;
	}
	case TypeId::STRUCT: {
		if (StructVector::HasEntries(target)) {
			// target already has entries: append to them
			auto &source_children = StructVector::GetEntries(source);
			auto &target_children = StructVector::GetEntries(target);
			assert(source_children.size() == target_children.size());
			for (idx_t i = 0; i < source_children.size(); i++) {
				assert(target_children[i].first == target_children[i].first);
				VectorOperations::Copy(*source_children[i].second, *target_children[i].second, sel, source_count,
				                       source_offset, target_offset);
			}
		} else {
			assert(target_offset == 0);
			// target has no entries: create new entries for the target
			auto &source_children = StructVector::GetEntries(source);
			for (auto &child : source_children) {
				auto child_copy = make_unique<Vector>(child.second->type);

				VectorOperations::Copy(*child.second, *child_copy, sel, source_count, source_offset, target_offset);
				StructVector::AddEntry(target, child.first, move(child_copy));
			}
		}
		break;
	}
	case TypeId::LIST: {
		assert(target.type == TypeId::LIST);
		if (ListVector::HasEntry(source)) {
			// if the source has list offsets, we need to append them to the target
			if (!ListVector::HasEntry(target)) {
				auto new_target_child = make_unique<ChunkCollection>();
				ListVector::SetEntry(target, move(new_target_child));
			}
			auto &source_child = ListVector::GetEntry(source);
			auto &target_child = ListVector::GetEntry(target);
			idx_t old_target_child_len = target_child.count;

			// append to list itself
			target_child.Append(source_child);
			// now write the list offsets
			auto ldata = FlatVector::GetData<list_entry_t>(source);
			auto tdata = FlatVector::GetData<list_entry_t>(target);
			for (idx_t i = 0; i < copy_count; i++) {
				auto source_idx = sel.get_index(source_offset + i);
				auto &source_entry = ldata[source_idx];
				auto &target_entry = tdata[target_offset + i];

				target_entry.length = source_entry.length;
				target_entry.offset = old_target_child_len + source_entry.offset;
			}
		}
		break;
	}
	default:
		throw NotImplementedException("Unimplemented type for copy!");
	}
}

void VectorOperations::Copy(Vector &source, Vector &target, idx_t source_count, idx_t source_offset,
                            idx_t target_offset) {
	switch (source.vector_type) {
	case VectorType::DICTIONARY_VECTOR: {
		// dictionary: continue into child with selection vector
		auto &child = DictionaryVector::Child(source);
		auto &dict_sel = DictionaryVector::SelVector(source);
		VectorOperations::Copy(child, target, dict_sel, source_count, source_offset, target_offset);
		break;
	}
	case VectorType::CONSTANT_VECTOR:
		VectorOperations::Copy(source, target, ConstantVector::ZeroSelectionVector, source_count, source_offset,
		                       target_offset);
		break;
	default:
		source.Normalify(source_count);
		VectorOperations::Copy(source, target, FlatVector::IncrementalSelectionVector, source_count, source_offset,
		                       target_offset);
		break;
	}
}
//===--------------------------------------------------------------------===//
// hash.cpp
// Description: This file contains the vectorized hash implementations
//===--------------------------------------------------------------------===//





using namespace duckdb;
using namespace std;

struct HashOp {
	template <class T> static inline hash_t Operation(T input, bool is_null) {
		return duckdb::Hash<T>(is_null ? duckdb::NullValue<T>() : input);
	}
};

template <bool HAS_RSEL, class T>
static inline void tight_loop_hash(T *__restrict ldata, hash_t *__restrict result_data, const SelectionVector *rsel,
                                   idx_t count, const SelectionVector *__restrict sel_vector, nullmask_t &nullmask) {
	if (nullmask.any()) {
		for (idx_t i = 0; i < count; i++) {
			auto ridx = HAS_RSEL ? rsel->get_index(i) : i;
			auto idx = sel_vector->get_index(ridx);
			result_data[ridx] = HashOp::Operation(ldata[idx], nullmask[idx]);
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto ridx = HAS_RSEL ? rsel->get_index(i) : i;
			auto idx = sel_vector->get_index(ridx);
			result_data[ridx] = duckdb::Hash<T>(ldata[idx]);
		}
	}
}

template <bool HAS_RSEL, class T>
static inline void templated_loop_hash(Vector &input, Vector &result, const SelectionVector *rsel, idx_t count) {
	if (input.vector_type == VectorType::CONSTANT_VECTOR) {
		result.vector_type = VectorType::CONSTANT_VECTOR;

		auto ldata = ConstantVector::GetData<T>(input);
		auto result_data = ConstantVector::GetData<hash_t>(result);
		*result_data = HashOp::Operation(*ldata, ConstantVector::IsNull(input));
	} else {
		result.vector_type = VectorType::FLAT_VECTOR;

		VectorData idata;
		input.Orrify(count, idata);

		tight_loop_hash<HAS_RSEL, T>((T *)idata.data, FlatVector::GetData<hash_t>(result), rsel, count, idata.sel,
		                             *idata.nullmask);
	}
}

template <bool HAS_RSEL>
static inline void hash_type_switch(Vector &input, Vector &result, const SelectionVector *rsel, idx_t count) {
	assert(result.type == TypeId::HASH);
	switch (input.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		templated_loop_hash<HAS_RSEL, int8_t>(input, result, rsel, count);
		break;
	case TypeId::INT16:
		templated_loop_hash<HAS_RSEL, int16_t>(input, result, rsel, count);
		break;
	case TypeId::INT32:
		templated_loop_hash<HAS_RSEL, int32_t>(input, result, rsel, count);
		break;
	case TypeId::INT64:
		templated_loop_hash<HAS_RSEL, int64_t>(input, result, rsel, count);
		break;
	case TypeId::FLOAT:
		templated_loop_hash<HAS_RSEL, float>(input, result, rsel, count);
		break;
	case TypeId::DOUBLE:
		templated_loop_hash<HAS_RSEL, double>(input, result, rsel, count);
		break;
	case TypeId::VARCHAR:
		templated_loop_hash<HAS_RSEL, string_t>(input, result, rsel, count);
		break;
	default:
		throw InvalidTypeException(input.type, "Invalid type for hash");
	}
}

void VectorOperations::Hash(Vector &input, Vector &result, idx_t count) {
	hash_type_switch<false>(input, result, nullptr, count);
}

void VectorOperations::Hash(Vector &input, Vector &result, const SelectionVector &sel, idx_t count) {
	hash_type_switch<true>(input, result, &sel, count);
}

static inline hash_t combine_hash(hash_t a, hash_t b) {
	return (a * UINT64_C(0xbf58476d1ce4e5b9)) ^ b;
}

template <bool HAS_RSEL, class T>
static inline void tight_loop_combine_hash_constant(T *__restrict ldata, hash_t constant_hash,
                                                    hash_t *__restrict hash_data, const SelectionVector *rsel,
                                                    idx_t count, const SelectionVector *__restrict sel_vector,
                                                    nullmask_t &nullmask) {
	if (nullmask.any()) {
		for (idx_t i = 0; i < count; i++) {
			auto ridx = HAS_RSEL ? rsel->get_index(i) : i;
			auto idx = sel_vector->get_index(ridx);
			auto other_hash = HashOp::Operation(ldata[idx], nullmask[idx]);
			hash_data[ridx] = combine_hash(constant_hash, other_hash);
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto ridx = HAS_RSEL ? rsel->get_index(i) : i;
			auto idx = sel_vector->get_index(ridx);
			auto other_hash = duckdb::Hash<T>(ldata[idx]);
			hash_data[ridx] = combine_hash(constant_hash, other_hash);
		}
	}
}

template <bool HAS_RSEL, class T>
static inline void tight_loop_combine_hash(T *__restrict ldata, hash_t *__restrict hash_data,
                                           const SelectionVector *rsel, idx_t count,
                                           const SelectionVector *__restrict sel_vector, nullmask_t &nullmask) {
	if (nullmask.any()) {
		for (idx_t i = 0; i < count; i++) {
			auto ridx = HAS_RSEL ? rsel->get_index(i) : i;
			auto idx = sel_vector->get_index(ridx);
			auto other_hash = HashOp::Operation(ldata[idx], nullmask[idx]);
			hash_data[ridx] = combine_hash(hash_data[ridx], other_hash);
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto ridx = HAS_RSEL ? rsel->get_index(i) : i;
			auto idx = sel_vector->get_index(ridx);
			auto other_hash = duckdb::Hash<T>(ldata[idx]);
			hash_data[ridx] = combine_hash(hash_data[ridx], other_hash);
		}
	}
}

template <bool HAS_RSEL, class T>
void templated_loop_combine_hash(Vector &input, Vector &hashes, const SelectionVector *rsel, idx_t count) {
	if (input.vector_type == VectorType::CONSTANT_VECTOR && hashes.vector_type == VectorType::CONSTANT_VECTOR) {
		auto ldata = ConstantVector::GetData<T>(input);
		auto hash_data = ConstantVector::GetData<hash_t>(hashes);

		auto other_hash = HashOp::Operation(*ldata, ConstantVector::IsNull(input));
		*hash_data = combine_hash(*hash_data, other_hash);
	} else {
		VectorData idata;
		input.Orrify(count, idata);
		if (hashes.vector_type == VectorType::CONSTANT_VECTOR) {
			// mix constant with non-constant, first get the constant value
			auto constant_hash = *ConstantVector::GetData<hash_t>(hashes);
			// now re-initialize the hashes vector to an empty flat vector
			hashes.Initialize(hashes.type);
			tight_loop_combine_hash_constant<HAS_RSEL, T>((T *)idata.data, constant_hash,
			                                              FlatVector::GetData<hash_t>(hashes), rsel, count, idata.sel,
			                                              *idata.nullmask);
		} else {
			assert(hashes.vector_type == VectorType::FLAT_VECTOR);
			tight_loop_combine_hash<HAS_RSEL, T>((T *)idata.data, FlatVector::GetData<hash_t>(hashes), rsel, count,
			                                     idata.sel, *idata.nullmask);
		}
	}
}

template <bool HAS_RSEL>
static inline void combine_hash_type_switch(Vector &hashes, Vector &input, const SelectionVector *rsel, idx_t count) {
	assert(hashes.type == TypeId::HASH);
	switch (input.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		templated_loop_combine_hash<HAS_RSEL, int8_t>(input, hashes, rsel, count);
		break;
	case TypeId::INT16:
		templated_loop_combine_hash<HAS_RSEL, int16_t>(input, hashes, rsel, count);
		break;
	case TypeId::INT32:
		templated_loop_combine_hash<HAS_RSEL, int32_t>(input, hashes, rsel, count);
		break;
	case TypeId::INT64:
		templated_loop_combine_hash<HAS_RSEL, int64_t>(input, hashes, rsel, count);
		break;
	case TypeId::FLOAT:
		templated_loop_combine_hash<HAS_RSEL, float>(input, hashes, rsel, count);
		break;
	case TypeId::DOUBLE:
		templated_loop_combine_hash<HAS_RSEL, double>(input, hashes, rsel, count);
		break;
	case TypeId::VARCHAR:
		templated_loop_combine_hash<HAS_RSEL, string_t>(input, hashes, rsel, count);
		break;
	default:
		throw InvalidTypeException(input.type, "Invalid type for hash");
	}
}

void VectorOperations::CombineHash(Vector &hashes, Vector &input, idx_t count) {
	combine_hash_type_switch<false>(hashes, input, nullptr, count);
}

void VectorOperations::CombineHash(Vector &hashes, Vector &input, const SelectionVector &rsel, idx_t count) {
	combine_hash_type_switch<true>(hashes, input, &rsel, count);
}




namespace duckdb {

template <class T> static void CopyToStorageLoop(VectorData &vdata, idx_t count, data_ptr_t target) {
	auto ldata = (T *)vdata.data;
	auto result_data = (T *)target;
	for (idx_t i = 0; i < count; i++) {
		auto idx = vdata.sel->get_index(i);
		if ((*vdata.nullmask)[idx]) {
			result_data[i] = NullValue<T>();
		} else {
			result_data[i] = ldata[idx];
		}
	}
}

void VectorOperations::WriteToStorage(Vector &source, idx_t count, data_ptr_t target) {
	if (count == 0) {
		return;
	}
	VectorData vdata;
	source.Orrify(count, vdata);

	switch (source.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		CopyToStorageLoop<int8_t>(vdata, count, target);
		break;
	case TypeId::INT16:
		CopyToStorageLoop<int16_t>(vdata, count, target);
		break;
	case TypeId::INT32:
		CopyToStorageLoop<int32_t>(vdata, count, target);
		break;
	case TypeId::INT64:
		CopyToStorageLoop<int64_t>(vdata, count, target);
		break;
	case TypeId::HASH:
		CopyToStorageLoop<hash_t>(vdata, count, target);
		break;
	case TypeId::POINTER:
		CopyToStorageLoop<uintptr_t>(vdata, count, target);
		break;
	case TypeId::FLOAT:
		CopyToStorageLoop<float>(vdata, count, target);
		break;
	case TypeId::DOUBLE:
		CopyToStorageLoop<double>(vdata, count, target);
		break;
	default:
		throw NotImplementedException("Unimplemented type for CopyToStorage");
	}
}

template <class T> static void ReadFromStorageLoop(data_ptr_t source, idx_t count, Vector &result) {
	auto ldata = (T *)source;
	auto result_data = FlatVector::GetData<T>(result);
	auto &nullmask = FlatVector::Nullmask(result);
	for (idx_t i = 0; i < count; i++) {
		if (IsNullValue<T>(ldata[i])) {
			nullmask[i] = true;
		} else {
			result_data[i] = ldata[i];
		}
	}
}

void VectorOperations::ReadFromStorage(data_ptr_t source, idx_t count, Vector &result) {
	result.vector_type = VectorType::FLAT_VECTOR;
	switch (result.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		ReadFromStorageLoop<int8_t>(source, count, result);
		break;
	case TypeId::INT16:
		ReadFromStorageLoop<int16_t>(source, count, result);
		break;
	case TypeId::INT32:
		ReadFromStorageLoop<int32_t>(source, count, result);
		break;
	case TypeId::INT64:
		ReadFromStorageLoop<int64_t>(source, count, result);
		break;
	case TypeId::HASH:
		ReadFromStorageLoop<hash_t>(source, count, result);
		break;
	case TypeId::POINTER:
		ReadFromStorageLoop<uintptr_t>(source, count, result);
		break;
	case TypeId::FLOAT:
		ReadFromStorageLoop<float>(source, count, result);
		break;
	case TypeId::DOUBLE:
		ReadFromStorageLoop<double>(source, count, result);
		break;
	default:
		throw NotImplementedException("Unimplemented type for CopyToStorage");
	}
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/aggregate_hashtable.hpp
//
//
//===----------------------------------------------------------------------===//









namespace duckdb {
class BoundAggregateExpression;

struct AggregateObject {
	AggregateObject(AggregateFunction function, idx_t child_count, idx_t payload_size, bool distinct,
	                TypeId return_type)
	    : function(move(function)), child_count(child_count), payload_size(payload_size), distinct(distinct),
	      return_type(return_type) {
	}

	AggregateFunction function;
	idx_t child_count;
	idx_t payload_size;
	bool distinct;
	TypeId return_type;

	static vector<AggregateObject> CreateAggregateObjects(vector<BoundAggregateExpression *> bindings);
};

//! SuperLargeHashTable is a linear probing HT that is used for computing
//! aggregates
/*!
    SuperLargeHashTable is a HT that is used for computing aggregates. It takes
   as input the set of groups and the types of the aggregates to compute and
   stores them in the HT. It uses linear probing for collision resolution, and
   supports both parallel and sequential modes.
*/
class SuperLargeHashTable {
public:
	SuperLargeHashTable(idx_t initial_capacity, vector<TypeId> group_types, vector<TypeId> payload_types,
	                    vector<BoundAggregateExpression *> aggregates, bool parallel = false);
	SuperLargeHashTable(idx_t initial_capacity, vector<TypeId> group_types, vector<TypeId> payload_types,
	                    vector<AggregateObject> aggregates, bool parallel = false);
	~SuperLargeHashTable();

	//! Resize the HT to the specified size. Must be larger than the current
	//! size.
	void Resize(idx_t size);
	//! Add the given data to the HT, computing the aggregates grouped by the
	//! data in the group chunk. When resize = true, aggregates will not be
	//! computed but instead just assigned.
	void AddChunk(DataChunk &groups, DataChunk &payload);
	//! Scan the HT starting from the scan_position until the result and group
	//! chunks are filled. scan_position will be updated by this function.
	//! Returns the amount of elements found.
	idx_t Scan(idx_t &scan_position, DataChunk &group, DataChunk &result);

	//! Fetch the aggregates for specific groups from the HT and place them in the result
	void FetchAggregates(DataChunk &groups, DataChunk &result);

	//! Finds or creates groups in the hashtable using the specified group keys. The addresses vector will be filled
	//! with pointers to the groups in the hash table, and the new_groups selection vector will point to the newly
	//! created groups. The return value is the amount of newly created groups.
	idx_t FindOrCreateGroups(DataChunk &groups, Vector &addresses, SelectionVector &new_groups);
	void FindOrCreateGroups(DataChunk &groups, Vector &addresses);

	//! The stringheap of the AggregateHashTable
	StringHeap string_heap;

private:
	void HashGroups(DataChunk &groups, Vector &addresses);

	//! The aggregates to be computed
	vector<AggregateObject> aggregates;
	//! The types of the group columns stored in the hashtable
	vector<TypeId> group_types;
	//! The types of the payload columns stored in the hashtable
	vector<TypeId> payload_types;
	//! The size of the groups in bytes
	idx_t group_width;
	//! The size of the payload (aggregations) in bytes
	idx_t payload_width;
	//! The total tuple size
	idx_t tuple_size;
	//! The capacity of the HT. This can be increased using
	//! SuperLargeHashTable::Resize
	idx_t capacity;
	//! The amount of entries stored in the HT currently
	idx_t entries;
	//! The data of the HT
	data_ptr_t data;
	//! The endptr of the hashtable
	data_ptr_t endptr;
	//! Whether or not the HT has to support parallel insertion operations
	bool parallel = false;
	//! The empty payload data
	unique_ptr<data_t[]> empty_payload_data;
	//! Bitmask for getting relevant bits from the hashes to determine the position
	uint64_t bitmask;

	vector<unique_ptr<SuperLargeHashTable>> distinct_hashes;

	//! The size of the initial flag for each cell
	static constexpr int FLAG_SIZE = sizeof(uint8_t);
	//! Flag indicating a cell is empty
	static constexpr int EMPTY_CELL = 0x00;
	//! Flag indicating a cell is full
	static constexpr int FULL_CELL = 0xFF;

	SuperLargeHashTable(const SuperLargeHashTable &) = delete;

	//! unique_ptr to indicate the ownership
	unique_ptr<data_t[]> owned_data;

private:
	void Destroy();
	void CallDestructors(Vector &state_vector, idx_t count);
	void ScatterGroups(DataChunk &groups, unique_ptr<VectorData[]> &group_data, Vector &addresses,
	                   const SelectionVector &sel, idx_t count);
};

} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_aggregate_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class BoundAggregateExpression : public Expression {
public:
	BoundAggregateExpression(TypeId return_type, AggregateFunction function, bool distinct);

	//! The bound function expression
	AggregateFunction function;
	//! True to aggregate on distinct values
	bool distinct;
	//! List of arguments to the function
	vector<unique_ptr<Expression>> children;
	//! Argument types
	vector<SQLType> arguments;
	//! The bound function data (if any)
	unique_ptr<FunctionData> bind_info;


public:
	bool IsAggregate() const override {
		return true;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override;

	hash_t Hash() const override;
	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb





#include <cmath>
#include <map>

using namespace duckdb;
using namespace std;

SuperLargeHashTable::SuperLargeHashTable(idx_t initial_capacity, vector<TypeId> group_types,
                                         vector<TypeId> payload_types, vector<BoundAggregateExpression *> bindings,
                                         bool parallel)
    : SuperLargeHashTable(initial_capacity, move(group_types), move(payload_types),
                          AggregateObject::CreateAggregateObjects(move(bindings)), parallel) {
}

vector<AggregateObject> AggregateObject::CreateAggregateObjects(vector<BoundAggregateExpression *> bindings) {
	vector<AggregateObject> aggregates;
	for (auto &binding : bindings) {
		auto payload_size = binding->function.state_size();
		aggregates.push_back(AggregateObject(binding->function, binding->children.size(), payload_size,
		                                     binding->distinct, binding->return_type));
	}
	return aggregates;
}

SuperLargeHashTable::SuperLargeHashTable(idx_t initial_capacity, vector<TypeId> group_types,
                                         vector<TypeId> payload_types, vector<AggregateObject> aggregate_objects,
                                         bool parallel)
    : aggregates(move(aggregate_objects)), group_types(group_types), payload_types(payload_types), group_width(0),
      payload_width(0), capacity(0), entries(0), data(nullptr), parallel(parallel) {
	// HT tuple layout is as follows:
	// [FLAG][GROUPS][PAYLOAD]
	// [FLAG] is the state of the tuple in memory
	// [GROUPS] is the groups
	// [PAYLOAD] is the payload (i.e. the aggregate states)
	for (idx_t i = 0; i < group_types.size(); i++) {
		group_width += GetTypeIdSize(group_types[i]);
	}
	for (idx_t i = 0; i < aggregates.size(); i++) {
		payload_width += aggregates[i].payload_size;
	}
	empty_payload_data = unique_ptr<data_t[]>(new data_t[payload_width]);
	// initialize the aggregates to the NULL value
	auto pointer = empty_payload_data.get();
	for (idx_t i = 0; i < aggregates.size(); i++) {
		auto &aggr = aggregates[i];
		aggr.function.initialize(pointer);
		pointer += aggr.payload_size;
	}

	// FIXME: this always creates this vector, even if no distinct if present.
	// it likely does not matter.
	distinct_hashes.resize(aggregates.size());

	// create additional hash tables for distinct aggrs
	idx_t payload_idx = 0;
	for (idx_t i = 0; i < aggregates.size(); i++) {
		auto &aggr = aggregates[i];
		if (aggr.distinct) {
			// group types plus aggr return type
			vector<TypeId> distinct_group_types(group_types);
			vector<TypeId> distinct_payload_types;
			vector<BoundAggregateExpression *> distinct_aggregates;
			distinct_group_types.push_back(payload_types[payload_idx]);
			distinct_hashes[i] = make_unique<SuperLargeHashTable>(initial_capacity, distinct_group_types,
			                                                      distinct_payload_types, distinct_aggregates);
		}
		if (aggr.child_count) {
			payload_idx += aggr.child_count;
		} else {
			payload_idx += 1;
		}
	}

	tuple_size = FLAG_SIZE + (group_width + payload_width);
	Resize(initial_capacity);
}

SuperLargeHashTable::~SuperLargeHashTable() {
	Destroy();
}

void SuperLargeHashTable::CallDestructors(Vector &state_vector, idx_t count) {
	if (count == 0) {
		return;
	}
	for (idx_t i = 0; i < aggregates.size(); i++) {
		auto &aggr = aggregates[i];
		if (aggr.function.destructor) {
			aggr.function.destructor(state_vector, count);
		}
		// move to the next aggregate state
		VectorOperations::AddInPlace(state_vector, aggr.payload_size, count);
	}
}

void SuperLargeHashTable::Destroy() {
	if (!data) {
		return;
	}
	// check if there is a destructor
	bool has_destructor = false;
	for (idx_t i = 0; i < aggregates.size(); i++) {
		if (aggregates[i].function.destructor) {
			has_destructor = true;
		}
	}
	if (!has_destructor) {
		return;
	}
	// there are aggregates with destructors: loop over the hash table
	// and call the destructor method for each of the aggregates
	data_ptr_t data_pointers[STANDARD_VECTOR_SIZE];
	Vector state_vector(TypeId::POINTER, (data_ptr_t)data_pointers);
	idx_t count = 0;
	for (data_ptr_t ptr = data, end = data + capacity * tuple_size; ptr < end; ptr += tuple_size) {
		if (*ptr == FULL_CELL) {
			// found entry
			data_pointers[count++] = ptr + FLAG_SIZE + group_width;
			if (count == STANDARD_VECTOR_SIZE) {
				// vector is full: call the destructors
				CallDestructors(state_vector, count);
				count = 0;
			}
		}
	}
	CallDestructors(state_vector, count);
}

void SuperLargeHashTable::Resize(idx_t size) {
	if (size <= capacity) {
		throw Exception("Cannot downsize a hash table!");
	}
	if (size < STANDARD_VECTOR_SIZE) {
		size = STANDARD_VECTOR_SIZE;
	}
	// size needs to be a power of 2
	assert((size & (size - 1)) == 0);
	bitmask = size - 1;

	if (entries > 0) {
		auto new_table = make_unique<SuperLargeHashTable>(size, group_types, payload_types, aggregates, parallel);

		DataChunk groups;
		groups.Initialize(group_types);

		Vector addresses(TypeId::POINTER);
		auto data_pointers = FlatVector::GetData<data_ptr_t>(addresses);

		data_ptr_t ptr = data;
		data_ptr_t end = data + capacity * tuple_size;

		assert(new_table->tuple_size == this->tuple_size);

		while (true) {
			groups.Reset();

			// scan the table for full cells starting from the scan position
			idx_t found_entries = 0;
			for (; ptr < end && found_entries < STANDARD_VECTOR_SIZE; ptr += tuple_size) {
				if (*ptr == FULL_CELL) {
					// found entry
					data_pointers[found_entries++] = ptr + FLAG_SIZE;
				}
			}
			if (found_entries == 0) {
				break;
			}
			// fetch the group columns
			groups.SetCardinality(found_entries);
			for (idx_t i = 0; i < groups.column_count(); i++) {
				auto &column = groups.data[i];
				VectorOperations::Gather::Set(addresses, column, found_entries);
			}

			groups.Verify();
			assert(groups.size() == found_entries);
			Vector new_addresses(TypeId::POINTER);
			new_table->FindOrCreateGroups(groups, new_addresses);

			// NB: both address vectors already point to the payload start
			assert(addresses.type == new_addresses.type && addresses.type == TypeId::POINTER);

			auto new_address_data = FlatVector::GetData<data_ptr_t>(new_addresses);
			for (idx_t i = 0; i < found_entries; i++) {
				memcpy(new_address_data[i], data_pointers[i], payload_width);
			}
		}

		assert(this->entries == new_table->entries);

		this->data = move(new_table->data);
		this->owned_data = move(new_table->owned_data);
		this->capacity = new_table->capacity;
		this->string_heap.MergeHeap(new_table->string_heap);
		new_table->data = nullptr;
	} else {
		data = new data_t[size * tuple_size];
		owned_data = unique_ptr<data_t[]>(data);
		for (idx_t i = 0; i < size; i++) {
			data[i * tuple_size] = EMPTY_CELL;
		}

		capacity = size;
	}

	endptr = data + tuple_size * capacity;
}

void SuperLargeHashTable::AddChunk(DataChunk &groups, DataChunk &payload) {
	if (groups.size() == 0) {
		return;
	}

	Vector addresses(TypeId::POINTER);
	FindOrCreateGroups(groups, addresses);

	// now every cell has an entry
	// update the aggregates
	idx_t payload_idx = 0;

	for (idx_t aggr_idx = 0; aggr_idx < aggregates.size(); aggr_idx++) {
		assert(payload.column_count() > payload_idx);

		// for any entries for which a group was found, update the aggregate
		auto &aggr = aggregates[aggr_idx];
		auto input_count = max((idx_t)1, (idx_t)aggr.child_count);
		if (aggr.distinct) {
			// construct chunk for secondary hash table probing
			vector<TypeId> probe_types(group_types);
			for (idx_t i = 0; i < aggr.child_count; i++) {
				probe_types.push_back(payload_types[payload_idx]);
			}
			DataChunk probe_chunk;
			probe_chunk.Initialize(probe_types);
			for (idx_t group_idx = 0; group_idx < group_types.size(); group_idx++) {
				probe_chunk.data[group_idx].Reference(groups.data[group_idx]);
			}
			for (idx_t i = 0; i < aggr.child_count; i++) {
				probe_chunk.data[group_types.size() + i].Reference(payload.data[payload_idx + i]);
			}
			probe_chunk.SetCardinality(groups);
			probe_chunk.Verify();

			Vector dummy_addresses(TypeId::POINTER);
			SelectionVector new_groups(STANDARD_VECTOR_SIZE);
			// this is the actual meat, find out which groups plus payload
			// value have not been seen yet
			idx_t new_group_count =
			    distinct_hashes[aggr_idx]->FindOrCreateGroups(probe_chunk, dummy_addresses, new_groups);

			// now fix up the payload and addresses accordingly by creating
			// a selection vector
			if (new_group_count > 0) {
				Vector distinct_addresses;
				distinct_addresses.Slice(addresses, new_groups, new_group_count);
				for (idx_t i = 0; i < aggr.child_count; i++) {
					payload.data[payload_idx + i].Slice(new_groups, new_group_count);
					payload.data[payload_idx + i].Verify(new_group_count);
				}

				distinct_addresses.Verify(new_group_count);

				aggr.function.update(&payload.data[payload_idx], input_count, distinct_addresses, new_group_count);
			}
		} else {
			aggr.function.update(&payload.data[payload_idx], input_count, addresses, payload.size());
		}

		// move to the next aggregate
		payload_idx += input_count;
		VectorOperations::AddInPlace(addresses, aggr.payload_size, payload.size());
	}
}

void SuperLargeHashTable::FetchAggregates(DataChunk &groups, DataChunk &result) {
	groups.Verify();
	assert(groups.column_count() == group_types.size());
	for (idx_t i = 0; i < result.column_count(); i++) {
		assert(result.data[i].type == payload_types[i]);
	}
	result.SetCardinality(groups);
	if (groups.size() == 0) {
		return;
	}
	// find the groups associated with the addresses
	// FIXME: this should not use the FindOrCreateGroups, creating them is unnecessary
	Vector addresses(TypeId::POINTER);
	FindOrCreateGroups(groups, addresses);
	// now fetch the aggregates
	for (idx_t aggr_idx = 0; aggr_idx < aggregates.size(); aggr_idx++) {
		assert(result.column_count() > aggr_idx);
		assert(payload_types[aggr_idx] == TypeId::INT64);

		VectorOperations::Gather::Set(addresses, result.data[aggr_idx], groups.size());
	}
}

void SuperLargeHashTable::HashGroups(DataChunk &groups, Vector &addresses) {
	// create a set of hashes for the groups
	Vector hashes(TypeId::HASH);
	groups.Hash(hashes);

	// now compute the entry in the table based on the hash using a modulo
	// multiply the position by the tuple size and add the base address
	UnaryExecutor::Execute<hash_t, data_ptr_t>(hashes, addresses, groups.size(), [&](hash_t element) {
		assert((element & bitmask) == (element % capacity));
		return data + ((element & bitmask) * tuple_size);
	});
}

template <class T>
static void templated_scatter(VectorData &gdata, Vector &addresses, const SelectionVector &sel, idx_t count,
                              idx_t type_size) {
	auto data = (T *)gdata.data;
	auto pointers = FlatVector::GetData<uintptr_t>(addresses);
	if (gdata.nullmask->any()) {
		for (idx_t i = 0; i < count; i++) {
			auto pointer_idx = sel.get_index(i);
			auto group_idx = gdata.sel->get_index(pointer_idx);
			auto ptr = (T *)pointers[pointer_idx];

			if ((*gdata.nullmask)[group_idx]) {
				*ptr = NullValue<T>();
			} else {
				*ptr = data[group_idx];
			}
			pointers[pointer_idx] += type_size;
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto pointer_idx = sel.get_index(i);
			auto group_idx = gdata.sel->get_index(pointer_idx);
			auto ptr = (T *)pointers[pointer_idx];

			*ptr = data[group_idx];
			pointers[pointer_idx] += type_size;
		}
	}
}

void SuperLargeHashTable::ScatterGroups(DataChunk &groups, unique_ptr<VectorData[]> &group_data, Vector &addresses,
                                        const SelectionVector &sel, idx_t count) {
	for (idx_t grp_idx = 0; grp_idx < groups.column_count(); grp_idx++) {
		auto &data = groups.data[grp_idx];
		auto &gdata = group_data[grp_idx];

		auto type_size = GetTypeIdSize(data.type);

		switch (data.type) {
		case TypeId::BOOL:
		case TypeId::INT8:
			templated_scatter<int8_t>(gdata, addresses, sel, count, type_size);
			break;
		case TypeId::INT16:
			templated_scatter<int16_t>(gdata, addresses, sel, count, type_size);
			break;
		case TypeId::INT32:
			templated_scatter<int32_t>(gdata, addresses, sel, count, type_size);
			break;
		case TypeId::INT64:
			templated_scatter<int64_t>(gdata, addresses, sel, count, type_size);
			break;
		case TypeId::FLOAT:
			templated_scatter<float>(gdata, addresses, sel, count, type_size);
			break;
		case TypeId::DOUBLE:
			templated_scatter<double>(gdata, addresses, sel, count, type_size);
			break;
		case TypeId::VARCHAR: {
			auto data = (string_t *)gdata.data;
			auto pointers = FlatVector::GetData<uintptr_t>(addresses);

			for (idx_t i = 0; i < count; i++) {
				auto pointer_idx = sel.get_index(i);
				auto group_idx = gdata.sel->get_index(pointer_idx);
				auto ptr = (string_t *)pointers[pointer_idx];

				if ((*gdata.nullmask)[group_idx]) {
					*ptr = NullValue<string_t>();
				} else if (data[group_idx].IsInlined()) {
					*ptr = data[group_idx];
				} else {
					*ptr = string_heap.AddString(data[group_idx]);
				}
				pointers[pointer_idx] += type_size;
			}
			break;
		}
		default:
			throw Exception("Unsupported type for group vector");
		}
	}
}

template <class T>
static void templated_compare_groups(VectorData &gdata, Vector &addresses, SelectionVector &sel, idx_t &count,
                                     idx_t type_size, SelectionVector &no_match, idx_t &no_match_count) {
	auto data = (T *)gdata.data;
	auto pointers = FlatVector::GetData<uintptr_t>(addresses);
	idx_t match_count = 0;
	if (gdata.nullmask->any()) {
		for (idx_t i = 0; i < count; i++) {
			auto idx = sel.get_index(i);
			auto group_idx = gdata.sel->get_index(idx);
			auto value = (T *)pointers[idx];

			if ((*gdata.nullmask)[group_idx]) {
				if (IsNullValue<T>(*value)) {
					// match: move to next value to compare
					sel.set_index(match_count++, idx);
					pointers[idx] += type_size;
				} else {
					no_match.set_index(no_match_count++, idx);
				}
			} else {
				if (Equals::Operation<T>(data[group_idx], *value)) {
					sel.set_index(match_count++, idx);
					pointers[idx] += type_size;
				} else {
					no_match.set_index(no_match_count++, idx);
				}
			}
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto idx = sel.get_index(i);
			auto group_idx = gdata.sel->get_index(idx);
			auto value = (T *)pointers[idx];

			if (Equals::Operation<T>(data[group_idx], *value)) {
				sel.set_index(match_count++, idx);
				pointers[idx] += type_size;
			} else {
				no_match.set_index(no_match_count++, idx);
			}
		}
	}
	count = match_count;
}

static idx_t CompareGroups(DataChunk &groups, unique_ptr<VectorData[]> &group_data, Vector &addresses,
                           SelectionVector &sel, idx_t count, SelectionVector &no_match) {
	idx_t no_match_count = 0;
	for (idx_t group_idx = 0; group_idx < groups.column_count(); group_idx++) {
		auto &data = groups.data[group_idx];
		auto &gdata = group_data[group_idx];
		auto type_size = GetTypeIdSize(data.type);
		switch (data.type) {
		case TypeId::BOOL:
		case TypeId::INT8:
			templated_compare_groups<int8_t>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		case TypeId::INT16:
			templated_compare_groups<int16_t>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		case TypeId::INT32:
			templated_compare_groups<int32_t>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		case TypeId::INT64:
			templated_compare_groups<int64_t>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		case TypeId::FLOAT:
			templated_compare_groups<float>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		case TypeId::DOUBLE:
			templated_compare_groups<double>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		case TypeId::VARCHAR:
			templated_compare_groups<string_t>(gdata, addresses, sel, count, type_size, no_match, no_match_count);
			break;
		default:
			throw Exception("Unsupported type for group vector");
		}
	}
	return no_match_count;
}

// this is to support distinct aggregations where we need to record whether we
// have already seen a value for a group
idx_t SuperLargeHashTable::FindOrCreateGroups(DataChunk &groups, Vector &addresses, SelectionVector &new_groups) {
	// resize at 50% capacity, also need to fit the entire vector
	if (entries > capacity / 2 || capacity - entries <= STANDARD_VECTOR_SIZE) {
		Resize(capacity * 2);
	}

	// we need to be able to fit at least one vector of data
	assert(capacity - entries > STANDARD_VECTOR_SIZE);
	assert(addresses.type == TypeId::POINTER);

	// hash the groups to get the addresses
	HashGroups(groups, addresses);

	addresses.Normalify(groups.size());
	auto data_pointers = FlatVector::GetData<data_ptr_t>(addresses);

	data_ptr_t group_pointers[STANDARD_VECTOR_SIZE];
	Vector pointers(TypeId::POINTER, (data_ptr_t)group_pointers);

	// set up the selection vectors
	SelectionVector v1(STANDARD_VECTOR_SIZE);
	SelectionVector v2(STANDARD_VECTOR_SIZE);
	SelectionVector empty_vector(STANDARD_VECTOR_SIZE);

	// we start out with all entries [0, 1, 2, ..., groups.size()]
	const SelectionVector *sel_vector = &FlatVector::IncrementalSelectionVector;
	SelectionVector *next_vector = &v1;
	SelectionVector *no_match_vector = &v2;
	idx_t remaining_entries = groups.size();

	// orrify all the groups
	auto group_data = unique_ptr<VectorData[]>(new VectorData[groups.column_count()]);
	for (idx_t grp_idx = 0; grp_idx < groups.column_count(); grp_idx++) {
		groups.data[grp_idx].Orrify(groups.size(), group_data[grp_idx]);
	}

	idx_t new_group_count = 0;
	while (remaining_entries > 0) {
		idx_t entry_count = 0;
		idx_t empty_count = 0;

		// first figure out for each remaining whether or not it belongs to a full or empty group
		for (idx_t i = 0; i < remaining_entries; i++) {
			idx_t index = sel_vector->get_index(i);
			auto entry = data_pointers[index];
			if (*entry == EMPTY_CELL) {
				// cell is empty; mark the cell as filled
				*entry = FULL_CELL;
				empty_vector.set_index(empty_count++, index);
				new_groups.set_index(new_group_count++, index);
				// initialize the payload info for the column
				memcpy(entry + FLAG_SIZE + group_width, empty_payload_data.get(), payload_width);
			} else {
				// cell is occupied: add to check list
				next_vector->set_index(entry_count++, index);
			}
			group_pointers[index] = entry + FLAG_SIZE;
			data_pointers[index] = entry + FLAG_SIZE + group_width;
		}

		if (empty_count > 0) {
			// for each of the locations that are empty, serialize the group columns to the locations
			ScatterGroups(groups, group_data, pointers, empty_vector, empty_count);
			entries += empty_count;
		}
		// now we have only the tuples remaining that might match to an existing group
		// start performing comparisons with each of the groups
		idx_t no_match_count = CompareGroups(groups, group_data, pointers, *next_vector, entry_count, *no_match_vector);

		// each of the entries that do not match we move them to the next entry in the HT
		for (idx_t i = 0; i < no_match_count; i++) {
			idx_t index = no_match_vector->get_index(i);
			data_pointers[index] += payload_width;
			assert(((uint64_t)(data_pointers[index] - data)) % tuple_size == 0);
			if (data_pointers[index] >= endptr) {
				data_pointers[index] = data;
			}
		}
		sel_vector = no_match_vector;
		std::swap(next_vector, no_match_vector);
		remaining_entries = no_match_count;
	}
	return new_group_count;
}

void SuperLargeHashTable::FindOrCreateGroups(DataChunk &groups, Vector &addresses) {
	// create a dummy new_groups sel vector
	SelectionVector new_groups(STANDARD_VECTOR_SIZE);
	FindOrCreateGroups(groups, addresses, new_groups);
}

idx_t SuperLargeHashTable::Scan(idx_t &scan_position, DataChunk &groups, DataChunk &result) {
	data_ptr_t ptr;
	data_ptr_t start = data + scan_position;
	data_ptr_t end = data + capacity * tuple_size;
	if (start >= end) {
		return 0;
	}

	Vector addresses(TypeId::POINTER);
	auto data_pointers = FlatVector::GetData<data_ptr_t>(addresses);

	// scan the table for full cells starting from the scan position
	idx_t entry = 0;
	for (ptr = start; ptr < end && entry < STANDARD_VECTOR_SIZE; ptr += tuple_size) {
		if (*ptr == FULL_CELL) {
			// found entry
			data_pointers[entry++] = ptr + FLAG_SIZE;
		}
	}
	if (entry == 0) {
		return 0;
	}
	groups.SetCardinality(entry);
	result.SetCardinality(entry);
	// fetch the group columns
	for (idx_t i = 0; i < groups.column_count(); i++) {
		auto &column = groups.data[i];
		VectorOperations::Gather::Set(addresses, column, groups.size());
	}

	for (idx_t i = 0; i < aggregates.size(); i++) {
		auto &target = result.data[i];
		auto &aggr = aggregates[i];
		aggr.function.finalize(addresses, target, groups.size());

		VectorOperations::AddInPlace(addresses, aggr.payload_size, groups.size());
	}
	scan_position = ptr - data;
	return entry;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/column_binding_resolver.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/column_binding_map.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

struct ColumnBindingHashFunction {
	uint64_t operator()(const ColumnBinding &a) const {
		return CombineHash(Hash<idx_t>(a.table_index), Hash<idx_t>(a.column_index));
	}
};

struct ColumnBindingEquality {
	bool operator()(const ColumnBinding &a, const ColumnBinding &b) const {
		return a == b;
	}
};

template <typename T>
using column_binding_map_t = unordered_map<ColumnBinding, T, ColumnBindingHashFunction, ColumnBindingEquality>;

using column_binding_set_t = unordered_set<ColumnBinding, ColumnBindingHashFunction, ColumnBindingEquality>;

} // namespace duckdb


namespace duckdb {

//! The ColumnBindingResolver resolves ColumnBindings into base tables
//! (table_index, column_index) into physical indices into the DataChunks that
//! are used within the execution engine
class ColumnBindingResolver : public LogicalOperatorVisitor {
public:
	ColumnBindingResolver();

	void VisitOperator(LogicalOperator &op) override;

protected:
	vector<ColumnBinding> bindings;

	unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr) override;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_comparison_join.hpp
//
//
//===----------------------------------------------------------------------===//





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/joinside.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! JoinCondition represents a left-right comparison join condition
struct JoinCondition {
public:
	JoinCondition() : null_values_are_equal(false) {
	}

	//! Turns the JoinCondition into an expression; note that this destroys the JoinCondition as the expression inherits
	//! the left/right expressions
	static unique_ptr<Expression> CreateExpression(JoinCondition cond);

public:
	unique_ptr<Expression> left;
	unique_ptr<Expression> right;
	ExpressionType comparison;
	//! NULL values are equal for just THIS JoinCondition (instead of the entire join).
	//! This is only supported by the HashJoin and can only be used in equality comparisons.
	bool null_values_are_equal = false;
};

// enum class JoinSide : uint8_t {
// 	NONE, LEFT, RIGHT, BOTH
// };

class JoinSide {
public:
	enum join_value : uint8_t { NONE, LEFT, RIGHT, BOTH };

	JoinSide() = default;
	constexpr JoinSide(join_value val) : value(val) {
	}

	bool operator==(JoinSide a) const {
		return value == a.value;
	}
	bool operator!=(JoinSide a) const {
		return value != a.value;
	}

	static JoinSide CombineJoinSide(JoinSide left, JoinSide right);
	static JoinSide GetJoinSide(idx_t table_binding, unordered_set<idx_t> &left_bindings,
	                            unordered_set<uint64_t> &right_bindings);
	static JoinSide GetJoinSide(Expression &expression, unordered_set<idx_t> &left_bindings,
	                            unordered_set<idx_t> &right_bindings);
	static JoinSide GetJoinSide(unordered_set<idx_t> bindings, unordered_set<idx_t> &left_bindings,
	                            unordered_set<idx_t> &right_bindings);

private:
	join_value value;
};

}; // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_join.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! LogicalJoin represents a join between two relations
class LogicalJoin : public LogicalOperator {
public:
	LogicalJoin(JoinType type, LogicalOperatorType logical_type = LogicalOperatorType::JOIN);

	// Gets the set of table references that are reachable from this node
	static void GetTableReferences(LogicalOperator &op, unordered_set<idx_t> &bindings);
	static void GetExpressionBindings(Expression &expr, unordered_set<idx_t> &bindings);

	//! The type of the join (INNER, OUTER, etc...)
	JoinType join_type;
	//! Table index used to refer to the MARK column (in case of a MARK join)
	idx_t mark_index;
	//! The columns of the LHS that are output by the join
	vector<idx_t> left_projection_map;
	//! The columns of the RHS that are output by the join
	vector<idx_t> right_projection_map;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};

} // namespace duckdb


namespace duckdb {

//! LogicalComparisonJoin represents a join that involves comparisons between the LHS and RHS
class LogicalComparisonJoin : public LogicalJoin {
public:
	LogicalComparisonJoin(JoinType type, LogicalOperatorType logical_type = LogicalOperatorType::COMPARISON_JOIN);

	//! The conditions of the join
	vector<JoinCondition> conditions;

public:
	string ParamsToString() const override;

public:
	static unique_ptr<LogicalOperator> CreateJoin(JoinType type, unique_ptr<LogicalOperator> left_child,
	                                              unique_ptr<LogicalOperator> right_child,
	                                              unordered_set<idx_t> &left_bindings,
	                                              unordered_set<idx_t> &right_bindings,
	                                              vector<unique_ptr<Expression>> &expressions);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_create_index.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class LogicalCreateIndex : public LogicalOperator {
public:
	LogicalCreateIndex(TableCatalogEntry &table, vector<column_t> column_ids,
	                   vector<unique_ptr<Expression>> expressions, unique_ptr<CreateIndexInfo> info)
	    : LogicalOperator(LogicalOperatorType::CREATE_INDEX), table(table), column_ids(column_ids),
	      info(std::move(info)) {
		for (auto &expr : expressions) {
			this->unbound_expressions.push_back(expr->Copy());
		}
		this->expressions = move(expressions);
	}

	//! The table to create the index for
	TableCatalogEntry &table;
	//! Column IDs needed for index creation
	vector<column_t> column_ids;
	// Info for index creation
	unique_ptr<CreateIndexInfo> info;
	//! Unbound expressions to be used in the optimizer
	vector<unique_ptr<Expression>> unbound_expressions;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::INT64);
	}
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_delim_join.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalDelimJoin represents a special "duplicate eliminated" join. This join type is only used for subquery
//! flattening, and involves performing duplicate elimination on the LEFT side which is then pushed into the RIGHT side.
class LogicalDelimJoin : public LogicalComparisonJoin {
public:
	LogicalDelimJoin(JoinType type) : LogicalComparisonJoin(type, LogicalOperatorType::DELIM_JOIN) {
	}

	//! The set of columns that will be duplicate eliminated from the LHS and pushed into the RHS
	vector<unique_ptr<Expression>> duplicate_eliminated_columns;
};

} // namespace duckdb







using namespace duckdb;
using namespace std;

ColumnBindingResolver::ColumnBindingResolver() {
}

void ColumnBindingResolver::VisitOperator(LogicalOperator &op) {
	if (op.type == LogicalOperatorType::COMPARISON_JOIN || op.type == LogicalOperatorType::DELIM_JOIN) {
		// special case: comparison join
		auto &comp_join = (LogicalComparisonJoin &)op;
		// first get the bindings of the LHS and resolve the LHS expressions
		VisitOperator(*comp_join.children[0]);
		for (auto &cond : comp_join.conditions) {
			VisitExpression(&cond.left);
		}
		if (op.type == LogicalOperatorType::DELIM_JOIN) {
			// visit the duplicate eliminated columns on the LHS, if any
			auto &delim_join = (LogicalDelimJoin &)op;
			for (auto &expr : delim_join.duplicate_eliminated_columns) {
				VisitExpression(&expr);
			}
		}
		// then get the bindings of the RHS and resolve the RHS expressions
		VisitOperator(*comp_join.children[1]);
		for (auto &cond : comp_join.conditions) {
			VisitExpression(&cond.right);
		}
		// finally update the bindings with the result bindings of the join
		bindings = op.GetColumnBindings();
		return;
	} else if (op.type == LogicalOperatorType::ANY_JOIN) {
		// ANY join, this join is different because we evaluate the expression on the bindings of BOTH join sides at
		// once i.e. we set the bindings first to the bindings of the entire join, and then resolve the expressions of
		// this operator
		VisitOperatorChildren(op);
		bindings = op.GetColumnBindings();
		VisitOperatorExpressions(op);
		return;
	} else if (op.type == LogicalOperatorType::CREATE_INDEX) {
		// CREATE INDEX statement, add the columns of the table with table index 0 to the binding set
		// afterwards bind the expressions of the CREATE INDEX statement
		auto &create_index = (LogicalCreateIndex &)op;
		bindings = LogicalOperator::GenerateColumnBindings(0, create_index.table.columns.size());
		VisitOperatorExpressions(op);
		return;
	} else if (op.type == LogicalOperatorType::GET) {
		//! We first need to update the current set of bindings and then visit operator expressions
		bindings = op.GetColumnBindings();
		VisitOperatorExpressions(op);
		return;
	}
	// general case
	// first visit the children of this operator
	VisitOperatorChildren(op);
	// now visit the expressions of this operator to resolve any bound column references
	VisitOperatorExpressions(op);
	// finally update the current set of bindings to the current set of column bindings
	bindings = op.GetColumnBindings();
}

unique_ptr<Expression> ColumnBindingResolver::VisitReplace(BoundColumnRefExpression &expr,
                                                           unique_ptr<Expression> *expr_ptr) {
	assert(expr.depth == 0);
	// check the current set of column bindings to see which index corresponds to the column reference
	for (idx_t i = 0; i < bindings.size(); i++) {
		if (expr.binding == bindings[i]) {
			return make_unique<BoundReferenceExpression>(expr.alias, expr.return_type, i);
		}
	}
	// could not bind the column reference, this should never happen and indicates a bug in the code
	// generate an error message
	string bound_columns = "[";
	for (idx_t i = 0; i < bindings.size(); i++) {
		if (i != 0) {
			bound_columns += " ";
		}
		bound_columns += to_string(bindings[i].table_index) + "." + to_string(bindings[i].column_index);
	}
	bound_columns += "]";

	throw InternalException("Failed to bind column reference \"%s\" [%d.%d] (bindings: %s)", expr.alias.c_str(),
	                        (int)expr.binding.table_index, (int)expr.binding.column_index, bound_columns.c_str());
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_between_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundBetweenExpression : public Expression {
public:
	BoundBetweenExpression(unique_ptr<Expression> input, unique_ptr<Expression> lower, unique_ptr<Expression> upper,
	                       bool lower_inclusive, bool upper_inclusive);

	unique_ptr<Expression> input;
	unique_ptr<Expression> lower;
	unique_ptr<Expression> upper;
	bool lower_inclusive;
	bool upper_inclusive;

public:
	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/vector_operations/ternary_executor.hpp
//
//
//===----------------------------------------------------------------------===//






#include <functional>

namespace duckdb {

struct TernaryExecutor {
private:
	template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE, class FUN>
	static inline void ExecuteLoop(A_TYPE *__restrict adata, B_TYPE *__restrict bdata, C_TYPE *__restrict cdata,
	                               RESULT_TYPE *__restrict result_data, idx_t count, const SelectionVector &asel,
	                               const SelectionVector &bsel, const SelectionVector &csel, nullmask_t &anullmask,
	                               nullmask_t &bnullmask, nullmask_t &cnullmask, nullmask_t &result_nullmask, FUN fun) {
		if (anullmask.any() || bnullmask.any() || cnullmask.any()) {
			for (idx_t i = 0; i < count; i++) {
				auto aidx = asel.get_index(i);
				auto bidx = bsel.get_index(i);
				auto cidx = csel.get_index(i);
				if (anullmask[aidx] || bnullmask[bidx] || cnullmask[cidx]) {
					result_nullmask[i] = true;
				} else {
					result_data[i] = fun(adata[aidx], bdata[bidx], cdata[cidx]);
				}
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				auto aidx = asel.get_index(i);
				auto bidx = bsel.get_index(i);
				auto cidx = csel.get_index(i);
				result_data[i] = fun(adata[aidx], bdata[bidx], cdata[cidx]);
			}
		}
	}

public:
	template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE,
	          class FUN = std::function<RESULT_TYPE(A_TYPE, B_TYPE, C_TYPE)>>
	static void Execute(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUN fun) {
		if (a.vector_type == VectorType::CONSTANT_VECTOR && b.vector_type == VectorType::CONSTANT_VECTOR &&
		    c.vector_type == VectorType::CONSTANT_VECTOR) {
			result.vector_type = VectorType::CONSTANT_VECTOR;
			if (ConstantVector::IsNull(a) || ConstantVector::IsNull(b) || ConstantVector::IsNull(c)) {
				ConstantVector::SetNull(result, true);
			} else {
				auto adata = ConstantVector::GetData<A_TYPE>(a);
				auto bdata = ConstantVector::GetData<B_TYPE>(b);
				auto cdata = ConstantVector::GetData<C_TYPE>(c);
				auto result_data = ConstantVector::GetData<RESULT_TYPE>(result);
				result_data[0] = fun(*adata, *bdata, *cdata);
			}
		} else {
			result.vector_type = VectorType::FLAT_VECTOR;

			VectorData adata, bdata, cdata;
			a.Orrify(count, adata);
			b.Orrify(count, bdata);
			c.Orrify(count, cdata);

			ExecuteLoop<A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE>(
			    (A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data,
			    FlatVector::GetData<RESULT_TYPE>(result), count, *adata.sel, *bdata.sel, *cdata.sel, *adata.nullmask,
			    *bdata.nullmask, *cdata.nullmask, FlatVector::Nullmask(result), fun);
		}
	}

private:
	template <class A_TYPE, class B_TYPE, class C_TYPE, class OP, bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
	static inline idx_t SelectLoop(A_TYPE *__restrict adata, B_TYPE *__restrict bdata, C_TYPE *__restrict cdata,
	                               const SelectionVector *result_sel, idx_t count, const SelectionVector &asel,
	                               const SelectionVector &bsel, const SelectionVector &csel, nullmask_t &anullmask,
	                               nullmask_t &bnullmask, nullmask_t &cnullmask, SelectionVector *true_sel,
	                               SelectionVector *false_sel) {
		idx_t true_count = 0, false_count = 0;
		for (idx_t i = 0; i < count; i++) {
			auto result_idx = result_sel->get_index(i);
			auto aidx = asel.get_index(i);
			auto bidx = bsel.get_index(i);
			auto cidx = csel.get_index(i);
			if ((NO_NULL || (!anullmask[aidx] && !bnullmask[bidx] && !cnullmask[cidx])) &&
			    OP::Operation(adata[aidx], bdata[bidx], cdata[cidx])) {
				if (HAS_TRUE_SEL) {
					true_sel->set_index(true_count++, result_idx);
				}
			} else {
				if (HAS_FALSE_SEL) {
					false_sel->set_index(false_count++, result_idx);
				}
			}
		}
		if (HAS_TRUE_SEL) {
			return true_count;
		} else {
			return count - false_count;
		}
	}

	template <class A_TYPE, class B_TYPE, class C_TYPE, class OP, bool NO_NULL>
	static inline idx_t SelectLoopSelSwitch(VectorData &adata, VectorData &bdata, VectorData &cdata,
	                                        const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
	                                        SelectionVector *false_sel) {
		if (true_sel && false_sel) {
			return SelectLoop<A_TYPE, B_TYPE, C_TYPE, OP, NO_NULL, true, true>(
			    (A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data, sel, count, *adata.sel, *bdata.sel,
			    *cdata.sel, *adata.nullmask, *bdata.nullmask, *cdata.nullmask, true_sel, false_sel);
		} else if (true_sel) {
			return SelectLoop<A_TYPE, B_TYPE, C_TYPE, OP, NO_NULL, true, false>(
			    (A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data, sel, count, *adata.sel, *bdata.sel,
			    *cdata.sel, *adata.nullmask, *bdata.nullmask, *cdata.nullmask, true_sel, false_sel);
		} else {
			assert(false_sel);
			return SelectLoop<A_TYPE, B_TYPE, C_TYPE, OP, NO_NULL, false, true>(
			    (A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data, sel, count, *adata.sel, *bdata.sel,
			    *cdata.sel, *adata.nullmask, *bdata.nullmask, *cdata.nullmask, true_sel, false_sel);
		}
	}

	template <class A_TYPE, class B_TYPE, class C_TYPE, class OP>
	static inline idx_t SelectLoopSwitch(VectorData &adata, VectorData &bdata, VectorData &cdata,
	                                     const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
	                                     SelectionVector *false_sel) {
		if (adata.nullmask->any() || bdata.nullmask->any() || cdata.nullmask->any()) {
			return SelectLoopSelSwitch<A_TYPE, B_TYPE, C_TYPE, OP, false>(adata, bdata, cdata, sel, count, true_sel,
			                                                              false_sel);
		} else {
			return SelectLoopSelSwitch<A_TYPE, B_TYPE, C_TYPE, OP, false>(adata, bdata, cdata, sel, count, true_sel,
			                                                              false_sel);
		}
	}

public:
	template <class A_TYPE, class B_TYPE, class C_TYPE, class OP>
	static idx_t Select(Vector &a, Vector &b, Vector &c, const SelectionVector *sel, idx_t count,
	                    SelectionVector *true_sel, SelectionVector *false_sel) {
		if (!sel) {
			sel = &FlatVector::IncrementalSelectionVector;
		}
		VectorData adata, bdata, cdata;
		a.Orrify(count, adata);
		b.Orrify(count, bdata);
		c.Orrify(count, cdata);

		return SelectLoopSwitch<A_TYPE, B_TYPE, C_TYPE, OP>(adata, bdata, cdata, sel, count, true_sel, false_sel);
	}
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

struct BothInclusiveBetweenOperator {
	template <class T> static inline bool Operation(T input, T lower, T upper) {
		return GreaterThanEquals::Operation<T>(input, lower) && LessThanEquals::Operation<T>(input, upper);
	}
};

struct LowerInclusiveBetweenOperator {
	template <class T> static inline bool Operation(T input, T lower, T upper) {
		return GreaterThanEquals::Operation<T>(input, lower) && LessThan::Operation<T>(input, upper);
	}
};

struct UpperInclusiveBetweenOperator {
	template <class T> static inline bool Operation(T input, T lower, T upper) {
		return GreaterThan::Operation<T>(input, lower) && LessThanEquals::Operation<T>(input, upper);
	}
};

struct ExclusiveBetweenOperator {
	template <class T> static inline bool Operation(T input, T lower, T upper) {
		return GreaterThan::Operation<T>(input, lower) && LessThan::Operation<T>(input, upper);
	}
};

template <class OP>
static idx_t between_loop_type_switch(Vector &input, Vector &lower, Vector &upper, const SelectionVector *sel,
                                      idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
	switch (input.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return TernaryExecutor::Select<int8_t, int8_t, int8_t, OP>(input, lower, upper, sel, count, true_sel,
		                                                           false_sel);
	case TypeId::INT16:
		return TernaryExecutor::Select<int16_t, int16_t, int16_t, OP>(input, lower, upper, sel, count, true_sel,
		                                                              false_sel);
	case TypeId::INT32:
		return TernaryExecutor::Select<int32_t, int32_t, int32_t, OP>(input, lower, upper, sel, count, true_sel,
		                                                              false_sel);
	case TypeId::INT64:
		return TernaryExecutor::Select<int64_t, int64_t, int64_t, OP>(input, lower, upper, sel, count, true_sel,
		                                                              false_sel);
	case TypeId::FLOAT:
		return TernaryExecutor::Select<float, float, float, OP>(input, lower, upper, sel, count, true_sel, false_sel);
	case TypeId::DOUBLE:
		return TernaryExecutor::Select<double, double, double, OP>(input, lower, upper, sel, count, true_sel,
		                                                           false_sel);
	case TypeId::VARCHAR:
		return TernaryExecutor::Select<string_t, string_t, string_t, OP>(input, lower, upper, sel, count, true_sel,
		                                                                 false_sel);
	default:
		throw InvalidTypeException(input.type, "Invalid type for BETWEEN");
	}
}

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundBetweenExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<ExpressionState>(expr, root);
	result->AddChild(expr.input.get());
	result->AddChild(expr.lower.get());
	result->AddChild(expr.upper.get());
	return result;
}

void ExpressionExecutor::Execute(BoundBetweenExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	// resolve the children
	Vector input(expr.input->return_type), lower(expr.lower->return_type), upper(expr.upper->return_type);
	Execute(*expr.input, state->child_states[0].get(), sel, count, input);
	Execute(*expr.lower, state->child_states[1].get(), sel, count, lower);
	Execute(*expr.upper, state->child_states[2].get(), sel, count, upper);

	Vector intermediate1(TypeId::BOOL);
	Vector intermediate2(TypeId::BOOL);

	if (expr.upper_inclusive && expr.lower_inclusive) {
		VectorOperations::GreaterThanEquals(input, lower, intermediate1, count);
		VectorOperations::LessThanEquals(input, upper, intermediate2, count);
	} else if (expr.lower_inclusive) {
		VectorOperations::GreaterThanEquals(input, lower, intermediate1, count);
		VectorOperations::LessThan(input, upper, intermediate2, count);
	} else if (expr.upper_inclusive) {
		VectorOperations::GreaterThan(input, lower, intermediate1, count);
		VectorOperations::LessThanEquals(input, upper, intermediate2, count);
	} else {
		VectorOperations::GreaterThan(input, lower, intermediate1, count);
		VectorOperations::LessThan(input, upper, intermediate2, count);
	}
	VectorOperations::And(intermediate1, intermediate2, result, count);
}

idx_t ExpressionExecutor::Select(BoundBetweenExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
	// resolve the children
	Vector input(expr.input->return_type), lower(expr.lower->return_type), upper(expr.upper->return_type);
	Execute(*expr.input, state->child_states[0].get(), sel, count, input);
	Execute(*expr.lower, state->child_states[1].get(), sel, count, lower);
	Execute(*expr.upper, state->child_states[2].get(), sel, count, upper);

	if (expr.upper_inclusive && expr.lower_inclusive) {
		return between_loop_type_switch<BothInclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel,
		                                                              false_sel);
	} else if (expr.lower_inclusive) {
		return between_loop_type_switch<LowerInclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel,
		                                                               false_sel);
	} else if (expr.upper_inclusive) {
		return between_loop_type_switch<UpperInclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel,
		                                                               false_sel);
	} else {
		return between_loop_type_switch<ExclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel, false_sel);
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_case_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundCaseExpression : public Expression {
public:
	BoundCaseExpression(unique_ptr<Expression> check, unique_ptr<Expression> res_if_true,
	                    unique_ptr<Expression> res_if_false);

	unique_ptr<Expression> check;
	unique_ptr<Expression> result_if_true;
	unique_ptr<Expression> result_if_false;

public:
	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

void Case(Vector &res_true, Vector &res_false, Vector &result, SelectionVector &tside, idx_t tcount,
          SelectionVector &fside, idx_t fcount);

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundCaseExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<ExpressionState>(expr, root);
	result->AddChild(expr.check.get());
	result->AddChild(expr.result_if_true.get());
	result->AddChild(expr.result_if_false.get());
	return result;
}

void ExpressionExecutor::Execute(BoundCaseExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	Vector res_true(expr.result_if_true->return_type), res_false(expr.result_if_false->return_type);

	auto check_state = state->child_states[0].get();
	auto res_true_state = state->child_states[1].get();
	auto res_false_state = state->child_states[2].get();

	// first execute the check expression
	SelectionVector true_sel(STANDARD_VECTOR_SIZE), false_sel(STANDARD_VECTOR_SIZE);
	idx_t tcount = Select(*expr.check, check_state, sel, count, &true_sel, &false_sel);
	idx_t fcount = count - tcount;
	if (fcount == 0) {
		// everything is true, only execute TRUE side
		Execute(*expr.result_if_true, res_true_state, sel, count, result);
	} else if (tcount == 0) {
		// everything is false, only execute FALSE side
		Execute(*expr.result_if_false, res_false_state, sel, count, result);
	} else {
		// have to execute both and mix and match
		Execute(*expr.result_if_true, res_true_state, &true_sel, tcount, res_true);
		Execute(*expr.result_if_false, res_false_state, &false_sel, fcount, res_false);

		Case(res_true, res_false, result, true_sel, tcount, false_sel, fcount);
		if (sel) {
			result.Slice(*sel, count);
		}
	}
}

template <class T> void fill_loop(Vector &vector, Vector &result, SelectionVector &sel, sel_t count) {
	auto res = FlatVector::GetData<T>(result);
	auto &result_nullmask = FlatVector::Nullmask(result);
	if (vector.vector_type == VectorType::CONSTANT_VECTOR) {
		auto data = ConstantVector::GetData<T>(vector);
		if (ConstantVector::IsNull(vector)) {
			for (idx_t i = 0; i < count; i++) {
				result_nullmask[sel.get_index(i)] = true;
			}
		} else {
			for (idx_t i = 0; i < count; i++) {
				res[sel.get_index(i)] = *data;
			}
		}
	} else {
		VectorData vdata;
		vector.Orrify(count, vdata);
		auto data = (T *)vdata.data;
		for (idx_t i = 0; i < count; i++) {
			auto source_idx = vdata.sel->get_index(i);
			auto res_idx = sel.get_index(i);

			res[res_idx] = data[source_idx];
			result_nullmask[res_idx] = (*vdata.nullmask)[source_idx];
		}
	}
}

template <class T>
void case_loop(Vector &res_true, Vector &res_false, Vector &result, SelectionVector &tside, idx_t tcount,
               SelectionVector &fside, idx_t fcount) {
	fill_loop<T>(res_true, result, tside, tcount);
	fill_loop<T>(res_false, result, fside, fcount);
}

void Case(Vector &res_true, Vector &res_false, Vector &result, SelectionVector &tside, idx_t tcount,
          SelectionVector &fside, idx_t fcount) {
	assert(res_true.type == res_false.type && res_true.type == result.type);

	switch (result.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		case_loop<int8_t>(res_true, res_false, result, tside, tcount, fside, fcount);
		break;
	case TypeId::INT16:
		case_loop<int16_t>(res_true, res_false, result, tside, tcount, fside, fcount);
		break;
	case TypeId::INT32:
		case_loop<int32_t>(res_true, res_false, result, tside, tcount, fside, fcount);
		break;
	case TypeId::INT64:
		case_loop<int64_t>(res_true, res_false, result, tside, tcount, fside, fcount);
		break;
	case TypeId::FLOAT:
		case_loop<float>(res_true, res_false, result, tside, tcount, fside, fcount);
		break;
	case TypeId::DOUBLE:
		case_loop<double>(res_true, res_false, result, tside, tcount, fside, fcount);
		break;
	case TypeId::VARCHAR:
		case_loop<string_t>(res_true, res_false, result, tside, tcount, fside, fcount);
		StringVector::AddHeapReference(result, res_true);
		StringVector::AddHeapReference(result, res_false);
		break;
	case TypeId::LIST: {
		auto result_cc = make_unique<ChunkCollection>();
		ListVector::SetEntry(result, move(result_cc));

		auto &result_child = ListVector::GetEntry(result);
		idx_t offset = 0;
		if (ListVector::HasEntry(res_true)) {
			auto &true_child = ListVector::GetEntry(res_true);
			assert(true_child.types.size() == 1);
			offset += true_child.count;
			result_child.Append(true_child);
		}
		if (ListVector::HasEntry(res_false)) {
			auto &false_child = ListVector::GetEntry(res_false);
			assert(false_child.types.size() == 1);
			result_child.Append(false_child);
		}

		// all the false offsets need to be incremented by true_child.count
		fill_loop<list_entry_t>(res_true, result, tside, tcount);

		// FIXME the nullmask here is likely borked
		// TODO uuugly
		VectorData fdata;
		res_false.Orrify(fcount, fdata);

		auto data = (list_entry_t *)fdata.data;
		auto res = FlatVector::GetData<list_entry_t>(result);
		auto &mask = FlatVector::Nullmask(result);

		for (idx_t i = 0; i < fcount; i++) {
			auto fidx = fdata.sel->get_index(i);
			auto res_idx = fside.get_index(i);
			auto list_entry = data[fidx];
			list_entry.offset += offset;
			res[res_idx] = list_entry;
			mask[res_idx] = (*fdata.nullmask)[fidx];
		}

		result.Verify(tcount + fcount);
		break;
	}
	default:
		throw NotImplementedException("Unimplemented type for case expression: %s",
		                              TypeIdToString(result.type).c_str());
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_cast_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundCastExpression : public Expression {
public:
	BoundCastExpression(TypeId target, unique_ptr<Expression> child, SQLType source_type, SQLType target_type);

	//! The child type
	unique_ptr<Expression> child;
	//! The SQL type of the child
	SQLType source_type;
	//! The SQL type to cast to
	SQLType target_type;

public:
	//! Cast an expression to the specified SQL type if required
	static unique_ptr<Expression> AddCastToType(unique_ptr<Expression> expr, SQLType source_type, SQLType target_type);

	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundCastExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<ExpressionState>(expr, root);
	result->AddChild(expr.child.get());
	return result;
}

void ExpressionExecutor::Execute(BoundCastExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	// resolve the child
	Vector child(expr.child->return_type);
	auto child_state = state->child_states[0].get();

	Execute(*expr.child, child_state, sel, count, child);
	if (child.type == expr.return_type) {
		// NOP cast
		result.Reference(child);
	} else {
		// cast it to the type specified by the cast expression
		VectorOperations::Cast(child, result, expr.source_type, expr.target_type, count);
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_comparison_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundComparisonExpression : public Expression {
public:
	BoundComparisonExpression(ExpressionType type, unique_ptr<Expression> left, unique_ptr<Expression> right);

	unique_ptr<Expression> left;
	unique_ptr<Expression> right;

public:
	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundComparisonExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<ExpressionState>(expr, root);
	result->AddChild(expr.left.get());
	result->AddChild(expr.right.get());
	return result;
}

void ExpressionExecutor::Execute(BoundComparisonExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	// resolve the children
	Vector left(expr.left->return_type), right(expr.right->return_type);
	Execute(*expr.left, state->child_states[0].get(), sel, count, left);
	Execute(*expr.right, state->child_states[1].get(), sel, count, right);

	switch (expr.type) {
	case ExpressionType::COMPARE_EQUAL:
		VectorOperations::Equals(left, right, result, count);
		break;
	case ExpressionType::COMPARE_NOTEQUAL:
		VectorOperations::NotEquals(left, right, result, count);
		break;
	case ExpressionType::COMPARE_LESSTHAN:
		VectorOperations::LessThan(left, right, result, count);
		break;
	case ExpressionType::COMPARE_GREATERTHAN:
		VectorOperations::GreaterThan(left, right, result, count);
		break;
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		VectorOperations::LessThanEquals(left, right, result, count);
		break;
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		VectorOperations::GreaterThanEquals(left, right, result, count);
		break;
	case ExpressionType::COMPARE_DISTINCT_FROM:
		throw NotImplementedException("Unimplemented compare: COMPARE_DISTINCT_FROM");
	default:
		throw NotImplementedException("Unknown comparison type!");
	}
}

template <class OP>
static idx_t templated_select_operation(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
                                        SelectionVector *true_sel, SelectionVector *false_sel) {
	// the inplace loops take the result as the last parameter
	switch (left.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return BinaryExecutor::Select<int8_t, int8_t, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::INT16:
		return BinaryExecutor::Select<int16_t, int16_t, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::INT32:
		return BinaryExecutor::Select<int32_t, int32_t, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::INT64:
		return BinaryExecutor::Select<int64_t, int64_t, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::POINTER:
		return BinaryExecutor::Select<uintptr_t, uintptr_t, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::FLOAT:
		return BinaryExecutor::Select<float, float, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::DOUBLE:
		return BinaryExecutor::Select<double, double, OP>(left, right, sel, count, true_sel, false_sel);
	case TypeId::VARCHAR:
		return BinaryExecutor::Select<string_t, string_t, OP>(left, right, sel, count, true_sel, false_sel);
	default:
		throw InvalidTypeException(left.type, "Invalid type for comparison");
	}
}

idx_t ExpressionExecutor::Select(BoundComparisonExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
	// resolve the children
	Vector left(expr.left->return_type), right(expr.right->return_type);
	Execute(*expr.left, state->child_states[0].get(), sel, count, left);
	Execute(*expr.right, state->child_states[1].get(), sel, count, right);

	switch (expr.type) {
	case ExpressionType::COMPARE_EQUAL:
		return templated_select_operation<duckdb::Equals>(left, right, sel, count, true_sel, false_sel);
	case ExpressionType::COMPARE_NOTEQUAL:
		return templated_select_operation<duckdb::NotEquals>(left, right, sel, count, true_sel, false_sel);
	case ExpressionType::COMPARE_LESSTHAN:
		return templated_select_operation<duckdb::LessThan>(left, right, sel, count, true_sel, false_sel);
	case ExpressionType::COMPARE_GREATERTHAN:
		return templated_select_operation<duckdb::GreaterThan>(left, right, sel, count, true_sel, false_sel);
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return templated_select_operation<duckdb::LessThanEquals>(left, right, sel, count, true_sel, false_sel);
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		return templated_select_operation<duckdb::GreaterThanEquals>(left, right, sel, count, true_sel, false_sel);
	case ExpressionType::COMPARE_DISTINCT_FROM:
		throw NotImplementedException("Unimplemented compare: COMPARE_DISTINCT_FROM");
	default:
		throw NotImplementedException("Unknown comparison type!");
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_conjunction_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundConjunctionExpression : public Expression {
public:
	BoundConjunctionExpression(ExpressionType type);
	BoundConjunctionExpression(ExpressionType type, unique_ptr<Expression> left, unique_ptr<Expression> right);

	vector<unique_ptr<Expression>> children;

public:
	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


#include <chrono>
#include <random>
#include <vector>

using namespace duckdb;
using namespace std;

struct ConjunctionState : public ExpressionState {
	ConjunctionState(Expression &expr, ExpressionExecutorState &root)
	    : ExpressionState(expr, root), iteration_count(0), observe_interval(10), execute_interval(20), warmup(true) {
		auto &conj_expr = (BoundConjunctionExpression &)expr;
		assert(conj_expr.children.size() > 1);
		for (idx_t idx = 0; idx < conj_expr.children.size(); idx++) {
			permutation.push_back(idx);
			if (idx != conj_expr.children.size() - 1) {
				swap_likeliness.push_back(100);
			}
		}
		right_random_border = 100 * (conj_expr.children.size() - 1);
	}

	// used for adaptive expression reordering
	idx_t iteration_count;
	idx_t swap_idx;
	idx_t right_random_border;
	idx_t observe_interval;
	idx_t execute_interval;
	double runtime_sum;
	double prev_mean;
	bool observe;
	bool warmup;
	vector<idx_t> permutation;
	vector<idx_t> swap_likeliness;
	std::default_random_engine generator;
};

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundConjunctionExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<ConjunctionState>(expr, root);
	for (auto &child : expr.children) {
		result->AddChild(child.get());
	}
	return move(result);
}

void ExpressionExecutor::Execute(BoundConjunctionExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	// execute the children
	for (idx_t i = 0; i < expr.children.size(); i++) {
		Vector current_result(TypeId::BOOL);
		Execute(*expr.children[i], state->child_states[i].get(), sel, count, current_result);
		if (i == 0) {
			// move the result
			result.Reference(current_result);
		} else {
			Vector intermediate(TypeId::BOOL);
			// AND/OR together
			switch (expr.type) {
			case ExpressionType::CONJUNCTION_AND:
				VectorOperations::And(current_result, result, intermediate, count);
				break;
			case ExpressionType::CONJUNCTION_OR:
				VectorOperations::Or(current_result, result, intermediate, count);
				break;
			default:
				throw NotImplementedException("Unknown conjunction type!");
			}
			result.Reference(intermediate);
		}
	}
}

void AdaptRuntimeStatistics(BoundConjunctionExpression &expr, ConjunctionState *state, double duration) {
	state->iteration_count++;
	state->runtime_sum += duration;

	if (!state->warmup) {
		// the last swap was observed
		if (state->observe && state->iteration_count == state->observe_interval) {
			// keep swap if runtime decreased, else reverse swap
			if (!(state->prev_mean - (state->runtime_sum / state->iteration_count) > 0)) {
				// reverse swap because runtime didn't decrease
				assert(state->swap_idx < expr.children.size() - 1);
				assert(expr.children.size() > 1);
				swap(state->permutation[state->swap_idx], state->permutation[state->swap_idx + 1]);

				// decrease swap likeliness, but make sure there is always a small likeliness left
				if (state->swap_likeliness[state->swap_idx] > 1) {
					state->swap_likeliness[state->swap_idx] /= 2;
				}
			} else {
				// keep swap because runtime decreased, reset likeliness
				state->swap_likeliness[state->swap_idx] = 100;
			}
			state->observe = false;

			// reset values
			state->iteration_count = 0;
			state->runtime_sum = 0.0;
		} else if (!state->observe && state->iteration_count == state->execute_interval) {
			// save old mean to evaluate swap
			state->prev_mean = state->runtime_sum / state->iteration_count;

			// get swap index and swap likeliness
			uniform_int_distribution<int> distribution(1, state->right_random_border); // a <= i <= b
			idx_t random_number = distribution(state->generator) - 1;

			state->swap_idx = random_number / 100;                    // index to be swapped
			idx_t likeliness = random_number - 100 * state->swap_idx; // random number between [0, 100)

			// check if swap is going to happen
			if (state->swap_likeliness[state->swap_idx] > likeliness) { // always true for the first swap of an index
				// swap
				assert(state->swap_idx < expr.children.size() - 1);
				assert(expr.children.size() > 1);
				swap(state->permutation[state->swap_idx], state->permutation[state->swap_idx + 1]);

				// observe whether swap will be applied
				state->observe = true;
			}

			// reset values
			state->iteration_count = 0;
			state->runtime_sum = 0.0;
		}
	} else {
		if (state->iteration_count == 5) {
			// initially set all values
			state->iteration_count = 0;
			state->runtime_sum = 0.0;
			state->observe = false;
			state->warmup = false;
		}
	}
}

idx_t ExpressionExecutor::Select(BoundConjunctionExpression &expr, ExpressionState *state_, const SelectionVector *sel,
                                 idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
	auto state = (ConjunctionState *)state_;

	if (expr.type == ExpressionType::CONJUNCTION_AND) {
		// get runtime statistics
		auto start_time = chrono::high_resolution_clock::now();

		const SelectionVector *current_sel = sel;
		idx_t current_count = count;
		idx_t false_count = 0;

		unique_ptr<SelectionVector> temp_true, temp_false;
		if (false_sel) {
			temp_false = make_unique<SelectionVector>(STANDARD_VECTOR_SIZE);
		}
		if (!true_sel) {
			temp_true = make_unique<SelectionVector>(STANDARD_VECTOR_SIZE);
			true_sel = temp_true.get();
		}
		for (idx_t i = 0; i < expr.children.size(); i++) {
			idx_t tcount =
			    Select(*expr.children[state->permutation[i]], state->child_states[state->permutation[i]].get(),
			           current_sel, current_count, true_sel, temp_false.get());
			idx_t fcount = current_count - tcount;
			if (fcount > 0 && false_sel) {
				// move failing tuples into the false_sel
				// tuples passed, move them into the actual result vector
				for (idx_t i = 0; i < fcount; i++) {
					false_sel->set_index(false_count++, temp_false->get_index(i));
				}
			}
			current_count = tcount;
			if (current_count == 0) {
				break;
			}
			if (current_count < count) {
				// tuples were filtered out: move on to using the true_sel to only evaluate passing tuples in subsequent
				// iterations
				current_sel = true_sel;
			}
		}

		// adapt runtime statistics
		auto end_time = chrono::high_resolution_clock::now();
		AdaptRuntimeStatistics(expr, state,
		                       chrono::duration_cast<chrono::duration<double>>(end_time - start_time).count());
		return current_count;
	} else {
		// get runtime statistics
		auto start_time = chrono::high_resolution_clock::now();

		const SelectionVector *current_sel = sel;
		idx_t current_count = count;
		idx_t result_count = 0;

		unique_ptr<SelectionVector> temp_true, temp_false;
		if (true_sel) {
			temp_true = make_unique<SelectionVector>(STANDARD_VECTOR_SIZE);
		}
		if (!false_sel) {
			temp_false = make_unique<SelectionVector>(STANDARD_VECTOR_SIZE);
			false_sel = temp_false.get();
		}
		for (idx_t i = 0; i < expr.children.size(); i++) {
			idx_t tcount =
			    Select(*expr.children[state->permutation[i]], state->child_states[state->permutation[i]].get(),
			           current_sel, current_count, temp_true.get(), false_sel);
			if (tcount > 0) {
				if (true_sel) {
					// tuples passed, move them into the actual result vector
					for (idx_t i = 0; i < tcount; i++) {
						true_sel->set_index(result_count++, temp_true->get_index(i));
					}
				}
				// now move on to check only the non-passing tuples
				current_count -= tcount;
				current_sel = false_sel;
			}
		}

		// adapt runtime statistics
		auto end_time = chrono::high_resolution_clock::now();
		AdaptRuntimeStatistics(expr, state,
		                       chrono::duration_cast<chrono::duration<double>>(end_time - start_time).count());
		return result_count;
	}
}




using namespace duckdb;
using namespace std;

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundConstantExpression &expr,
                                                                ExpressionExecutorState &root) {
	return nullptr;
}

void ExpressionExecutor::Execute(BoundConstantExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	result.Reference(expr.value);
}

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_function_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class ScalarFunctionCatalogEntry;

//! Represents a function call that has been bound to a base function
class BoundFunctionExpression : public Expression {
public:
	BoundFunctionExpression(TypeId return_type, ScalarFunction bound_function, bool is_operator);

	// The bound function expression
	ScalarFunction function;
	//! List of arguments to the function
	vector<unique_ptr<Expression>> children;
	//! Argument types
	vector<SQLType> arguments;
	//! The return type
	SQLType sql_return_type;
	//! Whether or not the function is an operator, only used for rendering
	bool is_operator;
	//! The bound function data (if any)
	unique_ptr<FunctionData> bind_info;

public:
	bool IsFoldable() const override;
	string ToString() const override;

	hash_t Hash() const override;
	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

struct FunctionState : public ExpressionState {
	FunctionState(Expression &expr, ExpressionExecutorState &root) : ExpressionState(expr, root) {
		auto &func = (BoundFunctionExpression &)expr;
		for (auto &child : func.children) {
			child_types.push_back(child->return_type);
		}
	}

	vector<TypeId> child_types;
};

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundFunctionExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<FunctionState>(expr, root);
	for (auto &child : expr.children) {
		result->AddChild(child.get());
	}
	return move(result);
}

void ExpressionExecutor::Execute(BoundFunctionExpression &expr, ExpressionState *state_, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	auto state = (FunctionState *)state_;
	DataChunk arguments;
	arguments.SetCardinality(count);
	if (state->child_types.size() > 0) {
		arguments.Initialize(state->child_types);
		for (idx_t i = 0; i < expr.children.size(); i++) {
			assert(state->child_types[i] == expr.children[i]->return_type);
			Execute(*expr.children[i], state->child_states[i].get(), sel, count, arguments.data[i]);
		}
		arguments.Verify();
	}
	expr.function.function(arguments, *state, result);
	if (result.type != expr.return_type) {
		throw TypeMismatchException(expr.return_type, result.type,
		                            "expected function to return the former "
		                            "but the function returned the latter");
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_operator_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundOperatorExpression : public Expression {
public:
	BoundOperatorExpression(ExpressionType type, TypeId return_type);

	vector<unique_ptr<Expression>> children;

public:
	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundOperatorExpression &expr,
                                                                ExpressionExecutorState &root) {
	auto result = make_unique<ExpressionState>(expr, root);
	for (auto &child : expr.children) {
		result->AddChild(child.get());
	}
	return result;
}

void ExpressionExecutor::Execute(BoundOperatorExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	// special handling for special snowflake 'IN'
	// IN has n children
	if (expr.type == ExpressionType::COMPARE_IN || expr.type == ExpressionType::COMPARE_NOT_IN) {
		if (expr.children.size() < 2) {
			throw Exception("IN needs at least two children");
		}
		Vector left(expr.children[0]->return_type);
		// eval left side
		Execute(*expr.children[0], state->child_states[0].get(), sel, count, left);

		// init result to false
		Vector intermediate(TypeId::BOOL);
		Value false_val = Value::BOOLEAN(false);
		intermediate.Reference(false_val);

		// in rhs is a list of constants
		// for every child, OR the result of the comparision with the left
		// to get the overall result.
		for (idx_t child = 1; child < expr.children.size(); child++) {
			Vector vector_to_check(expr.children[child]->return_type);
			Vector comp_res(TypeId::BOOL);

			Execute(*expr.children[child], state->child_states[child].get(), sel, count, vector_to_check);
			VectorOperations::Equals(left, vector_to_check, comp_res, count);

			if (child == 1) {
				// first child: move to result
				intermediate.Reference(comp_res);
			} else {
				// otherwise OR together
				Vector new_result(TypeId::BOOL, true, false);
				VectorOperations::Or(intermediate, comp_res, new_result, count);
				intermediate.Reference(new_result);
			}
		}
		if (expr.type == ExpressionType::COMPARE_NOT_IN) {
			// NOT IN: invert result
			VectorOperations::Not(intermediate, result, count);
		} else {
			// directly use the result
			result.Reference(intermediate);
		}
	} else if (expr.children.size() == 1) {
		Vector child(expr.children[0]->return_type);
		Execute(*expr.children[0], state->child_states[0].get(), sel, count, child);
		switch (expr.type) {
		case ExpressionType::OPERATOR_NOT: {
			VectorOperations::Not(child, result, count);
			break;
		}
		case ExpressionType::OPERATOR_IS_NULL: {
			VectorOperations::IsNull(child, result, count);
			break;
		}
		case ExpressionType::OPERATOR_IS_NOT_NULL: {
			VectorOperations::IsNotNull(child, result, count);
			break;
		}
		default:
			throw NotImplementedException("Unsupported operator type with 1 child!");
		}
	} else {
		throw NotImplementedException("operator");
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_parameter_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class BoundParameterExpression : public Expression {
public:
	BoundParameterExpression(idx_t parameter_nr);

	SQLType sql_type;
	idx_t parameter_nr;
	Value *value;

public:
	bool IsScalar() const override;
	bool HasParameter() const override;
	bool IsFoldable() const override;

	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;
	hash_t Hash() const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundParameterExpression &expr,
                                                                ExpressionExecutorState &root) {
	return nullptr;
}

void ExpressionExecutor::Execute(BoundParameterExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	assert(expr.value);
	assert(expr.value->type == expr.return_type);
	result.Reference(*expr.value);
}



using namespace duckdb;
using namespace std;

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundReferenceExpression &expr,
                                                                ExpressionExecutorState &root) {
	return nullptr;
}

void ExpressionExecutor::Execute(BoundReferenceExpression &expr, ExpressionState *state, const SelectionVector *sel,
                                 idx_t count, Vector &result) {
	assert(expr.index != INVALID_INDEX);
	assert(expr.index < chunk->column_count());
	if (sel) {
		result.Slice(chunk->data[expr.index], *sel, count);
	} else {
		result.Reference(chunk->data[expr.index]);
	}
}




using namespace duckdb;
using namespace std;

ExpressionExecutor::ExpressionExecutor() {
}

ExpressionExecutor::ExpressionExecutor(Expression *expression) {
	assert(expression);
	AddExpression(*expression);
}

ExpressionExecutor::ExpressionExecutor(Expression &expression) {
	AddExpression(expression);
}

ExpressionExecutor::ExpressionExecutor(vector<unique_ptr<Expression>> &exprs) {
	assert(exprs.size() > 0);
	for (auto &expr : exprs) {
		AddExpression(*expr);
	}
}

void ExpressionExecutor::AddExpression(Expression &expr) {
	expressions.push_back(&expr);
	auto state = make_unique<ExpressionExecutorState>();
	Initialize(expr, *state);
	states.push_back(move(state));
}

void ExpressionExecutor::Initialize(Expression &expression, ExpressionExecutorState &state) {
	state.root_state = InitializeState(expression, state);
	state.executor = this;
}

void ExpressionExecutor::Execute(DataChunk *input, DataChunk &result) {
	SetChunk(input);

	assert(expressions.size() == result.column_count());
	assert(expressions.size() > 0);
	result.Reset();
	for (idx_t i = 0; i < expressions.size(); i++) {
		ExecuteExpression(i, result.data[i]);
	}
	result.SetCardinality(input ? input->size() : 1);
	result.Verify();
}

void ExpressionExecutor::ExecuteExpression(DataChunk &input, Vector &result) {
	SetChunk(&input);
	ExecuteExpression(result);
}

idx_t ExpressionExecutor::SelectExpression(DataChunk &input, SelectionVector &sel) {
	assert(expressions.size() == 1);
	SetChunk(&input);
	return Select(*expressions[0], states[0]->root_state.get(), nullptr, input.size(), &sel, nullptr);
}

void ExpressionExecutor::ExecuteExpression(Vector &result) {
	assert(expressions.size() == 1);
	ExecuteExpression(0, result);
}

void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) {
	assert(expr_idx < expressions.size());
	assert(result.type == expressions[expr_idx]->return_type);
	Execute(*expressions[expr_idx], states[expr_idx]->root_state.get(), nullptr, chunk ? chunk->size() : 1, result);
}

Value ExpressionExecutor::EvaluateScalar(Expression &expr) {
	assert(expr.IsFoldable());
	// use an ExpressionExecutor to execute the expression
	ExpressionExecutor executor(expr);

	Vector result(expr.return_type);
	executor.ExecuteExpression(result);

	assert(result.vector_type == VectorType::CONSTANT_VECTOR);
	return result.GetValue(0);
}

void ExpressionExecutor::Verify(Expression &expr, Vector &vector, idx_t count) {
	assert(expr.return_type == vector.type);
	vector.Verify(count);
}

unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(Expression &expr, ExpressionExecutorState &state) {
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_REF:
		return InitializeState((BoundReferenceExpression &)expr, state);
	case ExpressionClass::BOUND_BETWEEN:
		return InitializeState((BoundBetweenExpression &)expr, state);
	case ExpressionClass::BOUND_CASE:
		return InitializeState((BoundCaseExpression &)expr, state);
	case ExpressionClass::BOUND_CAST:
		return InitializeState((BoundCastExpression &)expr, state);
	case ExpressionClass::BOUND_COMPARISON:
		return InitializeState((BoundComparisonExpression &)expr, state);
	case ExpressionClass::BOUND_CONJUNCTION:
		return InitializeState((BoundConjunctionExpression &)expr, state);
	case ExpressionClass::BOUND_CONSTANT:
		return InitializeState((BoundConstantExpression &)expr, state);
	case ExpressionClass::BOUND_FUNCTION:
		return InitializeState((BoundFunctionExpression &)expr, state);
	case ExpressionClass::BOUND_OPERATOR:
		return InitializeState((BoundOperatorExpression &)expr, state);
	case ExpressionClass::BOUND_PARAMETER:
		return InitializeState((BoundParameterExpression &)expr, state);
	default:
		throw NotImplementedException("Attempting to initialize state of expression of unknown type!");
	}
}

void ExpressionExecutor::Execute(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
                                 Vector &result) {
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_BETWEEN:
		Execute((BoundBetweenExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_REF:
		Execute((BoundReferenceExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_CASE:
		Execute((BoundCaseExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_CAST:
		Execute((BoundCastExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_COMPARISON:
		Execute((BoundComparisonExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_CONJUNCTION:
		Execute((BoundConjunctionExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_CONSTANT:
		Execute((BoundConstantExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_FUNCTION:
		Execute((BoundFunctionExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_OPERATOR:
		Execute((BoundOperatorExpression &)expr, state, sel, count, result);
		break;
	case ExpressionClass::BOUND_PARAMETER:
		Execute((BoundParameterExpression &)expr, state, sel, count, result);
		break;
	default:
		throw NotImplementedException("Attempting to execute expression of unknown type!");
	}
	Verify(expr, result, count);
}

idx_t ExpressionExecutor::Select(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count,
                                 SelectionVector *true_sel, SelectionVector *false_sel) {
	assert(true_sel || false_sel);
	assert(expr.return_type == TypeId::BOOL);
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_BETWEEN:
		return Select((BoundBetweenExpression &)expr, state, sel, count, true_sel, false_sel);
	case ExpressionClass::BOUND_COMPARISON:
		return Select((BoundComparisonExpression &)expr, state, sel, count, true_sel, false_sel);
	case ExpressionClass::BOUND_CONJUNCTION:
		return Select((BoundConjunctionExpression &)expr, state, sel, count, true_sel, false_sel);
	default:
		return DefaultSelect(expr, state, sel, count, true_sel, false_sel);
	}
}

template <bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
static inline idx_t DefaultSelectLoop(const SelectionVector *bsel, bool *__restrict bdata, nullmask_t &nullmask,
                                      const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
                                      SelectionVector *false_sel) {
	idx_t true_count = 0, false_count = 0;
	for (idx_t i = 0; i < count; i++) {
		auto bidx = bsel->get_index(i);
		auto result_idx = sel->get_index(i);
		if (bdata[bidx] && (NO_NULL || !nullmask[bidx])) {
			if (HAS_TRUE_SEL) {
				true_sel->set_index(true_count++, result_idx);
			}
		} else {
			if (HAS_FALSE_SEL) {
				false_sel->set_index(false_count++, result_idx);
			}
		}
	}
	if (HAS_TRUE_SEL) {
		return true_count;
	} else {
		return count - false_count;
	}
}

template <bool NO_NULL>
static inline idx_t DefaultSelectSwitch(VectorData &idata, const SelectionVector *sel, idx_t count,
                                        SelectionVector *true_sel, SelectionVector *false_sel) {
	if (true_sel && false_sel) {
		return DefaultSelectLoop<NO_NULL, true, true>(idata.sel, (bool *)idata.data, *idata.nullmask, sel, count,
		                                              true_sel, false_sel);
	} else if (true_sel) {
		return DefaultSelectLoop<NO_NULL, true, false>(idata.sel, (bool *)idata.data, *idata.nullmask, sel, count,
		                                               true_sel, false_sel);
	} else {
		assert(false_sel);
		return DefaultSelectLoop<NO_NULL, false, true>(idata.sel, (bool *)idata.data, *idata.nullmask, sel, count,
		                                               true_sel, false_sel);
	}
}

idx_t ExpressionExecutor::DefaultSelect(Expression &expr, ExpressionState *state, const SelectionVector *sel,
                                        idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
	// generic selection of boolean expression:
	// resolve the true/false expression first
	// then use that to generate the selection vector
	bool intermediate_bools[STANDARD_VECTOR_SIZE];
	Vector intermediate(TypeId::BOOL, (data_ptr_t)intermediate_bools);
	Execute(expr, state, sel, count, intermediate);

	VectorData idata;
	intermediate.Orrify(count, idata);
	if (!sel) {
		sel = &FlatVector::IncrementalSelectionVector;
	}
	if (idata.nullmask->any()) {
		return DefaultSelectSwitch<false>(idata, sel, count, true_sel, false_sel);
	} else {
		return DefaultSelectSwitch<true>(idata, sel, count, true_sel, false_sel);
	}
}




using namespace duckdb;
using namespace std;

void ExpressionState::AddChild(Expression *expr) {
	child_states.push_back(ExpressionExecutor::InitializeState(*expr, root));
}



#include <algorithm>
#include <ctgmath>

using namespace duckdb;
using namespace std;

ART::ART(DataTable &table, vector<column_t> column_ids, vector<unique_ptr<Expression>> unbound_expressions,
         bool is_unique)
    : Index(IndexType::ART, table, column_ids, move(unbound_expressions)), is_unique(is_unique) {
	tree = nullptr;
	expression_result.Initialize(types);
	int n = 1;
	//! little endian if true
	if (*(char *)&n == 1) {
		is_little_endian = true;
	} else {
		is_little_endian = false;
	}
	switch (types[0]) {
	case TypeId::INT8:
	case TypeId::INT16:
	case TypeId::INT32:
	case TypeId::INT64:
	case TypeId::FLOAT:
	case TypeId::DOUBLE:
	case TypeId::VARCHAR:
		break;
	default:
		throw InvalidTypeException(types[0], "Invalid type for index");
	}
}

ART::~ART() {
}

bool ART::LeafMatches(Node *node, Key &key, unsigned depth) {
	auto leaf = static_cast<Leaf *>(node);
	Key &leaf_key = *leaf->value;
	for (idx_t i = depth; i < leaf_key.len; i++) {
		if (leaf_key[i] != key[i]) {
			return false;
		}
	}

	return true;
}

unique_ptr<IndexScanState> ART::InitializeScanSinglePredicate(Transaction &transaction, vector<column_t> column_ids,
                                                              Value value, ExpressionType expression_type) {
	auto result = make_unique<ARTIndexScanState>(column_ids);
	result->values[0] = value;
	result->expressions[0] = expression_type;
	return move(result);
}

unique_ptr<IndexScanState> ART::InitializeScanTwoPredicates(Transaction &transaction, vector<column_t> column_ids,
                                                            Value low_value, ExpressionType low_expression_type,
                                                            Value high_value, ExpressionType high_expression_type) {
	auto result = make_unique<ARTIndexScanState>(column_ids);
	result->values[0] = low_value;
	result->expressions[0] = low_expression_type;
	result->values[1] = high_value;
	result->expressions[1] = high_expression_type;
	return move(result);
}

//===--------------------------------------------------------------------===//
// Insert
//===--------------------------------------------------------------------===//
template <class T>
static void generate_keys(Vector &input, idx_t count, vector<unique_ptr<Key>> &keys, bool is_little_endian) {
	VectorData idata;
	input.Orrify(count, idata);

	auto input_data = (T *)idata.data;
	for (idx_t i = 0; i < count; i++) {
		auto idx = idata.sel->get_index(i);
		if ((*idata.nullmask)[idx]) {
			keys.push_back(nullptr);
		} else {
			keys.push_back(Key::CreateKey<T>(input_data[idx], is_little_endian));
		}
	}
}

template <class T>
static void concatenate_keys(Vector &input, idx_t count, vector<unique_ptr<Key>> &keys, bool is_little_endian) {
	VectorData idata;
	input.Orrify(count, idata);

	auto input_data = (T *)idata.data;
	for (idx_t i = 0; i < count; i++) {
		auto idx = idata.sel->get_index(i);
		if ((*idata.nullmask)[idx] || !keys[i]) {
			// either this column is NULL, or the previous column is NULL!
			keys[i] = nullptr;
		} else {
			// concatenate the keys
			auto old_key = move(keys[i]);
			auto new_key = Key::CreateKey<T>(input_data[idx], is_little_endian);
			auto keyLen = old_key->len + new_key->len;
			auto compound_data = unique_ptr<data_t[]>(new data_t[keyLen]);
			memcpy(compound_data.get(), old_key->data.get(), old_key->len);
			memcpy(compound_data.get() + old_key->len, new_key->data.get(), new_key->len);
			keys[i] = make_unique<Key>(move(compound_data), keyLen);
		}
	}
}

void ART::GenerateKeys(DataChunk &input, vector<unique_ptr<Key>> &keys) {
	keys.reserve(STANDARD_VECTOR_SIZE);
	// generate keys for the first input column
	switch (input.data[0].type) {
	case TypeId::INT8:
		generate_keys<int8_t>(input.data[0], input.size(), keys, is_little_endian);
		break;
	case TypeId::INT16:
		generate_keys<int16_t>(input.data[0], input.size(), keys, is_little_endian);
		break;
	case TypeId::INT32:
		generate_keys<int32_t>(input.data[0], input.size(), keys, is_little_endian);
		break;
	case TypeId::INT64:
		generate_keys<int64_t>(input.data[0], input.size(), keys, is_little_endian);
		break;
	case TypeId::FLOAT:
		generate_keys<float>(input.data[0], input.size(), keys, is_little_endian);
		break;
	case TypeId::DOUBLE:
		generate_keys<double>(input.data[0], input.size(), keys, is_little_endian);
		break;
	case TypeId::VARCHAR:
		generate_keys<string_t>(input.data[0], input.size(), keys, is_little_endian);
		break;
	default:
		throw InvalidTypeException(input.data[0].type, "Invalid type for index");
	}
	for (idx_t i = 1; i < input.column_count(); i++) {
		// for each of the remaining columns, concatenate
		switch (input.data[i].type) {
		case TypeId::INT8:
			concatenate_keys<int8_t>(input.data[i], input.size(), keys, is_little_endian);
			break;
		case TypeId::INT16:
			concatenate_keys<int16_t>(input.data[i], input.size(), keys, is_little_endian);
			break;
		case TypeId::INT32:
			concatenate_keys<int32_t>(input.data[i], input.size(), keys, is_little_endian);
			break;
		case TypeId::INT64:
			concatenate_keys<int64_t>(input.data[i], input.size(), keys, is_little_endian);
			break;
		case TypeId::FLOAT:
			concatenate_keys<float>(input.data[i], input.size(), keys, is_little_endian);
			break;
		case TypeId::DOUBLE:
			concatenate_keys<double>(input.data[i], input.size(), keys, is_little_endian);
			break;
		case TypeId::VARCHAR:
			concatenate_keys<string_t>(input.data[i], input.size(), keys, is_little_endian);
			break;
		default:
			throw InvalidTypeException(input.data[0].type, "Invalid type for index");
		}
	}
}

bool ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) {
	assert(row_ids.type == ROW_TYPE);
	assert(types[0] == input.data[0].type);

	// generate the keys for the given input
	vector<unique_ptr<Key>> keys;
	GenerateKeys(input, keys);

	// now insert the elements into the index
	row_ids.Normalify(input.size());
	auto row_identifiers = FlatVector::GetData<row_t>(row_ids);
	idx_t failed_index = INVALID_INDEX;
	for (idx_t i = 0; i < input.size(); i++) {
		if (!keys[i]) {
			continue;
		}

		row_t row_id = row_identifiers[i];
		if (!Insert(tree, move(keys[i]), 0, row_id)) {
			// failed to insert because of constraint violation
			failed_index = i;
			break;
		}
	}
	if (failed_index != INVALID_INDEX) {
		// failed to insert because of constraint violation: remove previously inserted entries
		// generate keys again
		keys.clear();
		GenerateKeys(input, keys);
		unique_ptr<Key> key;

		// now erase the entries
		for (idx_t i = 0; i < failed_index; i++) {
			if (!keys[i]) {
				continue;
			}
			row_t row_id = row_identifiers[i];
			Erase(tree, *keys[i], 0, row_id);
		}
		return false;
	}
	return true;
}

bool ART::Append(IndexLock &lock, DataChunk &appended_data, Vector &row_identifiers) {
	// first resolve the expressions for the index
	ExecuteExpressions(appended_data, expression_result);

	// now insert into the index
	return Insert(lock, expression_result, row_identifiers);
}

void ART::VerifyAppend(DataChunk &chunk) {
	if (!is_unique) {
		return;
	}
	// unique index, check
	lock_guard<mutex> l(lock);
	// first resolve the expressions for the index
	ExecuteExpressions(chunk, expression_result);

	// generate the keys for the given input
	vector<unique_ptr<Key>> keys;
	GenerateKeys(expression_result, keys);

	for (idx_t i = 0; i < chunk.size(); i++) {
		if (!keys[i]) {
			continue;
		}
		if (Lookup(tree, *keys[i], 0) != nullptr) {
			// node already exists in tree
			throw ConstraintException("duplicate key value violates primary key or unique constraint");
		}
	}
}

bool ART::InsertToLeaf(Leaf &leaf, row_t row_id) {
	if (is_unique && leaf.num_elements != 0) {
		return false;
	}
	leaf.Insert(row_id);
	return true;
}

bool ART::Insert(unique_ptr<Node> &node, unique_ptr<Key> value, unsigned depth, row_t row_id) {
	Key &key = *value;
	if (!node) {
		// node is currently empty, create a leaf here with the key
		node = make_unique<Leaf>(*this, move(value), row_id);
		return true;
	}

	if (node->type == NodeType::NLeaf) {
		// Replace leaf with Node4 and store both leaves in it
		auto leaf = static_cast<Leaf *>(node.get());

		Key &existingKey = *leaf->value;
		uint32_t newPrefixLength = 0;
		// Leaf node is already there, update row_id vector
		if (depth + newPrefixLength == existingKey.len && existingKey.len == key.len) {
			return InsertToLeaf(*leaf, row_id);
		}
		while (existingKey[depth + newPrefixLength] == key[depth + newPrefixLength]) {
			newPrefixLength++;
			// Leaf node is already there, update row_id vector
			if (depth + newPrefixLength == existingKey.len && existingKey.len == key.len) {
				return InsertToLeaf(*leaf, row_id);
			}
		}

		unique_ptr<Node> newNode = make_unique<Node4>(*this, newPrefixLength);
		newNode->prefix_length = newPrefixLength;
		memcpy(newNode->prefix.get(), &key[depth], newPrefixLength);
		Node4::insert(*this, newNode, existingKey[depth + newPrefixLength], node);
		unique_ptr<Node> leaf_node = make_unique<Leaf>(*this, move(value), row_id);
		Node4::insert(*this, newNode, key[depth + newPrefixLength], leaf_node);
		node = move(newNode);
		return true;
	}

	// Handle prefix of inner node
	if (node->prefix_length) {
		uint32_t mismatchPos = Node::PrefixMismatch(*this, node.get(), key, depth);
		if (mismatchPos != node->prefix_length) {
			// Prefix differs, create new node
			unique_ptr<Node> newNode = make_unique<Node4>(*this, mismatchPos);
			newNode->prefix_length = mismatchPos;
			memcpy(newNode->prefix.get(), node->prefix.get(), mismatchPos);
			// Break up prefix
			auto node_ptr = node.get();
			Node4::insert(*this, newNode, node->prefix[mismatchPos], node);
			node_ptr->prefix_length -= (mismatchPos + 1);
			memmove(node_ptr->prefix.get(), node_ptr->prefix.get() + mismatchPos + 1, node_ptr->prefix_length);
			unique_ptr<Node> leaf_node = make_unique<Leaf>(*this, move(value), row_id);
			Node4::insert(*this, newNode, key[depth + mismatchPos], leaf_node);
			node = move(newNode);
			return true;
		}
		depth += node->prefix_length;
	}

	// Recurse
	idx_t pos = node->GetChildPos(key[depth]);
	if (pos != INVALID_INDEX) {
		auto child = node->GetChild(pos);
		return Insert(*child, move(value), depth + 1, row_id);
	}
	unique_ptr<Node> newNode = make_unique<Leaf>(*this, move(value), row_id);
	Node::InsertLeaf(*this, node, key[depth], newNode);
	return true;
}

//===--------------------------------------------------------------------===//
// Delete
//===--------------------------------------------------------------------===//
void ART::Delete(IndexLock &state, DataChunk &input, Vector &row_ids) {
	// first resolve the expressions
	ExecuteExpressions(input, expression_result);

	// then generate the keys for the given input
	vector<unique_ptr<Key>> keys;
	GenerateKeys(expression_result, keys);

	// now erase the elements from the database
	row_ids.Normalify(input.size());
	auto row_identifiers = FlatVector::GetData<row_t>(row_ids);

	for (idx_t i = 0; i < input.size(); i++) {
		if (!keys[i]) {
			continue;
		}
		Erase(tree, *keys[i], 0, row_identifiers[i]);
		// assert that the entry was erased properly
		assert(!is_unique || Lookup(tree, *keys[i], 0) == nullptr);
	}
}

void ART::Erase(unique_ptr<Node> &node, Key &key, unsigned depth, row_t row_id) {
	if (!node) {
		return;
	}
	// Delete a leaf from a tree
	if (node->type == NodeType::NLeaf) {
		// Make sure we have the right leaf
		if (ART::LeafMatches(node.get(), key, depth)) {
			node.reset();
		}
		return;
	}

	// Handle prefix
	if (node->prefix_length) {
		if (Node::PrefixMismatch(*this, node.get(), key, depth) != node->prefix_length) {
			return;
		}
		depth += node->prefix_length;
	}
	idx_t pos = node->GetChildPos(key[depth]);
	if (pos != INVALID_INDEX) {
		auto child = node->GetChild(pos);
		assert(child);

		unique_ptr<Node> &child_ref = *child;
		if (child_ref->type == NodeType::NLeaf && LeafMatches(child_ref.get(), key, depth)) {
			// Leaf found, remove entry
			auto leaf = static_cast<Leaf *>(child_ref.get());
			if (leaf->num_elements > 1) {
				// leaf has multiple rows: remove the row from the leaf
				leaf->Remove(row_id);
			} else {
				// Leaf only has one element, delete leaf, decrement node counter and maybe shrink node
				Node::Erase(*this, node, pos);
			}
		} else {
			// Recurse
			Erase(*child, key, depth + 1, row_id);
		}
	}
}

//===--------------------------------------------------------------------===//
// Point Query
//===--------------------------------------------------------------------===//
static unique_ptr<Key> CreateKey(ART &art, TypeId type, Value &value) {
	assert(type == value.type);
	switch (type) {
	case TypeId::INT8:
		return Key::CreateKey<int8_t>(value.value_.tinyint, art.is_little_endian);
	case TypeId::INT16:
		return Key::CreateKey<int16_t>(value.value_.smallint, art.is_little_endian);
	case TypeId::INT32:
		return Key::CreateKey<int32_t>(value.value_.integer, art.is_little_endian);
	case TypeId::INT64:
		return Key::CreateKey<int64_t>(value.value_.bigint, art.is_little_endian);
	case TypeId::FLOAT:
		return Key::CreateKey<float>(value.value_.float_, art.is_little_endian);
	case TypeId::DOUBLE:
		return Key::CreateKey<double>(value.value_.double_, art.is_little_endian);
	case TypeId::VARCHAR:
		return Key::CreateKey<string_t>(string_t(value.str_value.c_str(), value.str_value.size()),
		                                art.is_little_endian);
	default:
		throw InvalidTypeException(type, "Invalid type for index");
	}
}

void ART::SearchEqual(vector<row_t> &result_ids, ARTIndexScanState *state) {
	unique_ptr<Key> key = CreateKey(*this, types[0], state->values[0]);
	auto leaf = static_cast<Leaf *>(Lookup(tree, *key, 0));
	if (!leaf) {
		return;
	}
	for (idx_t i = 0; i < leaf->num_elements; i++) {
		row_t row_id = leaf->GetRowId(i);
		result_ids.push_back(row_id);
	}
}

Node *ART::Lookup(unique_ptr<Node> &node, Key &key, unsigned depth) {
	auto node_val = node.get();

	while (node_val) {
		if (node_val->type == NodeType::NLeaf) {
			auto leaf = static_cast<Leaf *>(node_val);
			Key &leafKey = *leaf->value;
			//! Check leaf
			for (idx_t i = depth; i < leafKey.len; i++) {
				if (leafKey[i] != key[i]) {
					return nullptr;
				}
			}
			return node_val;
		}
		if (node_val->prefix_length) {
			for (idx_t pos = 0; pos < node_val->prefix_length; pos++) {
				if (key[depth + pos] != node_val->prefix[pos]) {
					return nullptr;
				}
			}
			depth += node_val->prefix_length;
		}
		idx_t pos = node_val->GetChildPos(key[depth]);
		if (pos == INVALID_INDEX) {
			return nullptr;
		}
		node_val = node_val->GetChild(pos)->get();
		assert(node_val);

		depth++;
	}

	return nullptr;
}

//===--------------------------------------------------------------------===//
// Iterator scans
//===--------------------------------------------------------------------===//
template <bool HAS_BOUND, bool INCLUSIVE>
void ART::IteratorScan(ARTIndexScanState *state, Iterator *it, vector<row_t> &result_ids, Key *bound) {
	bool has_next;
	do {
		if (HAS_BOUND) {
			assert(bound);
			if (INCLUSIVE) {
				if (*it->node->value > *bound) {
					break;
				}
			} else {
				if (*it->node->value >= *bound) {
					break;
				}
			}
		}
		for (idx_t i = 0; i < it->node->num_elements; i++) {
			row_t row_id = it->node->GetRowId(i);
			result_ids.push_back(row_id);
		}
		has_next = ART::IteratorNext(*it);
	} while (has_next);
}

bool ART::IteratorNext(Iterator &it) {
	// Skip leaf
	if ((it.depth) && ((it.stack[it.depth - 1].node)->type == NodeType::NLeaf)) {
		it.depth--;
	}

	// Look for the next leaf
	while (it.depth > 0) {
		auto &top = it.stack[it.depth - 1];
		Node *node = top.node;

		if (node->type == NodeType::NLeaf) {
			// found a leaf: move to next node
			it.node = (Leaf *)node;
			return true;
		}

		// Find next node
		top.pos = node->GetNextPos(top.pos);
		if (top.pos != INVALID_INDEX) {
			// next node found: go there
			it.stack[it.depth].node = node->GetChild(top.pos)->get();
			it.stack[it.depth].pos = INVALID_INDEX;
			it.depth++;
		} else {
			// no node found: move up the tree
			it.depth--;
		}
	}
	return false;
}

//===--------------------------------------------------------------------===//
// Greater Than
// Returns: True (If found leaf >= key)
//          False (Otherwise)
//===--------------------------------------------------------------------===//
bool ART::Bound(unique_ptr<Node> &n, Key &key, Iterator &it, bool inclusive) {
	it.depth = 0;
	if (!n) {
		return false;
	}
	Node *node = n.get();

	idx_t depth = 0;
	while (true) {
		auto &top = it.stack[it.depth];
		top.node = node;
		it.depth++;

		if (node->type == NodeType::NLeaf) {
			// found a leaf node: check if it is bigger or equal than the current key
			auto leaf = static_cast<Leaf *>(node);
			it.node = leaf;
			// if the search is not inclusive the leaf node could still be equal to the current value
			// check if leaf is equal to the current key
			if (*leaf->value == key) {
				// if its not inclusive check if there is a next leaf
				if (!inclusive && !IteratorNext(it)) {
					return false;
				} else {
					return true;
				}
			}

			if (*leaf->value > key) {
				return true;
			}
			// Leaf is lower than key
			// Check if next leaf is still lower than key
			while (IteratorNext(it)) {
				if (*it.node->value == key) {
					// if its not inclusive check if there is a next leaf
					if (!inclusive && !IteratorNext(it)) {
						return false;
					} else {
						return true;
					}
				} else if (*it.node->value > key) {
					// if its not inclusive check if there is a next leaf
					return true;
				}
			}
			return false;
		}
		uint32_t mismatchPos = Node::PrefixMismatch(*this, node, key, depth);
		if (mismatchPos != node->prefix_length) {
			if (node->prefix[mismatchPos] < key[depth + mismatchPos]) {
				// Less
				it.depth--;
				return IteratorNext(it);
			} else {
				// Greater
				top.pos = INVALID_INDEX;
				return IteratorNext(it);
			}
		}
		// prefix matches, search inside the child for the key
		depth += node->prefix_length;

		top.pos = node->GetChildGreaterEqual(key[depth]);

		if (top.pos == INVALID_INDEX) {
			// Find min leaf
			top.pos = node->GetMin();
		}
		node = node->GetChild(top.pos)->get();
		depth++;
	}
}

void ART::SearchGreater(vector<row_t> &result_ids, ARTIndexScanState *state, bool inclusive) {
	Iterator *it = &state->iterator;
	auto key = CreateKey(*this, types[0], state->values[0]);

	// greater than scan: first set the iterator to the node at which we will start our scan by finding the lowest node
	// that satisfies our requirement
	if (!it->start) {
		bool found = ART::Bound(tree, *key, *it, inclusive);
		if (!found) {
			return;
		}
		it->start = true;
	}
	// after that we continue the scan; we don't need to check the bounds as any value following this value is
	// automatically bigger and hence satisfies our predicate
	IteratorScan<false, false>(state, it, result_ids, nullptr);
}

//===--------------------------------------------------------------------===//
// Less Than
//===--------------------------------------------------------------------===//
static Leaf &FindMinimum(Iterator &it, Node &node) {
	Node *next = nullptr;
	idx_t pos = 0;
	switch (node.type) {
	case NodeType::NLeaf:
		it.node = (Leaf *)&node;
		return (Leaf &)node;
	case NodeType::N4:
		next = ((Node4 &)node).child[0].get();
		break;
	case NodeType::N16:
		next = ((Node16 &)node).child[0].get();
		break;
	case NodeType::N48: {
		auto &n48 = (Node48 &)node;
		while (n48.childIndex[pos] == Node::EMPTY_MARKER) {
			pos++;
		}
		next = n48.child[n48.childIndex[pos]].get();
		break;
	}
	case NodeType::N256: {
		auto &n256 = (Node256 &)node;
		while (!n256.child[pos]) {
			pos++;
		}
		next = n256.child[pos].get();
		break;
	}
	}
	it.stack[it.depth].node = &node;
	it.stack[it.depth].pos = pos;
	it.depth++;
	return FindMinimum(it, *next);
}

void ART::SearchLess(vector<row_t> &result_ids, ARTIndexScanState *state, bool inclusive) {
	if (!tree) {
		return;
	}

	Iterator *it = &state->iterator;
	auto upper_bound = CreateKey(*this, types[0], state->values[0]);

	if (!it->start) {
		// first find the minimum value in the ART: we start scanning from this value
		auto &minimum = FindMinimum(state->iterator, *tree);
		// early out min value higher than upper bound query
		if (*minimum.value > *upper_bound) {
			return;
		}
		it->start = true;
	}
	// now continue the scan until we reach the upper bound
	if (inclusive) {
		IteratorScan<true, true>(state, it, result_ids, upper_bound.get());
	} else {
		IteratorScan<true, false>(state, it, result_ids, upper_bound.get());
	}
}

//===--------------------------------------------------------------------===//
// Closed Range Query
//===--------------------------------------------------------------------===//
void ART::SearchCloseRange(vector<row_t> &result_ids, ARTIndexScanState *state, bool left_inclusive,
                           bool right_inclusive) {
	auto lower_bound = CreateKey(*this, types[0], state->values[0]);
	auto upper_bound = CreateKey(*this, types[0], state->values[1]);
	Iterator *it = &state->iterator;
	// first find the first node that satisfies the left predicate
	if (!it->start) {
		bool found = ART::Bound(tree, *lower_bound, *it, left_inclusive);
		if (!found) {
			return;
		}
		it->start = true;
	}
	// now continue the scan until we reach the upper bound
	if (right_inclusive) {
		IteratorScan<true, true>(state, it, result_ids, upper_bound.get());
	} else {
		IteratorScan<true, false>(state, it, result_ids, upper_bound.get());
	}
}

void ART::Scan(Transaction &transaction, TableIndexScanState &table_state, DataChunk &result) {
	auto state = (ARTIndexScanState *)table_state.index_state.get();

	// scan the index
	if (!state->checked) {
		vector<row_t> result_ids;
		assert(state->values[0].type == types[0]);

		if (state->values[1].is_null) {
			lock_guard<mutex> l(lock);
			// single predicate
			switch (state->expressions[0]) {
			case ExpressionType::COMPARE_EQUAL:
				SearchEqual(result_ids, state);
				break;
			case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
				SearchGreater(result_ids, state, true);
				break;
			case ExpressionType::COMPARE_GREATERTHAN:
				SearchGreater(result_ids, state, false);
				break;
			case ExpressionType::COMPARE_LESSTHANOREQUALTO:
				SearchLess(result_ids, state, true);
				break;
			case ExpressionType::COMPARE_LESSTHAN:
				SearchLess(result_ids, state, false);
				break;
			default:
				throw NotImplementedException("Operation not implemented");
			}
		} else {
			lock_guard<mutex> l(lock);
			// two predicates
			assert(state->values[1].type == types[0]);
			bool left_inclusive = state->expressions[0] == ExpressionType ::COMPARE_GREATERTHANOREQUALTO;
			bool right_inclusive = state->expressions[1] == ExpressionType ::COMPARE_LESSTHANOREQUALTO;
			SearchCloseRange(result_ids, state, left_inclusive, right_inclusive);
		}
		state->checked = true;

		if (result_ids.size() == 0) {
			return;
		}

		// sort the row ids
		sort(result_ids.begin(), result_ids.end());
		// duplicate eliminate the row ids and append them to the row ids of the state
		state->result_ids.reserve(result_ids.size());

		state->result_ids.push_back(result_ids[0]);
		for (idx_t i = 1; i < result_ids.size(); i++) {
			if (result_ids[i] != result_ids[i - 1]) {
				state->result_ids.push_back(result_ids[i]);
			}
		}
	}

	if (state->result_index >= state->result_ids.size()) {
		// exhausted all row ids
		return;
	}

	// create a vector pointing to the current set of row ids
	Vector row_identifiers(ROW_TYPE, (data_ptr_t)&state->result_ids[state->result_index]);
	idx_t scan_count = std::min((idx_t)STANDARD_VECTOR_SIZE, (idx_t)state->result_ids.size() - state->result_index);

	// fetch the actual values from the base table
	table.Fetch(transaction, result, state->column_ids, row_identifiers, scan_count, table_state);

	// move to the next set of row ids
	state->result_index += scan_count;
}
#include <cfloat>
#include <limits.h>
#include <cstring> // strlen() on Solaris




using namespace duckdb;

//! these are optimized and assume a particular byte order
#define BSWAP16(x) ((uint16_t)((((uint16_t)(x)&0xff00) >> 8) | (((uint16_t)(x)&0x00ff) << 8)))

#define BSWAP32(x)                                                                                                     \
	((uint32_t)((((uint32_t)(x)&0xff000000) >> 24) | (((uint32_t)(x)&0x00ff0000) >> 8) |                               \
	            (((uint32_t)(x)&0x0000ff00) << 8) | (((uint32_t)(x)&0x000000ff) << 24)))

#define BSWAP64(x)                                                                                                     \
	((uint64_t)((((uint64_t)(x)&0xff00000000000000ull) >> 56) | (((uint64_t)(x)&0x00ff000000000000ull) >> 40) |        \
	            (((uint64_t)(x)&0x0000ff0000000000ull) >> 24) | (((uint64_t)(x)&0x000000ff00000000ull) >> 8) |         \
	            (((uint64_t)(x)&0x00000000ff000000ull) << 8) | (((uint64_t)(x)&0x0000000000ff0000ull) << 24) |         \
	            (((uint64_t)(x)&0x000000000000ff00ull) << 40) | (((uint64_t)(x)&0x00000000000000ffull) << 56)))

static uint8_t FlipSign(uint8_t key_byte) {
	return key_byte ^ 128;
}

uint32_t Key::EncodeFloat(float x) {
	unsigned long buff;

	//! zero
	if (x == 0) {
		buff = 0;
		buff |= (1u << 31);
		return buff;
	}
	//! infinity
	if (x > FLT_MAX) {
		return UINT_MAX;
	}
	//! -infinity
	if (x < -FLT_MAX) {
		return 0;
	}
	buff = reinterpret_cast<uint32_t *>(&x)[0];
	if ((buff & (1u << 31)) == 0) { //! +0 and positive numbers
		buff |= (1u << 31);
	} else {          //! negative numbers
		buff = ~buff; //! complement 1
	}

	return buff;
}

uint64_t Key::EncodeDouble(double x) {
	uint64_t buff;
	//! zero
	if (x == 0) {
		buff = 0;
		buff += (1ull << 63);
		return buff;
	}
	//! infinity
	if (x > DBL_MAX) {
		return ULLONG_MAX;
	}
	//! -infinity
	if (x < -DBL_MAX) {
		return 0;
	}
	buff = reinterpret_cast<uint64_t *>(&x)[0];
	if (buff < (1ull << 63)) { //! +0 and positive numbers
		buff += (1ull << 63);
	} else {          //! negative numbers
		buff = ~buff; //! complement 1
	}
	return buff;
}

Key::Key(unique_ptr<data_t[]> data, idx_t len) : len(len), data(move(data)) {
}

template <> unique_ptr<data_t[]> Key::CreateData(int8_t value, bool is_little_endian) {
	auto data = unique_ptr<data_t[]>(new data_t[sizeof(value)]);
	reinterpret_cast<uint8_t *>(data.get())[0] = value;
	data[0] = FlipSign(data[0]);
	return data;
}

template <> unique_ptr<data_t[]> Key::CreateData(int16_t value, bool is_little_endian) {
	auto data = unique_ptr<data_t[]>(new data_t[sizeof(value)]);
	reinterpret_cast<uint16_t *>(data.get())[0] = is_little_endian ? BSWAP16(value) : value;
	data[0] = FlipSign(data[0]);
	return data;
}

template <> unique_ptr<data_t[]> Key::CreateData(int32_t value, bool is_little_endian) {
	auto data = unique_ptr<data_t[]>(new data_t[sizeof(value)]);
	reinterpret_cast<uint32_t *>(data.get())[0] = is_little_endian ? BSWAP32(value) : value;
	data[0] = FlipSign(data[0]);
	return data;
}

template <> unique_ptr<data_t[]> Key::CreateData(int64_t value, bool is_little_endian) {
	auto data = unique_ptr<data_t[]>(new data_t[sizeof(value)]);
	reinterpret_cast<uint64_t *>(data.get())[0] = is_little_endian ? BSWAP64(value) : value;
	data[0] = FlipSign(data[0]);
	return data;
}

template <> unique_ptr<data_t[]> Key::CreateData(float value, bool is_little_endian) {
	uint32_t converted_value = EncodeFloat(value);
	auto data = unique_ptr<data_t[]>(new data_t[sizeof(converted_value)]);
	reinterpret_cast<uint32_t *>(data.get())[0] = is_little_endian ? BSWAP32(converted_value) : converted_value;
	return data;
}
template <> unique_ptr<data_t[]> Key::CreateData(double value, bool is_little_endian) {
	uint64_t converted_value = EncodeDouble(value);
	auto data = unique_ptr<data_t[]>(new data_t[sizeof(converted_value)]);
	reinterpret_cast<uint64_t *>(data.get())[0] = is_little_endian ? BSWAP64(converted_value) : converted_value;
	return data;
}

template <> unique_ptr<Key> Key::CreateKey(string_t value, bool is_little_endian) {
	idx_t len = value.GetSize() + 1;
	auto data = unique_ptr<data_t[]>(new data_t[len]);
	memcpy(data.get(), value.GetData(), len);
	return make_unique<Key>(move(data), len);
}

template <> unique_ptr<Key> Key::CreateKey(const char *value, bool is_little_endian) {
	return Key::CreateKey(string_t(value, strlen(value)), is_little_endian);
}

bool Key::operator>(const Key &k) const {
	for (idx_t i = 0; i < std::min(len, k.len); i++) {
		if (data[i] > k.data[i]) {
			return true;
		} else if (data[i] < k.data[i]) {
			return false;
		}
	}
	return len > k.len;
}

bool Key::operator<(const Key &k) const {
	for (idx_t i = 0; i < std::min(len, k.len); i++) {
		if (data[i] < k.data[i]) {
			return true;
		} else if (data[i] > k.data[i]) {
			return false;
		}
	}
	return len < k.len;
}

bool Key::operator>=(const Key &k) const {
	for (idx_t i = 0; i < std::min(len, k.len); i++) {
		if (data[i] > k.data[i]) {
			return true;
		} else if (data[i] < k.data[i]) {
			return false;
		}
	}
	return len >= k.len;
}

bool Key::operator==(const Key &k) const {
	if (len != k.len) {
		return false;
	}
	for (idx_t i = 0; i < len; i++) {
		if (data[i] != k.data[i]) {
			return false;
		}
	}
	return true;
}



#include <cstring>

using namespace duckdb;
using namespace std;

Leaf::Leaf(ART &art, unique_ptr<Key> value, row_t row_id) : Node(art, NodeType::NLeaf, 0) {
	this->value = move(value);
	this->capacity = 1;
	this->row_ids = unique_ptr<row_t[]>(new row_t[this->capacity]);
	this->row_ids[0] = row_id;
	this->num_elements = 1;
}

void Leaf::Insert(row_t row_id) {
	// Grow array
	if (num_elements == capacity) {
		auto new_row_id = unique_ptr<row_t[]>(new row_t[capacity * 2]);
		memcpy(new_row_id.get(), row_ids.get(), capacity * sizeof(row_t));
		capacity *= 2;
		row_ids = move(new_row_id);
	}
	row_ids[num_elements++] = row_id;
}

//! TODO: Maybe shrink array dynamically?
void Leaf::Remove(row_t row_id) {
	idx_t entry_offset = -1;
	for (idx_t i = 0; i < num_elements; i++) {
		if (row_ids[i] == row_id) {
			entry_offset = i;
			break;
		}
	}
	num_elements--;
	for (idx_t j = entry_offset; j < num_elements; j++) {
		row_ids[j] = row_ids[j + 1];
	}
}




using namespace duckdb;

Node::Node(ART &art, NodeType type, size_t compressedPrefixSize) : prefix_length(0), count(0), type(type) {
	this->prefix = unique_ptr<uint8_t[]>(new uint8_t[compressedPrefixSize]);
}

void Node::CopyPrefix(ART &art, Node *src, Node *dst) {
	dst->prefix_length = src->prefix_length;
	memcpy(dst->prefix.get(), src->prefix.get(), src->prefix_length);
}

unique_ptr<Node> *Node::GetChild(idx_t pos) {
	assert(0);
	return nullptr;
}

idx_t Node::GetMin() {
	assert(0);
	return 0;
}

uint32_t Node::PrefixMismatch(ART &art, Node *node, Key &key, uint64_t depth) {
	uint64_t pos;
	for (pos = 0; pos < node->prefix_length; pos++) {
		if (key[depth + pos] != node->prefix[pos]) {
			return pos;
		}
	}
	return pos;
}

void Node::InsertLeaf(ART &art, unique_ptr<Node> &node, uint8_t key, unique_ptr<Node> &newNode) {
	switch (node->type) {
	case NodeType::N4:
		Node4::insert(art, node, key, newNode);
		break;
	case NodeType::N16:
		Node16::insert(art, node, key, newNode);
		break;
	case NodeType::N48:
		Node48::insert(art, node, key, newNode);
		break;
	case NodeType::N256:
		Node256::insert(art, node, key, newNode);
		break;
	default:
		assert(0);
	}
}

void Node::Erase(ART &art, unique_ptr<Node> &node, idx_t pos) {
	switch (node->type) {
	case NodeType::N4: {
		Node4::erase(art, node, pos);
		break;
	}
	case NodeType::N16: {
		Node16::erase(art, node, pos);
		break;
	}
	case NodeType::N48: {
		Node48::erase(art, node, pos);
		break;
	}
	case NodeType::N256:
		Node256::erase(art, node, pos);
		break;
	default:
		assert(0);
		break;
	}
}




#include <cstring>

using namespace duckdb;

Node16::Node16(ART &art, size_t compressionLength) : Node(art, NodeType::N16, compressionLength) {
	memset(key, 16, sizeof(key));
}

// TODO : In the future this can be performed using SIMD (#include <emmintrin.h>  x86 SSE intrinsics)
idx_t Node16::GetChildPos(uint8_t k) {
	for (idx_t pos = 0; pos < count; pos++) {
		if (key[pos] == k) {
			return pos;
		}
	}
	return Node::GetChildPos(k);
}

idx_t Node16::GetChildGreaterEqual(uint8_t k) {
	for (idx_t pos = 0; pos < count; pos++) {
		if (key[pos] >= k) {
			return pos;
		}
	}
	return Node::GetChildGreaterEqual(k);
}

idx_t Node16::GetNextPos(idx_t pos) {
	if (pos == INVALID_INDEX) {
		return 0;
	}
	pos++;
	return pos < count ? pos : INVALID_INDEX;
}

unique_ptr<Node> *Node16::GetChild(idx_t pos) {
	assert(pos < count);
	return &child[pos];
}

idx_t Node16::GetMin() {
	return 0;
}

void Node16::insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child) {
	Node16 *n = static_cast<Node16 *>(node.get());

	if (n->count < 16) {
		// Insert element
		unsigned pos;
		for (pos = 0; (pos < node->count) && (n->key[pos] < keyByte); pos++)
			;
		if (n->child[pos] != nullptr) {
			for (unsigned i = n->count; i > pos; i--) {
				n->key[i] = n->key[i - 1];
				n->child[i] = move(n->child[i - 1]);
			}
		}
		n->key[pos] = keyByte;
		n->child[pos] = move(child);
		n->count++;
	} else {
		// Grow to Node48
		auto newNode = make_unique<Node48>(art, n->prefix_length);
		for (unsigned i = 0; i < node->count; i++) {
			newNode->childIndex[n->key[i]] = i;
			newNode->child[i] = move(n->child[i]);
		}
		CopyPrefix(art, n, newNode.get());
		newNode->count = node->count;
		node = move(newNode);

		Node48::insert(art, node, keyByte, child);
	}
}

void Node16::erase(ART &art, unique_ptr<Node> &node, int pos) {
	Node16 *n = static_cast<Node16 *>(node.get());
	// erase the child and decrease the count
	n->child[pos].reset();
	n->count--;
	// potentially move any children backwards
	for (; pos < n->count; pos++) {
		n->key[pos] = n->key[pos + 1];
		n->child[pos] = move(n->child[pos + 1]);
	}
	if (node->count <= 3) {
		// Shrink node
		auto newNode = make_unique<Node4>(art, n->prefix_length);
		for (unsigned i = 0; i < n->count; i++) {
			newNode->key[newNode->count] = n->key[i];
			newNode->child[newNode->count++] = move(n->child[i]);
		}
		CopyPrefix(art, n, newNode.get());
		node = move(newNode);
	}
}



using namespace duckdb;

Node256::Node256(ART &art, size_t compressionLength) : Node(art, NodeType::N256, compressionLength) {
}

idx_t Node256::GetChildPos(uint8_t k) {
	if (child[k]) {
		return k;
	} else {
		return INVALID_INDEX;
	}
}

idx_t Node256::GetChildGreaterEqual(uint8_t k) {
	for (idx_t pos = k; pos < 256; pos++) {
		if (child[pos]) {
			return pos;
		}
	}
	return INVALID_INDEX;
}

idx_t Node256::GetMin() {
	for (idx_t i = 0; i < 256; i++) {
		if (child[i]) {
			return i;
		}
	}
	return INVALID_INDEX;
}

idx_t Node256::GetNextPos(idx_t pos) {
	for (pos == INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) {
		if (child[pos]) {
			return pos;
		}
	}
	return Node::GetNextPos(pos);
}

unique_ptr<Node> *Node256::GetChild(idx_t pos) {
	assert(child[pos]);
	return &child[pos];
}

void Node256::insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child) {
	Node256 *n = static_cast<Node256 *>(node.get());

	n->count++;
	n->child[keyByte] = move(child);
}

void Node256::erase(ART &art, unique_ptr<Node> &node, int pos) {
	Node256 *n = static_cast<Node256 *>(node.get());

	n->child[pos].reset();
	n->count--;
	if (node->count <= 36) {
		auto newNode = make_unique<Node48>(art, n->prefix_length);
		CopyPrefix(art, n, newNode.get());
		for (idx_t i = 0; i < 256; i++) {
			if (n->child[i]) {
				newNode->childIndex[i] = newNode->count;
				newNode->child[newNode->count] = move(n->child[i]);
				newNode->count++;
			}
		}
		node = move(newNode);
	}
}




using namespace duckdb;

Node4::Node4(ART &art, size_t compressionLength) : Node(art, NodeType::N4, compressionLength) {
	memset(key, 0, sizeof(key));
}

idx_t Node4::GetChildPos(uint8_t k) {
	for (idx_t pos = 0; pos < count; pos++) {
		if (key[pos] == k) {
			return pos;
		}
	}
	return Node::GetChildPos(k);
}

idx_t Node4::GetChildGreaterEqual(uint8_t k) {
	for (idx_t pos = 0; pos < count; pos++) {
		if (key[pos] >= k) {
			return pos;
		}
	}
	return Node::GetChildGreaterEqual(k);
}

idx_t Node4::GetMin() {
	return 0;
}

idx_t Node4::GetNextPos(idx_t pos) {
	if (pos == INVALID_INDEX) {
		return 0;
	}
	pos++;
	return pos < count ? pos : INVALID_INDEX;
}

unique_ptr<Node> *Node4::GetChild(idx_t pos) {
	assert(pos < count);
	return &child[pos];
}

void Node4::insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child) {
	Node4 *n = static_cast<Node4 *>(node.get());

	// Insert leaf into inner node
	if (node->count < 4) {
		// Insert element
		unsigned pos;
		for (pos = 0; (pos < node->count) && (n->key[pos] < keyByte); pos++)
			;
		if (n->child[pos] != nullptr) {
			for (unsigned i = n->count; i > pos; i--) {
				n->key[i] = n->key[i - 1];
				n->child[i] = move(n->child[i - 1]);
			}
		}
		n->key[pos] = keyByte;
		n->child[pos] = move(child);
		n->count++;
	} else {
		// Grow to Node16
		auto newNode = make_unique<Node16>(art, n->prefix_length);
		newNode->count = 4;
		CopyPrefix(art, node.get(), newNode.get());
		for (unsigned i = 0; i < 4; i++) {
			newNode->key[i] = n->key[i];
			newNode->child[i] = move(n->child[i]);
		}
		node = move(newNode);
		Node16::insert(art, node, keyByte, child);
	}
}

void Node4::erase(ART &art, unique_ptr<Node> &node, int pos) {
	Node4 *n = static_cast<Node4 *>(node.get());
	assert(pos < n->count);

	// erase the child and decrease the count
	n->child[pos].reset();
	n->count--;
	// potentially move any children backwards
	for (; pos < n->count; pos++) {
		n->key[pos] = n->key[pos + 1];
		n->child[pos] = move(n->child[pos + 1]);
	}

	// This is a one way node
	if (n->count == 1) {
		auto childref = n->child[0].get();
		//! concatenate prefixes
		auto new_length = node->prefix_length + childref->prefix_length + 1;
		//! have to allocate space in our prefix array
		unique_ptr<uint8_t[]> new_prefix = unique_ptr<uint8_t[]>(new uint8_t[new_length]);
		;

		//! first move the existing prefix (if any)
		for (uint32_t i = 0; i < childref->prefix_length; i++) {
			new_prefix[new_length - (i + 1)] = childref->prefix[childref->prefix_length - (i + 1)];
		}
		//! now move the current key as part of the prefix
		new_prefix[node->prefix_length] = n->key[0];
		//! finally add the old prefix
		for (uint32_t i = 0; i < node->prefix_length; i++) {
			new_prefix[i] = node->prefix[i];
		}
		//! set new prefix and move the child
		childref->prefix = move(new_prefix);
		childref->prefix_length = new_length;
		node = move(n->child[0]);
	}
}




using namespace duckdb;

Node48::Node48(ART &art, size_t compressionLength) : Node(art, NodeType::N48, compressionLength) {
	for (idx_t i = 0; i < 256; i++) {
		childIndex[i] = Node::EMPTY_MARKER;
	}
}

idx_t Node48::GetChildPos(uint8_t k) {
	if (childIndex[k] == Node::EMPTY_MARKER) {
		return INVALID_INDEX;
	} else {
		return k;
	}
}

idx_t Node48::GetChildGreaterEqual(uint8_t k) {
	for (idx_t pos = k; pos < 256; pos++) {
		if (childIndex[pos] != Node::EMPTY_MARKER) {
			return pos;
		}
	}
	return Node::GetChildGreaterEqual(k);
}

idx_t Node48::GetNextPos(idx_t pos) {
	for (pos == INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) {
		if (childIndex[pos] != Node::EMPTY_MARKER) {
			return pos;
		}
	}
	return Node::GetNextPos(pos);
}

unique_ptr<Node> *Node48::GetChild(idx_t pos) {
	assert(childIndex[pos] != Node::EMPTY_MARKER);
	return &child[childIndex[pos]];
}

idx_t Node48::GetMin() {
	for (idx_t i = 0; i < 256; i++) {
		if (childIndex[i] != Node::EMPTY_MARKER) {
			return i;
		}
	}
	return INVALID_INDEX;
}

void Node48::insert(ART &art, unique_ptr<Node> &node, uint8_t keyByte, unique_ptr<Node> &child) {
	Node48 *n = static_cast<Node48 *>(node.get());

	// Insert leaf into inner node
	if (node->count < 48) {
		// Insert element
		idx_t pos = n->count;
		if (n->child[pos]) {
			// find an empty position in the node list if the current position is occupied
			pos = 0;
			while (n->child[pos]) {
				pos++;
			}
		}
		n->child[pos] = move(child);
		n->childIndex[keyByte] = pos;
		n->count++;
	} else {
		// Grow to Node256
		auto newNode = make_unique<Node256>(art, n->prefix_length);
		for (idx_t i = 0; i < 256; i++) {
			if (n->childIndex[i] != Node::EMPTY_MARKER) {
				newNode->child[i] = move(n->child[n->childIndex[i]]);
			}
		}
		newNode->count = n->count;
		CopyPrefix(art, n, newNode.get());
		node = move(newNode);
		Node256::insert(art, node, keyByte, child);
	}
}

void Node48::erase(ART &art, unique_ptr<Node> &node, int pos) {
	Node48 *n = static_cast<Node48 *>(node.get());

	n->child[n->childIndex[pos]].reset();
	n->childIndex[pos] = Node::EMPTY_MARKER;
	n->count--;
	if (node->count <= 12) {
		auto newNode = make_unique<Node16>(art, n->prefix_length);
		CopyPrefix(art, n, newNode.get());
		for (idx_t i = 0; i < 256; i++) {
			if (n->childIndex[i] != Node::EMPTY_MARKER) {
				newNode->key[newNode->count] = i;
				newNode->child[newNode->count++] = move(n->child[n->childIndex[i]]);
			}
		}
		node = move(newNode);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/join_hashtable.hpp
//
//
//===----------------------------------------------------------------------===//










#include <mutex>

namespace duckdb {
class BufferManager;
class BufferHandle;

//! JoinHashTable is a linear probing HT that is used for computing joins
/*!
   The JoinHashTable concatenates incoming chunks inside a linked list of
   data ptrs. The storage looks like this internally.
   [SERIALIZED ROW][NEXT POINTER]
   [SERIALIZED ROW][NEXT POINTER]
   There is a separate hash map of pointers that point into this table.
   This is what is used to resolve the hashes.
   [POINTER]
   [POINTER]
   [POINTER]
   The pointers are either NULL
*/
class JoinHashTable {
public:
	//! Scan structure that can be used to resume scans, as a single probe can
	//! return 1024*N values (where N is the size of the HT). This is
	//! returned by the JoinHashTable::Scan function and can be used to resume a
	//! probe.
	struct ScanStructure {
		unique_ptr<VectorData[]> key_data;
		Vector pointers;
		idx_t count;
		SelectionVector sel_vector;
		// whether or not the given tuple has found a match
		unique_ptr<bool[]> found_match;
		JoinHashTable &ht;
		bool finished;

		ScanStructure(JoinHashTable &ht);
		//! Get the next batch of data from the scan structure
		void Next(DataChunk &keys, DataChunk &left, DataChunk &result);

	private:
		void AdvancePointers();
		void AdvancePointers(const SelectionVector &sel, idx_t sel_count);

		//! Next operator for the inner join
		void NextInnerJoin(DataChunk &keys, DataChunk &left, DataChunk &result);
		//! Next operator for the semi join
		void NextSemiJoin(DataChunk &keys, DataChunk &left, DataChunk &result);
		//! Next operator for the anti join
		void NextAntiJoin(DataChunk &keys, DataChunk &left, DataChunk &result);
		//! Next operator for the left outer join
		void NextLeftJoin(DataChunk &keys, DataChunk &left, DataChunk &result);
		//! Next operator for the mark join
		void NextMarkJoin(DataChunk &keys, DataChunk &left, DataChunk &result);
		//! Next operator for the single join
		void NextSingleJoin(DataChunk &keys, DataChunk &left, DataChunk &result);

		//! Scan the hashtable for matches of the specified keys, setting the found_match[] array to true or false for
		//! every tuple
		void ScanKeyMatches(DataChunk &keys);
		template <bool MATCH> void NextSemiOrAntiJoin(DataChunk &keys, DataChunk &left, DataChunk &result);

		void ConstructMarkJoinResult(DataChunk &join_keys, DataChunk &child, DataChunk &result);

		idx_t ScanInnerJoin(DataChunk &keys, SelectionVector &result_vector);

		idx_t ResolvePredicates(DataChunk &keys, SelectionVector &match_sel);
		idx_t ResolvePredicates(DataChunk &keys, SelectionVector &match_sel, SelectionVector &no_match_sel);
		void GatherResult(Vector &result, const SelectionVector &result_vector, const SelectionVector &sel_vector,
		                  idx_t count, idx_t &offset);
		void GatherResult(Vector &result, const SelectionVector &sel_vector, idx_t count, idx_t &offset);

		template <bool NO_MATCH_SEL>
		idx_t ResolvePredicates(DataChunk &keys, SelectionVector *match_sel, SelectionVector *no_match_sel);
	};

private:
	//! Nodes store the actual data of the tuples inside the HT as a linked list
	struct HTDataBlock {
		idx_t count;
		idx_t capacity;
		block_id_t block_id;
	};

	idx_t AppendToBlock(HTDataBlock &block, BufferHandle &handle, idx_t count, data_ptr_t key_locations[],
	                    idx_t remaining);

	void Hash(DataChunk &keys, const SelectionVector &sel, idx_t count, Vector &hashes);

public:
	JoinHashTable(BufferManager &buffer_manager, vector<JoinCondition> &conditions, vector<TypeId> build_types,
	              JoinType type);
	~JoinHashTable();

	//! Add the given data to the HT
	void Build(DataChunk &keys, DataChunk &input);
	//! Finalize the build of the HT, constructing the actual hash table and making the HT ready for probing. Finalize
	//! must be called before any call to Probe, and after Finalize is called Build should no longer be ever called.
	void Finalize();
	//! Probe the HT with the given input chunk, resulting in the given result
	unique_ptr<ScanStructure> Probe(DataChunk &keys);

	idx_t size() {
		return count;
	}

	//! The stringheap of the JoinHashTable
	StringHeap string_heap;
	//! BufferManager
	BufferManager &buffer_manager;
	//! The types of the keys used in equality comparison
	vector<TypeId> equality_types;
	//! The types of the keys
	vector<TypeId> condition_types;
	//! The types of all conditions
	vector<TypeId> build_types;
	//! The comparison predicates
	vector<ExpressionType> predicates;
	//! Size of condition keys
	idx_t equality_size;
	//! Size of condition keys
	idx_t condition_size;
	//! Size of build tuple
	idx_t build_size;
	//! The size of an entry as stored in the HashTable
	idx_t entry_size;
	//! The total tuple size
	idx_t tuple_size;
	//! The join type of the HT
	JoinType join_type;
	//! Whether or not the HT has been finalized
	bool finalized;
	//! Whether or not any of the key elements contain NULL
	bool has_null;
	//! Bitmask for getting relevant bits from the hashes to determine the position
	uint64_t bitmask;
	//! The amount of entries stored per block
	idx_t block_capacity;

	struct {
		//! The types of the duplicate eliminated columns, only used in correlated MARK JOIN for flattening ANY()/ALL()
		//! expressions
		vector<TypeId> correlated_types;
		//! The aggregate expression nodes used by the HT
		vector<unique_ptr<Expression>> correlated_aggregates;
		//! The HT that holds the group counts for every correlated column
		unique_ptr<SuperLargeHashTable> correlated_counts;
		//! Group chunk used for aggregating into correlated_counts
		DataChunk group_chunk;
		//! Payload chunk used for aggregating into correlated_counts
		DataChunk payload_chunk;
		//! Result chunk used for aggregating into correlated_counts
		DataChunk result_chunk;
	} correlated_mark_join_info;

private:
	//! Apply a bitmask to the hashes
	void ApplyBitmask(Vector &hashes, idx_t count);
	void ApplyBitmask(Vector &hashes, const SelectionVector &sel, idx_t count, Vector &pointers);
	//! Insert the given set of locations into the HT with the given set of
	//! hashes. Caller should hold lock in parallel HT.
	void InsertHashes(Vector &hashes, idx_t count, data_ptr_t key_locations[]);

	idx_t PrepareKeys(DataChunk &keys, unique_ptr<VectorData[]> &key_data, const SelectionVector *&current_sel,
	                  SelectionVector &sel);
	void SerializeVectorData(VectorData &vdata, TypeId type, const SelectionVector &sel, idx_t count,
	                         data_ptr_t key_locations[]);
	void SerializeVector(Vector &v, idx_t vcount, const SelectionVector &sel, idx_t count, data_ptr_t key_locations[]);

	//! The amount of entries stored in the HT currently
	idx_t count;
	//! The blocks holding the main data of the hash table
	vector<HTDataBlock> blocks;
	//! Pinned handles, these are pinned during finalization only
	vector<unique_ptr<BufferHandle>> pinned_handles;
	//! The hash map of the HT, created after finalization
	unique_ptr<BufferHandle> hash_map;
	//! Whether or not NULL values are considered equal in each of the comparisons
	vector<bool> null_values_are_equal;

	//! Copying not allowed
	JoinHashTable(const JoinHashTable &) = delete;
};

} // namespace duckdb










using namespace std;

namespace duckdb {

using ScanStructure = JoinHashTable::ScanStructure;

JoinHashTable::JoinHashTable(BufferManager &buffer_manager, vector<JoinCondition> &conditions, vector<TypeId> btypes,
                             JoinType type)
    : buffer_manager(buffer_manager), build_types(move(btypes)), equality_size(0), condition_size(0), build_size(0),
      entry_size(0), tuple_size(0), join_type(type), finalized(false), has_null(false), count(0) {
	for (auto &condition : conditions) {
		assert(condition.left->return_type == condition.right->return_type);
		auto type = condition.left->return_type;
		auto type_size = GetTypeIdSize(type);
		if (condition.comparison == ExpressionType::COMPARE_EQUAL) {
			// all equality conditions should be at the front
			// all other conditions at the back
			// this assert checks that
			assert(equality_types.size() == condition_types.size());
			equality_types.push_back(type);
			equality_size += type_size;
		}
		predicates.push_back(condition.comparison);
		null_values_are_equal.push_back(condition.null_values_are_equal);
		assert(!condition.null_values_are_equal ||
		       (condition.null_values_are_equal && condition.comparison == ExpressionType::COMPARE_EQUAL));

		condition_types.push_back(type);
		condition_size += type_size;
	}
	// at least one equality is necessary
	assert(equality_types.size() > 0);

	if (type == JoinType::ANTI || type == JoinType::SEMI || type == JoinType::MARK) {
		// for ANTI, SEMI and MARK join, we only need to store the keys
		build_size = 0;
		build_types.clear();
	} else {
		// otherwise we need to store the entire build side for reconstruction
		// purposes
		for (idx_t i = 0; i < build_types.size(); i++) {
			build_size += GetTypeIdSize(build_types[i]);
		}
	}
	tuple_size = condition_size + build_size;
	// entry size is the tuple size and the size of the hash/next pointer
	entry_size = tuple_size + std::max(sizeof(hash_t), sizeof(uintptr_t));
	// compute the per-block capacity of this HT
	block_capacity = std::max((idx_t)STANDARD_VECTOR_SIZE, (Storage::BLOCK_ALLOC_SIZE / entry_size) + 1);
}

JoinHashTable::~JoinHashTable() {
	if (hash_map) {
		auto hash_id = hash_map->block_id;
		hash_map.reset();
		buffer_manager.DestroyBuffer(hash_id);
	}
	pinned_handles.clear();
	for (auto &block : blocks) {
		buffer_manager.DestroyBuffer(block.block_id);
	}
}

void JoinHashTable::ApplyBitmask(Vector &hashes, idx_t count) {
	if (hashes.vector_type == VectorType::CONSTANT_VECTOR) {
		assert(!ConstantVector::IsNull(hashes));
		auto indices = ConstantVector::GetData<hash_t>(hashes);
		*indices = *indices & bitmask;
	} else {
		hashes.Normalify(count);
		auto indices = FlatVector::GetData<hash_t>(hashes);
		for (idx_t i = 0; i < count; i++) {
			indices[i] &= bitmask;
		}
	}
}

void JoinHashTable::ApplyBitmask(Vector &hashes, const SelectionVector &sel, idx_t count, Vector &pointers) {
	VectorData hdata;
	hashes.Orrify(count, hdata);

	auto hash_data = (hash_t *)hdata.data;
	auto result_data = FlatVector::GetData<data_ptr_t *>(pointers);
	auto main_ht = (data_ptr_t *)hash_map->node->buffer;
	for (idx_t i = 0; i < count; i++) {
		auto rindex = sel.get_index(i);
		auto hindex = hdata.sel->get_index(rindex);
		auto hash = hash_data[hindex];
		result_data[rindex] = main_ht + (hash & bitmask);
	}
}

void JoinHashTable::Hash(DataChunk &keys, const SelectionVector &sel, idx_t count, Vector &hashes) {
	if (count == keys.size()) {
		// no null values are filtered: use regular hash functions
		VectorOperations::Hash(keys.data[0], hashes, keys.size());
		for (idx_t i = 1; i < equality_types.size(); i++) {
			VectorOperations::CombineHash(hashes, keys.data[i], keys.size());
		}
	} else {
		// null values were filtered: use selection vector
		VectorOperations::Hash(keys.data[0], hashes, sel, count);
		for (idx_t i = 1; i < equality_types.size(); i++) {
			VectorOperations::CombineHash(hashes, keys.data[i], sel, count);
		}
	}
}
template <class T>
static void templated_serialize_vdata(VectorData &vdata, const SelectionVector &sel, idx_t count,
                                      data_ptr_t key_locations[]) {
	auto source = (T *)vdata.data;
	if (vdata.nullmask->any()) {
		for (idx_t i = 0; i < count; i++) {
			auto idx = sel.get_index(i);
			auto source_idx = vdata.sel->get_index(idx);

			auto target = (T *)key_locations[i];
			if ((*vdata.nullmask)[source_idx]) {
				*target = NullValue<T>();
			} else {
				*target = source[source_idx];
			}
			key_locations[i] += sizeof(T);
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto idx = sel.get_index(i);
			auto source_idx = vdata.sel->get_index(idx);

			auto target = (T *)key_locations[i];
			*target = source[source_idx];
			key_locations[i] += sizeof(T);
		}
	}
}

void JoinHashTable::SerializeVectorData(VectorData &vdata, TypeId type, const SelectionVector &sel, idx_t count,
                                        data_ptr_t key_locations[]) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		templated_serialize_vdata<int8_t>(vdata, sel, count, key_locations);
		break;
	case TypeId::INT16:
		templated_serialize_vdata<int16_t>(vdata, sel, count, key_locations);
		break;
	case TypeId::INT32:
		templated_serialize_vdata<int32_t>(vdata, sel, count, key_locations);
		break;
	case TypeId::INT64:
		templated_serialize_vdata<int64_t>(vdata, sel, count, key_locations);
		break;
	case TypeId::FLOAT:
		templated_serialize_vdata<float>(vdata, sel, count, key_locations);
		break;
	case TypeId::DOUBLE:
		templated_serialize_vdata<double>(vdata, sel, count, key_locations);
		break;
	case TypeId::HASH:
		templated_serialize_vdata<hash_t>(vdata, sel, count, key_locations);
		break;
	case TypeId::VARCHAR: {
		auto source = (string_t *)vdata.data;
		for (idx_t i = 0; i < count; i++) {
			auto idx = sel.get_index(i);
			auto source_idx = vdata.sel->get_index(idx);

			auto target = (string_t *)key_locations[i];
			if ((*vdata.nullmask)[source_idx]) {
				*target = NullValue<string_t>();
			} else if (source[source_idx].IsInlined()) {
				*target = source[source_idx];
			} else {
				*target = string_heap.AddString(source[source_idx]);
			}
			key_locations[i] += sizeof(string_t);
		}
		break;
	}
	default:
		throw NotImplementedException("FIXME: unimplemented serialize");
	}
}

void JoinHashTable::SerializeVector(Vector &v, idx_t vcount, const SelectionVector &sel, idx_t count,
                                    data_ptr_t key_locations[]) {
	VectorData vdata;
	v.Orrify(vcount, vdata);

	SerializeVectorData(vdata, v.type, sel, count, key_locations);
}

idx_t JoinHashTable::AppendToBlock(HTDataBlock &block, BufferHandle &handle, idx_t count, data_ptr_t key_locations[],
                                   idx_t remaining) {
	idx_t append_count = std::min(remaining, block.capacity - block.count);
	auto dataptr = handle.node->buffer + block.count * entry_size;
	idx_t offset = count - remaining;
	for (idx_t i = 0; i < append_count; i++) {
		key_locations[offset + i] = dataptr;
		dataptr += entry_size;
	}
	block.count += append_count;
	return append_count;
}

static idx_t FilterNullValues(VectorData &vdata, const SelectionVector &sel, idx_t count, SelectionVector &result) {
	auto &nullmask = *vdata.nullmask;
	idx_t result_count = 0;
	for (idx_t i = 0; i < count; i++) {
		auto idx = sel.get_index(i);
		auto key_idx = vdata.sel->get_index(idx);
		if (!nullmask[key_idx]) {
			result.set_index(result_count++, idx);
		}
	}
	return result_count;
}

idx_t JoinHashTable::PrepareKeys(DataChunk &keys, unique_ptr<VectorData[]> &key_data,
                                 const SelectionVector *&current_sel, SelectionVector &sel) {
	key_data = keys.Orrify();

	// figure out which keys are NULL, and create a selection vector out of them
	current_sel = &FlatVector::IncrementalSelectionVector;
	idx_t added_count = keys.size();
	for (idx_t i = 0; i < keys.column_count(); i++) {
		if (!null_values_are_equal[i]) {
			if (!key_data[i].nullmask->any()) {
				continue;
			}
			added_count = FilterNullValues(key_data[i], *current_sel, added_count, sel);
			// null values are NOT equal for this column, filter them out
			current_sel = &sel;
		}
	}
	return added_count;
}

void JoinHashTable::Build(DataChunk &keys, DataChunk &payload) {
	assert(!finalized);
	assert(keys.size() == payload.size());
	if (keys.size() == 0) {
		return;
	}
	// special case: correlated mark join
	if (join_type == JoinType::MARK && correlated_mark_join_info.correlated_types.size() > 0) {
		auto &info = correlated_mark_join_info;
		// Correlated MARK join
		// for the correlated mark join we need to keep track of COUNT(*) and COUNT(COLUMN) for each of the correlated
		// columns push into the aggregate hash table
		assert(info.correlated_counts);
		info.group_chunk.SetCardinality(keys);
		for (idx_t i = 0; i < info.correlated_types.size(); i++) {
			info.group_chunk.data[i].Reference(keys.data[i]);
		}
		info.payload_chunk.SetCardinality(keys);
		for (idx_t i = 0; i < 2; i++) {
			info.payload_chunk.data[i].Reference(keys.data[info.correlated_types.size()]);
		}
		info.correlated_counts->AddChunk(info.group_chunk, info.payload_chunk);
	}

	// prepare the keys for processing
	unique_ptr<VectorData[]> key_data;
	const SelectionVector *current_sel;
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	idx_t added_count = PrepareKeys(keys, key_data, current_sel, sel);
	if (added_count < keys.size()) {
		has_null = true;
	}
	if (added_count == 0) {
		return;
	}
	count += added_count;

	vector<unique_ptr<BufferHandle>> handles;
	data_ptr_t key_locations[STANDARD_VECTOR_SIZE];
	// first allocate space of where to serialize the keys and payload columns
	idx_t remaining = added_count;
	// first append to the last block (if any)
	if (blocks.size() != 0) {
		auto &last_block = blocks.back();
		if (last_block.count < last_block.capacity) {
			// last block has space: pin the buffer of this block
			auto handle = buffer_manager.Pin(last_block.block_id);
			// now append to the block
			idx_t append_count = AppendToBlock(last_block, *handle, added_count, key_locations, remaining);
			remaining -= append_count;
			handles.push_back(move(handle));
		}
	}
	while (remaining > 0) {
		// now for the remaining data, allocate new buffers to store the data and append there
		auto handle = buffer_manager.Allocate(block_capacity * entry_size);

		HTDataBlock new_block;
		new_block.count = 0;
		new_block.capacity = block_capacity;
		new_block.block_id = handle->block_id;

		idx_t append_count = AppendToBlock(new_block, *handle, added_count, key_locations, remaining);
		remaining -= append_count;
		handles.push_back(move(handle));
		blocks.push_back(new_block);
	}

	// hash the keys and obtain an entry in the list
	// note that we only hash the keys used in the equality comparison
	Vector hash_values(TypeId::HASH);
	Hash(keys, *current_sel, added_count, hash_values);

	// serialize the keys to the key locations
	for (idx_t i = 0; i < keys.column_count(); i++) {
		SerializeVectorData(key_data[i], keys.data[i].type, *current_sel, added_count, key_locations);
	}
	// now serialize the payload
	if (build_types.size() > 0) {
		for (idx_t i = 0; i < payload.column_count(); i++) {
			SerializeVector(payload.data[i], payload.size(), *current_sel, added_count, key_locations);
		}
	}
	SerializeVector(hash_values, payload.size(), *current_sel, added_count, key_locations);
}

void JoinHashTable::InsertHashes(Vector &hashes, idx_t count, data_ptr_t key_locations[]) {
	assert(hashes.type == TypeId::HASH);

	// use bitmask to get position in array
	ApplyBitmask(hashes, count);

	hashes.Normalify(count);

	assert(hashes.vector_type == VectorType::FLAT_VECTOR);
	auto pointers = (data_ptr_t *)hash_map->node->buffer;
	auto indices = FlatVector::GetData<hash_t>(hashes);
	for (idx_t i = 0; i < count; i++) {
		auto index = indices[i];
		// set prev in current key to the value (NOTE: this will be nullptr if
		// there is none)
		auto prev_pointer = (data_ptr_t *)(key_locations[i] + tuple_size);
		*prev_pointer = pointers[index];

		// set pointer to current tuple
		pointers[index] = key_locations[i];
	}
}

void JoinHashTable::Finalize() {
	// the build has finished, now iterate over all the nodes and construct the final hash table
	// select a HT that has at least 50% empty space
	idx_t capacity = NextPowerOfTwo(std::max(count * 2, (idx_t)(Storage::BLOCK_ALLOC_SIZE / sizeof(data_ptr_t)) + 1));
	// size needs to be a power of 2
	assert((capacity & (capacity - 1)) == 0);
	bitmask = capacity - 1;

	// allocate the HT and initialize it with all-zero entries
	hash_map = buffer_manager.Allocate(capacity * sizeof(data_ptr_t));
	memset(hash_map->node->buffer, 0, capacity * sizeof(data_ptr_t));

	Vector hashes(TypeId::HASH);
	auto hash_data = FlatVector::GetData<hash_t>(hashes);
	data_ptr_t key_locations[STANDARD_VECTOR_SIZE];
	// now construct the actual hash table; scan the nodes
	// as we can the nodes we pin all the blocks of the HT and keep them pinned until the HT is destroyed
	// this is so that we can keep pointers around to the blocks
	// FIXME: if we cannot keep everything pinned in memory, we could switch to an out-of-memory merge join or so
	for (auto &block : blocks) {
		auto handle = buffer_manager.Pin(block.block_id);
		data_ptr_t dataptr = handle->node->buffer;
		idx_t entry = 0;
		while (entry < block.count) {
			// fetch the next vector of entries from the blocks
			idx_t next = std::min((idx_t)STANDARD_VECTOR_SIZE, block.count - entry);
			for (idx_t i = 0; i < next; i++) {
				hash_data[i] = *((hash_t *)(dataptr + tuple_size));
				key_locations[i] = dataptr;
				dataptr += entry_size;
			}
			// now insert into the hash table
			InsertHashes(hashes, next, key_locations);

			entry += next;
		}
		pinned_handles.push_back(move(handle));
	}
	finalized = true;
}

unique_ptr<ScanStructure> JoinHashTable::Probe(DataChunk &keys) {
	assert(count > 0); // should be handled before
	assert(finalized);

	// set up the scan structure
	auto ss = make_unique<ScanStructure>(*this);

	// first prepare the keys for probing
	const SelectionVector *current_sel;
	ss->count = PrepareKeys(keys, ss->key_data, current_sel, ss->sel_vector);
	if (ss->count == 0) {
		return ss;
	}

	// hash all the keys
	Vector hashes(TypeId::HASH);
	Hash(keys, *current_sel, ss->count, hashes);

	// now initialize the pointers of the scan structure based on the hashes
	ApplyBitmask(hashes, *current_sel, ss->count, ss->pointers);

	if (join_type != JoinType::INNER) {
		ss->found_match = unique_ptr<bool[]>(new bool[STANDARD_VECTOR_SIZE]);
		memset(ss->found_match.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE);
	}

	// create the selection vector linking to only non-empty entries
	idx_t count = 0;
	auto pointers = FlatVector::GetData<data_ptr_t>(ss->pointers);
	for (idx_t i = 0; i < ss->count; i++) {
		auto idx = current_sel->get_index(i);
		auto chain_pointer = (data_ptr_t *)(pointers[idx]);
		pointers[idx] = *chain_pointer;
		if (pointers[idx]) {
			ss->sel_vector.set_index(count++, idx);
		}
	}
	ss->count = count;
	return ss;
}

ScanStructure::ScanStructure(JoinHashTable &ht) : sel_vector(STANDARD_VECTOR_SIZE), ht(ht), finished(false) {
	pointers.Initialize(TypeId::POINTER);
}

void ScanStructure::Next(DataChunk &keys, DataChunk &left, DataChunk &result) {
	if (finished) {
		return;
	}

	switch (ht.join_type) {
	case JoinType::INNER:
		NextInnerJoin(keys, left, result);
		break;
	case JoinType::SEMI:
		NextSemiJoin(keys, left, result);
		break;
	case JoinType::MARK:
		NextMarkJoin(keys, left, result);
		break;
	case JoinType::ANTI:
		NextAntiJoin(keys, left, result);
		break;
	case JoinType::LEFT:
		NextLeftJoin(keys, left, result);
		break;
	case JoinType::SINGLE:
		NextSingleJoin(keys, left, result);
		break;
	default:
		throw Exception("Unhandled join type in JoinHashTable");
	}
}

template <bool NO_MATCH_SEL, class T, class OP>
static idx_t TemplatedGather(VectorData &vdata, Vector &pointers, const SelectionVector &current_sel, idx_t count,
                             idx_t offset, SelectionVector *match_sel, SelectionVector *no_match_sel,
                             idx_t &no_match_count) {
	idx_t result_count = 0;
	auto data = (T *)vdata.data;
	auto ptrs = FlatVector::GetData<uintptr_t>(pointers);
	for (idx_t i = 0; i < count; i++) {
		auto idx = current_sel.get_index(i);
		auto kidx = vdata.sel->get_index(idx);
		auto gdata = (T *)(ptrs[idx] + offset);
		if ((*vdata.nullmask)[kidx]) {
			if (IsNullValue<T>(*gdata)) {
				match_sel->set_index(result_count++, idx);
			} else {
				if (NO_MATCH_SEL) {
					no_match_sel->set_index(no_match_count++, idx);
				}
			}
		} else {
			if (OP::template Operation<T>(data[kidx], *gdata)) {
				match_sel->set_index(result_count++, idx);
			} else {
				if (NO_MATCH_SEL) {
					no_match_sel->set_index(no_match_count++, idx);
				}
			}
		}
	}
	return result_count;
}

template <bool NO_MATCH_SEL, class OP>
static idx_t GatherSwitch(VectorData &data, TypeId type, Vector &pointers, const SelectionVector &current_sel,
                          idx_t count, idx_t offset, SelectionVector *match_sel, SelectionVector *no_match_sel,
                          idx_t &no_match_count) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return TemplatedGather<NO_MATCH_SEL, int8_t, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                 no_match_sel, no_match_count);
	case TypeId::INT16:
		return TemplatedGather<NO_MATCH_SEL, int16_t, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                  no_match_sel, no_match_count);
	case TypeId::INT32:
		return TemplatedGather<NO_MATCH_SEL, int32_t, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                  no_match_sel, no_match_count);
	case TypeId::INT64:
		return TemplatedGather<NO_MATCH_SEL, int64_t, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                  no_match_sel, no_match_count);
	case TypeId::FLOAT:
		return TemplatedGather<NO_MATCH_SEL, float, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                no_match_sel, no_match_count);
	case TypeId::DOUBLE:
		return TemplatedGather<NO_MATCH_SEL, double, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                 no_match_sel, no_match_count);
	case TypeId::VARCHAR:
		return TemplatedGather<NO_MATCH_SEL, string_t, OP>(data, pointers, current_sel, count, offset, match_sel,
		                                                   no_match_sel, no_match_count);
	default:
		throw NotImplementedException("Unimplemented type for GatherSwitch");
	}
}

template <bool NO_MATCH_SEL>
idx_t ScanStructure::ResolvePredicates(DataChunk &keys, SelectionVector *match_sel, SelectionVector *no_match_sel) {
	SelectionVector *current_sel = &this->sel_vector;
	idx_t remaining_count = this->count;
	idx_t offset = 0;
	idx_t no_match_count = 0;
	for (idx_t i = 0; i < ht.predicates.size(); i++) {
		switch (ht.predicates[i]) {
		case ExpressionType::COMPARE_EQUAL:
			remaining_count =
			    GatherSwitch<NO_MATCH_SEL, Equals>(key_data[i], keys.data[i].type, this->pointers, *current_sel,
			                                       remaining_count, offset, match_sel, no_match_sel, no_match_count);
			break;
		case ExpressionType::COMPARE_NOTEQUAL:
			remaining_count =
			    GatherSwitch<NO_MATCH_SEL, NotEquals>(key_data[i], keys.data[i].type, this->pointers, *current_sel,
			                                          remaining_count, offset, match_sel, no_match_sel, no_match_count);
			break;
		case ExpressionType::COMPARE_GREATERTHAN:
			remaining_count = GatherSwitch<NO_MATCH_SEL, GreaterThan>(key_data[i], keys.data[i].type, this->pointers,
			                                                          *current_sel, remaining_count, offset, match_sel,
			                                                          no_match_sel, no_match_count);
			break;
		case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
			remaining_count = GatherSwitch<NO_MATCH_SEL, GreaterThanEquals>(
			    key_data[i], keys.data[i].type, this->pointers, *current_sel, remaining_count, offset, match_sel,
			    no_match_sel, no_match_count);
			break;
		case ExpressionType::COMPARE_LESSTHAN:
			remaining_count =
			    GatherSwitch<NO_MATCH_SEL, LessThan>(key_data[i], keys.data[i].type, this->pointers, *current_sel,
			                                         remaining_count, offset, match_sel, no_match_sel, no_match_count);
			break;
		case ExpressionType::COMPARE_LESSTHANOREQUALTO:
			remaining_count = GatherSwitch<NO_MATCH_SEL, LessThanEquals>(key_data[i], keys.data[i].type, this->pointers,
			                                                             *current_sel, remaining_count, offset,
			                                                             match_sel, no_match_sel, no_match_count);
			break;
		default:
			throw NotImplementedException("Unimplemented comparison type for join");
		}
		if (remaining_count == 0) {
			break;
		}
		current_sel = match_sel;
		offset += GetTypeIdSize(keys.data[i].type);
	}
	return remaining_count;
}

idx_t ScanStructure::ResolvePredicates(DataChunk &keys, SelectionVector &match_sel, SelectionVector &no_match_sel) {
	return ResolvePredicates<true>(keys, &match_sel, &no_match_sel);
}

idx_t ScanStructure::ResolvePredicates(DataChunk &keys, SelectionVector &match_sel) {
	return ResolvePredicates<false>(keys, &match_sel, nullptr);
}

idx_t ScanStructure::ScanInnerJoin(DataChunk &keys, SelectionVector &result_vector) {
	while (true) {
		// resolve the predicates for this set of keys
		idx_t result_count = ResolvePredicates(keys, result_vector);

		// after doing all the comparisons set the found_match vector
		if (found_match) {
			for (idx_t i = 0; i < result_count; i++) {
				auto idx = result_vector.get_index(i);
				found_match[idx] = true;
			}
		}
		if (result_count > 0) {
			return result_count;
		}
		// no matches found: check the next set of pointers
		AdvancePointers();
		if (this->count == 0) {
			return 0;
		}
	}
}

void ScanStructure::AdvancePointers(const SelectionVector &sel, idx_t sel_count) {
	// now for all the pointers, we move on to the next set of pointers
	idx_t new_count = 0;
	auto ptrs = FlatVector::GetData<data_ptr_t>(this->pointers);
	for (idx_t i = 0; i < sel_count; i++) {
		auto idx = sel.get_index(i);
		auto chain_pointer = (data_ptr_t *)(ptrs[idx] + ht.tuple_size);
		ptrs[idx] = *chain_pointer;
		if (ptrs[idx]) {
			this->sel_vector.set_index(new_count++, idx);
		}
	}
	this->count = new_count;
}

void ScanStructure::AdvancePointers() {
	AdvancePointers(this->sel_vector, this->count);
}

template <class T>
static void TemplatedGatherResult(Vector &result, uintptr_t *pointers, const SelectionVector &result_vector,
                                  const SelectionVector &sel_vector, idx_t count, idx_t offset) {
	auto rdata = FlatVector::GetData<T>(result);
	auto &nullmask = FlatVector::Nullmask(result);
	for (idx_t i = 0; i < count; i++) {
		auto ridx = result_vector.get_index(i);
		auto pidx = sel_vector.get_index(i);
		auto hdata = (T *)(pointers[pidx] + offset);
		if (IsNullValue<T>(*hdata)) {
			nullmask[ridx] = true;
		} else {
			rdata[ridx] = *hdata;
		}
	}
}

void ScanStructure::GatherResult(Vector &result, const SelectionVector &result_vector,
                                 const SelectionVector &sel_vector, idx_t count, idx_t &offset) {
	result.vector_type = VectorType::FLAT_VECTOR;
	auto ptrs = FlatVector::GetData<uintptr_t>(pointers);
	switch (result.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		TemplatedGatherResult<int8_t>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	case TypeId::INT16:
		TemplatedGatherResult<int16_t>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	case TypeId::INT32:
		TemplatedGatherResult<int32_t>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	case TypeId::INT64:
		TemplatedGatherResult<int64_t>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	case TypeId::FLOAT:
		TemplatedGatherResult<float>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	case TypeId::DOUBLE:
		TemplatedGatherResult<double>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	case TypeId::VARCHAR:
		TemplatedGatherResult<string_t>(result, ptrs, result_vector, sel_vector, count, offset);
		break;
	default:
		throw NotImplementedException("Unimplemented type for ScanStructure::GatherResult");
	}
	offset += GetTypeIdSize(result.type);
}

void ScanStructure::GatherResult(Vector &result, const SelectionVector &sel_vector, idx_t count, idx_t &offset) {
	GatherResult(result, FlatVector::IncrementalSelectionVector, sel_vector, count, offset);
}

void ScanStructure::NextInnerJoin(DataChunk &keys, DataChunk &left, DataChunk &result) {
	assert(result.column_count() == left.column_count() + ht.build_types.size());
	if (this->count == 0) {
		// no pointers left to chase
		return;
	}

	SelectionVector result_vector(STANDARD_VECTOR_SIZE);

	idx_t result_count = ScanInnerJoin(keys, result_vector);
	if (result_count > 0) {
		// matches were found
		// construct the result
		// on the LHS, we create a slice using the result vector
		result.Slice(left, result_vector, result_count);

		// on the RHS, we need to fetch the data from the hash table
		idx_t offset = ht.condition_size;
		for (idx_t i = 0; i < ht.build_types.size(); i++) {
			auto &vector = result.data[left.column_count() + i];
			assert(vector.type == ht.build_types[i]);
			GatherResult(vector, result_vector, result_count, offset);
		}
		AdvancePointers();
	}
}

void ScanStructure::ScanKeyMatches(DataChunk &keys) {
	// the semi-join, anti-join and mark-join we handle a differently from the inner join
	// since there can be at most STANDARD_VECTOR_SIZE results
	// we handle the entire chunk in one call to Next().
	// for every pointer, we keep chasing pointers and doing comparisons.
	// this results in a boolean array indicating whether or not the tuple has a match
	SelectionVector match_sel(STANDARD_VECTOR_SIZE), no_match_sel(STANDARD_VECTOR_SIZE);
	while (this->count > 0) {
		// resolve the predicates for the current set of pointers
		idx_t match_count = ResolvePredicates(keys, match_sel, no_match_sel);
		idx_t no_match_count = this->count - match_count;

		// mark each of the matches as found
		for (idx_t i = 0; i < match_count; i++) {
			found_match[match_sel.get_index(i)] = true;
		}
		// continue searching for the ones where we did not find a match yet
		AdvancePointers(no_match_sel, no_match_count);
	}
}

template <bool MATCH> void ScanStructure::NextSemiOrAntiJoin(DataChunk &keys, DataChunk &left, DataChunk &result) {
	assert(left.column_count() == result.column_count());
	assert(keys.size() == left.size());
	// create the selection vector from the matches that were found
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	idx_t result_count = 0;
	for (idx_t i = 0; i < keys.size(); i++) {
		if (found_match[i] == MATCH) {
			// part of the result
			sel.set_index(result_count++, i);
		}
	}
	// construct the final result
	if (result_count > 0) {
		// we only return the columns on the left side
		// reference the columns of the left side from the result
		result.Slice(left, sel, result_count);
	} else {
		assert(result.size() == 0);
	}
}

void ScanStructure::NextSemiJoin(DataChunk &keys, DataChunk &left, DataChunk &result) {
	// first scan for key matches
	ScanKeyMatches(keys);
	// then construct the result from all tuples with a match
	NextSemiOrAntiJoin<true>(keys, left, result);

	finished = true;
}

void ScanStructure::NextAntiJoin(DataChunk &keys, DataChunk &left, DataChunk &result) {
	// first scan for key matches
	ScanKeyMatches(keys);
	// then construct the result from all tuples that did not find a match
	NextSemiOrAntiJoin<false>(keys, left, result);

	finished = true;
}

void ScanStructure::ConstructMarkJoinResult(DataChunk &join_keys, DataChunk &child, DataChunk &result) {
	// for the initial set of columns we just reference the left side
	result.SetCardinality(child);
	for (idx_t i = 0; i < child.column_count(); i++) {
		result.data[i].Reference(child.data[i]);
	}
	auto &mark_vector = result.data.back();
	mark_vector.vector_type = VectorType::FLAT_VECTOR;
	// first we set the NULL values from the join keys
	// if there is any NULL in the keys, the result is NULL
	auto bool_result = FlatVector::GetData<bool>(mark_vector);
	auto &nullmask = FlatVector::Nullmask(mark_vector);
	for (idx_t col_idx = 0; col_idx < join_keys.column_count(); col_idx++) {
		if (ht.null_values_are_equal[col_idx]) {
			continue;
		}
		VectorData jdata;
		join_keys.data[col_idx].Orrify(join_keys.size(), jdata);
		if (jdata.nullmask->any()) {
			for (idx_t i = 0; i < join_keys.size(); i++) {
				auto jidx = jdata.sel->get_index(i);
				nullmask[i] = (*jdata.nullmask)[jidx];
			}
		}
	}
	// now set the remaining entries to either true or false based on whether a match was found
	if (found_match) {
		for (idx_t i = 0; i < child.size(); i++) {
			bool_result[i] = found_match[i];
		}
	} else {
		memset(bool_result, 0, sizeof(bool) * child.size());
	}
	// if the right side contains NULL values, the result of any FALSE becomes NULL
	if (ht.has_null) {
		for (idx_t i = 0; i < child.size(); i++) {
			if (!bool_result[i]) {
				nullmask[i] = true;
			}
		}
	}
}

void ScanStructure::NextMarkJoin(DataChunk &keys, DataChunk &input, DataChunk &result) {
	assert(result.column_count() == input.column_count() + 1);
	assert(result.data.back().type == TypeId::BOOL);
	// this method should only be called for a non-empty HT
	assert(ht.count > 0);

	ScanKeyMatches(keys);
	if (ht.correlated_mark_join_info.correlated_types.size() == 0) {
		ConstructMarkJoinResult(keys, input, result);
	} else {
		auto &info = ht.correlated_mark_join_info;
		// there are correlated columns
		// first we fetch the counts from the aggregate hashtable corresponding to these entries
		assert(keys.column_count() == info.group_chunk.column_count() + 1);
		info.group_chunk.SetCardinality(keys);
		for (idx_t i = 0; i < info.group_chunk.column_count(); i++) {
			info.group_chunk.data[i].Reference(keys.data[i]);
		}
		info.correlated_counts->FetchAggregates(info.group_chunk, info.result_chunk);

		// for the initial set of columns we just reference the left side
		result.SetCardinality(input);
		for (idx_t i = 0; i < input.column_count(); i++) {
			result.data[i].Reference(input.data[i]);
		}
		// create the result matching vector
		auto &last_key = keys.data.back();
		auto &result_vector = result.data.back();
		// first set the nullmask based on whether or not there were NULL values in the join key
		result_vector.vector_type = VectorType::FLAT_VECTOR;
		auto bool_result = FlatVector::GetData<bool>(result_vector);
		auto &nullmask = FlatVector::Nullmask(result_vector);
		switch (last_key.vector_type) {
		case VectorType::CONSTANT_VECTOR:
			if (ConstantVector::IsNull(last_key)) {
				nullmask.set();
			}
			break;
		case VectorType::FLAT_VECTOR:
			nullmask = FlatVector::Nullmask(last_key);
			break;
		default: {
			VectorData kdata;
			last_key.Orrify(keys.size(), kdata);
			for (idx_t i = 0; i < input.size(); i++) {
				auto kidx = kdata.sel->get_index(i);
				;
				nullmask[i] = (*kdata.nullmask)[kidx];
			}
			break;
		}
		}

		auto count_star = FlatVector::GetData<int64_t>(info.result_chunk.data[0]);
		auto count = FlatVector::GetData<int64_t>(info.result_chunk.data[1]);
		// set the entries to either true or false based on whether a match was found
		for (idx_t i = 0; i < input.size(); i++) {
			assert(count_star[i] >= count[i]);
			bool_result[i] = found_match ? found_match[i] : false;
			if (!bool_result[i] && count_star[i] > count[i]) {
				// RHS has NULL value and result is false: set to null
				nullmask[i] = true;
			}
			if (count_star[i] == 0) {
				// count == 0, set nullmask to false (we know the result is false now)
				nullmask[i] = false;
			}
		}
	}
	finished = true;
}

void ScanStructure::NextLeftJoin(DataChunk &keys, DataChunk &left, DataChunk &result) {
	// a LEFT OUTER JOIN is identical to an INNER JOIN except all tuples that do
	// not have a match must return at least one tuple (with the right side set
	// to NULL in every column)
	NextInnerJoin(keys, left, result);
	if (result.size() == 0) {
		// no entries left from the normal join
		// fill in the result of the remaining left tuples
		// together with NULL values on the right-hand side
		idx_t remaining_count = 0;
		SelectionVector sel(STANDARD_VECTOR_SIZE);
		for (idx_t i = 0; i < left.size(); i++) {
			if (!found_match[i]) {
				sel.set_index(remaining_count++, i);
			}
		}
		if (remaining_count > 0) {
			// have remaining tuples
			// slice the left side with tuples that did not find a match
			result.Slice(left, sel, remaining_count);

			// now set the right side to NULL
			for (idx_t i = left.column_count(); i < result.column_count(); i++) {
				result.data[i].vector_type = VectorType::CONSTANT_VECTOR;
				ConstantVector::SetNull(result.data[i], true);
			}
		}
		finished = true;
	}
}

void ScanStructure::NextSingleJoin(DataChunk &keys, DataChunk &input, DataChunk &result) {
	// single join
	// this join is similar to the semi join except that
	// (1) we actually return data from the RHS and
	// (2) we return NULL for that data if there is no match
	idx_t result_count = 0;
	SelectionVector result_sel(STANDARD_VECTOR_SIZE);
	SelectionVector match_sel(STANDARD_VECTOR_SIZE), no_match_sel(STANDARD_VECTOR_SIZE);
	while (this->count > 0) {
		// resolve the predicates for the current set of pointers
		idx_t match_count = ResolvePredicates(keys, match_sel, no_match_sel);
		idx_t no_match_count = this->count - match_count;

		// mark each of the matches as found
		for (idx_t i = 0; i < match_count; i++) {
			// found a match for this index
			auto index = match_sel.get_index(i);
			found_match[index] = true;
			result_sel.set_index(result_count++, index);
		}
		// continue searching for the ones where we did not find a match yet
		AdvancePointers(no_match_sel, no_match_count);
	}
	// reference the columns of the left side from the result
	assert(input.column_count() > 0);
	for (idx_t i = 0; i < input.column_count(); i++) {
		result.data[i].Reference(input.data[i]);
	}
	// now fetch the data from the RHS
	idx_t offset = ht.condition_size;
	for (idx_t i = 0; i < ht.build_types.size(); i++) {
		auto &vector = result.data[input.column_count() + i];
		// set NULL entries for every entry that was not found
		auto &nullmask = FlatVector::Nullmask(vector);
		nullmask.set();
		for (idx_t j = 0; j < result_count; j++) {
			nullmask[result_sel.get_index(j)] = false;
		}
		// for the remaining values we fetch the values
		GatherResult(vector, result_sel, result_sel, result_count, offset);
	}
	result.SetCardinality(input.size());

	// like the SEMI, ANTI and MARK join types, the SINGLE join only ever does one pass over the HT per input chunk
	finished = true;
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/merge_join.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

struct MergeOrder {
	SelectionVector order;
	idx_t count;
	VectorData vdata;
};

enum MergeInfoType : uint8_t { SCALAR_MERGE_INFO = 1, CHUNK_MERGE_INFO = 2 };

struct MergeInfo {
	MergeInfo(MergeInfoType info_type, TypeId type) : info_type(info_type), type(type) {
	}
	MergeInfoType info_type;
	TypeId type;
};

struct ScalarMergeInfo : public MergeInfo {
	MergeOrder &order;
	idx_t &pos;
	SelectionVector result;

	ScalarMergeInfo(MergeOrder &order, TypeId type, idx_t &pos)
	    : MergeInfo(MergeInfoType::SCALAR_MERGE_INFO, type), order(order), pos(pos), result(STANDARD_VECTOR_SIZE) {
	}
};

struct ChunkMergeInfo : public MergeInfo {
	ChunkCollection &data_chunks;
	vector<MergeOrder> &order_info;
	bool found_match[STANDARD_VECTOR_SIZE];

	ChunkMergeInfo(ChunkCollection &data_chunks, vector<MergeOrder> &order_info)
	    : MergeInfo(MergeInfoType::CHUNK_MERGE_INFO, data_chunks.types[0]), data_chunks(data_chunks),
	      order_info(order_info) {
		memset(found_match, 0, sizeof(found_match));
	}
};

struct MergeJoinInner {
	struct Equality {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r);
	};
	struct LessThan {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r);
	};
	struct LessThanEquals {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r);
	};
	struct GreaterThan {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) {
			return LessThan::Operation<T>(r, l);
		}
	};
	struct GreaterThanEquals {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) {
			return LessThanEquals::Operation<T>(r, l);
		}
	};

	static idx_t Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison_type);
};

struct MergeJoinMark {
	struct Equality {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r);
	};
	struct LessThan {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r);
	};
	struct LessThanEquals {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r);
	};
	struct GreaterThan {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r);
	};
	struct GreaterThanEquals {
		template <class T> static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r);
	};

	static idx_t Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison);
};

#define INSTANTIATE_MERGEJOIN_TEMPLATES(MJCLASS, OPNAME, L, R)                                                         \
	template idx_t MJCLASS::OPNAME::Operation<int8_t>(L & l, R & r);                                                   \
	template idx_t MJCLASS::OPNAME::Operation<int16_t>(L & l, R & r);                                                  \
	template idx_t MJCLASS::OPNAME::Operation<int32_t>(L & l, R & r);                                                  \
	template idx_t MJCLASS::OPNAME::Operation<int64_t>(L & l, R & r);                                                  \
	template idx_t MJCLASS::OPNAME::Operation<float>(L & l, R & r);                                                    \
	template idx_t MJCLASS::OPNAME::Operation<double>(L & l, R & r);                                                   \
	template idx_t MJCLASS::OPNAME::Operation<string_t>(L & l, R & r);

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/comparison_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! ComparisonExpression represents a boolean comparison (e.g. =, >=, <>). Always returns a boolean
//! and has two children.
class ComparisonExpression : public ParsedExpression {
public:
	ComparisonExpression(ExpressionType type, unique_ptr<ParsedExpression> left, unique_ptr<ParsedExpression> right);

	unique_ptr<ParsedExpression> left;
	unique_ptr<ParsedExpression> right;

public:
	string ToString() const override;

	static bool Equals(const ComparisonExpression *a, const ComparisonExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

template <class MJ, class L_ARG, class R_ARG> static idx_t merge_join(L_ARG &l, R_ARG &r) {
	switch (l.type) {
	case TypeId::INT8:
		return MJ::template Operation<int8_t>(l, r);
	case TypeId::INT16:
		return MJ::template Operation<int16_t>(l, r);
	case TypeId::INT32:
		return MJ::template Operation<int32_t>(l, r);
	case TypeId::INT64:
		return MJ::template Operation<int64_t>(l, r);
	case TypeId::FLOAT:
		return MJ::template Operation<float>(l, r);
	case TypeId::DOUBLE:
		return MJ::template Operation<double>(l, r);
	case TypeId::VARCHAR:
		return MJ::template Operation<string_t>(l, r);
	default:
		throw NotImplementedException("Type not implemented for merge join!");
	}
}

template <class T, class L_ARG, class R_ARG>
static idx_t perform_merge_join(L_ARG &l, R_ARG &r, ExpressionType comparison_type) {
	switch (comparison_type) {
	case ExpressionType::COMPARE_EQUAL:
		return merge_join<typename T::Equality, L_ARG, R_ARG>(l, r);
	case ExpressionType::COMPARE_LESSTHAN:
		return merge_join<typename T::LessThan, L_ARG, R_ARG>(l, r);
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return merge_join<typename T::LessThanEquals, L_ARG, R_ARG>(l, r);
	case ExpressionType::COMPARE_GREATERTHAN:
		return merge_join<typename T::GreaterThan, L_ARG, R_ARG>(l, r);
	default:
		// "Unimplemented comparison type for merge join!"
		assert(comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO);
		return merge_join<typename T::GreaterThanEquals, L_ARG, R_ARG>(l, r);
	}
}

idx_t MergeJoinInner::Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison_type) {
	assert(l.info_type == MergeInfoType::SCALAR_MERGE_INFO && r.info_type == MergeInfoType::SCALAR_MERGE_INFO);
	auto &left = (ScalarMergeInfo &)l;
	auto &right = (ScalarMergeInfo &)r;
	assert(left.type == right.type);
	if (left.order.count == 0 || right.order.count == 0) {
		return 0;
	}
	return perform_merge_join<MergeJoinInner, ScalarMergeInfo, ScalarMergeInfo>(left, right, comparison_type);
}

idx_t MergeJoinMark::Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison_type) {
	assert(l.info_type == MergeInfoType::SCALAR_MERGE_INFO && r.info_type == MergeInfoType::CHUNK_MERGE_INFO);
	auto &left = (ScalarMergeInfo &)l;
	auto &right = (ChunkMergeInfo &)r;
	assert(left.type == right.type);
	if (left.order.count == 0 || right.data_chunks.count == 0) {
		return 0;
	}
	return perform_merge_join<MergeJoinMark, ScalarMergeInfo, ChunkMergeInfo>(left, right, comparison_type);
}





using namespace duckdb;
using namespace std;

template <class T> idx_t MergeJoinInner::Equality::Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) {
	throw NotImplementedException("Merge Join with Equality not implemented");
	// if (l.pos >= l.count) {
	// 	return 0;
	// }
	// assert(l.sel_vector && r.sel_vector);
	// auto ldata = (T *)l.v.data;
	// auto rdata = (T *)r.v.data;
	// idx_t result_count = 0;
	// while (true) {
	// 	if (r.pos == r.count || duckdb::LessThan::Operation(ldata[l.sel_vector[l.pos]], rdata[r.sel_vector[r.pos]])) {
	// 		// left side smaller: move left pointer forward
	// 		l.pos++;
	// 		if (l.pos >= l.count) {
	// 			// left side exhausted
	// 			break;
	// 		}
	// 		// we might need to go back on the right-side after going
	// 		// forward on the left side because the new tuple might have
	// 		// matches with the right side
	// 		while (r.pos > 0 && duckdb::Equals::Operation(ldata[l.sel_vector[l.pos]], rdata[r.sel_vector[r.pos - 1]])) {
	// 			r.pos--;
	// 		}
	// 	} else if (duckdb::GreaterThan::Operation(ldata[l.sel_vector[l.pos]], rdata[r.sel_vector[r.pos]])) {
	// 		// right side smaller: move right pointer forward
	// 		r.pos++;
	// 	} else {
	// 		// tuples match
	// 		// output tuple
	// 		l.result[result_count] = l.sel_vector[l.pos];
	// 		r.result[result_count] = r.sel_vector[r.pos];
	// 		result_count++;
	// 		// move right side forward
	// 		r.pos++;
	// 		if (result_count == STANDARD_VECTOR_SIZE) {
	// 			// out of space!
	// 			break;
	// 		}
	// 	}
	// }
	// return result_count;
}

template <class T> idx_t MergeJoinInner::LessThan::Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) {
	if (r.pos >= r.order.count) {
		return 0;
	}
	auto ldata = (T *)l.order.vdata.data;
	auto rdata = (T *)r.order.vdata.data;
	auto &lorder = l.order.order;
	auto &rorder = r.order.order;
	idx_t result_count = 0;
	while (true) {
		if (l.pos < l.order.count) {
			auto lidx = lorder.get_index(l.pos);
			auto ridx = rorder.get_index(r.pos);
			auto dlidx = l.order.vdata.sel->get_index(lidx);
			auto dridx = r.order.vdata.sel->get_index(ridx);
			if (duckdb::LessThan::Operation(ldata[dlidx], rdata[dridx])) {
				// left side smaller: found match
				l.result.set_index(result_count, lidx);
				r.result.set_index(result_count, ridx);
				result_count++;
				// move left side forward
				l.pos++;
				if (result_count == STANDARD_VECTOR_SIZE) {
					// out of space!
					break;
				}
				continue;
			}
		}
		// right side smaller or equal, or left side exhausted: move
		// right pointer forward reset left side to start
		l.pos = 0;
		r.pos++;
		if (r.pos == r.order.count) {
			break;
		}
	}
	return result_count;
}

template <class T> idx_t MergeJoinInner::LessThanEquals::Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) {
	if (r.pos >= r.order.count) {
		return 0;
	}
	auto ldata = (T *)l.order.vdata.data;
	auto rdata = (T *)r.order.vdata.data;
	auto &lorder = l.order.order;
	auto &rorder = r.order.order;
	idx_t result_count = 0;
	while (true) {
		if (l.pos < l.order.count) {
			auto lidx = lorder.get_index(l.pos);
			auto ridx = rorder.get_index(r.pos);
			auto dlidx = l.order.vdata.sel->get_index(lidx);
			auto dridx = r.order.vdata.sel->get_index(ridx);
			if (duckdb::LessThanEquals::Operation(ldata[dlidx], rdata[dridx])) {
				// left side smaller: found match
				l.result.set_index(result_count, lidx);
				r.result.set_index(result_count, ridx);
				result_count++;
				// move left side forward
				l.pos++;
				if (result_count == STANDARD_VECTOR_SIZE) {
					// out of space!
					break;
				}
				continue;
			}
		}
		// right side smaller or equal, or left side exhausted: move
		// right pointer forward reset left side to start
		l.pos = 0;
		r.pos++;
		if (r.pos == r.order.count) {
			break;
		}
	}
	return result_count;
}

INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinInner, Equality, ScalarMergeInfo, ScalarMergeInfo);
INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinInner, LessThan, ScalarMergeInfo, ScalarMergeInfo);
INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinInner, LessThanEquals, ScalarMergeInfo, ScalarMergeInfo);





using namespace duckdb;
using namespace std;

template <class T> idx_t MergeJoinMark::Equality::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	throw NotImplementedException("Merge Join with Equality not implemented");
}

template <class T, class OP> static idx_t merge_join_mark_gt(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	auto ldata = (T *)l.order.vdata.data;
	auto &lorder = l.order.order;
	l.pos = l.order.count;
	for (idx_t chunk_idx = 0; chunk_idx < r.order_info.size(); chunk_idx++) {
		// we only care about the SMALLEST value in each of the RHS
		// because we want to figure out if they are greater than [or equal] to ANY value
		// get the smallest value from the RHS
		auto &rorder = r.order_info[chunk_idx];
		auto rdata = (T *)rorder.vdata.data;
		auto min_r_value = rdata[rorder.vdata.sel->get_index(rorder.order.get_index(0))];
		// now we start from the current lpos value and check if we found a new value that is [>= OR >] the min RHS
		// value
		while (true) {
			auto lidx = lorder.get_index(l.pos - 1);
			auto dlidx = l.order.vdata.sel->get_index(lidx);
			if (OP::Operation(ldata[dlidx], min_r_value)) {
				// found a match for lpos, set it in the found_match vector
				r.found_match[lidx] = true;
				l.pos--;
				if (l.pos == 0) {
					// early out: we exhausted the entire LHS and they all match
					return 0;
				}
			} else {
				// we found no match: any subsequent value from the LHS we scan now will be smaller and thus also not
				// match move to the next RHS chunk
				break;
			}
		}
	}
	return 0;
}
template <class T> idx_t MergeJoinMark::GreaterThan::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	return merge_join_mark_gt<T, duckdb::GreaterThan>(l, r);
}

template <class T> idx_t MergeJoinMark::GreaterThanEquals::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	return merge_join_mark_gt<T, duckdb::GreaterThanEquals>(l, r);
}

template <class T, class OP> static idx_t merge_join_mark_lt(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	auto ldata = (T *)l.order.vdata.data;
	auto &lorder = l.order.order;
	l.pos = 0;
	for (idx_t chunk_idx = 0; chunk_idx < r.order_info.size(); chunk_idx++) {
		// we only care about the BIGGEST value in each of the RHS
		// because we want to figure out if they are less than [or equal] to ANY value
		// get the biggest value from the RHS
		auto &rorder = r.order_info[chunk_idx];
		auto rdata = (T *)rorder.vdata.data;
		auto max_r_value = rdata[rorder.vdata.sel->get_index(rorder.order.get_index(rorder.count - 1))];
		// now we start from the current lpos value and check if we found a new value that is [<= OR <] the max RHS
		// value
		while (true) {
			auto lidx = lorder.get_index(l.pos);
			auto dlidx = l.order.vdata.sel->get_index(lidx);
			if (OP::Operation(ldata[dlidx], max_r_value)) {
				// found a match for lpos, set it in the found_match vector
				r.found_match[lidx] = true;
				l.pos++;
				if (l.pos == l.order.count) {
					// early out: we exhausted the entire LHS and they all match
					return 0;
				}
			} else {
				// we found no match: any subsequent value from the LHS we scan now will be bigger and thus also not
				// match move to the next RHS chunk
				break;
			}
		}
	}
	return 0;
}

template <class T> idx_t MergeJoinMark::LessThan::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	return merge_join_mark_lt<T, duckdb::LessThan>(l, r);
}

template <class T> idx_t MergeJoinMark::LessThanEquals::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) {
	return merge_join_mark_lt<T, duckdb::LessThanEquals>(l, r);
}

INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinMark, Equality, ScalarMergeInfo, ChunkMergeInfo);
INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinMark, LessThan, ScalarMergeInfo, ChunkMergeInfo);
INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinMark, LessThanEquals, ScalarMergeInfo, ChunkMergeInfo);
INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinMark, GreaterThan, ScalarMergeInfo, ChunkMergeInfo);
INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinMark, GreaterThanEquals, ScalarMergeInfo, ChunkMergeInfo);

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/nested_loop_join.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

struct NestedLoopJoinInner {
	static idx_t Perform(idx_t &ltuple, idx_t &rtuple, DataChunk &left_conditions, DataChunk &right_conditions,
	                     SelectionVector &lvector, SelectionVector &rvector, vector<JoinCondition> &conditions);
};

struct NestedLoopJoinMark {
	static void Perform(DataChunk &left, ChunkCollection &right, bool found_match[], vector<JoinCondition> &conditions);
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

struct InitialNestedLoopJoin {
	template <class T, class OP>
	static idx_t Operation(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
	                       SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count) {
		// initialize phase of nested loop join
		// fill lvector and rvector with matches from the base vectors
		VectorData left_data, right_data;
		left.Orrify(left_size, left_data);
		right.Orrify(right_size, right_data);

		auto ldata = (T *)left_data.data;
		auto rdata = (T *)right_data.data;
		idx_t result_count = 0;
		for (; rpos < right_size; rpos++) {
			idx_t right_position = right_data.sel->get_index(rpos);
			if ((*right_data.nullmask)[right_position]) {
				continue;
			}
			for (; lpos < left_size; lpos++) {
				if (result_count == STANDARD_VECTOR_SIZE) {
					// out of space!
					return result_count;
				}
				idx_t left_position = left_data.sel->get_index(lpos);
				if ((*left_data.nullmask)[left_position]) {
					continue;
				}
				if (OP::Operation(ldata[left_position], rdata[right_position])) {
					// emit tuple
					lvector.set_index(result_count, lpos);
					rvector.set_index(result_count, rpos);
					result_count++;
				}
			}
			lpos = 0;
		}
		return result_count;
	}
};

struct RefineNestedLoopJoin {
	template <class T, class OP>
	static idx_t Operation(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
	                       SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count) {
		VectorData left_data, right_data;
		left.Orrify(left_size, left_data);
		right.Orrify(right_size, right_data);

		// refine phase of the nested loop join
		// refine lvector and rvector based on matches of subsequent conditions (in case there are multiple conditions
		// in the join)
		assert(current_match_count > 0);
		auto ldata = (T *)left_data.data;
		auto rdata = (T *)right_data.data;
		idx_t result_count = 0;
		for (idx_t i = 0; i < current_match_count; i++) {
			auto lidx = lvector.get_index(i);
			auto ridx = rvector.get_index(i);
			auto left_idx = left_data.sel->get_index(lidx);
			auto right_idx = right_data.sel->get_index(ridx);
			// null values should be filtered out before
			if ((*left_data.nullmask)[left_idx] || (*right_data.nullmask)[right_idx]) {
				continue;
			}
			if (OP::Operation(ldata[left_idx], rdata[right_idx])) {
				lvector.set_index(result_count, lidx);
				rvector.set_index(result_count, ridx);
				result_count++;
			}
		}
		return result_count;
	}
};

template <class NLTYPE, class OP>
static idx_t nested_loop_join_inner_operator(Vector &left, Vector &right, idx_t left_size, idx_t right_size,
                                             idx_t &lpos, idx_t &rpos, SelectionVector &lvector,
                                             SelectionVector &rvector, idx_t current_match_count) {
	switch (left.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return NLTYPE::template Operation<int8_t, OP>(left, right, left_size, right_size, lpos, rpos, lvector, rvector,
		                                              current_match_count);
	case TypeId::INT16:
		return NLTYPE::template Operation<int16_t, OP>(left, right, left_size, right_size, lpos, rpos, lvector, rvector,
		                                               current_match_count);
	case TypeId::INT32:
		return NLTYPE::template Operation<int32_t, OP>(left, right, left_size, right_size, lpos, rpos, lvector, rvector,
		                                               current_match_count);
	case TypeId::INT64:
		return NLTYPE::template Operation<int64_t, OP>(left, right, left_size, right_size, lpos, rpos, lvector, rvector,
		                                               current_match_count);
	case TypeId::FLOAT:
		return NLTYPE::template Operation<float, OP>(left, right, left_size, right_size, lpos, rpos, lvector, rvector,
		                                             current_match_count);
	case TypeId::DOUBLE:
		return NLTYPE::template Operation<double, OP>(left, right, left_size, right_size, lpos, rpos, lvector, rvector,
		                                              current_match_count);
	case TypeId::VARCHAR:
		return NLTYPE::template Operation<string_t, OP>(left, right, left_size, right_size, lpos, rpos, lvector,
		                                                rvector, current_match_count);
	default:
		throw NotImplementedException("Unimplemented type for join!");
	}
}

template <class NLTYPE>
idx_t nested_loop_join_inner(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
                             SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count,
                             ExpressionType comparison_type) {
	assert(left.type == right.type);
	switch (comparison_type) {
	case ExpressionType::COMPARE_EQUAL:
		return nested_loop_join_inner_operator<NLTYPE, duckdb::Equals>(left, right, left_size, right_size, lpos, rpos,
		                                                               lvector, rvector, current_match_count);
	case ExpressionType::COMPARE_NOTEQUAL:
		return nested_loop_join_inner_operator<NLTYPE, duckdb::NotEquals>(left, right, left_size, right_size, lpos,
		                                                                  rpos, lvector, rvector, current_match_count);
	case ExpressionType::COMPARE_LESSTHAN:
		return nested_loop_join_inner_operator<NLTYPE, duckdb::LessThan>(left, right, left_size, right_size, lpos, rpos,
		                                                                 lvector, rvector, current_match_count);
	case ExpressionType::COMPARE_GREATERTHAN:
		return nested_loop_join_inner_operator<NLTYPE, duckdb::GreaterThan>(
		    left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return nested_loop_join_inner_operator<NLTYPE, duckdb::LessThanEquals>(
		    left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		return nested_loop_join_inner_operator<NLTYPE, duckdb::GreaterThanEquals>(
		    left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
	default:
		throw NotImplementedException("Unimplemented comparison type for join!");
	}
}

idx_t NestedLoopJoinInner::Perform(idx_t &lpos, idx_t &rpos, DataChunk &left_conditions, DataChunk &right_conditions,
                                   SelectionVector &lvector, SelectionVector &rvector,
                                   vector<JoinCondition> &conditions) {
	assert(left_conditions.column_count() == right_conditions.column_count());
	if (lpos >= left_conditions.size() || rpos >= right_conditions.size()) {
		return 0;
	}
	// for the first condition, lvector and rvector are not set yet
	// we initialize them using the InitialNestedLoopJoin
	idx_t match_count = nested_loop_join_inner<InitialNestedLoopJoin>(
	    left_conditions.data[0], right_conditions.data[0], left_conditions.size(), right_conditions.size(), lpos, rpos,
	    lvector, rvector, 0, conditions[0].comparison);
	// now resolve the rest of the conditions
	for (idx_t i = 1; i < conditions.size(); i++) {
		// check if we have run out of tuples to compare
		if (match_count == 0) {
			return 0;
		}
		// if not, get the vectors to compare
		Vector &l = left_conditions.data[i];
		Vector &r = right_conditions.data[i];
		// then we refine the currently obtained results using the RefineNestedLoopJoin
		match_count =
		    nested_loop_join_inner<RefineNestedLoopJoin>(l, r, left_conditions.size(), right_conditions.size(), lpos,
		                                                 rpos, lvector, rvector, match_count, conditions[i].comparison);
	}
	return match_count;
}




using namespace duckdb;
using namespace std;

template <class T, class OP>
static void mark_join_templated(Vector &left, Vector &right, idx_t lcount, idx_t rcount, bool found_match[]) {
	VectorData left_data, right_data;
	left.Orrify(lcount, left_data);
	right.Orrify(rcount, right_data);

	auto ldata = (T *)left_data.data;
	auto rdata = (T *)right_data.data;
	for (idx_t i = 0; i < lcount; i++) {
		if (found_match[i]) {
			continue;
		}
		auto lidx = left_data.sel->get_index(i);
		if ((*left_data.nullmask)[lidx]) {
			continue;
		}
		for (idx_t j = 0; j < rcount; j++) {
			auto ridx = right_data.sel->get_index(j);
			if ((*right_data.nullmask)[ridx]) {
				continue;
			}
			if (OP::Operation(ldata[lidx], rdata[ridx])) {
				found_match[i] = true;
				break;
			}
		}
	}
}

template <class OP>
static void mark_join_operator(Vector &left, Vector &right, idx_t lcount, idx_t rcount, bool found_match[]) {
	switch (left.type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return mark_join_templated<int8_t, OP>(left, right, lcount, rcount, found_match);
	case TypeId::INT16:
		return mark_join_templated<int16_t, OP>(left, right, lcount, rcount, found_match);
	case TypeId::INT32:
		return mark_join_templated<int32_t, OP>(left, right, lcount, rcount, found_match);
	case TypeId::INT64:
		return mark_join_templated<int64_t, OP>(left, right, lcount, rcount, found_match);
	case TypeId::FLOAT:
		return mark_join_templated<float, OP>(left, right, lcount, rcount, found_match);
	case TypeId::DOUBLE:
		return mark_join_templated<double, OP>(left, right, lcount, rcount, found_match);
	case TypeId::VARCHAR:
		return mark_join_templated<string_t, OP>(left, right, lcount, rcount, found_match);
	default:
		throw NotImplementedException("Unimplemented type for join!");
	}
}

static void mark_join(Vector &left, Vector &right, idx_t lcount, idx_t rcount, bool found_match[],
                      ExpressionType comparison_type) {
	assert(left.type == right.type);
	switch (comparison_type) {
	case ExpressionType::COMPARE_EQUAL:
		return mark_join_operator<duckdb::Equals>(left, right, lcount, rcount, found_match);
	case ExpressionType::COMPARE_NOTEQUAL:
		return mark_join_operator<duckdb::NotEquals>(left, right, lcount, rcount, found_match);
	case ExpressionType::COMPARE_LESSTHAN:
		return mark_join_operator<duckdb::LessThan>(left, right, lcount, rcount, found_match);
	case ExpressionType::COMPARE_GREATERTHAN:
		return mark_join_operator<duckdb::GreaterThan>(left, right, lcount, rcount, found_match);
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return mark_join_operator<duckdb::LessThanEquals>(left, right, lcount, rcount, found_match);
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		return mark_join_operator<duckdb::GreaterThanEquals>(left, right, lcount, rcount, found_match);
	default:
		throw NotImplementedException("Unimplemented comparison type for join!");
	}
}

void NestedLoopJoinMark::Perform(DataChunk &left, ChunkCollection &right, bool found_match[],
                                 vector<JoinCondition> &conditions) {
	// initialize a new temporary selection vector for the left chunk
	// loop over all chunks in the RHS
	for (idx_t chunk_idx = 0; chunk_idx < right.chunks.size(); chunk_idx++) {
		DataChunk &right_chunk = *right.chunks[chunk_idx];
		for (idx_t i = 0; i < conditions.size(); i++) {
			mark_join(left.data[i], right_chunk.data[i], left.size(), right_chunk.size(), found_match,
			          conditions[i].comparison);
		}
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/aggregate/physical_hash_aggregate.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! PhysicalHashAggregate is an group-by and aggregate implementation that uses
//! a hash table to perform the grouping
class PhysicalHashAggregate : public PhysicalOperator {
public:
	PhysicalHashAggregate(vector<TypeId> types, vector<unique_ptr<Expression>> expressions,
	                      PhysicalOperatorType type = PhysicalOperatorType::HASH_GROUP_BY);
	PhysicalHashAggregate(vector<TypeId> types, vector<unique_ptr<Expression>> expressions,
	                      vector<unique_ptr<Expression>> groups,
	                      PhysicalOperatorType type = PhysicalOperatorType::HASH_GROUP_BY);

	//! The groups
	vector<unique_ptr<Expression>> groups;
	//! The aggregates that have to be computed
	vector<unique_ptr<Expression>> aggregates;
	bool is_implicit_aggr;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb








using namespace duckdb;
using namespace std;

class PhysicalHashAggregateState : public PhysicalOperatorState {
public:
	PhysicalHashAggregateState(PhysicalHashAggregate *parent, PhysicalOperator *child);

	//! Materialized GROUP BY expression
	DataChunk group_chunk;
	//! Materialized aggregates
	DataChunk aggregate_chunk;
	//! The current position to scan the HT for output tuples
	idx_t ht_scan_position;
	idx_t tuples_scanned;
	//! The HT
	unique_ptr<SuperLargeHashTable> ht;
	//! The payload chunk, only used while filling the HT
	DataChunk payload_chunk;
	//! Expression executor for the GROUP BY chunk
	ExpressionExecutor group_executor;
	//! Expression state for the payload
	ExpressionExecutor payload_executor;
};

PhysicalHashAggregate::PhysicalHashAggregate(vector<TypeId> types, vector<unique_ptr<Expression>> expressions,
                                             PhysicalOperatorType type)
    : PhysicalHashAggregate(types, move(expressions), {}, type) {
}

PhysicalHashAggregate::PhysicalHashAggregate(vector<TypeId> types, vector<unique_ptr<Expression>> expressions,
                                             vector<unique_ptr<Expression>> groups, PhysicalOperatorType type)
    : PhysicalOperator(type, types), groups(move(groups)) {
	// get a list of all aggregates to be computed
	// fake a single group with a constant value for aggregation without groups
	if (this->groups.size() == 0) {
		auto ce = make_unique<BoundConstantExpression>(Value::TINYINT(42));
		this->groups.push_back(move(ce));
		is_implicit_aggr = true;
	} else {
		is_implicit_aggr = false;
	}
	for (auto &expr : expressions) {
		assert(expr->expression_class == ExpressionClass::BOUND_AGGREGATE);
		assert(expr->IsAggregate());
		aggregates.push_back(move(expr));
	}
}

void PhysicalHashAggregate::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalHashAggregateState *>(state_);
	do {
		// resolve the child chunk if there is one
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			break;
		}
		// aggregation with groups
		DataChunk &group_chunk = state->group_chunk;
		DataChunk &payload_chunk = state->payload_chunk;
		state->group_executor.Execute(state->child_chunk, group_chunk);
		state->payload_executor.SetChunk(state->child_chunk);

		payload_chunk.Reset();
		idx_t payload_idx = 0, payload_expr_idx = 0;
		payload_chunk.SetCardinality(group_chunk);
		for (idx_t i = 0; i < aggregates.size(); i++) {
			auto &aggr = (BoundAggregateExpression &)*aggregates[i];
			if (aggr.children.size()) {
				for (idx_t j = 0; j < aggr.children.size(); ++j) {
					state->payload_executor.ExecuteExpression(payload_expr_idx, payload_chunk.data[payload_idx]);
					payload_idx++;
					payload_expr_idx++;
				}
			} else {
				payload_idx++;
			}
		}

		group_chunk.Verify();
		payload_chunk.Verify();
		assert(payload_chunk.column_count() == 0 || group_chunk.size() == payload_chunk.size());

		state->ht->AddChunk(group_chunk, payload_chunk);
		state->tuples_scanned += state->child_chunk.size();
	} while (state->child_chunk.size() > 0);

	state->group_chunk.Reset();
	state->aggregate_chunk.Reset();
	idx_t elements_found = state->ht->Scan(state->ht_scan_position, state->group_chunk, state->aggregate_chunk);

	// special case hack to sort out aggregating from empty intermediates
	// for aggregations without groups
	if (elements_found == 0 && state->tuples_scanned == 0 && is_implicit_aggr) {
		assert(chunk.column_count() == aggregates.size());
		// for each column in the aggregates, set to initial state
		chunk.SetCardinality(1);
		for (idx_t i = 0; i < chunk.column_count(); i++) {
			assert(aggregates[i]->GetExpressionClass() == ExpressionClass::BOUND_AGGREGATE);
			auto &aggr = (BoundAggregateExpression &)*aggregates[i];
			auto aggr_state = unique_ptr<data_t[]>(new data_t[aggr.function.state_size()]);
			aggr.function.initialize(aggr_state.get());

			Vector state_vector(Value::POINTER((uintptr_t)aggr_state.get()));
			aggr.function.finalize(state_vector, chunk.data[i], 1);
		}
		state->finished = true;
		return;
	}
	if (elements_found == 0 && !state->finished) {
		state->finished = true;
		return;
	}
	// we finished the child chunk
	// actually compute the final projection list now
	idx_t chunk_index = 0;
	chunk.SetCardinality(elements_found);
	if (state->group_chunk.column_count() + state->aggregate_chunk.column_count() == chunk.column_count()) {
		for (idx_t col_idx = 0; col_idx < state->group_chunk.column_count(); col_idx++) {
			chunk.data[chunk_index++].Reference(state->group_chunk.data[col_idx]);
		}
	} else {
		assert(state->aggregate_chunk.column_count() == chunk.column_count());
	}

	for (idx_t col_idx = 0; col_idx < state->aggregate_chunk.column_count(); col_idx++) {
		chunk.data[chunk_index++].Reference(state->aggregate_chunk.data[col_idx]);
	}
}

unique_ptr<PhysicalOperatorState> PhysicalHashAggregate::GetOperatorState() {
	assert(children.size() > 0);
	auto state = make_unique<PhysicalHashAggregateState>(this, children[0].get());
	state->tuples_scanned = 0;
	vector<TypeId> group_types, payload_types;
	vector<BoundAggregateExpression *> aggregate_kind;
	for (auto &expr : groups) {
		group_types.push_back(expr->return_type);
	}
	for (auto &expr : aggregates) {
		assert(expr->GetExpressionClass() == ExpressionClass::BOUND_AGGREGATE);
		auto &aggr = (BoundAggregateExpression &)*expr;
		aggregate_kind.push_back(&aggr);
		if (aggr.children.size()) {
			for (idx_t i = 0; i < aggr.children.size(); ++i) {
				payload_types.push_back(aggr.children[i]->return_type);
				state->payload_executor.AddExpression(*aggr.children[i]);
			}
		} else {
			// COUNT(*)
			payload_types.push_back(TypeId::INT64);
		}
	}
	if (payload_types.size() > 0) {
		state->payload_chunk.Initialize(payload_types);
	}

	state->ht = make_unique<SuperLargeHashTable>(1024, group_types, payload_types, aggregate_kind);
	return move(state);
}

PhysicalHashAggregateState::PhysicalHashAggregateState(PhysicalHashAggregate *parent, PhysicalOperator *child)
    : PhysicalOperatorState(child), ht_scan_position(0), tuples_scanned(0), group_executor(parent->groups) {
	vector<TypeId> group_types, aggregate_types;
	for (auto &expr : parent->groups) {
		group_types.push_back(expr->return_type);
	}
	group_chunk.Initialize(group_types);
	for (auto &expr : parent->aggregates) {
		aggregate_types.push_back(expr->return_type);
	}
	if (aggregate_types.size() > 0) {
		aggregate_chunk.Initialize(aggregate_types);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/aggregate/physical_simple_aggregate.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! PhysicalSimpleAggregate is an aggregate operator that can only perform aggregates (1) without any groups, and (2)
//! without any DISTINCT aggregates
class PhysicalSimpleAggregate : public PhysicalOperator {
public:
	PhysicalSimpleAggregate(vector<TypeId> types, vector<unique_ptr<Expression>> expressions);

	//! The aggregates that have to be computed
	vector<unique_ptr<Expression>> aggregates;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb







using namespace duckdb;
using namespace std;

class PhysicalSimpleAggregateOperatorState : public PhysicalOperatorState {
public:
	PhysicalSimpleAggregateOperatorState(PhysicalSimpleAggregate *parent, PhysicalOperator *child);
	~PhysicalSimpleAggregateOperatorState() {
		assert(destructors.size() == aggregates.size());
		for (idx_t i = 0; i < destructors.size(); i++) {
			if (!destructors[i]) {
				continue;
			}
			Vector state_vector(Value::POINTER((uintptr_t)aggregates[i].get()));
			state_vector.vector_type = VectorType::FLAT_VECTOR;

			destructors[i](state_vector, 1);
		}
	}

	//! The aggregate values
	vector<unique_ptr<data_t[]>> aggregates;

	vector<aggregate_destructor_t> destructors;

	ExpressionExecutor child_executor;
	//! The payload chunk
	DataChunk payload_chunk;
};

PhysicalSimpleAggregate::PhysicalSimpleAggregate(vector<TypeId> types, vector<unique_ptr<Expression>> expressions)
    : PhysicalOperator(PhysicalOperatorType::SIMPLE_AGGREGATE, types), aggregates(move(expressions)) {
}

void PhysicalSimpleAggregate::GetChunkInternal(ClientContext &context, DataChunk &chunk,
                                               PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalSimpleAggregateOperatorState *>(state_);
	while (true) {
		// iterate over the child
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			break;
		}

		// now resolve the aggregates for each of the children
		idx_t payload_idx = 0, payload_expr_idx = 0;
		DataChunk &payload_chunk = state->payload_chunk;
		payload_chunk.Reset();
		state->child_executor.SetChunk(state->child_chunk);
		payload_chunk.SetCardinality(state->child_chunk);
		for (idx_t aggr_idx = 0; aggr_idx < aggregates.size(); aggr_idx++) {
			auto &aggregate = (BoundAggregateExpression &)*aggregates[aggr_idx];
			idx_t payload_cnt = 0;
			// resolve the child expression of the aggregate (if any)
			if (aggregate.children.size() > 0) {
				for (idx_t i = 0; i < aggregate.children.size(); ++i) {
					state->child_executor.ExecuteExpression(payload_expr_idx,
					                                        payload_chunk.data[payload_idx + payload_cnt]);
					payload_expr_idx++;
					payload_cnt++;
				}
			} else {
				payload_cnt++;
			}
			// perform the actual aggregation
			aggregate.function.simple_update(&payload_chunk.data[payload_idx], payload_cnt,
			                                 state->aggregates[aggr_idx].get(), payload_chunk.size());
			payload_idx += payload_cnt;
		}
	}
	// initialize the result chunk with the aggregate values
	chunk.SetCardinality(1);
	for (idx_t aggr_idx = 0; aggr_idx < aggregates.size(); aggr_idx++) {
		auto &aggregate = (BoundAggregateExpression &)*aggregates[aggr_idx];

		Vector state_vector(Value::POINTER((uintptr_t)state->aggregates[aggr_idx].get()));
		aggregate.function.finalize(state_vector, chunk.data[aggr_idx], 1);
	}
	state->finished = true;
}

unique_ptr<PhysicalOperatorState> PhysicalSimpleAggregate::GetOperatorState() {
	return make_unique<PhysicalSimpleAggregateOperatorState>(this, children[0].get());
}

PhysicalSimpleAggregateOperatorState::PhysicalSimpleAggregateOperatorState(PhysicalSimpleAggregate *parent,
                                                                           PhysicalOperator *child)
    : PhysicalOperatorState(child) {
	vector<TypeId> payload_types;
	for (auto &aggregate : parent->aggregates) {
		assert(aggregate->GetExpressionClass() == ExpressionClass::BOUND_AGGREGATE);
		auto &aggr = (BoundAggregateExpression &)*aggregate;
		// initialize the payload chunk
		if (aggr.children.size()) {
			for (idx_t i = 0; i < aggr.children.size(); ++i) {
				payload_types.push_back(aggr.children[i]->return_type);
				child_executor.AddExpression(*aggr.children[i]);
			}
		} else {
			// COUNT(*)
			payload_types.push_back(TypeId::INT64);
		}
		// initialize the aggregate values
		auto state = unique_ptr<data_t[]>(new data_t[aggr.function.state_size()]);
		aggr.function.initialize(state.get());
		aggregates.push_back(move(state));
		destructors.push_back(aggr.function.destructor);
	}
	payload_chunk.Initialize(payload_types);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/aggregate/physical_window.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalWindow implements window functions
class PhysicalWindow : public PhysicalOperator {
public:
	PhysicalWindow(LogicalOperator &op, vector<unique_ptr<Expression>> select_list,
	               PhysicalOperatorType type = PhysicalOperatorType::WINDOW);

	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	//! The projection list of the SELECT statement (that contains aggregates)
	vector<unique_ptr<Expression>> select_list;

public:
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/window_segment_tree.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class WindowSegmentTree {
public:
	WindowSegmentTree(AggregateFunction &aggregate, TypeId result_type, ChunkCollection *input);
	Value Compute(idx_t start, idx_t end);

private:
	void ConstructTree();
	void WindowSegmentValue(idx_t l_idx, idx_t begin, idx_t end);
	void AggregateInit();
	Value AggegateFinal();

	AggregateFunction aggregate;
	vector<data_t> state;
	DataChunk inputs;
	StandaloneVector statep;
	TypeId result_type;
	unique_ptr<data_t[]> levels_flat_native;
	vector<idx_t> levels_flat_start;

	ChunkCollection *input_ref;

	// TREE_FANOUT needs to cleanly divide STANDARD_VECTOR_SIZE
#if STANDARD_VECTOR_SIZE < 64
	static constexpr idx_t TREE_FANOUT = STANDARD_VECTOR_SIZE;
#else
	static constexpr idx_t TREE_FANOUT = 64;
#endif
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_window_expression.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/window_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

enum class WindowBoundary : uint8_t {
	INVALID = 0,
	UNBOUNDED_PRECEDING = 1,
	UNBOUNDED_FOLLOWING = 2,
	CURRENT_ROW_RANGE = 3,
	CURRENT_ROW_ROWS = 4,
	EXPR_PRECEDING = 5,
	EXPR_FOLLOWING = 6
};

//! The WindowExpression represents a window function in the query. They are a special case of aggregates which is why
//! they inherit from them.
class WindowExpression : public ParsedExpression {
public:
	WindowExpression(ExpressionType type, string schema_name, string function_name);

	//! Schema of the aggregate function
	string schema;
	//! Name of the aggregate function
	string function_name;
	//! The child expression of the main window aggregate
	vector<unique_ptr<ParsedExpression>> children;
	//! The set of expressions to partition by
	vector<unique_ptr<ParsedExpression>> partitions;
	//! The set of ordering clauses
	vector<OrderByNode> orders;
	//! The window boundaries
	WindowBoundary start = WindowBoundary::INVALID;
	WindowBoundary end = WindowBoundary::INVALID;

	unique_ptr<ParsedExpression> start_expr;
	unique_ptr<ParsedExpression> end_expr;
	//! Offset and default expressions for WINDOW_LEAD and WINDOW_LAG functions
	unique_ptr<ParsedExpression> offset_expr;
	unique_ptr<ParsedExpression> default_expr;

public:
	bool IsWindow() const override {
		return true;
	}

	string ToString() const override;

	static bool Equals(const WindowExpression *a, const WindowExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb




namespace duckdb {
class AggregateFunction;

class BoundWindowExpression : public Expression {
public:
	BoundWindowExpression(ExpressionType type, TypeId return_type, unique_ptr<AggregateFunction> aggregate);

	//! The bound aggregate function
	unique_ptr<AggregateFunction> aggregate;
	//! The child expressions of the main window aggregate
	vector<unique_ptr<Expression>> children;
	//! The set of expressions to partition by
	vector<unique_ptr<Expression>> partitions;
	//! The set of ordering clauses
	vector<BoundOrderByNode> orders;
	//! The window boundaries
	WindowBoundary start = WindowBoundary::INVALID;
	WindowBoundary end = WindowBoundary::INVALID;

	unique_ptr<Expression> start_expr;
	unique_ptr<Expression> end_expr;
	//! Offset and default expressions for WINDOW_LEAD and WINDOW_LAG functions
	unique_ptr<Expression> offset_expr;
	unique_ptr<Expression> default_expr;

public:
	bool IsWindow() const override {
		return true;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


#include <cmath>

using namespace duckdb;
using namespace std;

//! The operator state of the window
class PhysicalWindowOperatorState : public PhysicalOperatorState {
public:
	PhysicalWindowOperatorState(PhysicalOperator *child) : PhysicalOperatorState(child), position(0) {
	}

	idx_t position;
	ChunkCollection tuples;
	ChunkCollection window_results;
};

// this implements a sorted window functions variant
PhysicalWindow::PhysicalWindow(LogicalOperator &op, vector<unique_ptr<Expression>> select_list,
                               PhysicalOperatorType type)
    : PhysicalOperator(type, op.types), select_list(std::move(select_list)) {
}

static bool EqualsSubset(vector<Value> &a, vector<Value> &b, idx_t start, idx_t end) {
	assert(start <= end);
	for (idx_t i = start; i < end; i++) {
		if (a[i] != b[i]) {
			return false;
		}
	}
	return true;
}

static idx_t BinarySearchRightmost(ChunkCollection &input, vector<Value> row, idx_t l, idx_t r, idx_t comp_cols) {
	if (comp_cols == 0) {
		return r - 1;
	}
	while (l < r) {
		idx_t m = floor((l + r) / 2);
		bool less_than_equals = true;
		for (idx_t i = 0; i < comp_cols; i++) {
			if (input.GetRow(m)[i] > row[i]) {
				less_than_equals = false;
				break;
			}
		}
		if (less_than_equals) {
			l = m + 1;
		} else {
			r = m;
		}
	}
	return l - 1;
}

static void MaterializeExpressions(ClientContext &context, Expression **exprs, idx_t expr_count, ChunkCollection &input,
                                   ChunkCollection &output, bool scalar = false) {
	if (expr_count == 0) {
		return;
	}

	vector<TypeId> types;
	ExpressionExecutor executor;
	for (idx_t expr_idx = 0; expr_idx < expr_count; ++expr_idx) {
		types.push_back(exprs[expr_idx]->return_type);
		executor.AddExpression(*exprs[expr_idx]);
	}

	for (idx_t i = 0; i < input.chunks.size(); i++) {
		DataChunk chunk;
		chunk.Initialize(types);

		executor.Execute(*input.chunks[i], chunk);

		chunk.Verify();
		output.Append(chunk);

		if (scalar) {
			break;
		}
	}
}

static void MaterializeExpression(ClientContext &context, Expression *expr, ChunkCollection &input,
                                  ChunkCollection &output, bool scalar = false) {
	MaterializeExpressions(context, &expr, 1, input, output, scalar);
}

static void SortCollectionForWindow(ClientContext &context, BoundWindowExpression *wexpr, ChunkCollection &input,
                                    ChunkCollection &output, ChunkCollection &sort_collection) {
	vector<TypeId> sort_types;
	vector<OrderType> orders;
	ExpressionExecutor executor;

	// we sort by both 1) partition by expression list and 2) order by expressions
	for (idx_t prt_idx = 0; prt_idx < wexpr->partitions.size(); prt_idx++) {
		auto &pexpr = wexpr->partitions[prt_idx];
		sort_types.push_back(pexpr->return_type);
		orders.push_back(OrderType::ASCENDING);
		executor.AddExpression(*pexpr);
	}

	for (idx_t ord_idx = 0; ord_idx < wexpr->orders.size(); ord_idx++) {
		auto &oexpr = wexpr->orders[ord_idx].expression;
		sort_types.push_back(oexpr->return_type);
		orders.push_back(wexpr->orders[ord_idx].type);
		executor.AddExpression(*oexpr);
	}

	assert(sort_types.size() > 0);

	// create a chunkcollection for the results of the expressions in the window definitions
	for (idx_t i = 0; i < input.chunks.size(); i++) {
		DataChunk sort_chunk;
		sort_chunk.Initialize(sort_types);

		executor.Execute(*input.chunks[i], sort_chunk);

		sort_chunk.Verify();
		sort_collection.Append(sort_chunk);
	}

	assert(input.count == sort_collection.count);

	auto sorted_vector = unique_ptr<idx_t[]>(new idx_t[input.count]);
	sort_collection.Sort(orders, sorted_vector.get());

	input.Reorder(sorted_vector.get());
	output.Reorder(sorted_vector.get());
	sort_collection.Reorder(sorted_vector.get());
}

struct WindowBoundariesState {
	idx_t partition_start = 0;
	idx_t partition_end = 0;
	idx_t peer_start = 0;
	idx_t peer_end = 0;
	int64_t window_start = -1;
	int64_t window_end = -1;
	bool is_same_partition = false;
	bool is_peer = false;
	vector<Value> row_prev;
};

static bool WindowNeedsRank(BoundWindowExpression *wexpr) {
	return wexpr->type == ExpressionType::WINDOW_PERCENT_RANK || wexpr->type == ExpressionType::WINDOW_RANK ||
	       wexpr->type == ExpressionType::WINDOW_RANK_DENSE || wexpr->type == ExpressionType::WINDOW_CUME_DIST;
}

static void UpdateWindowBoundaries(BoundWindowExpression *wexpr, ChunkCollection &input, idx_t input_size,
                                   idx_t row_idx, ChunkCollection &boundary_start_collection,
                                   ChunkCollection &boundary_end_collection, WindowBoundariesState &bounds) {

	if (input.column_count() > 0) {
		vector<Value> row_cur = input.GetRow(row_idx);
		idx_t sort_col_count = wexpr->partitions.size() + wexpr->orders.size();

		// determine partition and peer group boundaries to ultimately figure out window size
		bounds.is_same_partition = EqualsSubset(bounds.row_prev, row_cur, 0, wexpr->partitions.size());
		bounds.is_peer = bounds.is_same_partition &&
		                 EqualsSubset(bounds.row_prev, row_cur, wexpr->partitions.size(), sort_col_count);
		bounds.row_prev = row_cur;

		// when the partition changes, recompute the boundaries
		if (!bounds.is_same_partition || row_idx == 0) { // special case for first row, need to init
			bounds.partition_start = row_idx;
			bounds.peer_start = row_idx;

			// find end of partition
			bounds.partition_end =
			    BinarySearchRightmost(input, row_cur, bounds.partition_start, input.count, wexpr->partitions.size()) +
			    1;

		} else if (!bounds.is_peer) {
			bounds.peer_start = row_idx;
		}

		if (wexpr->end == WindowBoundary::CURRENT_ROW_RANGE || wexpr->type == ExpressionType::WINDOW_CUME_DIST) {
			bounds.peer_end = BinarySearchRightmost(input, row_cur, row_idx, bounds.partition_end, sort_col_count) + 1;
		}
	} else {
		bounds.is_same_partition = 0;
		bounds.is_peer = true;
		bounds.partition_end = input_size;
		bounds.peer_end = bounds.partition_end;
	}

	// determine window boundaries depending on the type of expression
	bounds.window_start = -1;
	bounds.window_end = -1;

	switch (wexpr->start) {
	case WindowBoundary::UNBOUNDED_PRECEDING:
		bounds.window_start = bounds.partition_start;
		break;
	case WindowBoundary::CURRENT_ROW_ROWS:
		bounds.window_start = row_idx;
		break;
	case WindowBoundary::CURRENT_ROW_RANGE:
		bounds.window_start = bounds.peer_start;
		break;
	case WindowBoundary::UNBOUNDED_FOLLOWING:
		assert(0); // disallowed
		break;
	case WindowBoundary::EXPR_PRECEDING: {
		assert(boundary_start_collection.column_count() > 0);
		bounds.window_start =
		    (int64_t)row_idx -
		    boundary_start_collection.GetValue(0, wexpr->start_expr->IsScalar() ? 0 : row_idx).GetValue<int64_t>();
		break;
	}
	case WindowBoundary::EXPR_FOLLOWING: {
		assert(boundary_start_collection.column_count() > 0);
		bounds.window_start =
		    row_idx +
		    boundary_start_collection.GetValue(0, wexpr->start_expr->IsScalar() ? 0 : row_idx).GetValue<int64_t>();
		break;
	}

	default:
		throw NotImplementedException("Unsupported boundary");
	}

	switch (wexpr->end) {
	case WindowBoundary::UNBOUNDED_PRECEDING:
		assert(0); // disallowed
		break;
	case WindowBoundary::CURRENT_ROW_ROWS:
		bounds.window_end = row_idx + 1;
		break;
	case WindowBoundary::CURRENT_ROW_RANGE:
		bounds.window_end = bounds.peer_end;
		break;
	case WindowBoundary::UNBOUNDED_FOLLOWING:
		bounds.window_end = bounds.partition_end;
		break;
	case WindowBoundary::EXPR_PRECEDING:
		assert(boundary_end_collection.column_count() > 0);
		bounds.window_end =
		    (int64_t)row_idx -
		    boundary_end_collection.GetValue(0, wexpr->end_expr->IsScalar() ? 0 : row_idx).GetValue<int64_t>() + 1;
		break;
	case WindowBoundary::EXPR_FOLLOWING:
		assert(boundary_end_collection.column_count() > 0);
		bounds.window_end =
		    row_idx +
		    boundary_end_collection.GetValue(0, wexpr->end_expr->IsScalar() ? 0 : row_idx).GetValue<int64_t>() + 1;

		break;
	default:
		throw NotImplementedException("Unsupported boundary");
	}

	// clamp windows to partitions if they should exceed
	if (bounds.window_start < (int64_t)bounds.partition_start) {
		bounds.window_start = bounds.partition_start;
	}
	if ((idx_t)bounds.window_end > bounds.partition_end) {
		bounds.window_end = bounds.partition_end;
	}

	if (bounds.window_start < 0 || bounds.window_end < 0) {
		throw Exception("Failed to compute window boundaries");
	}
}

static void ComputeWindowExpression(ClientContext &context, BoundWindowExpression *wexpr, ChunkCollection &input,
                                    ChunkCollection &output, idx_t output_idx) {

	ChunkCollection sort_collection;
	bool needs_sorting = wexpr->partitions.size() + wexpr->orders.size() > 0;
	if (needs_sorting) {
		SortCollectionForWindow(context, wexpr, input, output, sort_collection);
	}

	// evaluate inner expressions of window functions, could be more complex
	ChunkCollection payload_collection;
	vector<Expression *> exprs;
	for (auto &child : wexpr->children) {
		exprs.push_back(child.get());
	}
	// TODO: child may be a scalar, don't need to materialize the whole collection then
	MaterializeExpressions(context, exprs.data(), exprs.size(), input, payload_collection);

	ChunkCollection leadlag_offset_collection;
	ChunkCollection leadlag_default_collection;
	if (wexpr->type == ExpressionType::WINDOW_LEAD || wexpr->type == ExpressionType::WINDOW_LAG) {
		if (wexpr->offset_expr) {
			MaterializeExpression(context, wexpr->offset_expr.get(), input, leadlag_offset_collection,
			                      wexpr->offset_expr->IsScalar());
		}
		if (wexpr->default_expr) {
			MaterializeExpression(context, wexpr->default_expr.get(), input, leadlag_default_collection,
			                      wexpr->default_expr->IsScalar());
		}
	}

	// evaluate boundaries if present.
	ChunkCollection boundary_start_collection;
	if (wexpr->start_expr &&
	    (wexpr->start == WindowBoundary::EXPR_PRECEDING || wexpr->start == WindowBoundary::EXPR_FOLLOWING)) {
		MaterializeExpression(context, wexpr->start_expr.get(), input, boundary_start_collection,
		                      wexpr->start_expr->IsScalar());
	}
	ChunkCollection boundary_end_collection;
	if (wexpr->end_expr &&
	    (wexpr->end == WindowBoundary::EXPR_PRECEDING || wexpr->end == WindowBoundary::EXPR_FOLLOWING)) {
		MaterializeExpression(context, wexpr->end_expr.get(), input, boundary_end_collection,
		                      wexpr->end_expr->IsScalar());
	}

	// build a segment tree for frame-adhering aggregates
	// see http://www.vldb.org/pvldb/vol8/p1058-leis.pdf
	unique_ptr<WindowSegmentTree> segment_tree = nullptr;

	if (wexpr->aggregate) {
		segment_tree = make_unique<WindowSegmentTree>(*(wexpr->aggregate), wexpr->return_type, &payload_collection);
	}

	WindowBoundariesState bounds;
	uint64_t dense_rank = 1, rank_equal = 0, rank = 1;

	if (needs_sorting) {
		bounds.row_prev = sort_collection.GetRow(0);
	}

	// this is the main loop, go through all sorted rows and compute window function result
	for (idx_t row_idx = 0; row_idx < input.count; row_idx++) {
		// special case, OVER (), aggregate over everything
		UpdateWindowBoundaries(wexpr, sort_collection, input.count, row_idx, boundary_start_collection,
		                       boundary_end_collection, bounds);
		if (WindowNeedsRank(wexpr)) {
			if (!bounds.is_same_partition || row_idx == 0) { // special case for first row, need to init
				dense_rank = 1;
				rank = 1;
				rank_equal = 0;
			} else if (!bounds.is_peer) {
				dense_rank++;
				rank += rank_equal;
				rank_equal = 0;
			}
			rank_equal++;
		}

		auto res = Value();

		// if no values are read for window, result is NULL
		if (bounds.window_start >= bounds.window_end) {
			output.SetValue(output_idx, row_idx, res);
			continue;
		}

		switch (wexpr->type) {
		case ExpressionType::WINDOW_AGGREGATE: {
			res = segment_tree->Compute(bounds.window_start, bounds.window_end);
			break;
		}
		case ExpressionType::WINDOW_ROW_NUMBER: {
			res = Value::Numeric(wexpr->return_type, row_idx - bounds.partition_start + 1);
			break;
		}
		case ExpressionType::WINDOW_RANK_DENSE: {
			res = Value::Numeric(wexpr->return_type, dense_rank);
			break;
		}
		case ExpressionType::WINDOW_RANK: {
			res = Value::Numeric(wexpr->return_type, rank);
			break;
		}
		case ExpressionType::WINDOW_PERCENT_RANK: {
			int64_t denom = (int64_t)bounds.partition_end - bounds.partition_start - 1;
			double percent_rank = denom > 0 ? ((double)rank - 1) / denom : 0;
			res = Value(percent_rank);
			break;
		}
		case ExpressionType::WINDOW_CUME_DIST: {
			int64_t denom = (int64_t)bounds.partition_end - bounds.partition_start;
			double cume_dist = denom > 0 ? ((double)(bounds.peer_end - bounds.partition_start)) / denom : 0;
			res = Value(cume_dist);
			break;
		}
		case ExpressionType::WINDOW_NTILE: {
			if (payload_collection.column_count() != 1) {
				throw Exception("NTILE needs a parameter");
			}
			auto n_param = payload_collection.GetValue(0, row_idx).GetValue<int64_t>();
			// With thanks from SQLite's ntileValueFunc()
			int64_t n_total = bounds.partition_end - bounds.partition_start;
			int64_t n_size = (n_total / n_param);
			if (n_size > 0) {
				int64_t n_large = n_total - n_param * n_size;
				int64_t i_small = n_large * (n_size + 1);

				assert((n_large * (n_size + 1) + (n_param - n_large) * n_size) == n_total);

				if (row_idx < (idx_t)i_small) {
					res = Value::Numeric(wexpr->return_type, 1 + row_idx / (n_size + 1));
				} else {
					res = Value::Numeric(wexpr->return_type, 1 + n_large + (row_idx - i_small) / n_size);
				}
			}
			break;
		}
		case ExpressionType::WINDOW_LEAD:
		case ExpressionType::WINDOW_LAG: {
			Value def_val = Value(wexpr->return_type);
			idx_t offset = 1;
			if (wexpr->offset_expr) {
				offset = leadlag_offset_collection.GetValue(0, wexpr->offset_expr->IsScalar() ? 0 : row_idx)
				             .GetValue<int64_t>();
			}
			if (wexpr->default_expr) {
				def_val = leadlag_default_collection.GetValue(0, wexpr->default_expr->IsScalar() ? 0 : row_idx);
			}
			if (wexpr->type == ExpressionType::WINDOW_LEAD) {
				auto lead_idx = row_idx + 1;
				if (lead_idx < bounds.partition_end) {
					res = payload_collection.GetValue(0, lead_idx);
				} else {
					res = def_val;
				}
			} else {
				int64_t lag_idx = (int64_t)row_idx - offset;
				if (lag_idx >= 0 && (idx_t)lag_idx >= bounds.partition_start) {
					res = payload_collection.GetValue(0, lag_idx);
				} else {
					res = def_val;
				}
			}

			break;
		}
		case ExpressionType::WINDOW_FIRST_VALUE: {
			res = payload_collection.GetValue(0, bounds.window_start);
			break;
		}
		case ExpressionType::WINDOW_LAST_VALUE: {
			res = payload_collection.GetValue(0, bounds.window_end - 1);
			break;
		}
		default:
			throw NotImplementedException("Window aggregate type %s", ExpressionTypeToString(wexpr->type).c_str());
		}

		output.SetValue(output_idx, row_idx, res);
	}
}

void PhysicalWindow::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalWindowOperatorState *>(state_);
	ChunkCollection &big_data = state->tuples;
	ChunkCollection &window_results = state->window_results;

	// this is a blocking operator, so compute complete result on first invocation
	if (state->position == 0) {
		do {
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			big_data.Append(state->child_chunk);
		} while (state->child_chunk.size() != 0);

		if (big_data.count == 0) {
			return;
		}

		vector<TypeId> window_types;
		for (idx_t expr_idx = 0; expr_idx < select_list.size(); expr_idx++) {
			window_types.push_back(select_list[expr_idx]->return_type);
		}

		for (idx_t i = 0; i < big_data.chunks.size(); i++) {
			DataChunk window_chunk;
			window_chunk.Initialize(window_types);
			window_chunk.SetCardinality(big_data.chunks[i]->size());
			for (idx_t col_idx = 0; col_idx < window_chunk.column_count(); col_idx++) {
				window_chunk.data[col_idx].vector_type = VectorType::CONSTANT_VECTOR;
				ConstantVector::SetNull(window_chunk.data[col_idx], true);
			}

			window_chunk.Verify();
			window_results.Append(window_chunk);
		}

		assert(window_results.column_count() == select_list.size());
		idx_t window_output_idx = 0;
		// we can have multiple window functions
		for (idx_t expr_idx = 0; expr_idx < select_list.size(); expr_idx++) {
			assert(select_list[expr_idx]->GetExpressionClass() == ExpressionClass::BOUND_WINDOW);
			// sort by partition and order clause in window def
			auto wexpr = reinterpret_cast<BoundWindowExpression *>(select_list[expr_idx].get());
			ComputeWindowExpression(context, wexpr, big_data, window_results, window_output_idx++);
		}
	}

	if (state->position >= big_data.count) {
		return;
	}

	// just return what was computed before, appending the result cols of the window expressions at the end
	auto &proj_ch = big_data.GetChunk(state->position);
	auto &wind_ch = window_results.GetChunk(state->position);

	idx_t out_idx = 0;
	assert(proj_ch.size() == wind_ch.size());
	chunk.SetCardinality(proj_ch);
	for (idx_t col_idx = 0; col_idx < proj_ch.column_count(); col_idx++) {
		chunk.data[out_idx++].Reference(proj_ch.data[col_idx]);
	}
	for (idx_t col_idx = 0; col_idx < wind_ch.column_count(); col_idx++) {
		chunk.data[out_idx++].Reference(wind_ch.data[col_idx]);
	}
	state->position += STANDARD_VECTOR_SIZE;
}

unique_ptr<PhysicalOperatorState> PhysicalWindow::GetOperatorState() {
	return make_unique<PhysicalWindowOperatorState>(children[0].get());
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/filter/physical_filter.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! PhysicalFilter represents a filter operator. It removes non-matching tuples
//! from the result. Note that it does not physically change the data, it only
//! adds a selection vector to the chunk.
class PhysicalFilter : public PhysicalOperator {
public:
	PhysicalFilter(vector<TypeId> types, vector<unique_ptr<Expression>> select_list);

	//! The filter expression
	unique_ptr<Expression> expression;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
	string ExtraRenderInformation() const override;
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

class PhysicalFilterState : public PhysicalOperatorState {
public:
	PhysicalFilterState(PhysicalOperator *child, Expression &expr) : PhysicalOperatorState(child), executor(expr) {
	}

	ExpressionExecutor executor;
};

PhysicalFilter::PhysicalFilter(vector<TypeId> types, vector<unique_ptr<Expression>> select_list)
    : PhysicalOperator(PhysicalOperatorType::FILTER, types) {
	assert(select_list.size() > 0);
	if (select_list.size() > 1) {
		// create a big AND out of the expressions
		auto conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_AND);
		for (auto &expr : select_list) {
			conjunction->children.push_back(move(expr));
		}
		expression = move(conjunction);
	} else {
		expression = move(select_list[0]);
	}
}

void PhysicalFilter::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalFilterState *>(state_);
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	idx_t initial_count;
	idx_t result_count;
	do {
		// fetch a chunk from the child and run the filter
		// we repeat this process until either (1) passing tuples are found, or (2) the child is completely exhausted
		children[0]->GetChunk(context, chunk, state->child_state.get());
		if (chunk.size() == 0) {
			return;
		}
		initial_count = chunk.size();
		result_count = state->executor.SelectExpression(chunk, sel);
	} while (result_count == 0);

	if (result_count == initial_count) {
		// nothing was filtered: skip adding any selection vectors
		return;
	}
	chunk.Slice(sel, result_count);
}

unique_ptr<PhysicalOperatorState> PhysicalFilter::GetOperatorState() {
	return make_unique<PhysicalFilterState>(children[0].get(), *expression);
}

string PhysicalFilter::ExtraRenderInformation() const {
	return expression->GetName();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_execute.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class PhysicalExecute : public PhysicalOperator {
public:
	PhysicalExecute(PhysicalOperator *plan) : PhysicalOperator(PhysicalOperatorType::EXECUTE, plan->types), plan(plan) {
	}

	PhysicalOperator *plan;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

void PhysicalExecute::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	assert(plan);
	plan->GetChunk(context, chunk, state_);
}

unique_ptr<PhysicalOperatorState> PhysicalExecute::GetOperatorState() {
	return plan->GetOperatorState();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_limit.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! PhyisicalLimit represents the LIMIT operator
class PhysicalLimit : public PhysicalOperator {
public:
	PhysicalLimit(LogicalOperator &op, idx_t limit, idx_t offset)
	    : PhysicalOperator(PhysicalOperatorType::LIMIT, op.types), limit(limit), offset(offset) {
	}

	idx_t limit;
	idx_t offset;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

class PhysicalLimitOperatorState : public PhysicalOperatorState {
public:
	PhysicalLimitOperatorState(PhysicalOperator *child, idx_t current_offset = 0)
	    : PhysicalOperatorState(child), current_offset(current_offset) {
	}

	idx_t current_offset;
};

void PhysicalLimit::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalLimitOperatorState *>(state_);

	idx_t max_element = limit + offset;
	if (state->current_offset >= max_element) {
		return;
	}

	// get the next chunk from the child
	children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
	if (state->child_chunk.size() == 0) {
		return;
	}

	if (state->current_offset < offset) {
		// we are not yet at the offset point
		if (state->current_offset + state->child_chunk.size() >= offset) {
			// however we will reach it in this chunk
			// we have to copy part of the chunk with an offset
			idx_t start_position = offset - state->current_offset;
			idx_t chunk_count = min(limit, state->child_chunk.size() - start_position);
			SelectionVector sel(STANDARD_VECTOR_SIZE);
			for (idx_t i = 0; i < chunk_count; i++) {
				sel.set_index(i, start_position + i);
			}
			// set up a slice of the input chunks
			chunk.Slice(state->child_chunk, sel, chunk_count);
		}
	} else {
		// have to copy either the entire chunk or part of it
		idx_t chunk_count;
		if (state->current_offset + state->child_chunk.size() >= max_element) {
			// have to limit the count of the chunk
			chunk_count = max_element - state->current_offset;
		} else {
			// we copy the entire chunk
			chunk_count = state->child_chunk.size();
		}
		// instead of copying we just change the pointer in the current chunk
		chunk.Reference(state->child_chunk);
		chunk.SetCardinality(chunk_count);
	}

	state->current_offset += state->child_chunk.size();
}

unique_ptr<PhysicalOperatorState> PhysicalLimit::GetOperatorState() {
	return make_unique<PhysicalLimitOperatorState>(children[0].get(), 0);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_pragma.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/pragma_info.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

enum class PragmaType : uint8_t { NOTHING, ASSIGNMENT, CALL };

struct PragmaInfo : public ParseInfo {
	//! Name of the PRAGMA statement
	string name;
	//! Type of pragma statement
	PragmaType pragma_type;
	//! Parameter list (if any)
	vector<Value> parameters;
};

} // namespace duckdb


namespace duckdb {

//! PhysicalPragma represents the PRAGMA operator
class PhysicalPragma : public PhysicalOperator {
public:
	PhysicalPragma(unique_ptr<PragmaInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::PRAGMA, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<PragmaInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb








#include <cctype>

using namespace duckdb;
using namespace std;

static idx_t ParseMemoryLimit(string arg);

void PhysicalPragma::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	auto &pragma = *info;
	auto &keyword = pragma.name;
	if (keyword == "enable_profile" || keyword == "enable_profiling") {
		// enable profiling
		if (pragma.pragma_type == PragmaType::ASSIGNMENT) {
			// enable_profiling with assignment
			// this is either enable_profiling = json, or enable_profiling = query_tree
			string assignment = pragma.parameters[0].ToString();
			if (assignment == "json") {
				context.profiler.automatic_print_format = ProfilerPrintFormat::JSON;
			} else if (assignment == "query_tree") {
				context.profiler.automatic_print_format = ProfilerPrintFormat::QUERY_TREE;
			} else {
				throw ParserException("Unrecognized print format %s, supported formats: [json, query_tree]",
				                      assignment.c_str());
			}
		} else if (pragma.pragma_type == PragmaType::NOTHING) {
			context.profiler.automatic_print_format = ProfilerPrintFormat::QUERY_TREE;
		} else {
			throw ParserException("Cannot call PRAGMA enable_profiling");
		}
		context.profiler.Enable();
	} else if (keyword == "disable_profile" || keyword == "disable_profiling") {
		if (pragma.pragma_type != PragmaType::NOTHING) {
			throw ParserException("disable_profiling cannot take parameters!");
		}
		// enable profiling
		context.profiler.Disable();
		context.profiler.automatic_print_format = ProfilerPrintFormat::NONE;
	} else if (keyword == "profiling_output" || keyword == "profile_output") {
		// set file location of where to save profiling output
		if (pragma.pragma_type != PragmaType::ASSIGNMENT || pragma.parameters[0].type != TypeId::VARCHAR) {
			throw ParserException(
			    "Profiling output must be an assignment (e.g. PRAGMA profile_output='/tmp/test.json')");
		}
		context.profiler.save_location = pragma.parameters[0].str_value;
	} else if (keyword == "memory_limit") {
		if (pragma.pragma_type != PragmaType::ASSIGNMENT) {
			throw ParserException("Memory limit must be an assignment (e.g. PRAGMA memory_limit='1GB')");
		}
		if (pragma.parameters[0].type == TypeId::VARCHAR) {
			idx_t new_limit = ParseMemoryLimit(pragma.parameters[0].str_value);
			// set the new limit in the buffer manager
			context.db.storage->buffer_manager->SetLimit(new_limit);
		} else {
			int64_t value = pragma.parameters[0].GetValue<int64_t>();
			if (value < 0) {
				// limit < 0, set limit to infinite
				context.db.storage->buffer_manager->SetLimit();
			} else {
				throw ParserException(
				    "Memory limit must be an assignment with a memory unit (e.g. PRAGMA memory_limit='1GB')");
			}
		}
	} else {
		throw ParserException("Unrecognized PRAGMA keyword: %s", keyword.c_str());
	}
}

idx_t ParseMemoryLimit(string arg) {
	// split based on the number/non-number
	idx_t idx = 0;
	while (std::isspace(arg[idx])) {
		idx++;
	}
	idx_t num_start = idx;
	while ((arg[idx] >= '0' && arg[idx] <= '9') || arg[idx] == '.' || arg[idx] == 'e' || arg[idx] == 'E' ||
	       arg[idx] == '-') {
		idx++;
	}
	if (idx == num_start) {
		throw ParserException("Memory limit must have a number (e.g. PRAGMA memory_limit=1GB");
	}
	string number = arg.substr(num_start, idx - num_start);

	// try to parse the number
	double limit = Cast::Operation<string_t, double>(number.c_str());

	// now parse the memory limit unit (e.g. bytes, gb, etc)
	while (std::isspace(arg[idx])) {
		idx++;
	}
	idx_t start = idx;
	while (idx < arg.size() && !std::isspace(arg[idx])) {
		idx++;
	}
	if (limit < 0) {
		// limit < 0, set limit to infinite
		return (idx_t)-1;
	}
	string unit = StringUtil::Lower(arg.substr(start, idx - start));
	idx_t multiplier;
	if (unit == "byte" || unit == "bytes" || unit == "b") {
		multiplier = 1;
	} else if (unit == "kilobyte" || unit == "kilobytes" || unit == "kb" || unit == "k") {
		multiplier = 1000LL;
	} else if (unit == "megabyte" || unit == "megabytes" || unit == "mb" || unit == "m") {
		multiplier = 1000LL * 1000LL;
	} else if (unit == "gigabyte" || unit == "gigabytes" || unit == "gb" || unit == "g") {
		multiplier = 1000LL * 1000LL * 1000LL;
	} else if (unit == "terabyte" || unit == "terabytes" || unit == "tb" || unit == "t") {
		multiplier = 1000LL * 1000LL * 1000LL * 1000LL;
	} else {
		throw ParserException("Unknown unit for memory_limit: %s (expected: b, mb, gb or tb)", unit.c_str());
	}
	return (idx_t)multiplier * limit;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_prepare.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class PhysicalPrepare : public PhysicalOperator {
public:
	PhysicalPrepare(string name, unique_ptr<PreparedStatementData> prepared)
	    : PhysicalOperator(PhysicalOperatorType::PREPARE, {TypeId::BOOL}), name(name), prepared(move(prepared)) {
	}

	string name;
	unique_ptr<PreparedStatementData> prepared;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

void PhysicalPrepare::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	// create the catalog entry
	auto entry = make_unique<PreparedStatementCatalogEntry>(name, move(prepared));
	entry->catalog = &context.catalog;

	// now store plan in context
	auto &dependencies = entry->prepared->dependencies;
	if (!context.prepared_statements->CreateEntry(context.ActiveTransaction(), name, move(entry), dependencies)) {
		throw Exception("Failed to prepare statement");
	}
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_prune_columns.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! PhysicalPruneColumns prunes (removes) columns from its input
class PhysicalPruneColumns : public PhysicalOperator {
public:
	PhysicalPruneColumns(LogicalOperator &op, idx_t column_limit)
	    : PhysicalOperator(PhysicalOperatorType::PRUNE_COLUMNS, op.types), column_limit(column_limit) {
	}

	idx_t column_limit;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

void PhysicalPruneColumns::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalOperatorState *>(state_);

	children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
	if (state->child_chunk.size() == 0) {
		return;
	}
	assert(column_limit <= state->child_chunk.column_count());
	chunk.SetCardinality(state->child_chunk.size());
	for (idx_t i = 0; i < column_limit; i++) {
		chunk.data[i].Reference(state->child_chunk.data[i]);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_transaction.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/transaction_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

enum class TransactionType : uint8_t { INVALID, BEGIN_TRANSACTION, COMMIT, ROLLBACK };

struct TransactionInfo : public ParseInfo {
	TransactionInfo(TransactionType type) : type(type) {
	}

	//! The type of transaction statement
	TransactionType type;
};

} // namespace duckdb


namespace duckdb {

//! PhysicalTransaction represents a transaction operator (e.g. BEGIN or COMMIT)
class PhysicalTransaction : public PhysicalOperator {
public:
	PhysicalTransaction(unique_ptr<TransactionInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::TRANSACTION, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<TransactionInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalTransaction::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	switch (info->type) {
	case TransactionType::BEGIN_TRANSACTION: {
		if (context.transaction.IsAutoCommit()) {
			// start the active transaction
			// if autocommit is active, we have already called
			// BeginTransaction by setting autocommit to false we
			// prevent it from being closed after this query, hence
			// preserving the transaction context for the next query
			context.transaction.SetAutoCommit(false);
		} else {
			throw TransactionException("cannot start a transaction within a transaction");
		}
		break;
	}
	case TransactionType::COMMIT: {
		if (context.transaction.IsAutoCommit()) {
			throw TransactionException("cannot commit - no transaction is active");
		} else {
			// explicitly commit the current transaction
			context.transaction.Commit();
		}
		break;
	}
	case TransactionType::ROLLBACK: {
		if (context.transaction.IsAutoCommit()) {
			throw TransactionException("cannot rollback - no transaction is active");
		} else {
			// explicitly rollback the current transaction
			context.transaction.Rollback();
		}
		break;
	}
	default:
		throw NotImplementedException("Unrecognized transaction type!");
	}
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/helper/physical_transaction.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/drop_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct VacuumInfo : public ParseInfo {
	// nothing for now
};

} // namespace duckdb


namespace duckdb {

//! PhysicalVacuum represents a VACUUM operation (e.g. VACUUM or ANALYZE)
class PhysicalVacuum : public PhysicalOperator {
public:
	PhysicalVacuum(unique_ptr<VacuumInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::VACUUM, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<VacuumInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalVacuum::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	// NOP
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_blockwise_nl_join.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_join.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalJoin represents the base class of the join operators
class PhysicalJoin : public PhysicalOperator {
public:
	PhysicalJoin(LogicalOperator &op, PhysicalOperatorType type, JoinType join_type);

	JoinType type;

public:
	template <bool MATCH>
	static void ConstructSemiOrAntiJoinResult(DataChunk &left, DataChunk &result, bool found_match[]);
	static void ConstructMarkJoinResult(DataChunk &join_keys, DataChunk &left, DataChunk &result, bool found_match[],
	                                    bool has_null);
};

} // namespace duckdb


namespace duckdb {

//! PhysicalBlockwiseNLJoin represents a nested loop join between two tables on arbitrary expressions. This is different
//! from the PhysicalNestedLoopJoin in that it does not require expressions to be comparisons between the LHS and the
//! RHS.
class PhysicalBlockwiseNLJoin : public PhysicalJoin {
public:
	PhysicalBlockwiseNLJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> left, unique_ptr<PhysicalOperator> right,
	                        unique_ptr<Expression> condition, JoinType join_type);

	unique_ptr<Expression> condition;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;

	string ExtraRenderInformation() const override;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

class PhysicalBlockwiseNLJoinState : public PhysicalOperatorState {
public:
	PhysicalBlockwiseNLJoinState(PhysicalOperator *left, PhysicalOperator *right, Expression &condition)
	    : PhysicalOperatorState(left), left_position(0), right_position(0), fill_in_rhs(false),
	      checked_found_match(false), executor(condition) {
		assert(left && right);
	}

	//! Whether or not a tuple on the LHS has found a match, only used for LEFT OUTER and FULL OUTER joins
	unique_ptr<bool[]> lhs_found_match;
	//! Whether or not a tuple on the RHS has found a match, only used for FULL OUTER joins
	unique_ptr<bool[]> rhs_found_match;
	ChunkCollection right_chunks;
	idx_t left_position;
	idx_t right_position;
	bool fill_in_rhs;
	bool checked_found_match;
	ExpressionExecutor executor;
};

PhysicalBlockwiseNLJoin::PhysicalBlockwiseNLJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> left,
                                                 unique_ptr<PhysicalOperator> right, unique_ptr<Expression> condition,
                                                 JoinType join_type)
    : PhysicalJoin(op, PhysicalOperatorType::BLOCKWISE_NL_JOIN, join_type), condition(move(condition)) {
	children.push_back(move(left));
	children.push_back(move(right));
	// MARK, SINGLE and RIGHT OUTER joins not handled
	assert(join_type != JoinType::MARK);
	assert(join_type != JoinType::RIGHT);
	assert(join_type != JoinType::SINGLE);
}

void PhysicalBlockwiseNLJoin::GetChunkInternal(ClientContext &context, DataChunk &chunk,
                                               PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalBlockwiseNLJoinState *>(state_);

	// first we fully materialize the right child, if we haven't done that yet
	if (state->right_chunks.column_count() == 0) {
		auto right_state = children[1]->GetOperatorState();
		auto left_types = children[0]->GetTypes();
		auto right_types = children[1]->GetTypes();

		DataChunk right_chunk;
		right_chunk.Initialize(right_types);
		while (true) {
			children[1]->GetChunk(context, right_chunk, right_state.get());
			if (right_chunk.size() == 0) {
				break;
			}
			state->right_chunks.Append(right_chunk);
		}

		if (state->right_chunks.count == 0) {
			if ((type == JoinType::INNER || type == JoinType::SEMI)) {
				// empty RHS with INNER or SEMI join means empty result set
				return;
			}
		}
		// initialize the found_match vectors for the left and right sides
		if (type == JoinType::LEFT || type == JoinType::OUTER) {
			state->lhs_found_match = unique_ptr<bool[]>(new bool[STANDARD_VECTOR_SIZE]);
		}
		if (type == JoinType::OUTER) {
			state->rhs_found_match = unique_ptr<bool[]>(new bool[state->right_chunks.count]);
			memset(state->rhs_found_match.get(), 0, sizeof(bool) * state->right_chunks.count);
		}
	}

	if (state->right_chunks.count == 0) {
		// empty join
		assert(type == JoinType::LEFT || type == JoinType::OUTER || type == JoinType::ANTI);
		// pull a chunk from the LHS
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			return;
		}
		// fill in the data from the chunk
		idx_t i;
		for (i = 0; i < state->child_chunk.column_count(); i++) {
			chunk.data[i].Reference(state->child_chunk.data[i]);
		}
		chunk.SetCardinality(state->child_chunk.size());
		if (type == JoinType::LEFT || type == JoinType::OUTER) {
			// LEFT OUTER or FULL OUTER join with empty RHS
			// fill any columns from the RHS with NULLs
			for (; i < chunk.column_count(); i++) {
				chunk.data[i].vector_type = VectorType::CONSTANT_VECTOR;
				ConstantVector::SetNull(chunk.data[i], true);
			}
		}
		return;
	}

	// now perform the actual join
	// we construct a combined DataChunk by referencing the LHS and the RHS
	// every step that we do not have output results we shift the vectors of the RHS one up or down
	// this creates a new "alignment" between the tuples, exhausting all possible O(n^2) combinations
	// while allowing us to use vectorized execution for every step
	idx_t result_count = 0;
	do {
		if (state->fill_in_rhs) {
			throw NotImplementedException("FIXME: full outer join");
		}
		if (state->left_position >= state->child_chunk.size()) {
			// exhausted LHS, have to pull new LHS chunk
			if (!state->checked_found_match && state->lhs_found_match) {
				// LEFT OUTER JOIN or FULL OUTER JOIN, first check if we need to create extra results because of
				// non-matching tuples
				SelectionVector sel(STANDARD_VECTOR_SIZE);
				for (idx_t i = 0; i < state->child_chunk.size(); i++) {
					if (!state->lhs_found_match[i]) {
						sel.set_index(result_count++, i);
					}
				}
				if (result_count > 0) {
					// have to create the chunk, set the selection vector and count
					// for the LHS, reference the child_chunk and set the sel_vector and count
					chunk.Slice(state->child_chunk, sel, result_count);
					// for the RHS, set the mask to NULL and set the sel_vector and count
					for (idx_t i = state->child_chunk.column_count(); i < chunk.column_count(); i++) {
						chunk.data[i].vector_type = VectorType::CONSTANT_VECTOR;
						ConstantVector::SetNull(chunk.data[i], true);
					}
					state->checked_found_match = true;
					return;
				}
			}
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			// no more data on LHS, if FULL OUTER JOIN iterate over RHS
			if (state->child_chunk.size() == 0) {
				if (type == JoinType::OUTER) {
					state->fill_in_rhs = true;
					continue;
				} else {
					return;
				}
			}
			state->child_chunk.Normalify();
			state->left_position = 0;
			state->right_position = 0;
			if (state->lhs_found_match) {
				state->checked_found_match = false;
				memset(state->lhs_found_match.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE);
			}
		}
		auto &lchunk = state->child_chunk;
		auto &rchunk = *state->right_chunks.chunks[state->right_position];

		// fill in the current element of the LHS into the chunk
		assert(chunk.column_count() == lchunk.column_count() + rchunk.column_count());
		for (idx_t i = 0; i < lchunk.column_count(); i++) {
			auto lvalue = lchunk.GetValue(i, state->left_position);
			chunk.data[i].Reference(lvalue);
		}
		// for the RHS we just reference the entire vector
		for (idx_t i = 0; i < rchunk.column_count(); i++) {
			chunk.data[lchunk.column_count() + i].Reference(rchunk.data[i]);
		}
		chunk.SetCardinality(rchunk.size());

		// now perform the computation
		SelectionVector match_sel(STANDARD_VECTOR_SIZE);
		result_count = state->executor.SelectExpression(chunk, match_sel);
		if (result_count > 0) {
			// found a match!
			// set the match flags in the LHS
			if (state->lhs_found_match) {
				state->lhs_found_match[state->left_position] = true;
			}
			chunk.Slice(match_sel, result_count);

			// set the match flags in the RHS
			if (state->rhs_found_match) {
				for (idx_t i = 0; i < result_count; i++) {
					auto idx = match_sel.get_index(i);
					state->rhs_found_match[state->right_position * STANDARD_VECTOR_SIZE + idx] = true;
				}
			}
		} else {
			// no result: reset the chunk
			chunk.Reset();
		}
		// move to the next tuple on the LHS
		state->left_position++;
		if (state->left_position >= state->child_chunk.size()) {
			// exhausted the current chunk, move to the next RHS chunk
			state->right_position++;
			if (state->right_position < state->right_chunks.chunks.size()) {
				// we still have chunks left! start over on the LHS
				state->left_position = 0;
			}
		}
	} while (result_count == 0);
}

unique_ptr<PhysicalOperatorState> PhysicalBlockwiseNLJoin::GetOperatorState() {
	return make_unique<PhysicalBlockwiseNLJoinState>(children[0].get(), children[1].get(), *condition);
}

string PhysicalBlockwiseNLJoin::ExtraRenderInformation() const {
	string extra_info = JoinTypeToString(type) + "\n";
	extra_info += condition->GetName();
	return extra_info;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_comparison_join.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalJoin represents the base class of the join operators
class PhysicalComparisonJoin : public PhysicalJoin {
public:
	PhysicalComparisonJoin(LogicalOperator &op, PhysicalOperatorType type, vector<JoinCondition> cond,
	                       JoinType join_type);

	vector<JoinCondition> conditions;

public:
	string ExtraRenderInformation() const override;
};

class PhysicalComparisonJoinState : public PhysicalOperatorState {
public:
	PhysicalComparisonJoinState(PhysicalOperator *left, PhysicalOperator *right, vector<JoinCondition> &conditions)
	    : PhysicalOperatorState(left) {
		assert(left && right);
		for (auto &cond : conditions) {
			lhs_executor.AddExpression(*cond.left);
			rhs_executor.AddExpression(*cond.right);
		}
	}

	ExpressionExecutor lhs_executor;
	ExpressionExecutor rhs_executor;
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

PhysicalComparisonJoin::PhysicalComparisonJoin(LogicalOperator &op, PhysicalOperatorType type,
                                               vector<JoinCondition> conditions_, JoinType join_type)
    : PhysicalJoin(op, type, join_type) {
	conditions.resize(conditions_.size());
	// we reorder conditions so the ones with COMPARE_EQUAL occur first
	idx_t equal_position = 0;
	idx_t other_position = conditions_.size() - 1;
	for (idx_t i = 0; i < conditions_.size(); i++) {
		if (conditions_[i].comparison == ExpressionType::COMPARE_EQUAL) {
			// COMPARE_EQUAL, move to the start
			conditions[equal_position++] = std::move(conditions_[i]);
		} else {
			// other expression, move to the end
			conditions[other_position--] = std::move(conditions_[i]);
		}
	}
}

string PhysicalComparisonJoin::ExtraRenderInformation() const {
	string extra_info = JoinTypeToString(type) + "\n";
	for (auto &it : conditions) {
		string op = ExpressionTypeToOperator(it.comparison);
		extra_info += it.left->GetName() + op + it.right->GetName() + "\n";
	}
	return extra_info;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_cross_product.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! PhysicalCrossProduct represents a cross product between two tables
class PhysicalCrossProduct : public PhysicalOperator {
public:
	PhysicalCrossProduct(LogicalOperator &op, unique_ptr<PhysicalOperator> left, unique_ptr<PhysicalOperator> right);

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

class PhysicalCrossProductOperatorState : public PhysicalOperatorState {
public:
	PhysicalCrossProductOperatorState(PhysicalOperator *left, PhysicalOperator *right)
	    : PhysicalOperatorState(left), left_position(0) {
		assert(left && right);
	}

	idx_t left_position;
	idx_t right_position;
	ChunkCollection right_data;
};

PhysicalCrossProduct::PhysicalCrossProduct(LogicalOperator &op, unique_ptr<PhysicalOperator> left,
                                           unique_ptr<PhysicalOperator> right)
    : PhysicalOperator(PhysicalOperatorType::CROSS_PRODUCT, op.types) {
	children.push_back(move(left));
	children.push_back(move(right));
}

void PhysicalCrossProduct::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalCrossProductOperatorState *>(state_);
	// first we fully materialize the right child, if we haven't done that yet
	if (state->right_data.column_count() == 0) {
		auto right_state = children[1]->GetOperatorState();
		auto types = children[1]->GetTypes();

		DataChunk new_chunk;
		new_chunk.Initialize(types);
		do {
			children[1]->GetChunk(context, new_chunk, right_state.get());
			if (new_chunk.size() == 0) {
				break;
			}
			state->right_data.Append(new_chunk);
		} while (new_chunk.size() > 0);

		if (state->right_data.count == 0) {
			return;
		}
		state->left_position = 0;
		state->right_position = 0;
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		state->child_chunk.Normalify();
	}

	if (state->left_position >= state->child_chunk.size()) {
		return;
	}

	auto &left_chunk = state->child_chunk;
	auto &right_chunk = *state->right_data.chunks[state->right_position];
	// now match the current row of the left relation with the current chunk
	// from the right relation
	chunk.SetCardinality(right_chunk.size());
	for (idx_t i = 0; i < left_chunk.column_count(); i++) {
		// first duplicate the values of the left side
		auto lvalue = left_chunk.GetValue(i, state->left_position);
		chunk.data[i].Reference(lvalue);
	}
	for (idx_t i = 0; i < right_chunk.column_count(); i++) {
		// now create a reference to the vectors of the right chunk
		chunk.data[left_chunk.column_count() + i].Reference(right_chunk.data[i]);
	}

	// for the next iteration, move to the next position on the left side
	state->left_position++;
	if (state->left_position >= state->child_chunk.size()) {
		// ran out of this chunk
		// move to the next chunk on the right side
		state->left_position = 0;
		state->right_position++;
		if (state->right_position >= state->right_data.chunks.size()) {
			state->right_position = 0;
			// move to the next chunk on the left side
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			state->child_chunk.Normalify();
		}
	}
}

unique_ptr<PhysicalOperatorState> PhysicalCrossProduct::GetOperatorState() {
	return make_unique<PhysicalCrossProductOperatorState>(children[0].get(), children[1].get());
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_delim_join.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! PhysicalDelimJoin represents a join where the LHS will be duplicate eliminated and pushed into a
//! PhysicalChunkCollectionScan in the RHS.
class PhysicalDelimJoin : public PhysicalOperator {
public:
	PhysicalDelimJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> original_join,
	                  vector<PhysicalOperator *> delim_scans);

	unique_ptr<PhysicalOperator> join;
	unique_ptr<PhysicalOperator> distinct;
	ChunkCollection lhs_data;
	ChunkCollection delim_data;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
	string ExtraRenderInformation() const override;
};

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_chunk_scan.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! The PhysicalChunkCollectionScan scans a Chunk Collection
class PhysicalChunkScan : public PhysicalOperator {
public:
	PhysicalChunkScan(vector<TypeId> types, PhysicalOperatorType op_type)
	    : PhysicalOperator(op_type, types), collection(nullptr) {
	}

	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;

public:
	// the chunk collection to scan
	ChunkCollection *collection;
	//! Owned chunk collection, if any
	unique_ptr<ChunkCollection> owned_collection;
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

class PhysicalDelimJoinState : public PhysicalOperatorState {
public:
	PhysicalDelimJoinState(PhysicalOperator *left) : PhysicalOperatorState(left) {
	}

	unique_ptr<PhysicalOperatorState> join_state;
};

PhysicalDelimJoin::PhysicalDelimJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> original_join,
                                     vector<PhysicalOperator *> delim_scans)
    : PhysicalOperator(PhysicalOperatorType::DELIM_JOIN, op.types), join(move(original_join)) {
	assert(delim_scans.size() > 0);
	assert(join->children.size() == 2);
	// for any duplicate eliminated scans in the RHS, point them to the duplicate eliminated chunk that we create here
	for (auto op : delim_scans) {
		assert(op->type == PhysicalOperatorType::DELIM_SCAN);
		auto scan = (PhysicalChunkScan *)op;
		scan->collection = &delim_data;
	}
	// now for the original join
	// we take its left child, this is the side that we will duplicate eliminate
	children.push_back(move(join->children[0]));
	// we replace it with a PhysicalChunkCollectionScan, that scans the ChunkCollection that we keep cached
	auto cached_chunk_scan = make_unique<PhysicalChunkScan>(children[0]->GetTypes(), PhysicalOperatorType::CHUNK_SCAN);
	cached_chunk_scan->collection = &lhs_data;
	join->children[0] = move(cached_chunk_scan);
}

void PhysicalDelimJoin::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalDelimJoinState *>(state_);
	assert(distinct);
	if (!state->join_state) {
		// first run: fully materialize the LHS
		ChunkCollection &big_data = lhs_data;
		do {
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			big_data.Append(state->child_chunk);
		} while (state->child_chunk.size() != 0);
		// now create the duplicate eliminated chunk by pulling from the DISTINCT aggregate
		DataChunk delim_chunk;
		distinct->InitializeChunk(delim_chunk);
		auto distinct_state = distinct->GetOperatorState();
		do {
			delim_chunk.Reset();
			distinct->GetChunkInternal(context, delim_chunk, distinct_state.get());
			delim_data.Append(delim_chunk);
		} while (delim_chunk.size() != 0);
		// create the state of the underlying join
		state->join_state = join->GetOperatorState();
	}
	// now pull from the RHS from the underlying join
	join->GetChunk(context, chunk, state->join_state.get());
}

unique_ptr<PhysicalOperatorState> PhysicalDelimJoin::GetOperatorState() {
	return make_unique<PhysicalDelimJoinState>(children[0].get());
}

string PhysicalDelimJoin::ExtraRenderInformation() const {
	return join->ExtraRenderInformation();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_hash_join.hpp
//
//
//===----------------------------------------------------------------------===//









namespace duckdb {

//! PhysicalHashJoin represents a hash loop join between two tables
class PhysicalHashJoin : public PhysicalComparisonJoin {
public:
	PhysicalHashJoin(ClientContext &context, LogicalOperator &op, unique_ptr<PhysicalOperator> left,
	                 unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond, JoinType join_type,
	                 vector<idx_t> left_projection_map, vector<idx_t> right_projection_map);
	PhysicalHashJoin(ClientContext &context, LogicalOperator &op, unique_ptr<PhysicalOperator> left,
	                 unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond, JoinType join_type);

	unique_ptr<JoinHashTable> hash_table;
	vector<idx_t> right_projection_map;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;

private:
	void BuildHashTable(ClientContext &context, PhysicalOperatorState *state_);
	void ProbeHashTable(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_);
};

} // namespace duckdb







using namespace duckdb;
using namespace std;

class PhysicalHashJoinState : public PhysicalComparisonJoinState {
public:
	PhysicalHashJoinState(PhysicalOperator *left, PhysicalOperator *right, vector<JoinCondition> &conditions)
	    : PhysicalComparisonJoinState(left, right, conditions), initialized(false) {
	}

	bool initialized;
	DataChunk cached_chunk;
	DataChunk join_keys;
	unique_ptr<JoinHashTable::ScanStructure> scan_structure;
};

PhysicalHashJoin::PhysicalHashJoin(ClientContext &context, LogicalOperator &op, unique_ptr<PhysicalOperator> left,
                                   unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond, JoinType join_type,
                                   vector<idx_t> left_projection_map, vector<idx_t> right_projection_map)
    : PhysicalComparisonJoin(op, PhysicalOperatorType::HASH_JOIN, move(cond), join_type),
      right_projection_map(right_projection_map) {
	children.push_back(move(left));
	children.push_back(move(right));

	assert(left_projection_map.size() == 0);

	hash_table =
	    make_unique<JoinHashTable>(BufferManager::GetBufferManager(context), conditions,
	                               LogicalOperator::MapTypes(children[1]->GetTypes(), right_projection_map), type);
}

PhysicalHashJoin::PhysicalHashJoin(ClientContext &context, LogicalOperator &op, unique_ptr<PhysicalOperator> left,
                                   unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond, JoinType join_type)
    : PhysicalHashJoin(context, op, move(left), move(right), move(cond), join_type, {}, {}) {
}

void PhysicalHashJoin::BuildHashTable(ClientContext &context, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalHashJoinState *>(state_);

	// build the HT
	auto right_state = children[1]->GetOperatorState();
	auto types = children[1]->GetTypes();

	DataChunk right_chunk, build_chunk;
	right_chunk.Initialize(types);

	if (right_projection_map.size() > 0) {
		build_chunk.Initialize(hash_table->build_types);
	}

	state->join_keys.Initialize(hash_table->condition_types);
	while (true) {
		// get the child chunk
		children[1]->GetChunk(context, right_chunk, right_state.get());
		if (right_chunk.size() == 0) {
			break;
		}
		// resolve the join keys for the right chunk
		state->rhs_executor.Execute(right_chunk, state->join_keys);
		// build the HT
		if (right_projection_map.size() > 0) {
			// there is a projection map: fill the build chunk with the projected columns
			build_chunk.Reset();
			build_chunk.SetCardinality(right_chunk);
			for (idx_t i = 0; i < right_projection_map.size(); i++) {
				build_chunk.data[i].Reference(right_chunk.data[right_projection_map[i]]);
			}
			hash_table->Build(state->join_keys, build_chunk);
		} else {
			// there is not a projected map: place the entire right chunk in the HT
			hash_table->Build(state->join_keys, right_chunk);
		}
	}
	hash_table->Finalize();
}

void PhysicalHashJoin::ProbeHashTable(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalHashJoinState *>(state_);
	if (state->child_chunk.size() > 0 && state->scan_structure) {
		// still have elements remaining from the previous probe (i.e. we got
		// >1024 elements in the previous probe)
		state->scan_structure->Next(state->join_keys, state->child_chunk, chunk);
		if (chunk.size() > 0) {
			return;
		}
		state->scan_structure = nullptr;
	}

	// probe the HT
	do {
		// fetch the chunk from the left side
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			return;
		}
		// remove any selection vectors
		if (hash_table->size() == 0) {
			// empty hash table, special case
			if (hash_table->join_type == JoinType::ANTI) {
				// anti join with empty hash table, NOP join
				// return the input
				assert(chunk.column_count() == state->child_chunk.column_count());
				chunk.Reference(state->child_chunk);
				return;
			} else if (hash_table->join_type == JoinType::MARK) {
				// MARK join with empty hash table
				assert(hash_table->join_type == JoinType::MARK);
				assert(chunk.column_count() == state->child_chunk.column_count() + 1);
				auto &result_vector = chunk.data.back();
				assert(result_vector.type == TypeId::BOOL);
				// for every data vector, we just reference the child chunk
				chunk.SetCardinality(state->child_chunk);
				for (idx_t i = 0; i < state->child_chunk.column_count(); i++) {
					chunk.data[i].Reference(state->child_chunk.data[i]);
				}
				// for the MARK vector:
				// if the HT has no NULL values (i.e. empty result set), return a vector that has false for every input
				// entry if the HT has NULL values (i.e. result set had values, but all were NULL), return a vector that
				// has NULL for every input entry
				if (!hash_table->has_null) {
					auto bool_result = FlatVector::GetData<bool>(result_vector);
					for (idx_t i = 0; i < chunk.size(); i++) {
						bool_result[i] = false;
					}
				} else {
					FlatVector::Nullmask(result_vector).set();
				}
				return;
			} else if (hash_table->join_type == JoinType::LEFT || hash_table->join_type == JoinType::OUTER ||
			           hash_table->join_type == JoinType::SINGLE) {
				// LEFT/FULL OUTER/SINGLE join and build side is empty
				// for the LHS we reference the data
				chunk.SetCardinality(state->child_chunk.size());
				for (idx_t i = 0; i < state->child_chunk.column_count(); i++) {
					chunk.data[i].Reference(state->child_chunk.data[i]);
				}
				// for the RHS
				for (idx_t k = state->child_chunk.column_count(); k < chunk.column_count(); k++) {
					chunk.data[k].vector_type = VectorType::CONSTANT_VECTOR;
					ConstantVector::SetNull(chunk.data[k], true);
				}
				return;
			}
		}
		// resolve the join keys for the left chunk
		state->lhs_executor.Execute(state->child_chunk, state->join_keys);

		// perform the actual probe
		state->scan_structure = hash_table->Probe(state->join_keys);
		state->scan_structure->Next(state->join_keys, state->child_chunk, chunk);
	} while (chunk.size() == 0);
}

unique_ptr<PhysicalOperatorState> PhysicalHashJoin::GetOperatorState() {
	return make_unique<PhysicalHashJoinState>(children[0].get(), children[1].get(), conditions);
}

void PhysicalHashJoin::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalHashJoinState *>(state_);
	if (!state->initialized) {
		state->cached_chunk.Initialize(types);
		BuildHashTable(context, state_);
		state->initialized = true;

		if (hash_table->size() == 0 &&
		    (hash_table->join_type == JoinType::INNER || hash_table->join_type == JoinType::SEMI)) {
			// empty hash table with INNER or SEMI join means empty result set
			return;
		}
	}
	do {
		ProbeHashTable(context, chunk, state);
#if STANDARD_VECTOR_SIZE >= 128
		if (chunk.size() == 0) {
			if (state->cached_chunk.size() > 0) {
				// finished probing but cached data remains, return cached chunk
				chunk.Reference(state->cached_chunk);
				state->cached_chunk.Reset();
			}
			return;
		} else if (chunk.size() < 64) {
			// small chunk: add it to chunk cache and continue
			state->cached_chunk.Append(chunk);
			if (state->cached_chunk.size() >= (STANDARD_VECTOR_SIZE - 64)) {
				// chunk cache full: return it
				chunk.Reference(state->cached_chunk);
				state->cached_chunk.Reset();
				return;
			} else {
				// chunk cache not full: probe again
				chunk.Reset();
			}
		} else {
			return;
		}
#else
		return;
#endif
	} while (true);
}


using namespace duckdb;
using namespace std;

PhysicalJoin::PhysicalJoin(LogicalOperator &op, PhysicalOperatorType type, JoinType join_type)
    : PhysicalOperator(type, op.types), type(join_type) {
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_nested_loop_join.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
idx_t nested_loop_join(ExpressionType op, Vector &left, Vector &right, idx_t &lpos, idx_t &rpos, sel_t lvector[],
                       sel_t rvector[]);
idx_t nested_loop_comparison(ExpressionType op, Vector &left, Vector &right, sel_t lvector[], sel_t rvector[],
                             idx_t count);

//! PhysicalNestedLoopJoin represents a nested loop join between two tables
class PhysicalNestedLoopJoin : public PhysicalComparisonJoin {
public:
	PhysicalNestedLoopJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> left, unique_ptr<PhysicalOperator> right,
	                       vector<JoinCondition> cond, JoinType join_type);

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb







using namespace std;

namespace duckdb {

class PhysicalNestedLoopJoinState : public PhysicalComparisonJoinState {
public:
	PhysicalNestedLoopJoinState(PhysicalOperator *left, PhysicalOperator *right, vector<JoinCondition> &conditions)
	    : PhysicalComparisonJoinState(left, right, conditions), right_chunk(0), has_null(false), left_tuple(0),
	      right_tuple(0) {
	}

	idx_t right_chunk;
	DataChunk left_join_condition;
	ChunkCollection right_data;
	ChunkCollection right_chunks;
	//! Whether or not the RHS of the nested loop join has NULL values
	bool has_null;

	idx_t left_tuple;
	idx_t right_tuple;
};

PhysicalNestedLoopJoin::PhysicalNestedLoopJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> left,
                                               unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond,
                                               JoinType join_type)
    : PhysicalComparisonJoin(op, PhysicalOperatorType::NESTED_LOOP_JOIN, move(cond), join_type) {
	children.push_back(move(left));
	children.push_back(move(right));
}

static bool HasNullValues(DataChunk &chunk) {
	for (idx_t col_idx = 0; col_idx < chunk.column_count(); col_idx++) {
		VectorData vdata;
		chunk.data[col_idx].Orrify(chunk.size(), vdata);

		if (vdata.nullmask->none()) {
			continue;
		}
		for (idx_t i = 0; i < chunk.size(); i++) {
			auto idx = vdata.sel->get_index(i);
			if ((*vdata.nullmask)[idx]) {
				return true;
			}
		}
	}
	return false;
}

template <bool MATCH>
void PhysicalJoin::ConstructSemiOrAntiJoinResult(DataChunk &left, DataChunk &result, bool found_match[]) {
	assert(left.column_count() == result.column_count());
	// create the selection vector from the matches that were found
	idx_t result_count = 0;
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	for (idx_t i = 0; i < left.size(); i++) {
		if (found_match[i] == MATCH) {
			sel.set_index(result_count++, i);
		}
	}
	// construct the final result
	if (result_count > 0) {
		// we only return the columns on the left side
		// project them using the result selection vector
		// reference the columns of the left side from the result
		result.Slice(left, sel, result_count);
	} else {
		result.SetCardinality(0);
	}
}

void PhysicalJoin::ConstructMarkJoinResult(DataChunk &join_keys, DataChunk &left, DataChunk &result, bool found_match[],
                                           bool has_null) {
	// for the initial set of columns we just reference the left side
	result.SetCardinality(left);
	for (idx_t i = 0; i < left.column_count(); i++) {
		result.data[i].Reference(left.data[i]);
	}
	auto &mark_vector = result.data.back();
	mark_vector.vector_type = VectorType::FLAT_VECTOR;
	// first we set the NULL values from the join keys
	// if there is any NULL in the keys, the result is NULL
	auto bool_result = FlatVector::GetData<bool>(mark_vector);
	auto &nullmask = FlatVector::Nullmask(mark_vector);
	for (idx_t col_idx = 0; col_idx < join_keys.column_count(); col_idx++) {
		VectorData jdata;
		join_keys.data[col_idx].Orrify(join_keys.size(), jdata);
		if (jdata.nullmask->any()) {
			for (idx_t i = 0; i < join_keys.size(); i++) {
				auto jidx = jdata.sel->get_index(i);
				nullmask[i] = (*jdata.nullmask)[jidx];
			}
		}
	}
	// now set the remaining entries to either true or false based on whether a match was found
	if (found_match) {
		for (idx_t i = 0; i < left.size(); i++) {
			bool_result[i] = found_match[i];
		}
	} else {
		memset(bool_result, 0, sizeof(bool) * left.size());
	}
	// if the right side contains NULL values, the result of any FALSE becomes NULL
	if (has_null) {
		for (idx_t i = 0; i < left.size(); i++) {
			if (!bool_result[i]) {
				nullmask[i] = true;
			}
		}
	}
}

void PhysicalNestedLoopJoin::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalNestedLoopJoinState *>(state_);

	// first we fully materialize the right child, if we haven't done that yet
	if (state->right_chunks.column_count() == 0) {
		vector<TypeId> condition_types;
		for (auto &cond : conditions) {
			assert(cond.left->return_type == cond.right->return_type);
			condition_types.push_back(cond.left->return_type);
		}

		auto right_state = children[1]->GetOperatorState();
		auto types = children[1]->GetTypes();

		DataChunk new_chunk, right_condition;
		new_chunk.Initialize(types);
		right_condition.Initialize(condition_types);
		do {
			children[1]->GetChunk(context, new_chunk, right_state.get());
			if (new_chunk.size() == 0) {
				break;
			}
			// resolve the join expression of the right side
			state->rhs_executor.Execute(new_chunk, right_condition);

			state->right_data.Append(new_chunk);
			state->right_chunks.Append(right_condition);
		} while (new_chunk.size() > 0);

		if (state->right_chunks.count == 0) {
			if ((type == JoinType::INNER || type == JoinType::SEMI)) {
				// empty RHS with INNER or SEMI join means empty result set
				return;
			}
		} else {
			// for the MARK join, we check if there are null values in any of the right chunks
			if (type == JoinType::MARK) {
				for (idx_t i = 0; i < state->right_chunks.chunks.size(); i++) {
					if (HasNullValues(*state->right_chunks.chunks[i])) {
						state->has_null = true;
					}
				}
			}
			// initialize the chunks for the join conditions
			state->left_join_condition.Initialize(condition_types);
			state->right_chunk = state->right_chunks.chunks.size() - 1;
			state->right_tuple = state->right_chunks.chunks[state->right_chunk]->size();
		}
	}

	if (state->right_chunks.count == 0) {
		// empty join, switch on type
		if (type == JoinType::MARK) {
			// pull a chunk from the LHS
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			if (state->child_chunk.size() == 0) {
				return;
			}
			// RHS empty: set FOUND MATCh vector to false
			chunk.Reference(state->child_chunk);
			auto &mark_vector = chunk.data.back();
			mark_vector.vector_type = VectorType::CONSTANT_VECTOR;
			mark_vector.SetValue(0, Value::BOOLEAN(false));
		} else if (type == JoinType::ANTI) {
			// ANTI join, just pull chunk from RHS
			children[0]->GetChunk(context, chunk, state->child_state.get());
		} else if (type == JoinType::LEFT) {
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			if (state->child_chunk.size() == 0) {
				return;
			}
			chunk.Reference(state->child_chunk);
			for (idx_t idx = state->child_chunk.column_count(); idx < chunk.column_count(); idx++) {
				chunk.data[idx].vector_type = VectorType::CONSTANT_VECTOR;
				ConstantVector::SetNull(chunk.data[idx], true);
			}
		} else {
			throw Exception("Unhandled type for empty NL join");
		}
		return;
	}

	if ((type == JoinType::INNER || type == JoinType::LEFT) &&
	    state->right_chunk >= state->right_chunks.chunks.size()) {
		return;
	}
	// now that we have fully materialized the right child
	// we have to perform the nested loop join
	do {
		// first check if we have to move to the next child on the right isde
		assert(state->right_chunk < state->right_chunks.chunks.size());
		if (state->right_tuple >= state->right_chunks.chunks[state->right_chunk]->size()) {
			// we exhausted the chunk on the right
			state->right_chunk++;
			if (state->right_chunk >= state->right_chunks.chunks.size()) {
				// we exhausted all right chunks!
				// move to the next left chunk
				do {
					children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
					if (state->child_chunk.size() == 0) {
						return;
					}

					// resolve the left join condition for the current chunk
					state->lhs_executor.Execute(state->child_chunk, state->left_join_condition);
				} while (state->left_join_condition.size() == 0);

				state->right_chunk = 0;
			}
			// move to the start of this chunk
			state->left_tuple = 0;
			state->right_tuple = 0;
		}

		switch (type) {
		case JoinType::SEMI:
		case JoinType::ANTI:
		case JoinType::MARK: {
			// MARK, SEMI and ANTI joins are handled separately because they scan the whole RHS in one go
			bool found_match[STANDARD_VECTOR_SIZE] = {false};
			NestedLoopJoinMark::Perform(state->left_join_condition, state->right_chunks, found_match, conditions);
			if (type == JoinType::MARK) {
				// now construct the mark join result from the found matches
				PhysicalJoin::ConstructMarkJoinResult(state->left_join_condition, state->child_chunk, chunk,
				                                      found_match, state->has_null);
			} else if (type == JoinType::SEMI) {
				// construct the semi join result from the found matches
				PhysicalJoin::ConstructSemiOrAntiJoinResult<true>(state->child_chunk, chunk, found_match);
			} else if (type == JoinType::ANTI) {
				PhysicalJoin::ConstructSemiOrAntiJoinResult<false>(state->child_chunk, chunk, found_match);
			}
			// move to the next LHS chunk in the next iteration
			state->right_tuple = state->right_chunks.chunks[state->right_chunk]->size();
			state->right_chunk = state->right_chunks.chunks.size() - 1;
			if (chunk.size() > 0) {
				return;
			} else {
				continue;
			}
		}
		default:
			break;
		}

		auto &left_chunk = state->child_chunk;
		auto &right_chunk = *state->right_chunks.chunks[state->right_chunk];
		auto &right_data = *state->right_data.chunks[state->right_chunk];

		// sanity check
		left_chunk.Verify();
		right_chunk.Verify();
		right_data.Verify();

		// now perform the join
		switch (type) {
		case JoinType::INNER: {
			SelectionVector lvector(STANDARD_VECTOR_SIZE), rvector(STANDARD_VECTOR_SIZE);
			idx_t match_count =
			    NestedLoopJoinInner::Perform(state->left_tuple, state->right_tuple, state->left_join_condition,
			                                 right_chunk, lvector, rvector, conditions);
			// we have finished resolving the join conditions
			if (match_count == 0) {
				// if there are no results, move on
				continue;
			}
			// we have matching tuples!
			// construct the result
			chunk.Slice(state->child_chunk, lvector, match_count);
			chunk.Slice(right_data, rvector, match_count, state->child_chunk.column_count());
			break;
		}
		default:
			throw NotImplementedException("Unimplemented type for nested loop join!");
		}
	} while (chunk.size() == 0);
}

unique_ptr<PhysicalOperatorState> PhysicalNestedLoopJoin::GetOperatorState() {
	return make_unique<PhysicalNestedLoopJoinState>(children[0].get(), children[1].get(), conditions);
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/join/physical_piecewise_merge_join.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalPiecewiseMergeJoin represents a piecewise merge loop join between
//! two tables
class PhysicalPiecewiseMergeJoin : public PhysicalComparisonJoin {
public:
	PhysicalPiecewiseMergeJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> left,
	                           unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond, JoinType join_type);

	vector<TypeId> join_key_types;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb







using namespace duckdb;
using namespace std;

static void OrderVector(Vector &vector, idx_t count, MergeOrder &order);

class PhysicalPiecewiseMergeJoinState : public PhysicalComparisonJoinState {
public:
	PhysicalPiecewiseMergeJoinState(PhysicalOperator *left, PhysicalOperator *right, vector<JoinCondition> &conditions)
	    : PhysicalComparisonJoinState(left, right, conditions), initialized(false), left_position(0), right_position(0),
	      right_chunk_index(0), has_null(false) {
	}

	bool initialized;
	idx_t left_position;
	idx_t right_position;
	idx_t right_chunk_index;
	DataChunk left_chunk;
	DataChunk join_keys;
	MergeOrder left_orders;
	ChunkCollection right_chunks;
	ChunkCollection right_conditions;
	vector<MergeOrder> right_orders;
	bool has_null;
};

PhysicalPiecewiseMergeJoin::PhysicalPiecewiseMergeJoin(LogicalOperator &op, unique_ptr<PhysicalOperator> left,
                                                       unique_ptr<PhysicalOperator> right, vector<JoinCondition> cond,
                                                       JoinType join_type)
    : PhysicalComparisonJoin(op, PhysicalOperatorType::PIECEWISE_MERGE_JOIN, move(cond), join_type) {
	// for now we only support one condition!
	assert(conditions.size() == 1);
	for (auto &cond : conditions) {
		// COMPARE NOT EQUAL not supported yet with merge join
		assert(cond.comparison != ExpressionType::COMPARE_NOTEQUAL);
		assert(cond.left->return_type == cond.right->return_type);
		join_key_types.push_back(cond.left->return_type);
	}
	children.push_back(move(left));
	children.push_back(move(right));
}

void PhysicalPiecewiseMergeJoin::GetChunkInternal(ClientContext &context, DataChunk &chunk,
                                                  PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalPiecewiseMergeJoinState *>(state_);
	assert(conditions.size() == 1);
	if (!state->initialized) {
		// create the sorted pieces
		auto right_state = children[1]->GetOperatorState();
		auto types = children[1]->GetTypes();

		DataChunk right_chunk;
		right_chunk.Initialize(types);
		state->join_keys.Initialize(join_key_types);
		// first fetch the entire right side
		while (true) {
			children[1]->GetChunk(context, right_chunk, right_state.get());
			if (right_chunk.size() == 0) {
				break;
			}
			// resolve the join keys for this chunk
			state->rhs_executor.SetChunk(right_chunk);

			state->join_keys.Reset();
			state->join_keys.SetCardinality(right_chunk);
			for (idx_t k = 0; k < conditions.size(); k++) {
				// resolve the join key
				state->rhs_executor.ExecuteExpression(k, state->join_keys.data[k]);
			}
			// append the join keys and the chunk to the chunk collection
			state->right_chunks.Append(right_chunk);
			state->right_conditions.Append(state->join_keys);
		}
		if (state->right_chunks.count == 0 && (type == JoinType::INNER || type == JoinType::SEMI)) {
			// empty RHS with INNER or SEMI join means empty result set
			return;
		}
		// now order all the chunks
		state->right_orders.resize(state->right_conditions.chunks.size());
		for (idx_t i = 0; i < state->right_conditions.chunks.size(); i++) {
			auto &chunk_to_order = *state->right_conditions.chunks[i];
			assert(chunk_to_order.column_count() == 1);
			for (idx_t col_idx = 0; col_idx < chunk_to_order.column_count(); col_idx++) {
				OrderVector(chunk_to_order.data[col_idx], chunk_to_order.size(), state->right_orders[i]);
				if (state->right_orders[i].count < chunk_to_order.size()) {
					// the amount of entries in the order vector is smaller than the amount of entries in the vector
					// this only happens if there are NULL values in the right-hand side
					// hence we set the has_null to true (this is required for the MARK join)
					state->has_null = true;
				}
			}
		}
		state->right_chunk_index = state->right_orders.size();
		state->initialized = true;
	}

	do {
		// check if we have to fetch a child from the left side
		if (state->right_chunk_index == state->right_orders.size()) {
			// fetch the chunk from the left side
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			if (state->child_chunk.size() == 0) {
				return;
			}

			// resolve the join keys for the left chunk
			state->join_keys.Reset();
			state->lhs_executor.SetChunk(state->child_chunk);
			state->join_keys.SetCardinality(state->child_chunk);
			for (idx_t k = 0; k < conditions.size(); k++) {
				state->lhs_executor.ExecuteExpression(k, state->join_keys.data[k]);
				// sort by join key
				OrderVector(state->join_keys.data[k], state->join_keys.size(), state->left_orders);
			}
			state->right_chunk_index = 0;
			state->left_position = 0;
			state->right_position = 0;
		}

		ScalarMergeInfo left_info(state->left_orders, state->join_keys.data[0].type, state->left_position);

		// first check if the join type is MARK, SEMI or ANTI
		// in this case we loop over the entire right collection immediately
		// because we can never return more than STANDARD_VECTOR_SIZE rows from a join
		switch (type) {
		case JoinType::MARK: {
			// MARK join
			if (state->right_chunks.count > 0) {
				ChunkMergeInfo right_info(state->right_conditions, state->right_orders);
				// first perform the MARK join
				// this method uses the LHS to loop over the entire RHS looking for matches
				MergeJoinMark::Perform(left_info, right_info, conditions[0].comparison);
				// now construct the mark join result from the found matches
				PhysicalJoin::ConstructMarkJoinResult(state->join_keys, state->child_chunk, chunk,
				                                      right_info.found_match, state->has_null);
			} else {
				// RHS empty: result is false for everything
				chunk.Reference(state->child_chunk);
				auto &mark_vector = chunk.data.back();
				mark_vector.vector_type = VectorType::CONSTANT_VECTOR;
				mark_vector.SetValue(0, Value::BOOLEAN(false));
			}
			state->right_chunk_index = state->right_orders.size();
			return;
		}
		default:
			// INNER, LEFT OUTER, etc... join that can return >STANDARD_VECTOR_SIZE entries
			break;
		}

		// perform the actual merge join
		auto &right_chunk = *state->right_chunks.chunks[state->right_chunk_index];
		auto &right_condition_chunk = *state->right_conditions.chunks[state->right_chunk_index];
		auto &right_orders = state->right_orders[state->right_chunk_index];

		ScalarMergeInfo right(right_orders, right_condition_chunk.data[0].type, state->right_position);
		// perform the merge join
		switch (type) {
		case JoinType::INNER: {
			idx_t result_count = MergeJoinInner::Perform(left_info, right, conditions[0].comparison);
			if (result_count == 0) {
				// exhausted this chunk on the right side
				// move to the next
				state->right_chunk_index++;
				state->left_position = 0;
				state->right_position = 0;
			} else {
				chunk.Slice(state->child_chunk, left_info.result, result_count);
				chunk.Slice(right_chunk, right.result, result_count, state->child_chunk.column_count());
			}
			break;
		}
		default:
			throw NotImplementedException("Unimplemented join type for merge join");
		}
	} while (chunk.size() == 0);
}

unique_ptr<PhysicalOperatorState> PhysicalPiecewiseMergeJoin::GetOperatorState() {
	return make_unique<PhysicalPiecewiseMergeJoinState>(children[0].get(), children[1].get(), conditions);
}

template <class T, class OP>
static sel_t templated_quicksort_initial(T *data, const SelectionVector &sel, const SelectionVector &not_null_sel,
                                         idx_t count, SelectionVector &result) {
	// select pivot
	auto pivot_idx = not_null_sel.get_index(0);
	auto dpivot_idx = sel.get_index(pivot_idx);
	sel_t low = 0, high = count - 1;
	// now insert elements
	for (idx_t i = 1; i < count; i++) {
		auto idx = not_null_sel.get_index(i);
		auto didx = sel.get_index(idx);
		if (OP::Operation(data[didx], data[dpivot_idx])) {
			result.set_index(low++, idx);
		} else {
			result.set_index(high--, idx);
		}
	}
	assert(low == high);
	result.set_index(low, pivot_idx);
	return low;
}

template <class T, class OP>
static void templated_quicksort_inplace(T *data, const SelectionVector &sel, idx_t count, SelectionVector &result,
                                        sel_t left, sel_t right) {
	if (left >= right) {
		return;
	}

	sel_t middle = left + (right - left) / 2;
	sel_t dpivot_idx = sel.get_index(result.get_index(middle));

	// move the mid point value to the front.
	sel_t i = left + 1;
	sel_t j = right;

	result.swap(middle, left);
	while (i <= j) {
		while (i <= j && (OP::Operation(data[sel.get_index(result.get_index(i))], data[dpivot_idx]))) {
			i++;
		}

		while (i <= j && OP::Operation(data[dpivot_idx], data[sel.get_index(result.get_index(j))])) {
			j--;
		}

		if (i < j) {
			result.swap(i, j);
		}
	}
	result.swap(i - 1, left);
	sel_t part = i - 1;

	if (part > 0) {
		templated_quicksort_inplace<T, OP>(data, sel, count, result, left, part - 1);
	}
	templated_quicksort_inplace<T, OP>(data, sel, count, result, part + 1, right);
}

template <class T, class OP>
void templated_quicksort(T *__restrict data, const SelectionVector &sel, const SelectionVector &not_null_sel,
                         idx_t count, SelectionVector &result) {
	auto part = templated_quicksort_initial<T, OP>(data, sel, not_null_sel, count, result);
	if (part > count) {
		return;
	}
	templated_quicksort_inplace<T, OP>(data, sel, count, result, 0, part);
	templated_quicksort_inplace<T, OP>(data, sel, count, result, part + 1, count - 1);
}

template <class T>
static void templated_quicksort(VectorData &vdata, const SelectionVector &not_null_sel, idx_t not_null_count,
                                SelectionVector &result) {
	if (not_null_count == 0) {
		return;
	}
	templated_quicksort<T, duckdb::LessThanEquals>((T *)vdata.data, *vdata.sel, not_null_sel, not_null_count, result);
}

void OrderVector(Vector &vector, idx_t count, MergeOrder &order) {
	if (count == 0) {
		order.count = 0;
		return;
	}
	vector.Orrify(count, order.vdata);
	auto &vdata = order.vdata;

	// first filter out all the non-null values
	idx_t not_null_count = 0;
	SelectionVector not_null(STANDARD_VECTOR_SIZE);
	for (idx_t i = 0; i < count; i++) {
		auto idx = vdata.sel->get_index(i);
		if (!(*vdata.nullmask)[idx]) {
			not_null.set_index(not_null_count++, i);
		}
	}
	order.count = not_null_count;
	order.order.Initialize(STANDARD_VECTOR_SIZE);
	switch (vector.type) {
	case TypeId::INT8:
		templated_quicksort<int8_t>(vdata, not_null, not_null_count, order.order);
		break;
	case TypeId::INT16:
		templated_quicksort<int16_t>(vdata, not_null, not_null_count, order.order);
		break;
	case TypeId::INT32:
		templated_quicksort<int32_t>(vdata, not_null, not_null_count, order.order);
		break;
	case TypeId::INT64:
		templated_quicksort<int64_t>(vdata, not_null, not_null_count, order.order);
		break;
	case TypeId::FLOAT:
		templated_quicksort<float>(vdata, not_null, not_null_count, order.order);
		break;
	case TypeId::DOUBLE:
		templated_quicksort<double>(vdata, not_null, not_null_count, order.order);
		break;
	case TypeId::VARCHAR:
		templated_quicksort<string_t>(vdata, not_null, not_null_count, order.order);
		break;
	default:
		throw NotImplementedException("Unimplemented type for sort");
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/order/physical_order.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a physical ordering of the data. Note that this will not change
//! the data but only add a selection vector.
class PhysicalOrder : public PhysicalOperator {
public:
	PhysicalOrder(vector<TypeId> types, vector<BoundOrderByNode> orders)
	    : PhysicalOperator(PhysicalOperatorType::ORDER_BY, move(types)), orders(move(orders)) {
	}

	vector<BoundOrderByNode> orders;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb








using namespace duckdb;
using namespace std;

class PhysicalOrderOperatorState : public PhysicalOperatorState {
public:
	PhysicalOrderOperatorState(PhysicalOperator *child) : PhysicalOperatorState(child), position(0) {
	}

	idx_t position;
	ChunkCollection sorted_data;
	unique_ptr<idx_t[]> sorted_vector;
};

void PhysicalOrder::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalOrderOperatorState *>(state_);
	ChunkCollection &big_data = state->sorted_data;
	if (state->position == 0) {
		// first concatenate all the data of the child chunks
		do {
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			big_data.Append(state->child_chunk);
		} while (state->child_chunk.size() != 0);

		// now perform the actual ordering of the data
		// compute the sorting columns from the input data
		ExpressionExecutor executor;
		vector<TypeId> sort_types;
		vector<OrderType> order_types;
		for (idx_t i = 0; i < orders.size(); i++) {
			auto &expr = orders[i].expression;
			sort_types.push_back(expr->return_type);
			order_types.push_back(orders[i].type);
			executor.AddExpression(*expr);
		}

		ChunkCollection sort_collection;
		for (idx_t i = 0; i < big_data.chunks.size(); i++) {
			DataChunk sort_chunk;
			sort_chunk.Initialize(sort_types);

			executor.Execute(*big_data.chunks[i], sort_chunk);
			sort_collection.Append(sort_chunk);
		}

		assert(sort_collection.count == big_data.count);

		// now perform the actual sort
		state->sorted_vector = unique_ptr<idx_t[]>(new idx_t[sort_collection.count]);
		sort_collection.Sort(order_types, state->sorted_vector.get());
	}

	if (state->position >= big_data.count) {
		return;
	}

	big_data.MaterializeSortedChunk(chunk, state->sorted_vector.get(), state->position);
	state->position += STANDARD_VECTOR_SIZE;
}

unique_ptr<PhysicalOperatorState> PhysicalOrder::GetOperatorState() {
	return make_unique<PhysicalOrderOperatorState>(children[0].get());
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/order/physical_top_n.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a physical ordering of the data. Note that this will not change
//! the data but only add a selection vector.
class PhysicalTopN : public PhysicalOperator {
public:
	PhysicalTopN(LogicalOperator &op, vector<BoundOrderByNode> orders, idx_t limit, idx_t offset)
	    : PhysicalOperator(PhysicalOperatorType::TOP_N, op.types), orders(move(orders)), limit(limit), offset(offset),
	      heap_size(0) {
	}

	vector<BoundOrderByNode> orders;
	idx_t limit;
	idx_t offset;
	idx_t heap_size;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
	void CalculateHeapSize(idx_t rows);
};

} // namespace duckdb








using namespace duckdb;
using namespace std;

class PhysicalTopNOperatorState : public PhysicalOperatorState {
public:
	PhysicalTopNOperatorState(PhysicalOperator *child) : PhysicalOperatorState(child), position(0) {
	}

	idx_t position;
	idx_t current_offset;
	ChunkCollection sorted_data;
	unique_ptr<idx_t[]> heap;
};

void PhysicalTopN::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalTopNOperatorState *>(state_);
	ChunkCollection &big_data = state->sorted_data;

	if (state->position == 0) {
		// first concatenate all the data of the child chunks
		do {
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			big_data.Append(state->child_chunk);
		} while (state->child_chunk.size() != 0);

		// now perform the actual ordering of the data
		// compute the sorting columns from the input data
		ExpressionExecutor executor;
		vector<TypeId> sort_types;
		vector<OrderType> order_types;
		for (idx_t i = 0; i < orders.size(); i++) {
			auto &expr = orders[i].expression;
			sort_types.push_back(expr->return_type);
			order_types.push_back(orders[i].type);
			executor.AddExpression(*expr);
		}

		CalculateHeapSize(big_data.count);
		if (heap_size == 0) {
			return;
		}

		ChunkCollection heap_collection;
		for (idx_t i = 0; i < big_data.chunks.size(); i++) {
			DataChunk heap_chunk;
			heap_chunk.Initialize(sort_types);

			executor.Execute(*big_data.chunks[i], heap_chunk);
			heap_collection.Append(heap_chunk);
		}

		assert(heap_collection.count == big_data.count);

		// create and use the heap
		state->heap = unique_ptr<idx_t[]>(new idx_t[heap_size]);
		heap_collection.Heap(order_types, state->heap.get(), heap_size);
	}

	if (state->position >= heap_size) {
		return;
	} else if (state->position < offset) {
		state->position = offset;
	}

	state->position += big_data.MaterializeHeapChunk(chunk, state->heap.get(), state->position, heap_size);
}

unique_ptr<PhysicalOperatorState> PhysicalTopN::GetOperatorState() {
	return make_unique<PhysicalTopNOperatorState>(children[0].get());
}

void PhysicalTopN::CalculateHeapSize(idx_t rows) {
	heap_size = (rows > offset) ? min(limit + offset, rows) : 0;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/persistent/buffered_csv_reader.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_data/copy_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//===--------------------------------------------------------------------===//
// External File Format Types
//===--------------------------------------------------------------------===//
enum class ExternalFileFormat : uint8_t { INVALID, CSV };

struct CopyInfo : public ParseInfo {
	CopyInfo()
	    : schema(DEFAULT_SCHEMA), is_from(false), delimiter(","), quote("\""), escape(""), header(false),
	      format(ExternalFileFormat::CSV), null_str(""), quote_all(false) {
	}

	//! The schema name to copy to/from
	string schema;
	//! The table name to copy to/from
	string table;
	//! List of columns to copy to/from
	vector<string> select_list;
	//! The file path to copy to/from
	string file_path;
	//! Whether or not this is a copy to file (false) or copy from a file (true)
	bool is_from;
	//! Delimiter to separate columns within each line
	string delimiter;
	//! Quote used for columns that contain reserved characters, e.g., delimiter
	string quote;
	//! Escape character to escape quote character
	string escape;
	//! Whether or not the file has a header line
	bool header;
	//! The file format of the external file
	ExternalFileFormat format;
	//! Specifies the string that represents a null value
	string null_str;
	//! Determines whether all columns must be quoted
	bool quote_all;
	//! Forces quoting to be used for all non-NULL values in each specified column
	vector<string> force_quote_list;
	//! True, if column with that index must be quoted
	vector<bool> force_quote;
	//! Null values will be read as zero-length strings in each specified column
	vector<string> force_not_null_list;
	//! True, if column with that index must skip null check
	vector<bool> force_not_null;
};

} // namespace duckdb


namespace duckdb {
struct CopyInfo;

//! The shifts array allows for linear searching of multi-byte values. For each position, it determines the next
//! position given that we encounter a byte with the given value.
/*! For example, if we have a string "ABAC", the shifts array will have the following values:
 *  [0] --> ['A'] = 1, all others = 0
 *  [1] --> ['B'] = 2, ['A'] = 1, all others = 0
 *  [2] --> ['A'] = 3, all others = 0
 *  [3] --> ['C'] = 4 (match), 'B' = 2, 'A' = 1, all others = 0
 * Suppose we then search in the following string "ABABAC", our progression will be as follows:
 * 'A' -> [1], 'B' -> [2], 'A' -> [3], 'B' -> [2], 'A' -> [3], 'C' -> [4] (match!)
 */
struct TextSearchShiftArray {
	TextSearchShiftArray(string search_term);

	inline bool Match(uint8_t &position, uint8_t byte_value) {
		position = shifts[position * 255 + byte_value];
		return position == length;
	}

	idx_t length;
	unique_ptr<uint8_t[]> shifts;
};

//! Buffered CSV reader is a class that reads values from a stream and parses them as a CSV file
class BufferedCSVReader {
	static constexpr idx_t INITIAL_BUFFER_SIZE = 16384;
	static constexpr idx_t MAXIMUM_CSV_LINE_SIZE = 1048576;

public:
	BufferedCSVReader(ClientContext &context, CopyInfo &info, vector<SQLType> sql_types);
	BufferedCSVReader(CopyInfo &info, vector<SQLType> sql_types, unique_ptr<std::istream> source);

	CopyInfo &info;
	vector<SQLType> sql_types;
	unique_ptr<std::istream> source;

	unique_ptr<char[]> buffer;
	idx_t buffer_size;
	idx_t position;
	idx_t start = 0;

	idx_t linenr = 0;

	TextSearchShiftArray delimiter_search, escape_search, quote_search;

	vector<unique_ptr<char[]>> cached_buffers;

	DataChunk parse_chunk;

public:
	//! Extract a single DataChunk from the CSV file and stores it in insert_chunk
	void ParseCSV(DataChunk &insert_chunk);

private:
	//! Parses a CSV file with a one-byte delimiter, escape and quote character
	void ParseSimpleCSV(DataChunk &insert_chunk);
	//! Parses more complex CSV files with multi-byte delimiters, escapes or quotes
	void ParseComplexCSV(DataChunk &insert_chunk);

	//! Adds a value to the current row
	void AddValue(char *str_val, idx_t length, idx_t &column, vector<idx_t> &escape_positions);
	//! Adds a row to the insert_chunk, returns true if the chunk is filled as a result of this row being added
	bool AddRow(DataChunk &insert_chunk, idx_t &column);
	//! Finalizes a chunk, parsing all values that have been added so far and adding them to the insert_chunk
	void Flush(DataChunk &insert_chunk);
	//! Reads a new buffer from the CSV file if the current one has been exhausted
	bool ReadBuffer(idx_t &start);

	unique_ptr<std::istream> OpenCSV(ClientContext &context, CopyInfo &info);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/persistent/physical_copy_from_file.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class BufferedCSVReader;

//! Parse a CSV file and return the set of chunks retrieved from the file
class PhysicalCopyFromFile : public PhysicalOperator {
public:
	PhysicalCopyFromFile(LogicalOperator &op, vector<SQLType> sql_types, unique_ptr<CopyInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::COPY_FROM_FILE, op.types), sql_types(sql_types), info(move(info)) {
	}

	//! The set of types to retrieve from the file
	vector<SQLType> sql_types;
	//! Settings for the COPY statement
	unique_ptr<CopyInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb














#include <algorithm>
#include <fstream>
#include <queue>
#include <cstring>

using namespace duckdb;
using namespace std;

static char is_newline(char c) {
	return c == '\n' || c == '\r';
}

TextSearchShiftArray::TextSearchShiftArray(string search_term) : length(search_term.size()) {
	if (length > 255) {
		throw Exception("Size of delimiter/quote/escape in CSV reader is limited to 255 bytes");
	}
	// initialize the shifts array
	shifts = unique_ptr<uint8_t[]>(new uint8_t[length * 255]);
	memset(shifts.get(), 0, length * 255 * sizeof(uint8_t));
	// iterate over each of the characters in the array
	for (idx_t main_idx = 0; main_idx < length; main_idx++) {
		uint8_t current_char = (uint8_t)search_term[main_idx];
		// now move over all the remaining positions
		for (idx_t i = main_idx; i < length; i++) {
			bool is_match = true;
			// check if the prefix matches at this position
			// if it does, we move to this position after encountering the current character
			for (idx_t j = 0; j < main_idx; j++) {
				if (search_term[i - main_idx + j] != search_term[j]) {
					is_match = false;
				}
			}
			if (!is_match) {
				continue;
			}
			shifts[i * 255 + current_char] = main_idx + 1;
		}
	}
}

BufferedCSVReader::BufferedCSVReader(ClientContext &context, CopyInfo &info, vector<SQLType> sql_types)
    : BufferedCSVReader(info, sql_types, OpenCSV(context, info)) {
}

BufferedCSVReader::BufferedCSVReader(CopyInfo &info, vector<SQLType> sql_types, unique_ptr<istream> ssource)
    : info(info), sql_types(sql_types), source(move(ssource)), buffer_size(0), position(0), start(0),
      delimiter_search(info.delimiter), escape_search(info.escape), quote_search(info.quote) {
	if (info.force_not_null.size() == 0) {
		info.force_not_null.resize(sql_types.size(), false);
	}

	assert(info.force_not_null.size() == sql_types.size());
	// initialize the parse_chunk with a set of VARCHAR types
	vector<TypeId> varchar_types;
	for (idx_t i = 0; i < sql_types.size(); i++) {
		varchar_types.push_back(TypeId::VARCHAR);
	}
	parse_chunk.Initialize(varchar_types);

	if (info.header) {
		// ignore the first line as a header line
		string read_line;
		getline(*source, read_line);
		linenr++;
	}
}

unique_ptr<istream> BufferedCSVReader::OpenCSV(ClientContext &context, CopyInfo &info) {
	if (!FileSystem::GetFileSystem(context).FileExists(info.file_path)) {
		throw IOException("File \"%s\" not found", info.file_path.c_str());
	}
	unique_ptr<istream> result;
	// decide based on the extension which stream to use
	if (StringUtil::EndsWith(StringUtil::Lower(info.file_path), ".gz")) {
		result = make_unique<GzipStream>(info.file_path);
	} else {
		auto csv_local = make_unique<ifstream>();
		csv_local->open(info.file_path);
		result = move(csv_local);
	}
	return result;
}

void BufferedCSVReader::ParseComplexCSV(DataChunk &insert_chunk) {
	// used for parsing algorithm
	bool finished_chunk = false;
	idx_t column = 0;
	vector<idx_t> escape_positions;
	uint8_t delimiter_pos = 0, escape_pos = 0, quote_pos = 0;
	idx_t offset = 0;

	// read values into the buffer (if any)
	if (position >= buffer_size) {
		if (!ReadBuffer(start)) {
			return;
		}
	}
	// start parsing the first value
	start = position;
	goto value_start;
value_start:
	/* state: value_start */
	// this state parses the first characters of a value
	offset = 0;
	delimiter_pos = 0;
	quote_pos = 0;
	do {
		idx_t count = 0;
		for (; position < buffer_size; position++) {
			quote_search.Match(quote_pos, buffer[position]);
			delimiter_search.Match(delimiter_pos, buffer[position]);
			count++;
			if (delimiter_pos == info.delimiter.size()) {
				// found a delimiter, add the value
				offset = info.delimiter.size() - 1;
				goto add_value;
			} else if (is_newline(buffer[position])) {
				// found a newline, add the row
				goto add_row;
			}
			if (count > quote_pos) {
				// did not find a quote directly at the start of the value, stop looking for the quote now
				goto normal;
			}
			if (quote_pos == info.quote.size()) {
				// found a quote, go to quoted loop and skip the initial quote
				start += info.quote.size();
				goto in_quotes;
			}
		}
	} while (ReadBuffer(start));
	// file ends while scanning for quote/delimiter, go to final state
	goto final_state;
normal:
	/* state: normal parsing state */
	// this state parses the remainder of a non-quoted value until we reach a delimiter or newline
	position++;
	do {
		for (; position < buffer_size; position++) {
			delimiter_search.Match(delimiter_pos, buffer[position]);
			if (delimiter_pos == info.delimiter.size()) {
				offset = info.delimiter.size() - 1;
				goto add_value;
			} else if (is_newline(buffer[position])) {
				goto add_row;
			}
		}
	} while (ReadBuffer(start));
	goto final_state;
add_value:
	AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
	// increase position by 1 and move start to the new position
	offset = 0;
	start = ++position;
	if (position >= buffer_size && !ReadBuffer(start)) {
		// file ends right after delimiter, go to final state
		goto final_state;
	}
	goto value_start;
add_row : {
	// check type of newline (\r or \n)
	bool carriage_return = buffer[position] == '\r';
	AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
	finished_chunk = AddRow(insert_chunk, column);
	// increase position by 1 and move start to the new position
	offset = 0;
	start = ++position;
	if (position >= buffer_size && !ReadBuffer(start)) {
		// file ends right after newline, go to final state
		goto final_state;
	}
	if (carriage_return) {
		// \r newline, go to special state that parses an optional \n afterwards
		goto carriage_return;
	} else {
		// \n newline, move to value start
		if (finished_chunk) {
			return;
		}
		goto value_start;
	}
}
in_quotes:
	/* state: in_quotes */
	// this state parses the remainder of a quoted value
	quote_pos = 0;
	escape_pos = 0;
	position++;
	do {
		for (; position < buffer_size; position++) {
			quote_search.Match(quote_pos, buffer[position]);
			escape_search.Match(escape_pos, buffer[position]);
			if (quote_pos == info.quote.size()) {
				goto unquote;
			} else if (escape_pos == info.escape.size()) {
				escape_positions.push_back(position - start - (info.escape.size() - 1));
				goto handle_escape;
			}
		}
	} while (ReadBuffer(start));
	// still in quoted state at the end of the file, error:
	throw ParserException("Error on line %lld: unterminated quotes", linenr);
unquote:
	/* state: unquote */
	// this state handles the state directly after we unquote
	// in this state we expect either another quote (entering the quoted state again, and escaping the quote)
	// or a delimiter/newline, ending the current value and moving on to the next value
	delimiter_pos = 0;
	quote_pos = 0;
	position++;
	if (position >= buffer_size && !ReadBuffer(start)) {
		// file ends right after unquote, go to final state
		offset = info.quote.size();
		goto final_state;
	}
	if (is_newline(buffer[position])) {
		// quote followed by newline, add row
		offset = info.quote.size();
		goto add_row;
	}
	do {
		idx_t count = 0;
		for (; position < buffer_size; position++) {
			quote_search.Match(quote_pos, buffer[position]);
			delimiter_search.Match(delimiter_pos, buffer[position]);
			count++;
			if (count > delimiter_pos && count > quote_pos) {
				throw ParserException(
				    "Error on line %lld: quote should be followed by end of value, end of row or another quote",
				    linenr);
			}
			if (delimiter_pos == info.delimiter.size()) {
				// quote followed by delimiter, add value
				offset = info.quote.size() + info.delimiter.size() - 1;
				goto add_value;
			} else if (quote_pos == info.quote.size()) {
				// quote followed by quote, go back to quoted state and add to escape
				escape_positions.push_back(position - start - (info.quote.size() - 1));
				goto in_quotes;
			}
		}
	} while (ReadBuffer(start));
	throw ParserException("Error on line %lld: quote should be followed by end of value, end of row or another quote",
	                      linenr);
handle_escape:
	escape_pos = 0;
	quote_pos = 0;
	position++;
	do {
		idx_t count = 0;
		for (; position < buffer_size; position++) {
			quote_search.Match(quote_pos, buffer[position]);
			escape_search.Match(escape_pos, buffer[position]);
			count++;
			if (count > escape_pos && count > quote_pos) {
				throw ParserException("Error on line %lld: neither QUOTE nor ESCAPE is proceeded by ESCAPE", linenr);
			}
			if (quote_pos == info.quote.size() || escape_pos == info.escape.size()) {
				// found quote or escape: move back to quoted state
				goto in_quotes;
			}
		}
	} while (ReadBuffer(start));
	throw ParserException("Error on line %lld: neither QUOTE nor ESCAPE is proceeded by ESCAPE", linenr);
carriage_return:
	/* state: carriage_return */
	// this stage optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line
	if (buffer[position] == '\n') {
		// newline after carriage return: skip
		start = ++position;
		if (position >= buffer_size && !ReadBuffer(start)) {
			// file ends right after newline, go to final state
			goto final_state;
		}
	}
	if (finished_chunk) {
		return;
	}
	goto value_start;
final_state:
	if (finished_chunk) {
		return;
	}
	if (column > 0 || position > start) {
		// remaining values to be added to the chunk
		AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
		finished_chunk = AddRow(insert_chunk, column);
	}
	// final stage, only reached after parsing the file is finished
	// flush the parsed chunk and finalize parsing
	Flush(insert_chunk);
}

void BufferedCSVReader::ParseSimpleCSV(DataChunk &insert_chunk) {
	// used for parsing algorithm
	bool finished_chunk = false;
	idx_t column = 0;
	idx_t offset = 0;
	vector<idx_t> escape_positions;

	// read values into the buffer (if any)
	if (position >= buffer_size) {
		if (!ReadBuffer(start)) {
			return;
		}
	}
	// start parsing the first value
	goto value_start;
value_start:
	offset = 0;
	/* state: value_start */
	// this state parses the first character of a value
	if (buffer[position] == info.quote[0]) {
		// quote: actual value starts in the next position
		// move to in_quotes state
		start = position + 1;
		goto in_quotes;
	} else {
		// no quote, move to normal parsing state
		start = position;
		goto normal;
	}
normal:
	/* state: normal parsing state */
	// this state parses the remainder of a non-quoted value until we reach a delimiter or newline
	do {
		for (; position < buffer_size; position++) {
			if (buffer[position] == info.delimiter[0]) {
				// delimiter: end the value and add it to the chunk
				goto add_value;
			} else if (is_newline(buffer[position])) {
				// newline: add row
				goto add_row;
			}
		}
	} while (ReadBuffer(start));
	// file ends during normal scan: go to end state
	goto final_state;
add_value:
	AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
	// increase position by 1 and move start to the new position
	offset = 0;
	start = ++position;
	if (position >= buffer_size && !ReadBuffer(start)) {
		// file ends right after delimiter, go to final state
		goto final_state;
	}
	goto value_start;
add_row : {
	// check type of newline (\r or \n)
	bool carriage_return = buffer[position] == '\r';
	AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
	finished_chunk = AddRow(insert_chunk, column);
	// increase position by 1 and move start to the new position
	offset = 0;
	start = ++position;
	if (position >= buffer_size && !ReadBuffer(start)) {
		// file ends right after delimiter, go to final state
		goto final_state;
	}
	if (carriage_return) {
		// \r newline, go to special state that parses an optional \n afterwards
		goto carriage_return;
	} else {
		// \n newline, move to value start
		if (finished_chunk) {
			return;
		}
		goto value_start;
	}
}
in_quotes:
	/* state: in_quotes */
	// this state parses the remainder of a quoted value
	position++;
	do {
		for (; position < buffer_size; position++) {
			if (buffer[position] == info.quote[0]) {
				// quote: move to unquoted state
				goto unquote;
			} else if (buffer[position] == info.escape[0]) {
				// escape: store the escaped position and move to handle_escape state
				escape_positions.push_back(position - start);
				goto handle_escape;
			}
		}
	} while (ReadBuffer(start));
	// still in quoted state at the end of the file, error:
	throw ParserException("Error on line %lld: unterminated quotes", linenr);
unquote:
	/* state: unquote */
	// this state handles the state directly after we unquote
	// in this state we expect either another quote (entering the quoted state again, and escaping the quote)
	// or a delimiter/newline, ending the current value and moving on to the next value
	position++;
	if (position >= buffer_size && !ReadBuffer(start)) {
		// file ends right after unquote, go to final state
		offset = 1;
		goto final_state;
	}
	if (buffer[position] == info.quote[0]) {
		// escaped quote, return to quoted state and store escape position
		escape_positions.push_back(position - start);
		goto in_quotes;
	} else if (buffer[position] == info.delimiter[0]) {
		// delimiter, add value
		offset = 1;
		goto add_value;
	} else if (is_newline(buffer[position])) {
		offset = 1;
		goto add_row;
	} else {
		throw ParserException(
		    "Error on line %lld: quote should be followed by end of value, end of row or another quote", linenr);
	}
handle_escape:
	/* state: handle_escape */
	// escape should be followed by a quote or another escape character
	position++;
	if (position >= buffer_size && !ReadBuffer(start)) {
		throw ParserException("Error on line %lld: neither QUOTE nor ESCAPE is proceeded by ESCAPE", linenr);
	}
	if (buffer[position] != info.quote[0] && buffer[position] != info.escape[0]) {
		throw ParserException("Error on line %lld: neither QUOTE nor ESCAPE is proceeded by ESCAPE", linenr);
	}
	// escape was followed by quote or escape, go back to quoted state
	goto in_quotes;
carriage_return:
	/* state: carriage_return */
	// this stage optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line
	if (buffer[position] == '\n') {
		// newline after carriage return: skip
		// increase position by 1 and move start to the new position
		start = ++position;
		if (position >= buffer_size && !ReadBuffer(start)) {
			// file ends right after delimiter, go to final state
			goto final_state;
		}
	}
	if (finished_chunk) {
		return;
	}
	goto value_start;
final_state:
	if (finished_chunk) {
		return;
	}
	if (column > 0 || position > start) {
		// remaining values to be added to the chunk
		AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
		finished_chunk = AddRow(insert_chunk, column);
	}
	// final stage, only reached after parsing the file is finished
	// flush the parsed chunk and finalize parsing
	Flush(insert_chunk);
}

bool BufferedCSVReader::ReadBuffer(idx_t &start) {
	auto old_buffer = move(buffer);

	// the remaining part of the last buffer
	idx_t remaining = buffer_size - start;
	idx_t buffer_read_size = INITIAL_BUFFER_SIZE;
	while (remaining > buffer_read_size) {
		buffer_read_size *= 2;
	}
	if (remaining + buffer_read_size > MAXIMUM_CSV_LINE_SIZE) {
		throw ParserException("Maximum line size of %llu bytes exceeded!", MAXIMUM_CSV_LINE_SIZE);
	}
	buffer = unique_ptr<char[]>(new char[buffer_read_size + remaining + 1]);
	buffer_size = remaining + buffer_read_size;
	if (remaining > 0) {
		// remaining from last buffer: copy it here
		memcpy(buffer.get(), old_buffer.get() + start, remaining);
	}
	source->read(buffer.get() + remaining, buffer_read_size);
	idx_t read_count = source->eof() ? source->gcount() : buffer_read_size;
	buffer_size = remaining + read_count;
	buffer[buffer_size] = '\0';
	if (old_buffer) {
		cached_buffers.push_back(move(old_buffer));
	}
	start = 0;
	position = remaining;

	return read_count > 0;
}

void BufferedCSVReader::ParseCSV(DataChunk &insert_chunk) {
	cached_buffers.clear();

	if (info.quote.size() == 1 && info.escape.size() == 1 && info.delimiter.size() == 1) {
		ParseSimpleCSV(insert_chunk);
	} else {
		ParseComplexCSV(insert_chunk);
	}
}

void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vector<idx_t> &escape_positions) {
	if (column == sql_types.size() && length == 0) {
		// skip a single trailing delimiter
		column++;
		return;
	}
	if (column >= sql_types.size()) {
		throw ParserException("Error on line %lld: expected %lld values but got %d", linenr, sql_types.size(),
		                      column + 1);
	}
	// insert the line number into the chunk
	idx_t row_entry = parse_chunk.size();

	str_val[length] = '\0';
	// test against null string
	if (!info.force_not_null[column] && strcmp(info.null_str.c_str(), str_val) == 0) {
		FlatVector::SetNull(parse_chunk.data[column], row_entry, true);
	} else {
		auto &v = parse_chunk.data[column];
		auto parse_data = FlatVector::GetData<string_t>(v);
		if (escape_positions.size() > 0) {
			// remove escape characters (if any)
			string old_val = str_val;
			string new_val = "";
			idx_t prev_pos = 0;
			for (idx_t i = 0; i < escape_positions.size(); i++) {
				idx_t next_pos = escape_positions[i];
				new_val += old_val.substr(prev_pos, next_pos - prev_pos);
				prev_pos = next_pos + info.escape.size();
			}
			new_val += old_val.substr(prev_pos, old_val.size() - prev_pos);
			escape_positions.clear();
			parse_data[row_entry] = StringVector::AddString(v, new_val.c_str(), new_val.size());
		} else {
			parse_data[row_entry] = string_t(str_val, length);
		}
	}

	// move to the next column
	column++;
}

bool BufferedCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) {
	if (column < sql_types.size()) {
		throw ParserException("Error on line %lld: expected %lld values but got %d", linenr, sql_types.size(), column);
	}
	parse_chunk.SetCardinality(parse_chunk.size() + 1);
	if (parse_chunk.size() == STANDARD_VECTOR_SIZE) {
		Flush(insert_chunk);
		return true;
	}
	column = 0;
	linenr++;
	return false;
}

void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
	if (parse_chunk.size() == 0) {
		return;
	}
	// convert the columns in the parsed chunk to the types of the table
	insert_chunk.SetCardinality(parse_chunk);
	for (idx_t col_idx = 0; col_idx < sql_types.size(); col_idx++) {
		if (sql_types[col_idx].id == SQLTypeId::VARCHAR) {

			// target type is varchar: no need to convert
			// just test that all strings are valid utf-8 strings
			auto parse_data = FlatVector::GetData<string_t>(parse_chunk.data[col_idx]);
			for (idx_t i = 0; i < parse_chunk.size(); i++) {
				if (!FlatVector::IsNull(parse_chunk.data[col_idx], i)) {
					auto s = parse_data[i];
					auto utf_type = Utf8Proc::Analyze(s.GetData(), s.GetSize());
					switch (utf_type) {
					case UnicodeType::INVALID:
						throw ParserException("Error on line %lld: file is not valid UTF8", linenr);
					case UnicodeType::ASCII:
						break;
					case UnicodeType::UNICODE: {
						auto normie = Utf8Proc::Normalize(s.GetData());
						parse_data[i] = StringVector::AddString(parse_chunk.data[col_idx], normie);
						free(normie);
						break;
					}
					}
				}
			}

			insert_chunk.data[col_idx].Reference(parse_chunk.data[col_idx]);
		} else {
			// target type is not varchar: perform a cast
			VectorOperations::Cast(parse_chunk.data[col_idx], insert_chunk.data[col_idx], SQLType::VARCHAR,
			                       sql_types[col_idx], parse_chunk.size());
		}
	}
	parse_chunk.Reset();
}





#include <algorithm>
#include <fstream>

using namespace duckdb;
using namespace std;

class PhysicalCopyFromFileOperatorState : public PhysicalOperatorState {
public:
	PhysicalCopyFromFileOperatorState();
	~PhysicalCopyFromFileOperatorState();

	//! The CSV reader
	unique_ptr<BufferedCSVReader> csv_reader;
};

void PhysicalCopyFromFile::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto &state = (PhysicalCopyFromFileOperatorState &)*state_;
	auto &info = *this->info;

	if (!state.csv_reader) {
		// initialize CSV reader
		state.csv_reader = make_unique<BufferedCSVReader>(context, info, sql_types);
	}
	// read from the CSV reader
	state.csv_reader->ParseCSV(chunk);
}

unique_ptr<PhysicalOperatorState> PhysicalCopyFromFile::GetOperatorState() {
	return make_unique<PhysicalCopyFromFileOperatorState>();
}

PhysicalCopyFromFileOperatorState::PhysicalCopyFromFileOperatorState() : PhysicalOperatorState(nullptr) {
}

PhysicalCopyFromFileOperatorState::~PhysicalCopyFromFileOperatorState() {
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/persistent/physical_copy_to_file.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! Copy the contents of a query into a table
class PhysicalCopyToFile : public PhysicalOperator {
public:
	PhysicalCopyToFile(LogicalOperator &op, unique_ptr<CopyInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::COPY_TO_FILE, op.types), info(move(info)) {
	}

	//! Settings for the COPY statement
	unique_ptr<CopyInfo> info;
	//! The names of the child expression
	vector<string> names;
	//! The types of the child expression
	vector<SQLType> sql_types;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};
} // namespace duckdb



#include <algorithm>
#include <fstream>

using namespace duckdb;
using namespace std;

class BufferedWriter {
	constexpr static idx_t BUFFER_SIZE = 4096 * 4;

public:
	BufferedWriter(string &path) : pos(0) {
		to_csv.open(path);
		if (to_csv.fail()) {
			throw IOException("Could not open CSV file");
		}
	}

	void Flush() {
		if (pos > 0) {
			to_csv.write(buffer, pos);
			pos = 0;
		}
	}

	void Close() {
		Flush();
		to_csv.close();
	}

	void Write(const char *buf, idx_t len) {
		if (len >= BUFFER_SIZE) {
			Flush();
			to_csv.write(buf, len);
			return;
		}
		if (pos + len > BUFFER_SIZE) {
			Flush();
		}
		memcpy(buffer + pos, buf, len);
		pos += len;
	}

	void Write(string &value) {
		Write(value.c_str(), value.size());
	}

private:
	char buffer[BUFFER_SIZE];
	idx_t pos = 0;

	ofstream to_csv;
};

string AddEscapes(string &to_be_escaped, string escape, string val) {
	idx_t i = 0;
	string new_val = "";
	idx_t found = val.find(to_be_escaped);

	while (found != string::npos) {
		while (i < found) {
			new_val += val[i];
			i++;
		}
		new_val += escape;
		found = val.find(to_be_escaped, found + escape.length());
	}
	while (i < val.length()) {
		new_val += val[i];
		i++;
	}
	return new_val;
}

static void WriteQuotedString(BufferedWriter &writer, string_t str_value, string &delimiter, string &quote,
                              string &escape, string &null_str, bool write_quoted) {
	// used for adding escapes
	bool add_escapes = false;
	auto str_data = str_value.GetData();
	string new_val(str_data, str_value.GetSize());

	// check for \n, \r, \n\r in string
	if (!write_quoted) {
		for (idx_t i = 0; i < str_value.GetSize(); i++) {
			if (str_data[i] == '\n' || str_data[i] == '\r') {
				// newline, write a quoted string
				write_quoted = true;
			}
		}
	}

	// check if value is null string
	if (!write_quoted) {
		if (new_val == null_str) {
			write_quoted = true;
		}
	}

	// check for delimiter
	if (!write_quoted) {
		if (new_val.find(delimiter) != string::npos) {
			write_quoted = true;
		}
	}

	// check for quote
	if (new_val.find(quote) != string::npos) {
		write_quoted = true;
		add_escapes = true;
	}

	// check for escapes in quoted string
	if (write_quoted && !add_escapes) {
		if (new_val.find(escape) != string::npos) {
			add_escapes = true;
		}
	}

	if (add_escapes) {
		new_val = AddEscapes(escape, escape, new_val);
		// also escape quotes
		if (escape != quote) {
			new_val = AddEscapes(quote, escape, new_val);
		}
	}

	if (!write_quoted) {
		writer.Write(new_val);
	} else {
		writer.Write(quote);
		writer.Write(new_val);
		writer.Write(quote);
	}
}

void PhysicalCopyToFile::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	auto &info = *this->info;
	idx_t total = 0;

	string newline = "\n";
	BufferedWriter writer(info.file_path);
	if (info.header) {
		// write the header line
		for (idx_t i = 0; i < names.size(); i++) {
			if (i != 0) {
				writer.Write(info.delimiter);
			}
			WriteQuotedString(writer, names[i].c_str(), info.delimiter, info.quote, info.escape, info.null_str, false);
		}
		writer.Write(newline);
	}
	// create a chunk with VARCHAR columns
	vector<TypeId> types;
	for (idx_t col_idx = 0; col_idx < state->child_chunk.column_count(); col_idx++) {
		types.push_back(TypeId::VARCHAR);
	}
	DataChunk cast_chunk;
	cast_chunk.Initialize(types);

	while (true) {
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			break;
		}
		// cast the columns of the chunk to varchar
		cast_chunk.SetCardinality(state->child_chunk);
		for (idx_t col_idx = 0; col_idx < state->child_chunk.column_count(); col_idx++) {
			if (sql_types[col_idx].id == SQLTypeId::VARCHAR) {
				// VARCHAR, just create a reference
				cast_chunk.data[col_idx].Reference(state->child_chunk.data[col_idx]);
			} else {
				// non varchar column, perform the cast
				VectorOperations::Cast(state->child_chunk.data[col_idx], cast_chunk.data[col_idx], sql_types[col_idx],
				                       SQLType::VARCHAR, cast_chunk.size());
			}
		}
		cast_chunk.Normalify();
		// now loop over the vectors and output the values
		for (idx_t i = 0; i < cast_chunk.size(); i++) {
			// write values
			for (idx_t col_idx = 0; col_idx < state->child_chunk.column_count(); col_idx++) {
				if (col_idx != 0) {
					writer.Write(info.delimiter);
				}
				if (FlatVector::IsNull(cast_chunk.data[col_idx], i)) {
					// write null value
					writer.Write(info.null_str);
					continue;
				}

				// non-null value, fetch the string value from the cast chunk
				auto str_data = FlatVector::GetData<string_t>(cast_chunk.data[col_idx]);
				auto str_value = str_data[i];
				WriteQuotedString(writer, str_value, info.delimiter, info.quote, info.escape, info.null_str,
				                  info.force_quote[col_idx]);
			}
			writer.Write(newline);
		}
		total += cast_chunk.size();
	}
	writer.Close();

	chunk.SetCardinality(1);
	chunk.SetValue(0, 0, Value::BIGINT(total));

	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/persistent/physical_delete.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class DataTable;

//! Physically delete data from a table
class PhysicalDelete : public PhysicalOperator {
public:
	PhysicalDelete(LogicalOperator &op, TableCatalogEntry &tableref, DataTable &table, idx_t row_id_index)
	    : PhysicalOperator(PhysicalOperatorType::DELETE, op.types), tableref(tableref), table(table),
	      row_id_index(row_id_index) {
	}

	TableCatalogEntry &tableref;
	DataTable &table;
	idx_t row_id_index;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

void PhysicalDelete::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	int64_t deleted_count = 0;
	while (true) {
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			break;
		}
		// delete data in the base table
		// the row ids are given to us as the last column of the child chunk
		table.Delete(tableref, context, state->child_chunk.data[row_id_index], state->child_chunk.size());
		deleted_count += state->child_chunk.size();
	}

	chunk.SetCardinality(1);
	chunk.SetValue(0, 0, Value::BIGINT(deleted_count));

	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/persistent/physical_insert.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Physically insert a set of data into a table
class PhysicalInsert : public PhysicalOperator {
public:
	PhysicalInsert(LogicalOperator &op, TableCatalogEntry *table, vector<idx_t> column_index_map,
	               vector<unique_ptr<Expression>> bound_defaults)
	    : PhysicalOperator(PhysicalOperatorType::INSERT, op.types), column_index_map(column_index_map), table(table),
	      bound_defaults(move(bound_defaults)) {
	}

	vector<idx_t> column_index_map;
	TableCatalogEntry *table;
	vector<unique_ptr<Expression>> bound_defaults;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb








using namespace duckdb;
using namespace std;

void PhysicalInsert::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {

	int64_t insert_count = 0;
	// create the chunk to insert from
	DataChunk insert_chunk;
	auto types = table->GetTypes();

	// initialize executor for bound default expressions
	ExpressionExecutor default_executor(bound_defaults);

	insert_chunk.Initialize(types);
	while (true) {
		// scan the children for chunks to insert
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			break;
		}
		auto &chunk = state->child_chunk;

		chunk.Normalify();
		default_executor.SetChunk(chunk);

		insert_chunk.Reset();
		insert_chunk.SetCardinality(chunk);
		if (column_index_map.size() > 0) {
			// columns specified by the user, use column_index_map
			for (idx_t i = 0; i < table->columns.size(); i++) {
				if (column_index_map[i] == INVALID_INDEX) {
					// insert default value
					default_executor.ExecuteExpression(i, insert_chunk.data[i]);
				} else {
					// get value from child chunk
					assert((idx_t)column_index_map[i] < chunk.column_count());
					assert(insert_chunk.data[i].type == chunk.data[column_index_map[i]].type);
					insert_chunk.data[i].Reference(chunk.data[column_index_map[i]]);
				}
			}
		} else {
			// no columns specified, just append directly
			for (idx_t i = 0; i < insert_chunk.column_count(); i++) {
				assert(insert_chunk.data[i].type == chunk.data[i].type);
				insert_chunk.data[i].Reference(chunk.data[i]);
			}
		}
		table->storage->Append(*table, context, insert_chunk);
		insert_count += chunk.size();
	}

	chunk.SetCardinality(1);
	chunk.SetValue(0, 0, Value::BIGINT(insert_count));

	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/persistent/physical_update.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class DataTable;

//! Physically update data in a table
class PhysicalUpdate : public PhysicalOperator {
public:
	PhysicalUpdate(LogicalOperator &op, TableCatalogEntry &tableref, DataTable &table, vector<column_t> columns,
	               vector<unique_ptr<Expression>> expressions, vector<unique_ptr<Expression>> bound_defaults)
	    : PhysicalOperator(PhysicalOperatorType::UPDATE, op.types), tableref(tableref), table(table), columns(columns),
	      expressions(move(expressions)), bound_defaults(move(bound_defaults)) {
	}

	TableCatalogEntry &tableref;
	DataTable &table;
	vector<column_t> columns;
	vector<unique_ptr<Expression>> expressions;
	vector<unique_ptr<Expression>> bound_defaults;
	bool is_index_update;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb








using namespace duckdb;
using namespace std;

void PhysicalUpdate::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	vector<TypeId> update_types;
	for (auto &expr : expressions) {
		update_types.push_back(expr->return_type);
	}
	DataChunk update_chunk;
	update_chunk.Initialize(update_types);

	// initialize states for bound default expressions
	ExpressionExecutor default_executor(bound_defaults);

	int64_t updated_count = 0;

	DataChunk mock_chunk;
	if (is_index_update) {
		mock_chunk.Initialize(table.types);
	}

	while (true) {
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			break;
		}
		state->child_chunk.Normalify();
		default_executor.SetChunk(state->child_chunk);

		// update data in the base table
		// the row ids are given to us as the last column of the child chunk
		auto &row_ids = state->child_chunk.data[state->child_chunk.column_count() - 1];
		update_chunk.SetCardinality(state->child_chunk);
		for (idx_t i = 0; i < expressions.size(); i++) {
			if (expressions[i]->type == ExpressionType::VALUE_DEFAULT) {
				// default expression, set to the default value of the column
				default_executor.ExecuteExpression(columns[i], update_chunk.data[i]);
			} else {
				assert(expressions[i]->type == ExpressionType::BOUND_REF);
				// index into child chunk
				auto &binding = (BoundReferenceExpression &)*expressions[i];
				update_chunk.data[i].Reference(state->child_chunk.data[binding.index]);
			}
		}

		if (is_index_update) {
			// index update, perform a delete and an append instead
			table.Delete(tableref, context, row_ids, update_chunk.size());
			mock_chunk.SetCardinality(update_chunk);
			for (idx_t i = 0; i < columns.size(); i++) {
				mock_chunk.data[columns[i]].Reference(update_chunk.data[i]);
			}
			table.Append(tableref, context, mock_chunk);
		} else {
			table.Update(tableref, context, row_ids, columns, update_chunk);
		}
		updated_count += state->child_chunk.size();
	}

	chunk.SetCardinality(1);
	chunk.SetValue(0, 0, Value::BIGINT(updated_count));

	state->finished = true;

	chunk.Verify();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/projection/physical_projection.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class PhysicalProjection : public PhysicalOperator {
public:
	PhysicalProjection(vector<TypeId> &types, vector<unique_ptr<Expression>> select_list)
	    : PhysicalOperator(PhysicalOperatorType::PROJECTION, types), select_list(move(select_list)) {
	}
	PhysicalProjection(LogicalOperator &op, vector<unique_ptr<Expression>> select_list)
	    : PhysicalProjection(op.types, move(select_list)) {
	}

	vector<unique_ptr<Expression>> select_list;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
	string ExtraRenderInformation() const override;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

class PhysicalProjectionState : public PhysicalOperatorState {
public:
	PhysicalProjectionState(PhysicalOperator *child, vector<unique_ptr<Expression>> &expressions)
	    : PhysicalOperatorState(child), executor(expressions) {
		assert(child);
	}

	ExpressionExecutor executor;
};

void PhysicalProjection::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalProjectionState *>(state_);

	// get the next chunk from the child
	children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
	if (state->child_chunk.size() == 0) {
		return;
	}

	state->executor.Execute(state->child_chunk, chunk);
}

unique_ptr<PhysicalOperatorState> PhysicalProjection::GetOperatorState() {
	return make_unique<PhysicalProjectionState>(children[0].get(), select_list);
}

string PhysicalProjection::ExtraRenderInformation() const {
	string extra_info;
	for (auto &expr : select_list) {
		extra_info += expr->GetName() + "\n";
	}
	return extra_info;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/aggregate/physical_window.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalWindow implements window functions
class PhysicalUnnest : public PhysicalOperator {
public:
	PhysicalUnnest(LogicalOperator &op, vector<unique_ptr<Expression>> select_list,
	               PhysicalOperatorType type = PhysicalOperatorType::UNNEST);

	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

	//! The projection list of the SELECT statement (that contains aggregates)
	vector<unique_ptr<Expression>> select_list;

public:
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_unnest_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a function call that has been bound to a base function
class BoundUnnestExpression : public Expression {
public:
	BoundUnnestExpression(SQLType return_type);

	unique_ptr<Expression> child;
	//! The child and return type
	SQLType sql_return_type;

public:
	bool IsFoldable() const override;
	string ToString() const override;

	hash_t Hash() const override;
	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

//! The operator state of the window
class PhysicalUnnestOperatorState : public PhysicalOperatorState {
public:
	PhysicalUnnestOperatorState(PhysicalOperator *child)
	    : PhysicalOperatorState(child), parent_position(0), list_position(0), list_length(-1) {
	}

	idx_t parent_position;
	idx_t list_position;
	int64_t list_length = -1;

	DataChunk list_data;
};

// this implements a sorted window functions variant
PhysicalUnnest::PhysicalUnnest(LogicalOperator &op, vector<unique_ptr<Expression>> select_list,
                               PhysicalOperatorType type)
    : PhysicalOperator(type, op.types), select_list(std::move(select_list)) {

	assert(this->select_list.size() > 0);
}

void PhysicalUnnest::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalUnnestOperatorState *>(state_);
	while (true) { // repeat until we actually have produced some rows
		if (state->child_chunk.size() == 0 || state->parent_position >= state->child_chunk.size()) {
			// get the child data
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			if (state->child_chunk.size() == 0) {
				return;
			}
			state->parent_position = 0;
			state->list_position = 0;
			state->list_length = -1;

			// get the list data to unnest
			ExpressionExecutor executor;
			vector<TypeId> list_data_types;
			for (auto &exp : select_list) {
				assert(exp->type == ExpressionType::BOUND_UNNEST);
				auto bue = (BoundUnnestExpression *)exp.get();
				list_data_types.push_back(bue->child->return_type);
				executor.AddExpression(*bue->child.get());
			}
			state->list_data.Destroy();
			state->list_data.Initialize(list_data_types);
			executor.Execute(state->child_chunk, state->list_data);

			// paranoia aplenty
			state->child_chunk.Verify();
			state->list_data.Verify();
			assert(state->child_chunk.size() == state->list_data.size());
			assert(state->list_data.column_count() == select_list.size());
		}

		// need to figure out how many times we need to repeat for current row
		if (state->list_length < 0) {
			for (idx_t col_idx = 0; col_idx < state->list_data.column_count(); col_idx++) {
				auto &v = state->list_data.data[col_idx];

				assert(v.type == TypeId::LIST);
				// TODO deal with NULL values here!
				auto list_data = FlatVector::GetData<list_entry_t>(v);
				auto list_entry = list_data[state->parent_position];
				if ((int64_t)list_entry.length > state->list_length) {
					state->list_length = list_entry.length;
				}
			}
		}

		assert(state->list_length >= 0);

		auto this_chunk_len = min((idx_t)STANDARD_VECTOR_SIZE, state->list_length - state->list_position);

		// first cols are from child, last n cols from unnest
		chunk.SetCardinality(this_chunk_len);

		for (idx_t col_idx = 0; col_idx < state->child_chunk.column_count(); col_idx++) {
			auto val = state->child_chunk.data[col_idx].GetValue(state->parent_position);
			chunk.data[col_idx].Reference(val);
		}

		// FIXME do not use GetValue/SetValue here
		// TODO now that list entries are chunk collections, simply scan them!
		for (idx_t col_idx = 0; col_idx < state->list_data.column_count(); col_idx++) {
			auto target_col = col_idx + state->child_chunk.column_count();
			auto &v = state->list_data.data[col_idx];
			auto list_data = FlatVector::GetData<list_entry_t>(v);
			auto list_entry = list_data[state->parent_position];
			auto &child_cc = ListVector::GetEntry(v);

			idx_t i = 0;
			if (list_entry.length > state->list_position) {
				for (i = 0; i < min((idx_t)this_chunk_len, list_entry.length - state->list_position); i++) {
					chunk.data[target_col].SetValue(i,
					                                child_cc.GetValue(0, list_entry.offset + i + state->list_position));
				}
			}
			for (; i < (idx_t)this_chunk_len; i++) {
				chunk.data[target_col].SetValue(i, Value());
			}
		}

		state->list_position += this_chunk_len;
		if ((int64_t)state->list_position == state->list_length) {
			state->parent_position++;
			state->list_length = -1;
			state->list_position = 0;
		}

		chunk.Verify();
		if (chunk.size() > 0) {
			return;
		}
	}
}

unique_ptr<PhysicalOperatorState> PhysicalUnnest::GetOperatorState() {
	return make_unique<PhysicalUnnestOperatorState>(children[0].get());
}


using namespace duckdb;
using namespace std;

class PhysicalChunkScanState : public PhysicalOperatorState {
public:
	PhysicalChunkScanState() : PhysicalOperatorState(nullptr), chunk_index(0) {
	}

	//! The current position in the scan
	idx_t chunk_index;
};

void PhysicalChunkScan::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = (PhysicalChunkScanState *)state_;
	assert(collection);
	if (collection->count == 0) {
		return;
	}
	assert(chunk.GetTypes() == collection->types);
	if (state->chunk_index >= collection->chunks.size()) {
		return;
	}
	auto &collection_chunk = *collection->chunks[state->chunk_index];
	chunk.Reference(collection_chunk);
	state->chunk_index++;
}

unique_ptr<PhysicalOperatorState> PhysicalChunkScan::GetOperatorState() {
	return make_unique<PhysicalChunkScanState>();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_dummy_scan.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class PhysicalDummyScan : public PhysicalOperator {
public:
	PhysicalDummyScan(vector<TypeId> types) : PhysicalOperator(PhysicalOperatorType::DUMMY_SCAN, types) {
	}

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

void PhysicalDummyScan::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	state->finished = true;
	// return a single row on the first call to the dummy scan
	chunk.SetCardinality(1);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_empty_result.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class PhysicalEmptyResult : public PhysicalOperator {
public:
	PhysicalEmptyResult(vector<TypeId> types) : PhysicalOperator(PhysicalOperatorType::EMPTY_RESULT, types) {
	}

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

void PhysicalEmptyResult::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_expression_scan.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! The PhysicalExpressionScan scans a set of expressions
class PhysicalExpressionScan : public PhysicalOperator {
public:
	PhysicalExpressionScan(vector<TypeId> types, vector<vector<unique_ptr<Expression>>> expressions)
	    : PhysicalOperator(PhysicalOperatorType::EXPRESSION_SCAN, types), expressions(move(expressions)) {
	}

	//! The set of expressions to scan
	vector<vector<unique_ptr<Expression>>> expressions;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

class PhysicalExpressionScanState : public PhysicalOperatorState {
public:
	PhysicalExpressionScanState(PhysicalOperator *child) : PhysicalOperatorState(child), expression_index(0) {
	}

	//! The current position in the scan
	idx_t expression_index;

	unique_ptr<ExpressionExecutor> executor;
};

void PhysicalExpressionScan::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = (PhysicalExpressionScanState *)state_;
	if (state->expression_index >= expressions.size()) {
		// finished executing all expression lists
		return;
	}

	if (state->expression_index == 0) {
		// first run, fetch the chunk from the child
		assert(children.size() == 1);
		children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
		if (state->child_chunk.size() == 0) {
			return;
		}
	}
	// now execute the expressions of the nth expression list for the child chunk list
	state->executor = make_unique<ExpressionExecutor>(expressions[state->expression_index]);
	state->executor->Execute(state->child_chunk, chunk);

	state->expression_index++;
}

unique_ptr<PhysicalOperatorState> PhysicalExpressionScan::GetOperatorState() {
	return make_unique<PhysicalExpressionScanState>(children[0].get());
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_index_scan.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a scan of an index
class PhysicalIndexScan : public PhysicalOperator {
public:
	PhysicalIndexScan(LogicalOperator &op, TableCatalogEntry &tableref, DataTable &table, Index &index,
	                  vector<column_t> column_ids)
	    : PhysicalOperator(PhysicalOperatorType::INDEX_SCAN, op.types), tableref(tableref), table(table), index(index),
	      column_ids(column_ids) {
	}

	//! The table to scan
	TableCatalogEntry &tableref;
	//! The physical data table to scan
	DataTable &table;
	//! The index to use for the scan
	Index &index;
	//! The column ids to project
	vector<column_t> column_ids;

	//! The value for the query predicate
	Value low_value;
	Value high_value;
	Value equal_value;

	//! If the predicate is low, high or equal
	bool low_index = false;
	bool high_index = false;
	bool equal_index = false;

	//! The expression type (e.g., >, <, >=, <=)
	ExpressionType low_expression_type;
	ExpressionType high_expression_type;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	string ExtraRenderInformation() const override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

class PhysicalIndexScanOperatorState : public PhysicalOperatorState {
public:
	PhysicalIndexScanOperatorState() : PhysicalOperatorState(nullptr), initialized(false) {
	}

	bool initialized;
	TableIndexScanState scan_state;
};

void PhysicalIndexScan::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalIndexScanOperatorState *>(state_);
	if (column_ids.size() == 0) {
		return;
	}

	auto &transaction = Transaction::GetTransaction(context);
	if (!state->initialized) {
		// initialize the scan state of the index
		if (low_index && high_index) {
			// two predicates
			table.InitializeIndexScan(transaction, state->scan_state, index, low_value, low_expression_type, high_value,
			                          high_expression_type, column_ids);
		} else {
			// single predicate
			Value value;
			ExpressionType type;
			if (low_index) {
				// > or >=
				value = low_value;
				type = low_expression_type;
			} else if (high_index) {
				// < or <=
				value = high_value;
				type = high_expression_type;
			} else {
				// equality
				assert(equal_index);
				value = equal_value;
				type = ExpressionType::COMPARE_EQUAL;
			}
			table.InitializeIndexScan(transaction, state->scan_state, index, value, type, column_ids);
		}
		state->initialized = true;
	}
	// scan the index
	table.IndexScan(transaction, chunk, state->scan_state);
}

string PhysicalIndexScan::ExtraRenderInformation() const {
	return tableref.name + "[" + low_value.ToString() + "]";
}

unique_ptr<PhysicalOperatorState> PhysicalIndexScan::GetOperatorState() {
	return make_unique<PhysicalIndexScanOperatorState>();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_table_function.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a scan of a base table
class PhysicalTableFunction : public PhysicalOperator {
public:
	PhysicalTableFunction(vector<TypeId> types, TableFunctionCatalogEntry *function, unique_ptr<FunctionData> bind_data,
	                      vector<Value> parameters)
	    : PhysicalOperator(PhysicalOperatorType::TABLE_FUNCTION, types), function(function), bind_data(move(bind_data)),
	      parameters(move(parameters)) {
	}

	//! Function to call
	TableFunctionCatalogEntry *function;
	//! The bind data
	unique_ptr<FunctionData> bind_data;
	//! Parameters
	vector<Value> parameters;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb







using namespace duckdb;
using namespace std;

void PhysicalTableFunction::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	// run main code
	function->function.function(context, parameters, chunk, bind_data.get());
	if (chunk.size() == 0) {
		// finished, call clean up
		if (function->function.final) {
			function->function.final(context, bind_data.get());
		}
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/scan/physical_table_scan.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! Represents a scan of a base table
class PhysicalTableScan : public PhysicalOperator {
public:
	PhysicalTableScan(LogicalOperator &op, TableCatalogEntry &tableref, DataTable &table, vector<column_t> column_ids,
	                  vector<unique_ptr<Expression>> filter, vector<TableFilter> tableFilters);

	//! The table to scan
	TableCatalogEntry &tableref;
	//! The physical data table to scan
	DataTable &table;
	//! The column ids to project
	vector<column_t> column_ids;

	//! The filter expression
	unique_ptr<Expression> expression;
	//! Filters pushed down to table scan
	vector<TableFilter> table_filters;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	string ExtraRenderInformation() const override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

} // namespace duckdb






using namespace duckdb;
using namespace std;

class PhysicalTableScanOperatorState : public PhysicalOperatorState {
public:
	PhysicalTableScanOperatorState(Expression &expr)
	    : PhysicalOperatorState(nullptr), initialized(false), executor(expr) {
	}
	PhysicalTableScanOperatorState() : PhysicalOperatorState(nullptr), initialized(false) {
	}
	//! Whether or not the scan has been initialized
	bool initialized;
	//! The current position in the scan
	TableScanState scan_offset;
	//! Execute filters inside the table
	ExpressionExecutor executor;
};

PhysicalTableScan::PhysicalTableScan(LogicalOperator &op, TableCatalogEntry &tableref, DataTable &table,
                                     vector<column_t> column_ids, vector<unique_ptr<Expression>> filter,
                                     vector<TableFilter> tableFilters)
    : PhysicalOperator(PhysicalOperatorType::SEQ_SCAN, op.types), tableref(tableref), table(table),
      column_ids(column_ids), table_filters(tableFilters) {
	if (filter.size() > 1) {
		//! create a big AND out of the expressions
		auto conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_AND);
		for (auto &expr : filter) {
			conjunction->children.push_back(move(expr));
		}
		expression = move(conjunction);
	} else if (filter.size() == 1) {
		expression = move(filter[0]);
	}
}
void PhysicalTableScan::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalTableScanOperatorState *>(state_);

	if (column_ids.size() == 0) {
		return;
	}
	auto &transaction = Transaction::GetTransaction(context);
	if (!state->initialized) {
		table.InitializeScan(transaction, state->scan_offset, column_ids);
		state->initialized = true;
	}
	//! Get max value
	idx_t result_count = -1;
	do {
		chunk.Reset();
		table.Scan(transaction, chunk, state->scan_offset, table_filters);
		if (expression) {
			SelectionVector sel(STANDARD_VECTOR_SIZE);
			idx_t initial_count = chunk.size();
			result_count = state->executor.SelectExpression(chunk, sel);
			if (result_count == initial_count) {
				//! Nothing was filtered: skip adding any selection vectors
				return;
			}
			chunk.Slice(sel, result_count);
		}
	} while (result_count == 0);
}

string PhysicalTableScan::ExtraRenderInformation() const {
	return tableref.name;
}

unique_ptr<PhysicalOperatorState> PhysicalTableScan::GetOperatorState() {
	if (expression) {
		return make_unique<PhysicalTableScanOperatorState>(*expression);
	} else {
		return make_unique<PhysicalTableScanOperatorState>();
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_alter.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalAlter represents an ALTER TABLE command
class PhysicalAlter : public PhysicalOperator {
public:
	PhysicalAlter(unique_ptr<AlterInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::ALTER, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<AlterInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalAlter::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	context.catalog.AlterTable(context, (AlterTableInfo *)info.get());
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_create_index.hpp
//
//
//===----------------------------------------------------------------------===//









#include <fstream>

namespace duckdb {

//! Physically CREATE INDEX statement
class PhysicalCreateIndex : public PhysicalOperator {
public:
	PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry &table, vector<column_t> column_ids,
	                    vector<unique_ptr<Expression>> expressions, unique_ptr<CreateIndexInfo> info,
	                    vector<unique_ptr<Expression>> unbinded_expressions)
	    : PhysicalOperator(PhysicalOperatorType::CREATE_INDEX, op.types), table(table), column_ids(column_ids),
	      expressions(move(expressions)), info(std::move(info)), unbound_expressions(move(unbinded_expressions)) {
	}

	//! The table to create the index for
	TableCatalogEntry &table;
	//! The list of column IDs required for the index
	vector<column_t> column_ids;
	//! Set of expressions to index by
	vector<unique_ptr<Expression>> expressions;
	//! Info for index creation
	unique_ptr<CreateIndexInfo> info;
	//! Unbinded expressions to be used in the optimizer
	vector<unique_ptr<Expression>> unbound_expressions;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;

private:
	void CreateARTIndex();
};
} // namespace duckdb






using namespace duckdb;
using namespace std;

void PhysicalCreateIndex::CreateARTIndex() {
	auto art = make_unique<ART>(*table.storage, column_ids, move(unbound_expressions), info->unique);

	table.storage->AddIndex(move(art), expressions);
}

void PhysicalCreateIndex::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	if (column_ids.size() == 0) {
		throw NotImplementedException("CREATE INDEX does not refer to any columns in the base table!");
	}

	auto &schema = *table.schema;
	if (!schema.CreateIndex(context, info.get())) {
		// index already exists, but error ignored because of CREATE ... IF NOT
		// EXISTS
		return;
	}

	// create the chunk to hold intermediate expression results

	switch (info->index_type) {
	case IndexType::ART: {
		CreateARTIndex();
		break;
	}
	default:
		assert(0);
		throw NotImplementedException("Unimplemented index type");
	}

	chunk.SetCardinality(0);

	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_create_schema.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalCreateSchema represents a CREATE SCHEMA command
class PhysicalCreateSchema : public PhysicalOperator {
public:
	PhysicalCreateSchema(unique_ptr<CreateSchemaInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::CREATE_SCHEMA, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<CreateSchemaInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalCreateSchema::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	Catalog::GetCatalog(context).CreateSchema(context, info.get());
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_create_sequence.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalCreateSequence represents a CREATE SEQUENCE command
class PhysicalCreateSequence : public PhysicalOperator {
public:
	PhysicalCreateSequence(unique_ptr<CreateSequenceInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::CREATE_SEQUENCE, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<CreateSequenceInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalCreateSequence::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	Catalog::GetCatalog(context).CreateSequence(context, info.get());
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_create_table.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! Physically CREATE TABLE statement
class PhysicalCreateTable : public PhysicalOperator {
public:
	PhysicalCreateTable(LogicalOperator &op, SchemaCatalogEntry *schema, unique_ptr<BoundCreateTableInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::CREATE, op.types), schema(schema), info(move(info)) {
	}

	//! Schema to insert to
	SchemaCatalogEntry *schema;
	//! Table name to create
	unique_ptr<BoundCreateTableInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};
} // namespace duckdb







using namespace duckdb;
using namespace std;

void PhysicalCreateTable::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	int64_t inserted_count = 0;

	auto table = (TableCatalogEntry *)schema->CreateTable(context, info.get());
	if (table && children.size() > 0) {
		while (true) {
			children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
			if (state->child_chunk.size() == 0) {
				break;
			}
			inserted_count += state->child_chunk.size();
			table->storage->Append(*table, context, state->child_chunk);
		}
		chunk.SetCardinality(1);
		chunk.SetValue(0, 0, Value::BIGINT(inserted_count));
	}

	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_create_view.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalCreateView represents a CREATE VIEW command
class PhysicalCreateView : public PhysicalOperator {
public:
	PhysicalCreateView(unique_ptr<CreateViewInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::CREATE_VIEW, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<CreateViewInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalCreateView::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	Catalog::GetCatalog(context).CreateView(context, info.get());
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/schema/physical_drop.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! PhysicalDrop represents a DROP [...] command
class PhysicalDrop : public PhysicalOperator {
public:
	PhysicalDrop(unique_ptr<DropInfo> info)
	    : PhysicalOperator(PhysicalOperatorType::DROP, {TypeId::BOOL}), info(move(info)) {
	}

	unique_ptr<DropInfo> info;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

void PhysicalDrop::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	switch (info->type) {
	case CatalogType::PREPARED_STATEMENT:
		if (!context.prepared_statements->DropEntry(context.ActiveTransaction(), info->name, false)) {
			// silently ignore
		}
		break;
	default:
		Catalog::GetCatalog(context).DropEntry(context, info.get());
		break;
	}
	state->finished = true;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/set/physical_recursive_cte.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class PhysicalRecursiveCTE : public PhysicalOperator {
public:
	PhysicalRecursiveCTE(LogicalOperator &op, bool union_all, unique_ptr<PhysicalOperator> top,
	                     unique_ptr<PhysicalOperator> bottom);

	bool union_all;
	std::shared_ptr<ChunkCollection> working_table;
	ChunkCollection intermediate_table;

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;

private:
	//! Probe Hash Table and eliminate duplicate rows
	idx_t ProbeHT(DataChunk &chunk, PhysicalOperatorState *state);
};

}; // namespace duckdb







using namespace duckdb;
using namespace std;

class PhysicalRecursiveCTEState : public PhysicalOperatorState {
public:
	PhysicalRecursiveCTEState() : PhysicalOperatorState(nullptr), top_done(false) {
	}
	unique_ptr<PhysicalOperatorState> top_state;
	unique_ptr<PhysicalOperatorState> bottom_state;
	unique_ptr<SuperLargeHashTable> ht;

	bool top_done = false;

	bool recursing = false;
	bool intermediate_empty = true;
};

PhysicalRecursiveCTE::PhysicalRecursiveCTE(LogicalOperator &op, bool union_all, unique_ptr<PhysicalOperator> top,
                                           unique_ptr<PhysicalOperator> bottom)
    : PhysicalOperator(PhysicalOperatorType::RECURSIVE_CTE, op.types), union_all(union_all) {
	children.push_back(move(top));
	children.push_back(move(bottom));
}

// first exhaust non recursive term, then exhaust recursive term iteratively until no (new) rows are generated.
void PhysicalRecursiveCTE::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalRecursiveCTEState *>(state_);

	if (!state->recursing) {
		do {
			children[0]->GetChunk(context, chunk, state->top_state.get());
			if (!union_all) {
				idx_t match_count = ProbeHT(chunk, state);
				if (match_count > 0) {
					working_table->Append(chunk);
				}
			} else {
				working_table->Append(chunk);
			}

			if (chunk.size() != 0)
				return;
		} while (chunk.size() != 0);
		state->recursing = true;
	}

	while (true) {
		children[1]->GetChunk(context, chunk, state->bottom_state.get());

		if (chunk.size() == 0) {
			// Done if there is nothing in the intermediate table
			if (state->intermediate_empty) {
				state->finished = true;
				break;
			}

			working_table->count = 0;
			working_table->chunks.clear();

			working_table->count = intermediate_table.count;
			working_table->chunks = move(intermediate_table.chunks);

			intermediate_table.count = 0;
			intermediate_table.chunks.clear();

			state->bottom_state = children[1]->GetOperatorState();

			state->intermediate_empty = true;
			continue;
		}

		if (!union_all) {
			// If we evaluate using UNION semantics, we have to eliminate duplicates before appending them to
			// intermediate tables.
			idx_t match_count = ProbeHT(chunk, state);
			if (match_count > 0) {
				intermediate_table.Append(chunk);
				state->intermediate_empty = false;
			}
		} else {
			intermediate_table.Append(chunk);
			state->intermediate_empty = false;
		}

		return;
	}
}

idx_t PhysicalRecursiveCTE::ProbeHT(DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalRecursiveCTEState *>(state_);

	Vector dummy_addresses(TypeId::POINTER);

	// Use the HT to eliminate duplicate rows
	SelectionVector new_groups(STANDARD_VECTOR_SIZE);
	idx_t new_group_count = state->ht->FindOrCreateGroups(chunk, dummy_addresses, new_groups);

	// we only return entries we have not seen before (i.e. new groups)
	chunk.Slice(new_groups, new_group_count);

	return new_group_count;
}

unique_ptr<PhysicalOperatorState> PhysicalRecursiveCTE::GetOperatorState() {
	auto state = make_unique<PhysicalRecursiveCTEState>();
	state->top_state = children[0]->GetOperatorState();
	state->bottom_state = children[1]->GetOperatorState();
	state->ht = make_unique<SuperLargeHashTable>(1024, types, vector<TypeId>(), vector<BoundAggregateExpression *>());
	return (move(state));
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/operator/set/physical_union.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class PhysicalUnion : public PhysicalOperator {
public:
	PhysicalUnion(LogicalOperator &op, unique_ptr<PhysicalOperator> top, unique_ptr<PhysicalOperator> bottom);

public:
	void GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) override;
	unique_ptr<PhysicalOperatorState> GetOperatorState() override;
};

}; // namespace duckdb




using namespace duckdb;
using namespace std;

class PhysicalUnionOperatorState : public PhysicalOperatorState {
public:
	PhysicalUnionOperatorState() : PhysicalOperatorState(nullptr), top_done(false) {
	}
	unique_ptr<PhysicalOperatorState> top_state;
	unique_ptr<PhysicalOperatorState> bottom_state;
	bool top_done = false;
};

PhysicalUnion::PhysicalUnion(LogicalOperator &op, unique_ptr<PhysicalOperator> top, unique_ptr<PhysicalOperator> bottom)
    : PhysicalOperator(PhysicalOperatorType::UNION, op.types) {
	children.push_back(move(top));
	children.push_back(move(bottom));
}

// first exhaust top, then exhaust bottom. state to remember which.
void PhysicalUnion::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
	auto state = reinterpret_cast<PhysicalUnionOperatorState *>(state_);
	if (!state->top_done) {
		children[0]->GetChunk(context, chunk, state->top_state.get());
		if (chunk.size() == 0) {
			state->top_done = true;
		}
	}
	if (state->top_done) {
		children[1]->GetChunk(context, chunk, state->bottom_state.get());
	}
	if (chunk.size() == 0) {
		state->finished = true;
	}
}

unique_ptr<PhysicalOperatorState> PhysicalUnion::GetOperatorState() {
	auto state = make_unique<PhysicalUnionOperatorState>();
	state->top_state = children[0]->GetOperatorState();
	state->bottom_state = children[1]->GetOperatorState();
	return (move(state));
}





using namespace duckdb;
using namespace std;

string PhysicalOperator::ToString(idx_t depth) const {
	string extra_info = StringUtil::Replace(ExtraRenderInformation(), "\n", " ");
	StringUtil::RTrim(extra_info);
	if (!extra_info.empty()) {
		extra_info = "[" + extra_info + "]";
	}
	string result = PhysicalOperatorToString(type) + extra_info;
	if (children.size() > 0) {
		for (idx_t i = 0; i < children.size(); i++) {
			result += "\n" + string(depth * 4, ' ');
			auto &child = children[i];
			result += child->ToString(depth + 1);
		}
		result += "";
	}
	return result;
}

PhysicalOperatorState::PhysicalOperatorState(PhysicalOperator *child) : finished(false) {
	if (child) {
		child->InitializeChunk(child_chunk);
		child_state = child->GetOperatorState();
	}
}

void PhysicalOperator::GetChunk(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
	if (context.interrupted) {
		throw InterruptException();
	}

	chunk.Reset();
	if (state->finished) {
		return;
	}

	context.profiler.StartOperator(this);
	GetChunkInternal(context, chunk, state);
	context.profiler.EndOperator(chunk);

	chunk.Verify();
}

void PhysicalOperator::Print() {
	Printer::Print(ToString());
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/execution/physical_plan_generator.hpp
//
//
//===----------------------------------------------------------------------===//









namespace duckdb {
class ClientContext;

//! The physical plan generator generates a physical execution plan from a
//! logical query plan
class PhysicalPlanGenerator {
public:
	PhysicalPlanGenerator(ClientContext &context) : context(context) {
	}

	unordered_set<CatalogEntry *> dependencies;
	//! Recursive CTEs require at least one ChunkScan, referencing the working_table.
	//! This data structure is used to establish it.
	unordered_map<idx_t, std::shared_ptr<ChunkCollection>> rec_ctes;

public:
	//! Creates a plan from the logical operator. This involves resolving column bindings and generating physical
	//! operator nodes.
	unique_ptr<PhysicalOperator> CreatePlan(unique_ptr<LogicalOperator> logical);

protected:
	unique_ptr<PhysicalOperator> CreatePlan(LogicalOperator &op);

	unique_ptr<PhysicalOperator> CreatePlan(LogicalAggregate &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalAnyJoin &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalChunkGet &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalComparisonJoin &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCreate &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCreateTable &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCreateIndex &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCrossProduct &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalDelete &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalDelimGet &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalDelimJoin &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalDistinct &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalEmptyResult &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalExpressionGet &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalFilter &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalGet &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalLimit &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalIndexScan &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalOrder &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalTopN &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalProjection &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalInsert &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCopyFromFile &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCopyToFile &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalExplain &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalSetOperation &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalUpdate &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalTableFunction &expr);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalPruneColumns &expr);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalPrepare &expr);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalWindow &expr);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalExecute &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalSimple &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalUnnest &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalRecursiveCTE &op);
	unique_ptr<PhysicalOperator> CreatePlan(LogicalCTERef &op);

	unique_ptr<PhysicalOperator> CreateDistinct(unique_ptr<PhysicalOperator> child);
	unique_ptr<PhysicalOperator> CreateDistinctOn(unique_ptr<PhysicalOperator> child,
	                                              vector<unique_ptr<Expression>> distinct_targets);

private:
	ClientContext &context;
};
} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_aggregate.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalAggregate represents an aggregate operation with (optional) GROUP BY
//! operator.
class LogicalAggregate : public LogicalOperator {
public:
	LogicalAggregate(idx_t group_index, idx_t aggregate_index, vector<unique_ptr<Expression>> select_list);

	//! The table index for the groups of the LogicalAggregate
	idx_t group_index;
	//! The table index for the aggregates of the LogicalAggregate
	idx_t aggregate_index;
	//! The set of groups (optional).
	vector<unique_ptr<Expression>> groups;

public:
	string ParamsToString() const override;

	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalAggregate &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);
	if (op.groups.size() == 0) {
		// no groups, check if we can use a simple aggregation
		// special case: aggregate entire columns together
		bool use_simple_aggregation = true;
		for (idx_t i = 0; i < op.expressions.size(); i++) {
			auto &aggregate = (BoundAggregateExpression &)*op.expressions[i];
			if (!aggregate.function.simple_update || aggregate.distinct) {
				// unsupported aggregate for simple aggregation: use hash aggregation
				use_simple_aggregation = false;
				break;
			}
		}
		if (use_simple_aggregation) {
			auto groupby = make_unique<PhysicalSimpleAggregate>(op.types, move(op.expressions));
			groupby->children.push_back(move(plan));
			return move(groupby);
		} else {
			auto groupby = make_unique<PhysicalHashAggregate>(op.types, move(op.expressions));
			groupby->children.push_back(move(plan));
			return move(groupby);
		}
	} else {
		// groups! create a GROUP BY aggregator
		auto groupby = make_unique<PhysicalHashAggregate>(op.types, move(op.expressions), move(op.groups));
		groupby->children.push_back(move(plan));
		return move(groupby);
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_any_join.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalAnyJoin represents a join with an arbitrary expression as JoinCondition
class LogicalAnyJoin : public LogicalJoin {
public:
	LogicalAnyJoin(JoinType type);

	//! The JoinCondition on which this join is performed
	unique_ptr<Expression> condition;

public:
	string ParamsToString() const override;
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalAnyJoin &op) {
	// first visit the child nodes
	assert(op.children.size() == 2);
	assert(op.condition);

	auto left = CreatePlan(*op.children[0]);
	auto right = CreatePlan(*op.children[1]);

	// create the blockwise NL join
	return make_unique<PhysicalBlockwiseNLJoin>(op, move(left), move(right), move(op.condition), op.join_type);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_chunk_get.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalChunkGet represents a scan operation from a ChunkCollection
class LogicalChunkGet : public LogicalOperator {
public:
	LogicalChunkGet(idx_t table_index, vector<TypeId> types, unique_ptr<ChunkCollection> collection)
	    : LogicalOperator(LogicalOperatorType::CHUNK_GET), table_index(table_index), collection(move(collection)) {
		assert(types.size() > 0);
		chunk_types = types;
	}

	//! The table index in the current bind context
	idx_t table_index;
	//! The types of the chunk
	vector<TypeId> chunk_types;
	//! The chunk collection to scan
	unique_ptr<ChunkCollection> collection;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, chunk_types.size());
	}

protected:
	void ResolveTypes() override {
		// types are resolved in the constructor
		this->types = chunk_types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalChunkGet &op) {
	assert(op.children.size() == 0);
	assert(op.collection);

	// create a PhysicalChunkScan pointing towards the owned collection
	auto chunk_scan = make_unique<PhysicalChunkScan>(op.types, PhysicalOperatorType::CHUNK_SCAN);
	chunk_scan->owned_collection = move(op.collection);
	chunk_scan->collection = chunk_scan->owned_collection.get();
	return move(chunk_scan);
}







using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalComparisonJoin &op) {
	// now visit the children
	assert(op.children.size() == 2);

	auto left = CreatePlan(*op.children[0]);
	auto right = CreatePlan(*op.children[1]);
	assert(left && right);

	if (op.conditions.size() == 0) {
		// no conditions: insert a cross product
		return make_unique<PhysicalCrossProduct>(op, move(left), move(right));
	}

	bool has_equality = false;
	bool has_inequality = false;
	bool has_null_equal_conditions = false;
	for (auto &cond : op.conditions) {
		if (cond.comparison == ExpressionType::COMPARE_EQUAL) {
			has_equality = true;
		}
		if (cond.comparison == ExpressionType::COMPARE_NOTEQUAL) {
			has_inequality = true;
		}
		if (cond.null_values_are_equal) {
			has_null_equal_conditions = true;
			assert(cond.comparison == ExpressionType::COMPARE_EQUAL);
		}
	}
	unique_ptr<PhysicalOperator> plan;
	if (has_equality) {
		// equality join: use hash join
		plan = make_unique<PhysicalHashJoin>(context, op, move(left), move(right), move(op.conditions), op.join_type,
		                                     op.left_projection_map, op.right_projection_map);
	} else {
		assert(!has_null_equal_conditions); // don't support this for anything but hash joins for now
		if (op.conditions.size() == 1 && (op.join_type == JoinType::MARK || op.join_type == JoinType::INNER) &&
		    !has_inequality) {
			// range join: use piecewise merge join
			plan =
			    make_unique<PhysicalPiecewiseMergeJoin>(op, move(left), move(right), move(op.conditions), op.join_type);
		} else {
			// inequality join: use nested loop
			plan = make_unique<PhysicalNestedLoopJoin>(op, move(left), move(right), move(op.conditions), op.join_type);
		}
	}
	return plan;
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_copy_from_file.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class LogicalCopyFromFile : public LogicalOperator {
public:
	LogicalCopyFromFile(idx_t table_index, unique_ptr<CopyInfo> info, vector<SQLType> sql_types)
	    : LogicalOperator(LogicalOperatorType::COPY_FROM_FILE), table_index(table_index), info(move(info)),
	      sql_types(sql_types) {
	}

	idx_t table_index;
	unique_ptr<CopyInfo> info;
	vector<SQLType> sql_types;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, sql_types.size());
	}

protected:
	void ResolveTypes() override {
		for (auto &type : sql_types) {
			types.push_back(GetInternalType(type));
		}
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCopyFromFile &op) {
	// COPY from file into a table
	return make_unique<PhysicalCopyFromFile>(op, op.sql_types, move(op.info));
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_copy_to_file.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class LogicalCopyToFile : public LogicalOperator {
public:
	LogicalCopyToFile(unique_ptr<CopyInfo> info)
	    : LogicalOperator(LogicalOperatorType::COPY_TO_FILE), info(move(info)) {
	}

	unique_ptr<CopyInfo> info;
	vector<string> names;
	vector<SQLType> sql_types;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::INT64);
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCopyToFile &op) {
	auto plan = CreatePlan(*op.children[0]);
	// COPY from select statement to file
	auto copy = make_unique<PhysicalCopyToFile>(op, move(op.info));
	copy->names = op.names;
	copy->sql_types = op.sql_types;

	copy->children.push_back(move(plan));
	return move(copy);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_create.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalCreate represents a CREATE operator
class LogicalCreate : public LogicalOperator {
public:
	LogicalCreate(LogicalOperatorType type, unique_ptr<BoundCreateInfo> info)
	    : LogicalOperator(type), info(move(info)) {
	}

	unique_ptr<BoundCreateInfo> info;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::BOOL);
	}
};
} // namespace duckdb






namespace duckdb {

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreate &op) {
	switch (op.type) {
	case LogicalOperatorType::CREATE_SEQUENCE:
		return make_unique<PhysicalCreateSequence>(unique_ptr_cast<ParseInfo, CreateSequenceInfo>(move(op.info->base)));
	case LogicalOperatorType::CREATE_VIEW:
		return make_unique<PhysicalCreateView>(unique_ptr_cast<ParseInfo, CreateViewInfo>(move(op.info->base)));
	case LogicalOperatorType::CREATE_SCHEMA:
		return make_unique<PhysicalCreateSchema>(unique_ptr_cast<ParseInfo, CreateSchemaInfo>(move(op.info->base)));
	default:
		throw NotImplementedException("Unimplemented type for logical simple create");
	}
}

} // namespace duckdb





using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateIndex &op) {
	assert(op.children.size() == 0);
	dependencies.insert(&op.table);
	return make_unique<PhysicalCreateIndex>(op, op.table, op.column_ids, move(op.expressions), move(op.info),
	                                        move(op.unbound_expressions));
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_iterator.hpp
//
//
//===----------------------------------------------------------------------===//






#include <functional>

namespace duckdb {
class BoundQueryNode;
class BoundTableRef;

class ExpressionIterator {
public:
	static void EnumerateChildren(const Expression &expression, std::function<void(const Expression &child)> callback);
	static void EnumerateChildren(Expression &expression, std::function<void(Expression &child)> callback);
	static void EnumerateChildren(Expression &expression,
	                              std::function<unique_ptr<Expression>(unique_ptr<Expression> child)> callback);

	static void EnumerateExpression(unique_ptr<Expression> &expr, std::function<void(Expression &child)> callback);

	static void EnumerateTableRefChildren(BoundTableRef &ref, std::function<void(Expression &child)> callback);
	static void EnumerateQueryNodeChildren(BoundQueryNode &node, std::function<void(Expression &child)> callback);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_create_table.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class LogicalCreateTable : public LogicalOperator {
public:
	LogicalCreateTable(SchemaCatalogEntry *schema, unique_ptr<BoundCreateTableInfo> info)
	    : LogicalOperator(LogicalOperatorType::CREATE_TABLE), schema(schema), info(move(info)) {
	}

	//! Schema to insert to
	SchemaCatalogEntry *schema;
	//! Create Table information
	unique_ptr<BoundCreateTableInfo> info;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::INT64);
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

static void ExtractDependencies(Expression &expr, unordered_set<CatalogEntry *> &dependencies) {
	if (expr.type == ExpressionType::BOUND_FUNCTION) {
		auto &function = (BoundFunctionExpression &)expr;
		if (function.function.dependency) {
			function.function.dependency(function, dependencies);
		}
	}
	ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { ExtractDependencies(child, dependencies); });
}

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateTable &op) {
	// extract dependencies from any default values
	for (auto &default_value : op.info->bound_defaults) {
		if (default_value) {
			ExtractDependencies(*default_value, op.info->dependencies);
		}
	}
	auto create = make_unique<PhysicalCreateTable>(op, op.schema, move(op.info));
	if (op.children.size() > 0) {
		assert(op.children.size() == 1);
		auto plan = CreatePlan(*op.children[0]);
		create->children.push_back(move(plan));
	}
	return move(create);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_cross_product.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalCrossProduct represents a cross product between two relations
class LogicalCrossProduct : public LogicalOperator {
public:
	LogicalCrossProduct();

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCrossProduct &op) {
	assert(op.children.size() == 2);

	auto left = CreatePlan(*op.children[0]);
	auto right = CreatePlan(*op.children[1]);
	return make_unique<PhysicalCrossProduct>(op, move(left), move(right));
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_delete.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class LogicalDelete : public LogicalOperator {
public:
	LogicalDelete(TableCatalogEntry *table) : LogicalOperator(LogicalOperatorType::DELETE), table(table) {
	}

	TableCatalogEntry *table;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::INT64);
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalDelete &op) {
	assert(op.children.size() == 1);
	assert(op.expressions.size() == 1);
	assert(op.expressions[0]->type == ExpressionType::BOUND_REF);

	auto plan = CreatePlan(*op.children[0]);

	// get the index of the row_id column
	auto &bound_ref = (BoundReferenceExpression &)*op.expressions[0];

	dependencies.insert(op.table);
	auto del = make_unique<PhysicalDelete>(op, *op.table, *op.table->storage, bound_ref.index);
	del->children.push_back(move(plan));
	return move(del);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_delim_get.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalDelimGet represents a duplicate eliminated scan belonging to a DelimJoin
class LogicalDelimGet : public LogicalOperator {
public:
	LogicalDelimGet(idx_t table_index, vector<TypeId> types)
	    : LogicalOperator(LogicalOperatorType::DELIM_GET), table_index(table_index) {
		assert(types.size() > 0);
		chunk_types = types;
	}

	//! The table index in the current bind context
	idx_t table_index;
	//! The types of the chunk
	vector<TypeId> chunk_types;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, chunk_types.size());
	}

protected:
	void ResolveTypes() override {
		// types are resolved in the constructor
		this->types = chunk_types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalDelimGet &op) {
	assert(op.children.size() == 0);

	// create a PhysicalChunkScan without an owned_collection, the collection will be added later
	auto chunk_scan = make_unique<PhysicalChunkScan>(op.types, PhysicalOperatorType::DELIM_SCAN);
	return move(chunk_scan);
}






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/aggregate/distributive_functions.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

struct StandardDistributiveFunction {
	template <class STATE> static void Initialize(STATE *state) {
		*state = NullValue<STATE>();
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void Operation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t idx) {
		if (IsNullValue<INPUT_TYPE>(*state)) {
			*state = input[idx];
		} else {
			OP::template Execute<INPUT_TYPE, STATE>(state, input[idx]);
		}
	}

	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		nullmask[idx] = IsNullValue<T>(*state);
		target[idx] = *state;
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		if (IsNullValue<STATE>(source)) {
			// source is NULL, nothing to do
			return;
		}
		if (IsNullValue<STATE>(*target)) {
			// target is NULL, use source value directly
			*target = source;
		} else {
			// else perform the operation
			OP::template Execute<STATE, STATE>(target, source);
		}
	}

	static bool IgnoreNull() {
		return true;
	}
};

struct CountStarFun {
	static AggregateFunction GetFunction();

	static void RegisterFunction(BuiltinFunctions &set);
};

struct CountFun {
	static AggregateFunction GetFunction();

	static void RegisterFunction(BuiltinFunctions &set);
};

struct FirstFun {
	static AggregateFunction GetFunction(SQLType type);

	static void RegisterFunction(BuiltinFunctions &set);
};

struct MaxFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct MinFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SumFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct StringAggFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

static void GatherDelimScans(PhysicalOperator *op, vector<PhysicalOperator *> &delim_scans) {
	assert(op);
	if (op->type == PhysicalOperatorType::DELIM_SCAN) {
		delim_scans.push_back(op);
	}
	for (auto &child : op->children) {
		GatherDelimScans(child.get(), delim_scans);
	}
}

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalDelimJoin &op) {
	// first create the underlying join
	auto plan = CreatePlan((LogicalComparisonJoin &)op);
	// this should create a join, not a cross product
	assert(plan && plan->type != PhysicalOperatorType::CROSS_PRODUCT);
	// duplicate eliminated join
	// first gather the scans on the duplicate eliminated data set from the RHS
	vector<PhysicalOperator *> delim_scans;
	GatherDelimScans(plan->children[1].get(), delim_scans);
	if (delim_scans.size() == 0) {
		// no duplicate eliminated scans in the RHS!
		// in this case we don't need to create a delim join
		// just push the normal join
		return plan;
	}
	vector<TypeId> delim_types;
	for (auto &delim_expr : op.duplicate_eliminated_columns) {
		delim_types.push_back(delim_expr->return_type);
	}
	if (op.join_type == JoinType::MARK) {
		assert(plan->type == PhysicalOperatorType::HASH_JOIN);
		auto &hash_join = (PhysicalHashJoin &)*plan;
		// correlated MARK join
		if (delim_types.size() + 1 == hash_join.conditions.size()) {
			// the correlated MARK join has one more condition than the amount of correlated columns
			// this is the case in a correlated ANY() expression
			// in this case we need to keep track of additional entries, namely:
			// - (1) the total amount of elements per group
			// - (2) the amount of non-null elements per group
			// we need these to correctly deal with the cases of either:
			// - (1) the group being empty [in which case the result is always false, even if the comparison is NULL]
			// - (2) the group containing a NULL value [in which case FALSE becomes NULL]
			auto &info = hash_join.hash_table->correlated_mark_join_info;

			vector<TypeId> payload_types = {TypeId::INT64, TypeId::INT64}; // COUNT types
			vector<AggregateFunction> aggregate_functions = {CountStarFun::GetFunction(), CountFun::GetFunction()};
			vector<BoundAggregateExpression *> correlated_aggregates;
			for (idx_t i = 0; i < aggregate_functions.size(); ++i) {
				auto aggr = make_unique<BoundAggregateExpression>(payload_types[i], aggregate_functions[i], false);
				correlated_aggregates.push_back(&*aggr);
				info.correlated_aggregates.push_back(move(aggr));
			}
			info.correlated_counts =
			    make_unique<SuperLargeHashTable>(1024, delim_types, payload_types, correlated_aggregates);
			info.correlated_types = delim_types;
			// FIXME: these can be initialized "empty" (without allocating empty vectors)
			info.group_chunk.Initialize(delim_types);
			info.payload_chunk.Initialize(payload_types);
			info.result_chunk.Initialize(payload_types);
		}
	}
	// now create the duplicate eliminated join
	auto delim_join = make_unique<PhysicalDelimJoin>(op, move(plan), delim_scans);
	// we still have to create the DISTINCT clause that is used to generate the duplicate eliminated chunk
	// we create a ChunkCollectionScan that pulls from the delim_join LHS
	auto chunk_scan =
	    make_unique<PhysicalChunkScan>(delim_join->children[0]->GetTypes(), PhysicalOperatorType::CHUNK_SCAN);
	chunk_scan->collection = &delim_join->lhs_data;
	// now we need to create a projection that projects only the duplicate eliminated columns
	assert(op.duplicate_eliminated_columns.size() > 0);
	auto projection = make_unique<PhysicalProjection>(delim_types, move(op.duplicate_eliminated_columns));
	projection->children.push_back(move(chunk_scan));
	// finally create the distinct clause on top of the projection
	delim_join->distinct = CreateDistinct(move(projection));
	return move(delim_join);
}







//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_distinct.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalDistinct filters duplicate entries from its child operator
class LogicalDistinct : public LogicalOperator {
public:
	LogicalDistinct(vector<unique_ptr<Expression>> targets)
	    : LogicalOperator(LogicalOperatorType::DISTINCT), distinct_targets(move(targets)) {
	}
	//! The set of distinct targets (optional).
	vector<unique_ptr<Expression>> distinct_targets;

public:
	string ParamsToString() const override;

	vector<ColumnBinding> GetColumnBindings() override {
		return children[0]->GetColumnBindings();
	}

protected:
	void ResolveTypes() override {
		types = children[0]->types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreateDistinct(unique_ptr<PhysicalOperator> child) {
	assert(child);
	// create a PhysicalHashAggregate that groups by the input columns
	auto &types = child->GetTypes();
	vector<unique_ptr<Expression>> groups, expressions;
	for (idx_t i = 0; i < types.size(); i++) {
		groups.push_back(make_unique<BoundReferenceExpression>(types[i], i));
	}

	auto groupby =
	    make_unique<PhysicalHashAggregate>(types, move(expressions), move(groups), PhysicalOperatorType::DISTINCT);
	groupby->children.push_back(move(child));
	return move(groupby);
}

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreateDistinctOn(unique_ptr<PhysicalOperator> child,
                                                                     vector<unique_ptr<Expression>> distinct_targets) {
	assert(child);
	assert(distinct_targets.size() > 0);

	auto &types = child->GetTypes();
	vector<unique_ptr<Expression>> groups, aggregates, projections;
	// creates one group per distinct_target
	for (auto &target : distinct_targets) {
		groups.push_back(move(target));
	}
	// we need the projection to fetch the select_list
	auto &child_projection = (PhysicalProjection &)*child;
	// we need to create one aggregate per column in the select_list
	for (idx_t i = 0; i < child_projection.select_list.size(); ++i) {
		// first we create an aggregate that returns the FIRST element
		auto bound = make_unique<BoundReferenceExpression>(types[i], i);
		auto first_aggregate = make_unique<BoundAggregateExpression>(
		    types[i], FirstFun::GetFunction(SQLTypeFromInternalType(types[i])), false);
		first_aggregate->children.push_back(move(bound));
		// and push it to the list of aggregates
		aggregates.push_back(move(first_aggregate));
		projections.push_back(make_unique<BoundReferenceExpression>(types[i], i));
	}

	// we add a physical hash aggregation in the plan to select the distinct groups
	auto groupby =
	    make_unique<PhysicalHashAggregate>(types, move(aggregates), move(groups), PhysicalOperatorType::DISTINCT);
	groupby->children.push_back(move(child));

	// we add a physical projection on top of the aggregation to project all members in the select list
	auto aggr_projection = make_unique<PhysicalProjection>(types, move(projections));
	aggr_projection->children.push_back(move(groupby));

	return move(aggr_projection);
}

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalDistinct &op) {
	assert(op.children.size() == 1);
	auto plan = CreatePlan(*op.children[0]);
	if (op.distinct_targets.size() > 0) {
		return CreateDistinctOn(move(plan), move(op.distinct_targets));
	} else {
		return CreateDistinct(move(plan));
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_empty_result.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalEmptyResult returns an empty result. This is created by the optimizer if it can reason that ceratin parts of
//! the tree will always return an empty result.
class LogicalEmptyResult : public LogicalOperator {
public:
	LogicalEmptyResult(unique_ptr<LogicalOperator> op);

	//! The set of return types of the empty result
	vector<TypeId> return_types;
	//! The columns that would be bound at this location (if the subtree was not optimized away)
	vector<ColumnBinding> bindings;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return bindings;
	}

protected:
	void ResolveTypes() override {
		this->types = return_types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalEmptyResult &op) {
	assert(op.children.size() == 0);
	return make_unique<PhysicalEmptyResult>(op.types);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_execute.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class LogicalExecute : public LogicalOperator {
public:
	LogicalExecute(PreparedStatementData *prepared) : LogicalOperator(LogicalOperatorType::EXECUTE), prepared(prepared) {
		assert(prepared);
		types = prepared->types;
	}

	PreparedStatementData *prepared;

protected:
	void ResolveTypes() override {
		// already resolved
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalExecute &op) {
	assert(op.children.size() == 0);
	return make_unique<PhysicalExecute>(op.prepared->plan.get());
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_explain.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class LogicalExplain : public LogicalOperator {
public:
	LogicalExplain(unique_ptr<LogicalOperator> plan) : LogicalOperator(LogicalOperatorType::EXPLAIN) {
		children.push_back(move(plan));
	}

	string physical_plan;
	string logical_plan_unopt;
	string logical_plan_opt;

protected:
	void ResolveTypes() override {
		types = {TypeId::VARCHAR, TypeId::VARCHAR};
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalExplain &op) {
	assert(op.children.size() == 1);
	auto logical_plan_opt = op.children[0]->ToString();
	auto plan = CreatePlan(*op.children[0]);

	op.physical_plan = plan->ToString();

	// the output of the explain
	vector<string> keys = {"logical_plan", "logical_opt", "physical_plan"};
	vector<string> values = {op.logical_plan_unopt, logical_plan_opt, op.physical_plan};
	// create a ChunkCollection from the output
	auto collection = make_unique<ChunkCollection>();

	DataChunk chunk;
	chunk.Initialize(op.types);
	for (idx_t i = 0; i < keys.size(); i++) {
		chunk.SetValue(0, chunk.size(), Value(keys[i]));
		chunk.SetValue(1, chunk.size(), Value(values[i]));
		chunk.SetCardinality(chunk.size() + 1);
		if (chunk.size() == STANDARD_VECTOR_SIZE) {
			collection->Append(chunk);
			chunk.Reset();
		}
	}
	collection->Append(chunk);

	// create a chunk scan to output the result
	auto chunk_scan = make_unique<PhysicalChunkScan>(op.types, PhysicalOperatorType::CHUNK_SCAN);
	chunk_scan->owned_collection = move(collection);
	chunk_scan->collection = chunk_scan->owned_collection.get();
	return move(chunk_scan);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_expression_get.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalExpressionGet represents a scan operation over a set of to-be-executed expressions
class LogicalExpressionGet : public LogicalOperator {
public:
	LogicalExpressionGet(idx_t table_index, vector<TypeId> types, vector<vector<unique_ptr<Expression>>> expressions)
	    : LogicalOperator(LogicalOperatorType::EXPRESSION_GET), table_index(table_index), expr_types(types),
	      expressions(move(expressions)) {
	}

	//! The table index in the current bind context
	idx_t table_index;
	//! The types of the expressions
	vector<TypeId> expr_types;
	//! The set of expressions
	vector<vector<unique_ptr<Expression>>> expressions;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, expr_types.size());
	}

protected:
	void ResolveTypes() override {
		// types are resolved in the constructor
		this->types = expr_types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalExpressionGet &op) {
	assert(op.children.size() == 1);
	auto plan = CreatePlan(*op.children[0]);

	auto expr_scan = make_unique<PhysicalExpressionScan>(op.types, move(op.expressions));
	expr_scan->children.push_back(move(plan));
	return move(expr_scan);
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/matcher/expression_matcher.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/matcher/expression_type_matcher.hpp
//
//
//===----------------------------------------------------------------------===//






#include <algorithm>

namespace duckdb {

//! The ExpressionTypeMatcher class contains a set of matchers that can be used to pattern match ExpressionTypes
class ExpressionTypeMatcher {
public:
	virtual ~ExpressionTypeMatcher() {
	}

	virtual bool Match(ExpressionType type) = 0;
};

//! The SpecificExpressionTypeMatcher class matches a single specified Expression type
class SpecificExpressionTypeMatcher : public ExpressionTypeMatcher {
public:
	SpecificExpressionTypeMatcher(ExpressionType type) : type(type) {
	}

	bool Match(ExpressionType type) override {
		return type == this->type;
	}

private:
	ExpressionType type;
};

//! The ManyExpressionTypeMatcher class matches a set of ExpressionTypes
class ManyExpressionTypeMatcher : public ExpressionTypeMatcher {
public:
	ManyExpressionTypeMatcher(vector<ExpressionType> types) : types(move(types)) {
	}

	bool Match(ExpressionType type) override {
		return std::find(types.begin(), types.end(), type) != types.end();
	}

private:
	vector<ExpressionType> types;
};

//! The ComparisonExpressionTypeMatcher class matches a comparison expression
class ComparisonExpressionTypeMatcher : public ExpressionTypeMatcher {
public:
	bool Match(ExpressionType type) override {
		return type == ExpressionType::COMPARE_EQUAL || type == ExpressionType::COMPARE_GREATERTHANOREQUALTO ||
		       type == ExpressionType::COMPARE_LESSTHANOREQUALTO || type == ExpressionType::COMPARE_LESSTHAN ||
		       type == ExpressionType::COMPARE_GREATERTHAN;
	}
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/matcher/set_matcher.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class SetMatcher {
public:
	//! The policy used by the SetMatcher
	enum class Policy {
		//! All entries have to be matched, and the matches have to be ordered
		ORDERED,
		//! All entries have to be matched, but the order of the matches does not matter
		UNORDERED,
		//! Only some entries have to be matched, the order of the matches does not matter
		SOME,
	};

	/* The double {{}} in the intializer for excluded_entries is intentional, workaround for bug in gcc-4.9 */
	template <class T, class MATCHER>
	static bool MatchRecursive(vector<unique_ptr<MATCHER>> &matchers, vector<T *> &entries, vector<T *> &bindings,
	                           unordered_set<idx_t> excluded_entries, idx_t m_idx = 0) {
		if (m_idx == matchers.size()) {
			// matched all matchers!
			return true;
		}
		// try to find a match for the current matcher (m_idx)
		idx_t previous_binding_count = bindings.size();
		for (idx_t e_idx = 0; e_idx < entries.size(); e_idx++) {
			// first check if this entry has already been matched
			if (excluded_entries.find(e_idx) != excluded_entries.end()) {
				// it has been matched: skip this entry
				continue;
			}
			// otherwise check if the current matcher matches this entry
			if (matchers[m_idx]->Match(entries[e_idx], bindings)) {
				// m_idx matches e_idx!
				// check if we can find a complete match for this path
				// first add e_idx to the new set of excluded entries
				unordered_set<idx_t> new_excluded_entries;
				new_excluded_entries = excluded_entries;
				new_excluded_entries.insert(e_idx);
				// then match the next matcher in the set
				if (MatchRecursive(matchers, entries, bindings, new_excluded_entries, m_idx + 1)) {
					// we found a match for this path! success
					return true;
				} else {
					// we did not find a match! remove any bindings we added in the call to Match()
					bindings.erase(bindings.begin() + previous_binding_count, bindings.end());
				}
			}
		}
		return false;
	}

	template <class T, class MATCHER>
	static bool Match(vector<unique_ptr<MATCHER>> &matchers, vector<T *> &entries, vector<T *> &bindings,
	                  Policy policy) {
		if (policy == Policy::ORDERED) {
			// ordered policy, count has to match
			if (matchers.size() != entries.size()) {
				return false;
			}
			// now entries have to match in order
			for (idx_t i = 0; i < matchers.size(); i++) {
				if (!matchers[i]->Match(entries[i], bindings)) {
					return false;
				}
			}
			return true;
		} else {
			if (policy == Policy::UNORDERED && matchers.size() != entries.size()) {
				// unordered policy, count does not match: no match
				return false;
			} else if (policy == Policy::SOME && matchers.size() > entries.size()) {
				// some policy, every matcher has to match a unique entry
				// this is not possible if there are more matchers than entries
				return false;
			}
			// now perform the actual matching
			// every matcher has to match a UNIQUE entry
			// we perform this matching in a recursive way
			unordered_set<idx_t> excluded_entries;
			if (!MatchRecursive(matchers, entries, bindings, excluded_entries)) {
				return false;
			}
			return true;
		}
	}

	template <class T, class MATCHER>
	static bool Match(vector<unique_ptr<MATCHER>> &matchers, vector<unique_ptr<T>> &entries, vector<T *> &bindings,
	                  Policy policy) {
		// convert vector of unique_ptr to vector of normal pointers
		vector<T *> ptr_entries;
		for (auto &entry : entries) {
			ptr_entries.push_back(entry.get());
		}
		// then just call the normal match function
		return Match(matchers, ptr_entries, bindings, policy);
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/matcher/type_matcher.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The TypeMatcher class contains a set of matchers that can be used to pattern match TypeIds for Rules
class TypeMatcher {
public:
	virtual ~TypeMatcher() {
	}

	virtual bool Match(TypeId type) = 0;
};

//! The SpecificTypeMatcher class matches only a single specified type
class SpecificTypeMatcher : public TypeMatcher {
public:
	SpecificTypeMatcher(TypeId type) : type(type) {
	}

	bool Match(TypeId type) override {
		return type == this->type;
	}

private:
	TypeId type;
};

//! The NumericTypeMatcher class matches any numeric type (DECIMAL, INTEGER, etc...)
class NumericTypeMatcher : public TypeMatcher {
public:
	bool Match(TypeId type) override {
		return TypeIsNumeric(type);
	}
};

//! The IntegerTypeMatcher class matches only integer types (INTEGER, SMALLINT, TINYINT, BIGINT)
class IntegerTypeMatcher : public TypeMatcher {
public:
	bool Match(TypeId type) override {
		return TypeIsInteger(type);
	}
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/matcher/function_matcher.hpp
//
//
//===----------------------------------------------------------------------===//





#include <algorithm>

namespace duckdb {

//! The FunctionMatcher class contains a set of matchers that can be used to pattern match specific functions
class FunctionMatcher {
public:
	virtual ~FunctionMatcher() {
	}

	virtual bool Match(string &name) = 0;

	static bool Match(unique_ptr<FunctionMatcher> &matcher, string &name) {
		if (!matcher) {
			return true;
		}
		return matcher->Match(name);
	}
};

//! The SpecificFunctionMatcher class matches a single specified function name
class SpecificFunctionMatcher : public FunctionMatcher {
public:
	SpecificFunctionMatcher(string name) : name(move(name)) {
	}

	bool Match(string &name) override {
		return name == this->name;
	}

private:
	string name;
};

//! The ManyFunctionMatcher class matches a set of functions
class ManyFunctionMatcher : public FunctionMatcher {
public:
	ManyFunctionMatcher(unordered_set<string> names) : names(move(names)) {
	}

	bool Match(string &name) override {
		return names.find(name) != names.end();
	}

private:
	unordered_set<string> names;
};

} // namespace duckdb



namespace duckdb {

//! The ExpressionMatcher class contains a set of matchers that can be used to pattern match Expressions
class ExpressionMatcher {
public:
	ExpressionMatcher(ExpressionClass type = ExpressionClass::INVALID) : expr_class(type) {
	}
	virtual ~ExpressionMatcher() {
	}

	//! Checks if the given expression matches this ExpressionMatcher. If it does, the expression is appended to the
	//! bindings list and true is returned. Otherwise, false is returned.
	virtual bool Match(Expression *expr, vector<Expression *> &bindings);

	//! The ExpressionClass of the to-be-matched expression. ExpressionClass::INVALID for ANY.
	ExpressionClass expr_class;
	//! Matcher for the ExpressionType of the operator (nullptr for ANY)
	unique_ptr<ExpressionTypeMatcher> expr_type;
	//! Matcher for the return_type of the expression (nullptr for ANY)
	unique_ptr<TypeMatcher> type;
};

//! The ExpressionEqualityMatcher matches on equality with another (given) expression
class ExpressionEqualityMatcher : public ExpressionMatcher {
public:
	ExpressionEqualityMatcher(Expression *expr) : ExpressionMatcher(ExpressionClass::INVALID), expression(expr) {
	}

	bool Match(Expression *expr, vector<Expression *> &bindings) override;

private:
	Expression *expression;
};

class ConstantExpressionMatcher : public ExpressionMatcher {
public:
	ConstantExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CONSTANT) {
	}
};

class CaseExpressionMatcher : public ExpressionMatcher {
public:
	CaseExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CASE) {
	}
	//! The check expression to match (if any)
	unique_ptr<ExpressionMatcher> check;
	//! The result_if_true expression to match (if any)
	unique_ptr<ExpressionMatcher> result_if_true;
	//! The result_if_false expression to match (if any)
	unique_ptr<ExpressionMatcher> result_if_false;

	bool Match(Expression *expr_, vector<Expression *> &bindings) override;
};

class CastExpressionMatcher : public ExpressionMatcher {
public:
	CastExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CAST) {
	}
	//! The child expression to match (if any)
	unique_ptr<ExpressionMatcher> child;

	bool Match(Expression *expr_, vector<Expression *> &bindings) override;
};

class ComparisonExpressionMatcher : public ExpressionMatcher {
public:
	ComparisonExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_COMPARISON) {
	}
	//! The matchers for the child expressions
	vector<unique_ptr<ExpressionMatcher>> matchers;
	//! The set matcher matching policy to use
	SetMatcher::Policy policy;

	bool Match(Expression *expr_, vector<Expression *> &bindings) override;
};

class ConjunctionExpressionMatcher : public ExpressionMatcher {
public:
	ConjunctionExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CONJUNCTION) {
	}
	//! The matchers for the child expressions
	vector<unique_ptr<ExpressionMatcher>> matchers;
	//! The set matcher matching policy to use
	SetMatcher::Policy policy;

	bool Match(Expression *expr_, vector<Expression *> &bindings) override;
};

class OperatorExpressionMatcher : public ExpressionMatcher {
public:
	OperatorExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_OPERATOR) {
	}
	//! The matchers for the child expressions
	vector<unique_ptr<ExpressionMatcher>> matchers;
	//! The set matcher matching policy to use
	SetMatcher::Policy policy;

	bool Match(Expression *expr_, vector<Expression *> &bindings) override;
};

class FunctionExpressionMatcher : public ExpressionMatcher {
public:
	FunctionExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_FUNCTION) {
	}
	//! The matchers for the child expressions
	vector<unique_ptr<ExpressionMatcher>> matchers;
	//! The set matcher matching policy to use
	SetMatcher::Policy policy;
	//! The function name to match
	unique_ptr<FunctionMatcher> function;

	bool Match(Expression *expr_, vector<Expression *> &bindings) override;
};

//! The FoldableConstant matcher matches any expression that is foldable into a constant by the ExpressionExecutor (i.e.
//! scalar but not aggregate/window/parameter)
class FoldableConstantMatcher : public ExpressionMatcher {
public:
	FoldableConstantMatcher() : ExpressionMatcher(ExpressionClass::INVALID) {
	}

	bool Match(Expression *expr, vector<Expression *> &bindings) override;
};

} // namespace duckdb




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_filter.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalFilter represents a filter operation (e.g. WHERE or HAVING clause)
class LogicalFilter : public LogicalOperator {
public:
	LogicalFilter(unique_ptr<Expression> expression);
	LogicalFilter();

	vector<idx_t> projection_map;

public:
	vector<ColumnBinding> GetColumnBindings() override;

	bool SplitPredicates() {
		return SplitPredicates(expressions);
	}
	//! Splits up the predicates of the LogicalFilter into a set of predicates
	//! separated by AND Returns whether or not any splits were made
	static bool SplitPredicates(vector<unique_ptr<Expression>> &expressions);

protected:
	void ResolveTypes() override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_get.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

//! LogicalGet represents a scan operation from a data source
class LogicalGet : public LogicalOperator {
public:
	LogicalGet(idx_t table_index);
	LogicalGet(TableCatalogEntry *table, idx_t table_index, vector<column_t> column_ids);

	idx_t EstimateCardinality() override;

	//! The base table to retrieve data from
	TableCatalogEntry *table;
	//! The table index in the current bind context
	idx_t table_index;
	//! Bound column IDs
	vector<column_t> column_ids;
	//! Filters pushed down for table scan
	vector<TableFilter> tableFilters;
	string ParamsToString() const override;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalFilter &op) {
	assert(op.children.size() == 1);
	unique_ptr<PhysicalOperator> plan = CreatePlan(*op.children[0]);
	if (op.expressions.size() > 0) {
		// create a filter if there is anything to filter
		auto filter = make_unique<PhysicalFilter>(op.children[0]->types, move(op.expressions));
		filter->children.push_back(move(plan));
		plan = move(filter);

		if (op.projection_map.size() > 0) {
			// there is a projection map, generate a physical projection
			vector<unique_ptr<Expression>> select_list;
			for (idx_t i = 0; i < op.projection_map.size(); i++) {
				select_list.push_back(make_unique<BoundReferenceExpression>(op.types[i], op.projection_map[i]));
			}
			auto proj = make_unique<PhysicalProjection>(op.types, move(select_list));
			proj->children.push_back(move(plan));
			plan = move(proj);
		}
	}
	return plan;
}





using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalGet &op) {
	assert(op.children.size() == 0);

	if (!op.table) {
		return make_unique<PhysicalDummyScan>(op.types);
	} else {
		for (auto &tableFilter : op.tableFilters) {
			for (idx_t i = 0; i < op.column_ids.size(); i++) {
				if (tableFilter.column_index == op.column_ids[i]) {
					tableFilter.column_index = i;
					break;
				}
			}
		}
		dependencies.insert(op.table);
		return make_unique<PhysicalTableScan>(op, *op.table, *op.table->storage, op.column_ids, move(op.expressions),
		                                      move(op.tableFilters));
	}
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_index_scan.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! LogicalIndex represents an Index Scan operation
class LogicalIndexScan : public LogicalOperator {
public:
	LogicalIndexScan(TableCatalogEntry &tableref, DataTable &table, Index &index, vector<column_t> column_ids,
	                 idx_t table_index)
	    : LogicalOperator(LogicalOperatorType::INDEX_SCAN), tableref(tableref), table(table), index(index),
	      column_ids(column_ids), table_index(table_index) {
	}

	//! The table to scan
	TableCatalogEntry &tableref;
	//! The physical data table to scan
	DataTable &table;
	//! The index to use for the scan
	Index &index;
	//! The column ids to project
	vector<column_t> column_ids;

	//! The value for the query predicate
	Value low_value;
	Value high_value;
	Value equal_value;

	//! If the predicate is low, high or equal
	bool low_index = false;
	bool high_index = false;
	bool equal_index = false;

	//! The expression type (e.g., >, <, >=, <=)
	ExpressionType low_expression_type;
	ExpressionType high_expression_type;

	//! The table index in the current bind context
	idx_t table_index;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, column_ids.size());
	}

protected:
	void ResolveTypes() override {
		if (column_ids.size() == 0) {
			types = {TypeId::INT32};
		} else {
			types = tableref.GetTypes(column_ids);
		}
	}
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalIndexScan &op) {
	unique_ptr<PhysicalOperator> plan;
	auto node = make_unique<PhysicalIndexScan>(op, op.tableref, op.table, op.index, op.column_ids);
	if (op.equal_index) {
		node->equal_value = op.equal_value;
		node->equal_index = true;
	}
	if (op.low_index) {
		node->low_value = op.low_value;
		node->low_index = true;
		node->low_expression_type = op.low_expression_type;
	}
	if (op.high_index) {
		node->high_value = op.high_value;
		node->high_index = true;
		node->high_expression_type = op.high_expression_type;
	}
	plan = move(node);
	return plan;
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_insert.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalInsert represents an insertion of data into a base table
class LogicalInsert : public LogicalOperator {
public:
	LogicalInsert(TableCatalogEntry *table, vector<unique_ptr<Expression>> bound_defaults)
	    : LogicalOperator(LogicalOperatorType::INSERT), table(table), bound_defaults(move(bound_defaults)) {
	}

	vector<vector<unique_ptr<Expression>>> insert_values;
	vector<idx_t> column_index_map;

	//! The base table to insert into
	TableCatalogEntry *table;
	//! The default statements used by the table
	vector<unique_ptr<Expression>> bound_defaults;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::INT64);
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalInsert &op) {
	unique_ptr<PhysicalOperator> plan;
	if (op.children.size() > 0) {
		assert(op.children.size() == 1);
		plan = CreatePlan(*op.children[0]);
	}

	dependencies.insert(op.table);
	auto insert = make_unique<PhysicalInsert>(op, op.table, op.column_index_map, move(op.bound_defaults));
	if (plan) {
		insert->children.push_back(move(plan));
	}
	return move(insert);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_limit.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalLimit represents a LIMIT clause
class LogicalLimit : public LogicalOperator {
public:
	LogicalLimit(int64_t limit, int64_t offset)
	    : LogicalOperator(LogicalOperatorType::LIMIT), limit(limit), offset(offset) {
	}

	//! The maximum amount of elements to emit
	int64_t limit;
	//! The offset from the start to begin emitting elements
	int64_t offset;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return children[0]->GetColumnBindings();
	}

protected:
	void ResolveTypes() override {
		types = children[0]->types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalLimit &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);

	auto limit = make_unique<PhysicalLimit>(op, op.limit, op.offset);
	limit->children.push_back(move(plan));
	return move(limit);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_order.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalOrder represents an ORDER BY clause, sorting the data
class LogicalOrder : public LogicalOperator {
public:
	LogicalOrder(vector<BoundOrderByNode> orders)
	    : LogicalOperator(LogicalOperatorType::ORDER_BY), orders(move(orders)) {
	}

	vector<BoundOrderByNode> orders;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return children[0]->GetColumnBindings();
	}

protected:
	void ResolveTypes() override {
		types = children[0]->types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalOrder &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);

	auto order = make_unique<PhysicalOrder>(op.types, move(op.orders));
	order->children.push_back(move(plan));
	return move(order);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_prepare.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

class TableCatalogEntry;

class LogicalPrepare : public LogicalOperator {
public:
	LogicalPrepare(string name, unique_ptr<PreparedStatementData> prepared, unique_ptr<LogicalOperator> logical_plan)
	    : LogicalOperator(LogicalOperatorType::PREPARE), name(name), prepared(move(prepared)) {
		children.push_back(move(logical_plan));
	}

	string name;
	unique_ptr<PreparedStatementData> prepared;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::BOOL);
	}
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalPrepare &op) {
	assert(op.children.size() == 1);

	// generate physical plan
	auto plan = CreatePlan(*op.children[0]);
	op.prepared->types = plan->types;
	op.prepared->plan = move(plan);
	op.prepared->dependencies = move(dependencies);

	return make_unique<PhysicalPrepare>(op.name, move(op.prepared));
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_projection.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalProjection represents the projection list in a SELECT clause
class LogicalProjection : public LogicalOperator {
public:
	LogicalProjection(idx_t table_index, vector<unique_ptr<Expression>> select_list);

	idx_t table_index;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalProjection &op) {
	assert(op.children.size() == 1);
	auto plan = CreatePlan(*op.children[0]);

#ifdef DEBUG
	for (auto &expr : op.expressions) {
		assert(!expr->IsWindow() && !expr->IsAggregate());
	}
#endif

	auto projection = make_unique<PhysicalProjection>(op, move(op.expressions));
	projection->children.push_back(move(plan));
	return move(projection);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_prune_columns.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalPruneColumns represents a node that prunes extra columns from its
//! children
class LogicalPruneColumns : public LogicalOperator {
public:
	LogicalPruneColumns(idx_t column_limit)
	    : LogicalOperator(LogicalOperatorType::PRUNE_COLUMNS), column_limit(column_limit) {
	}

	idx_t column_limit;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalPruneColumns &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);
	if (plan->GetTypes().size() > op.column_limit) {
		// only prune if we need to
		auto node = make_unique<PhysicalPruneColumns>(op, op.column_limit);
		node->children.push_back(move(plan));
		plan = move(node);
	}
	return plan;
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_recursive_cte.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class LogicalRecursiveCTE : public LogicalOperator {
public:
	LogicalRecursiveCTE(idx_t table_index, idx_t column_count, bool union_all, unique_ptr<LogicalOperator> top,
	                    unique_ptr<LogicalOperator> bottom, LogicalOperatorType type)
	    : LogicalOperator(type), union_all(union_all), table_index(table_index), column_count(column_count) {
		assert(type == LogicalOperatorType::RECURSIVE_CTE);
		children.push_back(move(top));
		children.push_back(move(bottom));
	}

	bool union_all;
	idx_t table_index;
	idx_t column_count;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, column_count);
	}

protected:
	void ResolveTypes() override {
		types = children[0]->types;
	}
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_cteref.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalChunkGet represents a scan operation from a ChunkCollection
class LogicalCTERef : public LogicalOperator {
public:
	LogicalCTERef(idx_t table_index, idx_t cte_index, vector<TypeId> types, vector<string> colnames)
	    : LogicalOperator(LogicalOperatorType::CTE_REF), table_index(table_index), cte_index(cte_index) {
		assert(types.size() > 0);
		chunk_types = types;
		bound_columns = colnames;
	}

	vector<string> bound_columns;
	//! The table index in the current bind context
	idx_t table_index;
	//! CTE index
	idx_t cte_index;
	//! The types of the chunk
	vector<TypeId> chunk_types;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, chunk_types.size());
	}

protected:
	void ResolveTypes() override {
		// types are resolved in the constructor
		this->types = chunk_types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalRecursiveCTE &op) {
	assert(op.children.size() == 2);

	// Create the working_table that the PhysicalRecursiveCTE will use for evaluation.
	auto working_table = std::make_shared<ChunkCollection>();

	// Add the ChunkCollection to the context of this PhysicalPlanGenerator
	rec_ctes[op.table_index] = working_table;

	auto left = CreatePlan(*op.children[0]);
	auto right = CreatePlan(*op.children[1]);

	auto cte = make_unique<PhysicalRecursiveCTE>(op, op.union_all, move(left), move(right));
	cte->working_table = working_table;

	return move(cte);
}

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCTERef &op) {
	assert(op.children.size() == 0);

	auto chunk_scan = make_unique<PhysicalChunkScan>(op.types, PhysicalOperatorType::CHUNK_SCAN);

	// CreatePlan of a LogicalRecursiveCTE must have happened before.
	auto cte = rec_ctes.find(op.cte_index);
	if (cte == rec_ctes.end()) {
		throw Exception("Referenced recursive CTE does not exist.");
	}
	chunk_scan->collection = cte->second.get();
	return move(chunk_scan);
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_set_operation.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class LogicalSetOperation : public LogicalOperator {
public:
	LogicalSetOperation(idx_t table_index, idx_t column_count, unique_ptr<LogicalOperator> top,
	                    unique_ptr<LogicalOperator> bottom, LogicalOperatorType type)
	    : LogicalOperator(type), table_index(table_index), column_count(column_count) {
		assert(type == LogicalOperatorType::UNION || type == LogicalOperatorType::EXCEPT ||
		       type == LogicalOperatorType::INTERSECT);
		children.push_back(move(top));
		children.push_back(move(bottom));
	}

	idx_t table_index;
	idx_t column_count;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return GenerateColumnBindings(table_index, column_count);
	}

protected:
	void ResolveTypes() override {
		types = children[0]->types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSetOperation &op) {
	assert(op.children.size() == 2);

	auto left = CreatePlan(*op.children[0]);
	auto right = CreatePlan(*op.children[1]);

	if (left->GetTypes() != right->GetTypes()) {
		throw Exception("Type mismatch for SET OPERATION");
	}

	switch (op.type) {
	case LogicalOperatorType::UNION:
		// UNION
		return make_unique<PhysicalUnion>(op, move(left), move(right));
	default: {
		// EXCEPT/INTERSECT
		assert(op.type == LogicalOperatorType::EXCEPT || op.type == LogicalOperatorType::INTERSECT);
		auto &types = left->GetTypes();
		vector<JoinCondition> conditions;
		// create equality condition for all columns
		for (idx_t i = 0; i < types.size(); i++) {
			JoinCondition cond;
			cond.comparison = ExpressionType::COMPARE_EQUAL;
			cond.left = make_unique<BoundReferenceExpression>(types[i], i);
			cond.right = make_unique<BoundReferenceExpression>(types[i], i);
			cond.null_values_are_equal = true;
			conditions.push_back(move(cond));
		}
		// EXCEPT is ANTI join
		// INTERSECT is SEMI join
		JoinType join_type = op.type == LogicalOperatorType::EXCEPT ? JoinType::ANTI : JoinType::SEMI;
		return make_unique<PhysicalHashJoin>(context, op, move(left), move(right), move(conditions), join_type);
	}
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_simple.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! LogicalSimple represents a simple logical operator that only passes on the parse info
class LogicalSimple : public LogicalOperator {
public:
	LogicalSimple(LogicalOperatorType type, unique_ptr<ParseInfo> info) : LogicalOperator(type), info(move(info)) {
	}

	unique_ptr<ParseInfo> info;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::BOOL);
	}
};
} // namespace duckdb











using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSimple &op) {
	switch (op.type) {
	case LogicalOperatorType::ALTER:
		return make_unique<PhysicalAlter>(unique_ptr_cast<ParseInfo, AlterInfo>(move(op.info)));
	case LogicalOperatorType::DROP:
		return make_unique<PhysicalDrop>(unique_ptr_cast<ParseInfo, DropInfo>(move(op.info)));
	case LogicalOperatorType::PRAGMA:
		return make_unique<PhysicalPragma>(unique_ptr_cast<ParseInfo, PragmaInfo>(move(op.info)));
	case LogicalOperatorType::TRANSACTION:
		return make_unique<PhysicalTransaction>(unique_ptr_cast<ParseInfo, TransactionInfo>(move(op.info)));
	case LogicalOperatorType::VACUUM:
		return make_unique<PhysicalVacuum>(unique_ptr_cast<ParseInfo, VacuumInfo>(move(op.info)));
	default:
		throw NotImplementedException("Unimplemented type for logical simple operator");
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_table_function.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! LogicalTableFunction represents a call to a table-producing function
class LogicalTableFunction : public LogicalOperator {
public:
	LogicalTableFunction(TableFunctionCatalogEntry *function, idx_t table_index, unique_ptr<FunctionData> bind_data,
	                     vector<Value> parameters, vector<SQLType> return_types, vector<string> names)
	    : LogicalOperator(LogicalOperatorType::TABLE_FUNCTION), function(function), table_index(table_index),
	      bind_data(move(bind_data)), parameters(move(parameters)), return_types(move(return_types)),
	      names(move(names)) {
	}

	//! The function
	TableFunctionCatalogEntry *function;
	//! The table index of the table-producing function
	idx_t table_index;
	//! The bind data of the function
	unique_ptr<FunctionData> bind_data;
	//! The input parameters
	vector<Value> parameters;
	//! The set of returned sql types
	vector<SQLType> return_types;
	//! The set of returned column names
	vector<string> names;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalTableFunction &op) {
	assert(op.children.size() == 0);

	return make_unique<PhysicalTableFunction>(op.types, op.function, move(op.bind_data), move(op.parameters));
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_top_n.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! LogicalTopN represents a comibination of ORDER BY and LIMIT clause, using Min/Max Heap
class LogicalTopN : public LogicalOperator {
public:
	LogicalTopN(vector<BoundOrderByNode> orders, int64_t limit, int64_t offset)
	    : LogicalOperator(LogicalOperatorType::TOP_N), orders(move(orders)), limit(limit), offset(offset) {
	}

	vector<BoundOrderByNode> orders;
	//! The maximum amount of elements to emit
	int64_t limit;
	//! The offset from the start to begin emitting elements
	int64_t offset;

public:
	vector<ColumnBinding> GetColumnBindings() override {
		return children[0]->GetColumnBindings();
	}

protected:
	void ResolveTypes() override {
		types = children[0]->types;
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalTopN &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);

	auto top_n = make_unique<PhysicalTopN>(op, move(op.orders), op.limit, op.offset);
	top_n->children.push_back(move(plan));
	return move(top_n);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_window.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalAggregate represents an aggregate operation with (optional) GROUP BY
//! operator.
class LogicalUnnest : public LogicalOperator {
public:
	LogicalUnnest(idx_t unnest_index) : LogicalOperator(LogicalOperatorType::UNNEST), unnest_index(unnest_index) {
	}

	idx_t unnest_index;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalUnnest &op) {
	assert(op.children.size() == 1);
	auto plan = CreatePlan(*op.children[0]);
	auto unnest = make_unique<PhysicalUnnest>(op, move(op.expressions));
	unnest->children.push_back(move(plan));
	return move(unnest);
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_update.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class LogicalUpdate : public LogicalOperator {
public:
	LogicalUpdate(TableCatalogEntry *table, vector<column_t> columns, vector<unique_ptr<Expression>> expressions,
	              vector<unique_ptr<Expression>> bound_defaults)
	    : LogicalOperator(LogicalOperatorType::UPDATE, std::move(expressions)), table(table), columns(columns),
	      bound_defaults(move(bound_defaults)) {
	}

	TableCatalogEntry *table;
	vector<column_t> columns;
	vector<unique_ptr<Expression>> bound_defaults;
	bool is_index_update;

protected:
	void ResolveTypes() override {
		types.push_back(TypeId::INT64);
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalUpdate &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);

	dependencies.insert(op.table);
	auto update = make_unique<PhysicalUpdate>(op, *op.table, *op.table->storage, op.columns, move(op.expressions),
	                                          move(op.bound_defaults));
	update->is_index_update = op.is_index_update;
	update->children.push_back(move(plan));
	return move(update);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/operator/logical_window.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! LogicalAggregate represents an aggregate operation with (optional) GROUP BY
//! operator.
class LogicalWindow : public LogicalOperator {
public:
	LogicalWindow(idx_t window_index) : LogicalOperator(LogicalOperatorType::WINDOW), window_index(window_index) {
	}

	idx_t window_index;

public:
	vector<ColumnBinding> GetColumnBindings() override;

protected:
	void ResolveTypes() override;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalWindow &op) {
	assert(op.children.size() == 1);

	auto plan = CreatePlan(*op.children[0]);
#ifdef DEBUG
	for (auto &expr : op.expressions) {
		assert(expr->IsWindow());
	}
#endif

	auto window = make_unique<PhysicalWindow>(op, move(op.expressions));
	window->children.push_back(move(plan));
	return move(window);
}







using namespace duckdb;
using namespace std;

namespace duckdb {

class DependencyExtractor : public LogicalOperatorVisitor {
public:
	DependencyExtractor(unordered_set<CatalogEntry *> &dependencies) : dependencies(dependencies) {
	}

protected:
	unique_ptr<Expression> VisitReplace(BoundFunctionExpression &expr, unique_ptr<Expression> *expr_ptr) override {
		// extract dependencies from the bound function expression
		if (expr.function.dependency) {
			expr.function.dependency(expr, dependencies);
		}
		return nullptr;
	}

private:
	unordered_set<CatalogEntry *> &dependencies;
};
} // namespace duckdb

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(unique_ptr<LogicalOperator> op) {
	// first resolve column references
	context.profiler.StartPhase("column_binding");
	ColumnBindingResolver resolver;
	resolver.VisitOperator(*op);
	context.profiler.EndPhase();

	// now resolve types of all the operators
	context.profiler.StartPhase("resolve_types");
	op->ResolveOperatorTypes();
	context.profiler.EndPhase();

	// extract dependencies from the logical plan
	DependencyExtractor extractor(dependencies);
	extractor.VisitOperator(*op);

	// then create the main physical plan
	context.profiler.StartPhase("create_plan");
	auto plan = CreatePlan(*op);
	context.profiler.EndPhase();
	return plan;
}

unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalOperator &op) {
	switch (op.type) {
	case LogicalOperatorType::GET:
		return CreatePlan((LogicalGet &)op);
	case LogicalOperatorType::PROJECTION:
		return CreatePlan((LogicalProjection &)op);
	case LogicalOperatorType::EMPTY_RESULT:
		return CreatePlan((LogicalEmptyResult &)op);
	case LogicalOperatorType::FILTER:
		return CreatePlan((LogicalFilter &)op);
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY:
		return CreatePlan((LogicalAggregate &)op);
	case LogicalOperatorType::WINDOW:
		return CreatePlan((LogicalWindow &)op);
	case LogicalOperatorType::UNNEST:
		return CreatePlan((LogicalUnnest &)op);
	case LogicalOperatorType::LIMIT:
		return CreatePlan((LogicalLimit &)op);
	case LogicalOperatorType::ORDER_BY:
		return CreatePlan((LogicalOrder &)op);
	case LogicalOperatorType::TOP_N:
		return CreatePlan((LogicalTopN &)op);
	case LogicalOperatorType::COPY_FROM_FILE:
		return CreatePlan((LogicalCopyFromFile &)op);
	case LogicalOperatorType::COPY_TO_FILE:
		return CreatePlan((LogicalCopyToFile &)op);
	case LogicalOperatorType::TABLE_FUNCTION:
		return CreatePlan((LogicalTableFunction &)op);
	case LogicalOperatorType::ANY_JOIN:
		return CreatePlan((LogicalAnyJoin &)op);
	case LogicalOperatorType::DELIM_JOIN:
		return CreatePlan((LogicalDelimJoin &)op);
	case LogicalOperatorType::COMPARISON_JOIN:
		return CreatePlan((LogicalComparisonJoin &)op);
	case LogicalOperatorType::CROSS_PRODUCT:
		return CreatePlan((LogicalCrossProduct &)op);
	case LogicalOperatorType::UNION:
	case LogicalOperatorType::EXCEPT:
	case LogicalOperatorType::INTERSECT:
		return CreatePlan((LogicalSetOperation &)op);
	case LogicalOperatorType::INSERT:
		return CreatePlan((LogicalInsert &)op);
	case LogicalOperatorType::DELETE:
		return CreatePlan((LogicalDelete &)op);
	case LogicalOperatorType::CHUNK_GET:
		return CreatePlan((LogicalChunkGet &)op);
	case LogicalOperatorType::DELIM_GET:
		return CreatePlan((LogicalDelimGet &)op);
	case LogicalOperatorType::EXPRESSION_GET:
		return CreatePlan((LogicalExpressionGet &)op);
	case LogicalOperatorType::UPDATE:
		return CreatePlan((LogicalUpdate &)op);
	case LogicalOperatorType::CREATE_TABLE:
		return CreatePlan((LogicalCreateTable &)op);
	case LogicalOperatorType::CREATE_INDEX:
		return CreatePlan((LogicalCreateIndex &)op);
	case LogicalOperatorType::EXPLAIN:
		return CreatePlan((LogicalExplain &)op);
	case LogicalOperatorType::DISTINCT:
		return CreatePlan((LogicalDistinct &)op);
	case LogicalOperatorType::PRUNE_COLUMNS:
		return CreatePlan((LogicalPruneColumns &)op);
	case LogicalOperatorType::PREPARE:
		return CreatePlan((LogicalPrepare &)op);
	case LogicalOperatorType::EXECUTE:
		return CreatePlan((LogicalExecute &)op);
	case LogicalOperatorType::INDEX_SCAN:
		return CreatePlan((LogicalIndexScan &)op);
	case LogicalOperatorType::CREATE_VIEW:
	case LogicalOperatorType::CREATE_SEQUENCE:
	case LogicalOperatorType::CREATE_SCHEMA:
		return CreatePlan((LogicalCreate &)op);
	case LogicalOperatorType::TRANSACTION:
	case LogicalOperatorType::ALTER:
	case LogicalOperatorType::DROP:
	case LogicalOperatorType::PRAGMA:
	case LogicalOperatorType::VACUUM:
		return CreatePlan((LogicalSimple &)op);
	case LogicalOperatorType::RECURSIVE_CTE:
		return CreatePlan((LogicalRecursiveCTE &)op);
	case LogicalOperatorType::CTE_REF:
		return CreatePlan((LogicalCTERef &)op);
	default:
		throw NotImplementedException("Unimplemented logical operator type!");
	}
}




#include <cmath>

using namespace duckdb;
using namespace std;

WindowSegmentTree::WindowSegmentTree(AggregateFunction &aggregate, TypeId result_type, ChunkCollection *input)
    : aggregate(aggregate), state(aggregate.state_size()), statep(TypeId::POINTER), result_type(result_type),
      input_ref(input) {
	statep.SetCount(STANDARD_VECTOR_SIZE);
	Value ptr_val = Value::POINTER((idx_t)state.data());
	statep.Reference(ptr_val);
	statep.Normalify(STANDARD_VECTOR_SIZE);

	if (input_ref && input_ref->column_count() > 0) {
		inputs.Initialize(input_ref->types);
		if (aggregate.combine) {
			ConstructTree();
		}
	}
}

void WindowSegmentTree::AggregateInit() {
	aggregate.initialize(state.data());
}

Value WindowSegmentTree::AggegateFinal() {
	Vector statev(Value::POINTER((idx_t)state.data()));
	Vector result(result_type);
	result.vector_type = VectorType::CONSTANT_VECTOR;
	ConstantVector::SetNull(result, false);
	aggregate.finalize(statev, result, 1);

	return result.GetValue(0);
}

void WindowSegmentTree::WindowSegmentValue(idx_t l_idx, idx_t begin, idx_t end) {
	assert(begin <= end);
	if (begin == end) {
		return;
	}
	inputs.SetCardinality(end - begin);

	idx_t start_in_vector = begin % STANDARD_VECTOR_SIZE;
	Vector s;
	s.Slice(statep, start_in_vector);
	if (l_idx == 0) {
		const auto input_count = input_ref->column_count();
		auto &chunk = input_ref->GetChunk(begin);
		for (idx_t i = 0; i < input_count; ++i) {
			auto &v = inputs.data[i];
			auto &vec = chunk.data[i];
			v.Slice(vec, start_in_vector);
			v.Verify(inputs.size());
		}
		aggregate.update(&inputs.data[0], input_count, s, inputs.size());
	} else {
		assert(end - begin <= STANDARD_VECTOR_SIZE);
		data_ptr_t ptr = levels_flat_native.get() + state.size() * (begin + levels_flat_start[l_idx - 1]);
		Vector v(result_type, ptr);
		v.Verify(inputs.size());
		aggregate.combine(v, s, inputs.size());
	}
}

void WindowSegmentTree::ConstructTree() {
	assert(input_ref);
	assert(inputs.column_count() > 0);

	// compute space required to store internal nodes of segment tree
	idx_t internal_nodes = 0;
	idx_t level_nodes = input_ref->count;
	do {
		level_nodes = (idx_t)ceil((double)level_nodes / TREE_FANOUT);
		internal_nodes += level_nodes;
	} while (level_nodes > 1);
	levels_flat_native = unique_ptr<data_t[]>(new data_t[internal_nodes * state.size()]);
	levels_flat_start.push_back(0);

	idx_t levels_flat_offset = 0;
	idx_t level_current = 0;
	// level 0 is data itself
	idx_t level_size;
	while ((level_size = (level_current == 0 ? input_ref->count
	                                         : levels_flat_offset - levels_flat_start[level_current - 1])) > 1) {
		for (idx_t pos = 0; pos < level_size; pos += TREE_FANOUT) {
			AggregateInit();
			WindowSegmentValue(level_current, pos, min(level_size, pos + TREE_FANOUT));

			memcpy(levels_flat_native.get() + (levels_flat_offset * state.size()), state.data(), state.size());

			levels_flat_offset++;
		}

		levels_flat_start.push_back(levels_flat_offset);
		level_current++;
	}
}

Value WindowSegmentTree::Compute(idx_t begin, idx_t end) {
	assert(input_ref);

	// No arguments, so just count
	if (inputs.column_count() == 0) {
		return Value::Numeric(result_type, end - begin);
	}

	AggregateInit();

	// Aggregate everything at once if we can't combine states
	if (!aggregate.combine) {
		WindowSegmentValue(0, begin, end);
		return AggegateFinal();
	}

	for (idx_t l_idx = 0; l_idx < levels_flat_start.size() + 1; l_idx++) {
		idx_t parent_begin = begin / TREE_FANOUT;
		idx_t parent_end = end / TREE_FANOUT;
		if (parent_begin == parent_end) {
			WindowSegmentValue(l_idx, begin, end);
			return AggegateFinal();
		}
		idx_t group_begin = parent_begin * TREE_FANOUT;
		if (begin != group_begin) {
			WindowSegmentValue(l_idx, begin, group_begin + TREE_FANOUT);
			parent_begin++;
		}
		idx_t group_end = parent_end * TREE_FANOUT;
		if (end != group_end) {
			WindowSegmentValue(l_idx, group_end, end);
		}
		begin = parent_begin;
		end = parent_end;
	}

	return AggegateFinal();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/aggregate/algebraic_functions.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct AvgFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CovarSampFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CovarPopFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct StdDevSampFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct StdDevPopFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct VarPopFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct VarSampFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb






using namespace duckdb;
using namespace std;

template <class T> struct avg_state_t {
	uint64_t count;
	T sum;
};

struct AverageFunction {
	template <class STATE> static void Initialize(STATE *state) {
		state->count = 0;
		state->sum = 0;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void Operation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t idx) {
		state->sum += input[idx];
		state->count++;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t count) {
		state->count += count;
		state->sum += input[0] * count;
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		target->count += source.count;
		target->sum += source.sum;
	}

	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (state->count == 0) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->sum / state->count;
		}
	}

	static bool IgnoreNull() {
		return true;
	}
};

void AvgFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet avg("avg");
	avg.AddFunction(AggregateFunction::UnaryAggregate<avg_state_t<double>, double, double, AverageFunction>(
	    SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(avg);
}





#include <cmath>

using namespace duckdb;
using namespace std;

struct covar_state_t {
	uint64_t count;
	double meanx;
	double meany;
	double co_moment;
};

struct CovarOperation {
	template <class STATE> static void Initialize(STATE *state) {
		state->count = 0;
		state->meanx = 0;
		state->meany = 0;
		state->co_moment = 0;
	}

	template <class A_TYPE, class B_TYPE, class STATE, class OP>
	static void Operation(STATE *state, A_TYPE *x_data, B_TYPE *y_data, nullmask_t &anullmask, nullmask_t &bnullmask,
	                      idx_t xidx, idx_t yidx) {
		// update running mean and d^2
		const uint64_t n = ++(state->count);

		const auto x = x_data[xidx];
		const double dx = (x - state->meanx);
		const double meanx = state->meanx + dx / n;

		const auto y = y_data[yidx];
		const double dy = (y - state->meany);
		const double meany = state->meany + dy / n;

		const double C = state->co_moment + dx * (y - meany);

		state->meanx = meanx;
		state->meany = meany;
		state->co_moment = C;
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		if (target->count == 0) {
			*target = source;
		} else if (source.count > 0) {
			const auto count = target->count + source.count;
			const auto meanx = (source.count * source.meanx + target->count * target->meanx) / count;
			const auto meany = (source.count * source.meany + target->count * target->meany) / count;

			//  Schubert and Gertz SSDBM 2018, equation 21
			const auto deltax = target->meanx - source.meanx;
			const auto deltay = target->meany - source.meany;
			target->co_moment =
			    source.co_moment + target->co_moment + deltax * deltay * source.count * target->count / count;
			target->meanx = meanx;
			target->meany = meany;
			target->count = count;
		}
	}

	static bool IgnoreNull() {
		return true;
	}
};

struct CovarPopOperation : public CovarOperation {
	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (state->count == 0) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->co_moment / state->count;
		}
	}
};

struct CovarSampOperation : public CovarOperation {
	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if ((state->count) < 2) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->co_moment / (state->count - 1);
		}
	}
};

void CovarPopFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet covar_pop("covar_pop");
	covar_pop.AddFunction(AggregateFunction::BinaryAggregate<covar_state_t, double, double, double, CovarPopOperation>(
	    SQLType::DOUBLE, SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(covar_pop);
}

void CovarSampFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet covar_samp("covar_samp");
	covar_samp.AddFunction(
	    AggregateFunction::BinaryAggregate<covar_state_t, double, double, double, CovarSampOperation>(
	        SQLType::DOUBLE, SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(covar_samp);
}




#include <cmath>

using namespace duckdb;
using namespace std;

struct stddev_state_t {
	uint64_t count;  //  n
	double mean;     //  M1
	double dsquared; //  M2
};

// Streaming approximate standard deviation using Welford's
// method, DOI: 10.2307/1266577
struct STDDevBaseOperation {
	template <class STATE> static void Initialize(STATE *state) {
		state->count = 0;
		state->mean = 0;
		state->dsquared = 0;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void Operation(STATE *state, INPUT_TYPE *input_data, nullmask_t &nullmask, idx_t idx) {
		// update running mean and d^2
		state->count++;
		const double input = input_data[idx];
		const double mean_differential = (input - state->mean) / state->count;
		const double new_mean = state->mean + mean_differential;
		const double dsquared_increment = (input - new_mean) * (input - state->mean);
		const double new_dsquared = state->dsquared + dsquared_increment;

		state->mean = new_mean;
		state->dsquared = new_dsquared;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input_data, nullmask_t &nullmask, idx_t count) {
		for (idx_t i = 0; i < count; i++) {
			Operation<INPUT_TYPE, STATE, OP>(state, input_data, nullmask, 0);
		}
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		if (target->count == 0) {
			*target = source;
		} else if (source.count > 0) {
			const auto count = target->count + source.count;
			const auto mean = (source.count * source.mean + target->count * target->mean) / count;
			const auto delta = source.mean - target->mean;
			target->dsquared =
			    source.dsquared + target->dsquared + delta * delta * source.count * target->count / count;
			target->mean = mean;
			target->count = count;
		}
	}

	static bool IgnoreNull() {
		return true;
	}
};

struct VarSampOperation : public STDDevBaseOperation {
	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (state->count == 0) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->count > 1 ? (state->dsquared / (state->count - 1)) : 0;
		}
	}
};

struct VarPopOperation : public STDDevBaseOperation {
	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (state->count == 0) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->count > 1 ? (state->dsquared / state->count) : 0;
		}
	}
};

struct STDDevSampOperation : public STDDevBaseOperation {
	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (state->count == 0) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->count > 1 ? sqrt(state->dsquared / (state->count - 1)) : 0;
		}
	}
};

struct STDDevPopOperation : public STDDevBaseOperation {
	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (state->count == 0) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->count > 1 ? sqrt(state->dsquared / state->count) : 0;
		}
	}
};

void StdDevSampFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet stddev_samp("stddev_samp");
	stddev_samp.AddFunction(AggregateFunction::UnaryAggregate<stddev_state_t, double, double, STDDevSampOperation>(
	    SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(stddev_samp);
}

void StdDevPopFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet stddev_pop("stddev_pop");
	stddev_pop.AddFunction(AggregateFunction::UnaryAggregate<stddev_state_t, double, double, STDDevPopOperation>(
	    SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(stddev_pop);
}

void VarPopFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet var_pop("var_pop");
	var_pop.AddFunction(AggregateFunction::UnaryAggregate<stddev_state_t, double, double, VarPopOperation>(
	    SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(var_pop);
}

void VarSampFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet var_samp("var_samp");
	var_samp.AddFunction(AggregateFunction::UnaryAggregate<stddev_state_t, double, double, VarSampOperation>(
	    SQLType::DOUBLE, SQLType::DOUBLE));
	set.AddFunction(var_samp);
}



using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterAlgebraicAggregates() {
	Register<AvgFun>();

	Register<CovarSampFun>();
	Register<CovarPopFun>();

	Register<StdDevSampFun>();
	Register<StdDevPopFun>();
	Register<VarPopFun>();
	Register<VarSampFun>();
}

} // namespace duckdb





using namespace std;

namespace duckdb {

struct BaseCountFunction {
	template <class STATE> static void Initialize(STATE *state) {
		*state = 0;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void Operation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t idx) {
		*state += 1;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t count) {
		*state += count;
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		*target += source;
	}

	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		target[idx] = *state;
	}
};

struct CountStarFunction : public BaseCountFunction {
	static bool IgnoreNull() {
		return false;
	}
};

struct CountFunction : public BaseCountFunction {
	static bool IgnoreNull() {
		return true;
	}
};

AggregateFunction CountFun::GetFunction() {
	return AggregateFunction::UnaryAggregate<int64_t, int64_t, int64_t, CountFunction>(SQLType(SQLTypeId::ANY),
	                                                                                   SQLType::BIGINT);
}

AggregateFunction CountStarFun::GetFunction() {
	return AggregateFunction::UnaryAggregate<int64_t, int64_t, int64_t, CountStarFunction>(SQLType(SQLTypeId::ANY),
	                                                                                       SQLType::BIGINT);
}

void CountFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunction count_function = CountFun::GetFunction();
	AggregateFunctionSet count("count");
	count.AddFunction(count_function);
	// the count function can also be called without arguments
	count_function.arguments.clear();
	count.AddFunction(count_function);
	set.AddFunction(count);
}

void CountStarFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet count("count_star");
	count.AddFunction(CountStarFun::GetFunction());
	set.AddFunction(count);
}

} // namespace duckdb





using namespace std;

namespace duckdb {

template <class T> struct FirstState {
	bool is_set;
	T value;
};

struct FirstFunctionBase {
	template <class STATE> static void Initialize(STATE *state) {
		state->is_set = false;
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		if (!target->is_set) {
			*target = source;
		}
	}

	static bool IgnoreNull() {
		return false;
	}
};

struct FirstFunction : public FirstFunctionBase {
	template <class INPUT_TYPE, class STATE, class OP>
	static void Operation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t idx) {
		if (!state->is_set) {
			state->is_set = true;
			if (nullmask[idx]) {
				state->value = NullValue<INPUT_TYPE>();
			} else {
				state->value = input[idx];
			}
		}
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t count) {
		Operation<INPUT_TYPE, STATE, OP>(state, input, nullmask, 0);
	}

	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (!state->is_set || IsNullValue<T>(state->value)) {
			nullmask[idx] = true;
		} else {
			target[idx] = state->value;
		}
	}
};

struct FirstFunctionString : public FirstFunctionBase {
	template <class INPUT_TYPE, class STATE, class OP>
	static void Operation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t idx) {
		if (!state->is_set) {
			state->is_set = true;
			if (nullmask[idx]) {
				state->value = NullValue<INPUT_TYPE>();
			} else {
				if (input[idx].IsInlined()) {
					state->value = input[idx];
				} else {
					// non-inlined string, need to allocate space for it
					auto len = input[idx].GetSize();
					auto ptr = new char[len + 1];
					memcpy(ptr, input[idx].GetData(), len + 1);

					state->value = string_t(ptr, len);
				}
			}
		}
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t count) {
		Operation<INPUT_TYPE, STATE, OP>(state, input, nullmask, 0);
	}

	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (!state->is_set || IsNullValue<T>(state->value)) {
			nullmask[idx] = true;
		} else {
			target[idx] = StringVector::AddString(result, state->value);
		}
	}

	template <class STATE> static void Destroy(STATE *state) {
		if (state->is_set && !state->value.IsInlined()) {
			delete[] state->value.GetData();
		}
	}
};

template <class T> static AggregateFunction GetFirstAggregateTemplated(SQLType type) {
	return AggregateFunction::UnaryAggregate<FirstState<T>, T, T, FirstFunction>(type, type);
}

AggregateFunction FirstFun::GetFunction(SQLType type) {
	switch (type.id) {
	case SQLTypeId::BOOLEAN:
		return GetFirstAggregateTemplated<bool>(type);
	case SQLTypeId::TINYINT:
		return GetFirstAggregateTemplated<int8_t>(type);
	case SQLTypeId::SMALLINT:
		return GetFirstAggregateTemplated<int16_t>(type);
	case SQLTypeId::INTEGER:
		return GetFirstAggregateTemplated<int32_t>(type);
	case SQLTypeId::BIGINT:
		return GetFirstAggregateTemplated<int64_t>(type);
	case SQLTypeId::FLOAT:
		return GetFirstAggregateTemplated<float>(type);
	case SQLTypeId::DOUBLE:
		return GetFirstAggregateTemplated<double>(type);
	case SQLTypeId::DECIMAL:
		return GetFirstAggregateTemplated<double>(type);
	case SQLTypeId::DATE:
		return GetFirstAggregateTemplated<date_t>(type);
	case SQLTypeId::TIMESTAMP:
		return GetFirstAggregateTemplated<timestamp_t>(type);
	case SQLTypeId::VARCHAR:
		return AggregateFunction::UnaryAggregateDestructor<FirstState<string_t>, string_t, string_t,
		                                                   FirstFunctionString>(type, type);
	default:
		throw NotImplementedException("Unimplemented type for FIRST aggregate");
	}
}

void FirstFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet first("first");
	for (auto type : SQLType::ALL_TYPES) {
		first.AddFunction(FirstFun::GetFunction(type));
	}
	set.AddFunction(first);
}

} // namespace duckdb








using namespace std;

namespace duckdb {

struct MinMaxBase : public StandardDistributiveFunction {
	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t count) {
		assert(!nullmask[0]);
		if (IsNullValue<INPUT_TYPE>(*state)) {
			*state = input[0];
		} else {
			OP::template Execute<INPUT_TYPE, STATE>(state, input[0]);
		}
	}
};

struct MinOperation : public MinMaxBase {
	template <class INPUT_TYPE, class STATE> static void Execute(STATE *state, INPUT_TYPE input) {
		if (LessThan::Operation<INPUT_TYPE>(input, *state)) {
			*state = input;
		}
	}
};

struct MaxOperation : public MinMaxBase {
	template <class INPUT_TYPE, class STATE> static void Execute(STATE *state, INPUT_TYPE input) {
		if (GreaterThan::Operation<INPUT_TYPE>(input, *state)) {
			*state = input;
		}
	}
};

void MinFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet min("min");
	for (auto type : SQLType::ALL_TYPES) {
		min.AddFunction(AggregateFunction::GetUnaryAggregate<MinOperation>(type));
	}
	set.AddFunction(min);
}

void MaxFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet max("max");
	for (auto type : SQLType::ALL_TYPES) {
		max.AddFunction(AggregateFunction::GetUnaryAggregate<MaxOperation>(type));
	}
	set.AddFunction(max);
}

} // namespace duckdb




#include <string>

using namespace std;

namespace duckdb {

struct string_agg_state_t {
	char *dataptr;
	idx_t size;
	idx_t alloc_size;
};

struct StringAggFunction {
	template <class STATE> static void Initialize(STATE *state) {
		state->dataptr = nullptr;
		state->alloc_size = 0;
		state->size = 0;
	}

	template <class A_TYPE, class B_TYPE, class STATE, class OP>
	static void Operation(STATE *state, A_TYPE *str_data, B_TYPE *sep_data, nullmask_t &str_nullmask,
	                      nullmask_t &sep_nullmask, idx_t str_idx, idx_t sep_idx) {
		auto str = str_data[str_idx].GetData();
		auto sep = sep_data[sep_idx].GetData();
		auto str_size = str_data[str_idx].GetSize() + 1;
		auto sep_size = sep_data[sep_idx].GetSize();

		if (state->dataptr == nullptr) {
			// first iteration: allocate space for the string and copy it into the state
			state->alloc_size = std::max((idx_t)8, (idx_t)NextPowerOfTwo(str_size));
			state->dataptr = new char[state->alloc_size];
			state->size = str_size - 1;
			memcpy(state->dataptr, str, str_size);
		} else {
			// subsequent iteration: first check if we have space to place the string and separator
			idx_t required_size = state->size + str_size + sep_size;
			if (required_size > state->alloc_size) {
				// no space! allocate extra space
				while (state->alloc_size < required_size) {
					state->alloc_size *= 2;
				}
				auto new_data = new char[state->alloc_size];
				memcpy(new_data, state->dataptr, state->size);
				delete[] state->dataptr;
				state->dataptr = new_data;
			}
			// copy the separator
			memcpy(state->dataptr + state->size, sep, sep_size);
			state->size += sep_size;
			// copy the string
			memcpy(state->dataptr + state->size, str, str_size);
			state->size += str_size - 1;
		}
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		throw NotImplementedException("String aggregate combine!");
	}

	template <class T, class STATE>
	static void Finalize(Vector &result, STATE *state, T *target, nullmask_t &nullmask, idx_t idx) {
		if (!state->dataptr) {
			nullmask[idx] = true;
		} else {
			target[idx] = StringVector::AddString(result, state->dataptr, state->size);
		}
	}

	template <class STATE> static void Destroy(STATE *state) {
		if (state->dataptr) {
			delete[] state->dataptr;
		}
	}

	static bool IgnoreNull() {
		return true;
	}
};

void StringAggFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet string_agg("string_agg");
	string_agg.AddFunction(AggregateFunction::BinaryAggregateDestructor<string_agg_state_t, string_t, string_t,
	                                                                    string_t, StringAggFunction>(
	    SQLType::VARCHAR, SQLType::VARCHAR, SQLType::VARCHAR));
	set.AddFunction(string_agg);
}

} // namespace duckdb







using namespace std;

namespace duckdb {

struct SumOperation : public StandardDistributiveFunction {
	template <class INPUT_TYPE, class STATE> static void Execute(STATE *state, INPUT_TYPE input) {
		*state += input;
	}

	template <class INPUT_TYPE, class STATE, class OP>
	static void ConstantOperation(STATE *state, INPUT_TYPE *input, nullmask_t &nullmask, idx_t count) {
		assert(!nullmask[0]);
		if (IsNullValue<INPUT_TYPE>(*state)) {
			*state = 0;
		}
		*state += input[0] * count;
	}
};

void SumFun::RegisterFunction(BuiltinFunctions &set) {
	AggregateFunctionSet sum("sum");
	// integer sums to bigint
	sum.AddFunction(
	    AggregateFunction::UnaryAggregate<int64_t, int64_t, int64_t, SumOperation>(SQLType::BIGINT, SQLType::BIGINT));
	// float sums to float
	sum.AddFunction(
	    AggregateFunction::UnaryAggregate<double, double, double, SumOperation>(SQLType::DOUBLE, SQLType::DOUBLE));

	set.AddFunction(sum);
}

} // namespace duckdb






using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterDistributiveAggregates() {
	Register<CountStarFun>();
	Register<CountFun>();
	Register<FirstFun>();
	Register<MaxFun>();
	Register<MinFun>();
	Register<SumFun>();
	Register<StringAggFun>();
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/aggregate/distributive_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {


struct ListBindData : public FunctionData {
	ListBindData() {
	}

	unique_ptr<FunctionData> Copy() override {
		return make_unique<ListBindData>();
	}
};

struct ListFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb




using namespace std;

namespace duckdb {

struct list_agg_state_t {
	ChunkCollection *cc;
};

struct ListFunction {
	template <class STATE> static void Initialize(STATE *state) {
		state->cc = nullptr;
	}

	template <class STATE, class OP> static void Combine(STATE source, STATE *target) {
		throw NotImplementedException("COMBINE not implemented for LIST");
	}

	template <class STATE> static void Destroy(STATE *state) {
		if (state->cc) {
			delete state->cc;
		}
	}
	static bool IgnoreNull() {
		return true;
	}
};

static void list_update(Vector inputs[], idx_t input_count, Vector &state_vector, idx_t count) {
	assert(input_count == 1);

	auto &input = inputs[0];
	VectorData sdata;
	state_vector.Orrify(count, sdata);

	DataChunk insert_chunk;

	vector<TypeId> chunk_types;
	chunk_types.push_back(input.type);
	insert_chunk.Initialize(chunk_types);
	insert_chunk.SetCardinality(1);

	auto states = (list_agg_state_t **)sdata.data;
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	for (idx_t i = 0; i < count; i++) {
		auto state = states[sdata.sel->get_index(i)];
		if (!state->cc) {
			state->cc = new ChunkCollection();
		}
		sel.set_index(0, i);
		insert_chunk.data[0].Slice(input, sel, 1);
		state->cc->Append(insert_chunk);
	}
}

static void list_finalize(Vector &state_vector, Vector &result, idx_t count) {
	VectorData sdata;
	state_vector.Orrify(count, sdata);
	auto states = (list_agg_state_t **)sdata.data;

	result.Initialize(TypeId::LIST);
	auto list_struct_data = FlatVector::GetData<list_entry_t>(result);

	size_t total_len = 0;
	for (idx_t i = 0; i < count; i++) {
		auto state = states[sdata.sel->get_index(i)];
		assert(state->cc);
		auto &state_cc = *state->cc;
		assert(state_cc.types.size() == 1);
		list_struct_data[i].length = state_cc.count;
		list_struct_data[i].offset = total_len;
		total_len += state_cc.count;
	}

	auto list_child = make_unique<ChunkCollection>();
	for (idx_t i = 0; i < count; i++) {
		auto state = states[sdata.sel->get_index(i)];
		auto &state_cc = *state->cc;
		assert(state_cc.chunks[0]->column_count() == 1);
		list_child->Append(state_cc);
	}
	assert(list_child->count == total_len);
	ListVector::SetEntry(result, move(list_child));
}

unique_ptr<FunctionData> list_bind(BoundAggregateExpression &expr, ClientContext &context, SQLType &return_type) {
	assert(expr.children.size() == 1);
	return_type = SQLType::LIST;
	return_type.child_type.push_back(make_pair("", expr.arguments[0]));
	return make_unique<ListBindData>(); // TODO atm this is not used anywhere but it might not be required after all
	                                    // except for sanity checking
}

void ListFun::RegisterFunction(BuiltinFunctions &set) {
	auto agg = AggregateFunction("list", {SQLType::ANY}, SQLType::LIST, AggregateFunction::StateSize<list_agg_state_t>,
	                             AggregateFunction::StateInitialize<list_agg_state_t, ListFunction>, list_update,
	                             AggregateFunction::StateCombine<list_agg_state_t, ListFunction>, list_finalize,
	                             nullptr, list_bind, AggregateFunction::StateDestroy<list_agg_state_t, ListFunction>);
	set.AddFunction(agg);
}

} // namespace duckdb


using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterNestedAggregates() {
	Register<ListFun>();
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/cast_rules.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Contains a list of rules for casting
class CastRules {
public:
	//! Returns the cost of performing an implicit cost from "from" to "to", or -1 if an implicit cast is not possible
	static int64_t ImplicitCast(SQLType from, SQLType to);
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

//! The target type determines the preferred implicit casts
static int64_t TargetTypeCost(SQLType type) {
	switch (type.id) {
	case SQLTypeId::INTEGER:
		return 103;
	case SQLTypeId::BIGINT:
		return 101;
	case SQLTypeId::DOUBLE:
		return 102;
	case SQLTypeId::VARCHAR:
		return 199;
	default:
		return 110;
	}
}

static int64_t ImplicitCastTinyint(SQLType to) {
	switch (to.id) {
	case SQLTypeId::SMALLINT:
	case SQLTypeId::INTEGER:
	case SQLTypeId::BIGINT:
	case SQLTypeId::FLOAT:
	case SQLTypeId::DOUBLE:
	case SQLTypeId::DECIMAL:
		return TargetTypeCost(to);
	default:
		return -1;
	}
}

static int64_t ImplicitCastSmallint(SQLType to) {
	switch (to.id) {
	case SQLTypeId::INTEGER:
	case SQLTypeId::BIGINT:
	case SQLTypeId::FLOAT:
	case SQLTypeId::DOUBLE:
	case SQLTypeId::DECIMAL:
		return TargetTypeCost(to);
	default:
		return -1;
	}
}

static int64_t ImplicitCastInteger(SQLType to) {
	switch (to.id) {
	case SQLTypeId::BIGINT:
	case SQLTypeId::FLOAT:
	case SQLTypeId::DOUBLE:
	case SQLTypeId::DECIMAL:
		return TargetTypeCost(to);
	default:
		return -1;
	}
}

static int64_t ImplicitCastBigint(SQLType to) {
	switch (to.id) {
	case SQLTypeId::FLOAT:
	case SQLTypeId::DOUBLE:
	case SQLTypeId::DECIMAL:
		return TargetTypeCost(to);
	default:
		return -1;
	}
}

static int64_t ImplicitCastFloat(SQLType to) {
	switch (to.id) {
	case SQLTypeId::DOUBLE:
	case SQLTypeId::DECIMAL:
		return TargetTypeCost(to);
	default:
		return -1;
	}
}

static int64_t ImplicitCastDouble(SQLType to) {
	switch (to.id) {
	case SQLTypeId::DECIMAL:
		return TargetTypeCost(to);
	default:
		return -1;
	}
}

int64_t CastRules::ImplicitCast(SQLType from, SQLType to) {
	if (to.id == SQLTypeId::ANY) {
		// anything can be cast to ANY type for no cost
		return 0;
	}
	if (from.id == SQLTypeId::SQLNULL || from.id == SQLTypeId::UNKNOWN) {
		// NULL expression or parameter expression can be cast to anything
		return TargetTypeCost(to);
	}
	if (to.id == SQLTypeId::VARCHAR) {
		// everything can be cast to VARCHAR, but this cast has a high cost
		return TargetTypeCost(to);
	}
	switch (from.id) {
	case SQLTypeId::TINYINT:
		return ImplicitCastTinyint(to);
	case SQLTypeId::SMALLINT:
		return ImplicitCastSmallint(to);
	case SQLTypeId::INTEGER:
		return ImplicitCastInteger(to);
	case SQLTypeId::BIGINT:
		return ImplicitCastBigint(to);
	case SQLTypeId::FLOAT:
		return ImplicitCastFloat(to);
	case SQLTypeId::DOUBLE:
		return ImplicitCastDouble(to);
	default:
		return -1;
	}
}















using namespace duckdb;
using namespace std;

// add your initializer for new functions here
void BuiltinFunctions::Initialize() {
	RegisterSQLiteFunctions();
	RegisterReadFunctions();

	RegisterAlgebraicAggregates();
	RegisterDistributiveAggregates();
	RegisterNestedAggregates();

	RegisterDateFunctions();
	RegisterMathFunctions();
	RegisterOperators();
	RegisterSequenceFunctions();
	RegisterStringFunctions();
	RegisterNestedFunctions();
	RegisterTrigonometricsFunctions();
}

BuiltinFunctions::BuiltinFunctions(ClientContext &context, Catalog &catalog) : context(context), catalog(catalog) {
}

void BuiltinFunctions::AddFunction(AggregateFunctionSet set) {
	CreateAggregateFunctionInfo info(set);
	catalog.CreateFunction(context, &info);
}

void BuiltinFunctions::AddFunction(AggregateFunction function) {
	CreateAggregateFunctionInfo info(function);
	catalog.CreateFunction(context, &info);
}

void BuiltinFunctions::AddFunction(ScalarFunction function) {
	CreateScalarFunctionInfo info(function);
	catalog.CreateFunction(context, &info);
}

void BuiltinFunctions::AddFunction(ScalarFunctionSet set) {
	CreateScalarFunctionInfo info(set);
	catalog.CreateFunction(context, &info);
}

void BuiltinFunctions::AddFunction(TableFunction function) {
	CreateTableFunctionInfo info(function);
	catalog.CreateTableFunction(context, &info);
}

string Function::CallToString(string name, vector<SQLType> arguments) {
	string result = name + "(";
	result += StringUtil::Join(arguments, arguments.size(), ", ",
	                           [](const SQLType &argument) { return SQLTypeToString(argument); });
	return result + ")";
}

string Function::CallToString(string name, vector<SQLType> arguments, SQLType return_type) {
	string result = CallToString(name, arguments);
	result += " -> " + SQLTypeToString(return_type);
	return result;
}

static int64_t BindVarArgsFunctionCost(SimpleFunction &func, vector<SQLType> &arguments) {
	if (arguments.size() < func.arguments.size()) {
		// not enough arguments to fulfill the non-vararg part of the function
		return -1;
	}
	int64_t cost = 0;
	for (idx_t i = 0; i < arguments.size(); i++) {
		SQLType arg_type = i < func.arguments.size() ? func.arguments[i] : func.varargs;
		if (arguments[i] == arg_type) {
			// arguments match: do nothing
			continue;
		}
		int64_t cast_cost = CastRules::ImplicitCast(arguments[i], arg_type);
		if (cast_cost >= 0) {
			// we can implicitly cast, add the cost to the total cost
			cost += cast_cost;
		} else {
			// we can't implicitly cast: throw an error
			return -1;
		}
	}
	return cost;
}

static int64_t BindFunctionCost(SimpleFunction &func, vector<SQLType> &arguments) {
	if (func.HasVarArgs()) {
		// special case varargs function
		return BindVarArgsFunctionCost(func, arguments);
	}
	if (func.arguments.size() != arguments.size()) {
		// invalid argument count: check the next function
		return -1;
	}
	int64_t cost = 0;
	for (idx_t i = 0; i < arguments.size(); i++) {
		if (arguments[i] == func.arguments[i]) {
			// arguments match: do nothing
			continue;
		}
		int64_t cast_cost = CastRules::ImplicitCast(arguments[i], func.arguments[i]);
		if (cast_cost >= 0) {
			// we can implicitly cast, add the cost to the total cost
			cost += cast_cost;
		} else {
			// we can't implicitly cast: throw an error
			return -1;
		}
	}
	return cost;
}

template <class T>
static idx_t BindFunctionFromArguments(string name, vector<T> &functions, vector<SQLType> &arguments) {
	idx_t best_function = INVALID_INDEX;
	int64_t lowest_cost = numeric_limits<int64_t>::max();
	vector<idx_t> conflicting_functions;
	for (idx_t f_idx = 0; f_idx < functions.size(); f_idx++) {
		auto &func = functions[f_idx];
		// check the arguments of the function
		int64_t cost = BindFunctionCost(func, arguments);
		if (cost < 0) {
			// auto casting was not possible
			continue;
		}
		if (cost == lowest_cost) {
			conflicting_functions.push_back(f_idx);
			continue;
		}
		if (cost > lowest_cost) {
			continue;
		}
		conflicting_functions.clear();
		lowest_cost = cost;
		best_function = f_idx;
	}
	if (conflicting_functions.size() > 0) {
		// there are multiple possible function definitions
		// throw an exception explaining which overloads are there
		conflicting_functions.push_back(best_function);
		string call_str = Function::CallToString(name, arguments);
		string candidate_str = "";
		for (auto &conf : conflicting_functions) {
			auto &f = functions[conf];
			candidate_str += "\t" + f.ToString() + "\n";
		}
		throw BinderException("Could not choose a best candidate function for the function call \"%s\". In order to "
		                      "select one, please add explicit type casts.\n\tCandidate functions:\n%s",
		                      call_str.c_str(), candidate_str.c_str());
	}
	if (best_function == INVALID_INDEX) {
		// no matching function was found, throw an error
		string call_str = Function::CallToString(name, arguments);
		string candidate_str = "";
		for (auto &f : functions) {
			candidate_str += "\t" + f.ToString() + "\n";
		}
		throw BinderException("No function matches the given name and argument types '%s'. You might need to add "
		                      "explicit type casts.\n\tCandidate functions:\n%s",
		                      call_str.c_str(), candidate_str.c_str());
	}
	return best_function;
}

idx_t Function::BindFunction(string name, vector<ScalarFunction> &functions, vector<SQLType> &arguments) {
	return BindFunctionFromArguments(name, functions, arguments);
}

idx_t Function::BindFunction(string name, vector<AggregateFunction> &functions, vector<SQLType> &arguments) {
	return BindFunctionFromArguments(name, functions, arguments);
}

void SimpleFunction::CastToFunctionArguments(vector<unique_ptr<Expression>> &children, vector<SQLType> &types) {
	for (idx_t i = 0; i < types.size(); i++) {
		auto target_type = i < this->arguments.size() ? this->arguments[i] : this->varargs;
		if (target_type.id != SQLTypeId::ANY && types[i] != target_type) {
			// type of child does not match type of function argument: add a cast
			children[i] = BoundCastExpression::AddCastToType(move(children[i]), types[i], target_type);
		}
	}
}

unique_ptr<BoundFunctionExpression> ScalarFunction::BindScalarFunction(ClientContext &context, string schema,
                                                                       string name, vector<SQLType> &arguments,
                                                                       vector<unique_ptr<Expression>> children,
                                                                       bool is_operator) {
	// bind the function
	auto function = Catalog::GetCatalog(context).GetEntry(context, CatalogType::SCALAR_FUNCTION, schema, name);
	assert(function && function->type == CatalogType::SCALAR_FUNCTION);
	return ScalarFunction::BindScalarFunction(context, (ScalarFunctionCatalogEntry &)*function, arguments,
	                                          move(children), is_operator);
}

unique_ptr<BoundFunctionExpression>
ScalarFunction::BindScalarFunction(ClientContext &context, ScalarFunctionCatalogEntry &func, vector<SQLType> &arguments,
                                   vector<unique_ptr<Expression>> children, bool is_operator) {
	// bind the function
	idx_t best_function = Function::BindFunction(func.name, func.functions, arguments);
	// found a matching function!
	auto &bound_function = func.functions[best_function];
	// check if we need to add casts to the children
	bound_function.CastToFunctionArguments(children, arguments);

	// now create the function
	auto result =
	    make_unique<BoundFunctionExpression>(GetInternalType(bound_function.return_type), bound_function, is_operator);
	result->children = move(children);
	result->arguments = arguments;
	result->sql_return_type = bound_function.return_type;
	if (bound_function.bind) {
		result->bind_info = bound_function.bind(*result, context);
	}
	return result;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/date_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct AgeFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct DatePartFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct DateTruncFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CurrentTimeFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CurrentDateFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CurrentTimestampFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb







using namespace std;

namespace duckdb {

static const char *age_scalar_function(timestamp_t input1, timestamp_t input2, string &output) {
	auto interval = Timestamp::GetDifference(input1, input2);
	auto timestamp = Timestamp::IntervalToTimestamp(interval);
	auto years = timestamp.year;
	auto months = timestamp.month;
	auto days = timestamp.day;
	auto time = interval.time;

	output = "";
	if (years == 0 && months == 0 && days == 0) {
		output += "00:00:00";
	} else {
		if (years != 0) {
			output = std::to_string(years);
			output += " years ";
		}
		if (months != 0) {
			output += std::to_string(months);
			output += " mons ";
		}
		if (days != 0) {
			output += std::to_string(days);
			output += " days";
		}
		if (time != 0) {
			output += " ";
			output += Time::ToString(time);
		}
	}
	return output.c_str();
}

static void age_function_standard(DataChunk &input, ExpressionState &state, Vector &result) {
	assert(input.column_count() == 1);
	auto current_timestamp = Timestamp::GetCurrentTimestamp();

	string output_buffer;
	UnaryExecutor::Execute<timestamp_t, string_t, true>(input.data[0], result, input.size(), [&](timestamp_t input) {
		return StringVector::AddString(result, age_scalar_function(input, current_timestamp, output_buffer));
	});
}

static void age_function(DataChunk &input, ExpressionState &state, Vector &result) {
	assert(input.column_count() == 2);

	string output_buffer;
	BinaryExecutor::Execute<timestamp_t, timestamp_t, string_t, true>(
	    input.data[0], input.data[1], result, input.size(), [&](timestamp_t input1, timestamp_t input2) {
		    return StringVector::AddString(result, age_scalar_function(input1, input2, output_buffer));
	    });
}

void AgeFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet age("age");
	age.AddFunction(ScalarFunction({SQLType::TIMESTAMP}, SQLType::VARCHAR, age_function_standard));
	age.AddFunction(ScalarFunction({SQLType::TIMESTAMP, SQLType::TIMESTAMP}, SQLType::VARCHAR, age_function));
	set.AddFunction(age);
}

} // namespace duckdb







using namespace std;

namespace duckdb {

static void current_time_function(DataChunk &input, ExpressionState &state, Vector &result) {
	assert(input.column_count() == 0);

	auto val = Value::INTEGER(Timestamp::GetTime(Timestamp::GetCurrentTimestamp()));
	result.Reference(val);
}

static void current_date_function(DataChunk &input, ExpressionState &state, Vector &result) {
	assert(input.column_count() == 0);

	auto val = Value::INTEGER(Timestamp::GetDate(Timestamp::GetCurrentTimestamp()));
	result.Reference(val);
}

static void current_timestamp_function(DataChunk &input, ExpressionState &state, Vector &result) {
	assert(input.column_count() == 0);

	auto val = Value::TIMESTAMP(Timestamp::GetCurrentTimestamp());
	result.Reference(val);
}

void CurrentTimeFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet current_time("current_time");
	current_time.AddFunction(ScalarFunction({}, SQLType::TIME, current_time_function));
	set.AddFunction(current_time);
}

void CurrentDateFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet current_date("current_date");
	current_date.AddFunction(ScalarFunction({}, SQLType::DATE, current_date_function));
	set.AddFunction(current_date);
}

void CurrentTimestampFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet current_timestamp("current_timestamp");
	current_timestamp.AddFunction(ScalarFunction({}, SQLType::TIMESTAMP, current_timestamp_function));
	set.AddFunction(current_timestamp);

	ScalarFunctionSet now("now");
	now.AddFunction(ScalarFunction({}, SQLType::TIMESTAMP, current_timestamp_function));
	set.AddFunction(now);
}

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/date_part_specifier.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

enum class DatePartSpecifier : uint8_t {
	YEAR,
	MONTH,
	DAY,
	DECADE,
	CENTURY,
	MILLENNIUM,
	MICROSECONDS,
	MILLISECONDS,
	SECOND,
	MINUTE,
	HOUR,
	EPOCH,
	DOW,
	ISODOW,
	WEEK,
	QUARTER,
	DOY
};

DatePartSpecifier GetDatePartSpecifier(string specifier);

} // namespace duckdb






using namespace std;

namespace duckdb {

DatePartSpecifier GetDatePartSpecifier(string specifier) {
	specifier = StringUtil::Lower(specifier);
	if (specifier == "year") {
		return DatePartSpecifier::YEAR;
	} else if (specifier == "month") {
		return DatePartSpecifier::MONTH;
	} else if (specifier == "day") {
		return DatePartSpecifier::DAY;
	} else if (specifier == "decade") {
		return DatePartSpecifier::DECADE;
	} else if (specifier == "century") {
		return DatePartSpecifier::CENTURY;
	} else if (specifier == "millennium") {
		return DatePartSpecifier::MILLENNIUM;
	} else if (specifier == "microseconds") {
		return DatePartSpecifier::MICROSECONDS;
	} else if (specifier == "milliseconds") {
		return DatePartSpecifier::MILLISECONDS;
	} else if (specifier == "second") {
		return DatePartSpecifier::SECOND;
	} else if (specifier == "minute") {
		return DatePartSpecifier::MINUTE;
	} else if (specifier == "hour") {
		return DatePartSpecifier::HOUR;
	} else if (specifier == "epoch") {
		// seconds since 1970-01-01
		return DatePartSpecifier::EPOCH;
	} else if (specifier == "dow") {
		// day of the week (Sunday = 0, Saturday = 6)
		return DatePartSpecifier::DOW;
	} else if (specifier == "isodow") {
		// isodow (Monday = 1, Sunday = 7)
		return DatePartSpecifier::ISODOW;
	} else if (specifier == "week") {
		// week number
		return DatePartSpecifier::WEEK;
	} else if (specifier == "doy") {
		// day of the year (1-365/366)
		return DatePartSpecifier::DOY;
	} else if (specifier == "quarter") {
		// quarter of the year (1-4)
		return DatePartSpecifier::QUARTER;
	} else {
		throw ConversionException("extract specifier \"%s\" not recognized", specifier.c_str());
	}
}

struct YearOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractYear(input);
	}
};

template <> int64_t YearOperator::Operation(timestamp_t input) {
	return YearOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct MonthOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractMonth(input);
	}
};

template <> int64_t MonthOperator::Operation(timestamp_t input) {
	return MonthOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct DayOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractDay(input);
	}
};

template <> int64_t DayOperator::Operation(timestamp_t input) {
	return DayOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct DecadeOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractYear(input) / 10;
	}
};

template <> int64_t DecadeOperator::Operation(timestamp_t input) {
	return DecadeOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct CenturyOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return ((Date::ExtractYear(input) - 1) / 100) + 1;
	}
};

template <> int64_t CenturyOperator::Operation(timestamp_t input) {
	return CenturyOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct MilleniumOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return ((Date::ExtractYear(input) - 1) / 1000) + 1;
	}
};

template <> int64_t MilleniumOperator::Operation(timestamp_t input) {
	return MilleniumOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct QuarterOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractMonth(input) / 4;
	}
};

template <> int64_t QuarterOperator::Operation(timestamp_t input) {
	return QuarterOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct DayOfWeekOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		// day of the week (Sunday = 0, Saturday = 6)
		// turn sunday into 0 by doing mod 7
		return Date::ExtractISODayOfTheWeek(input) % 7;
	}
};

template <> int64_t DayOfWeekOperator::Operation(timestamp_t input) {
	return DayOfWeekOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct ISODayOfWeekOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		// isodow (Monday = 1, Sunday = 7)
		return Date::ExtractISODayOfTheWeek(input);
	}
};

template <> int64_t ISODayOfWeekOperator::Operation(timestamp_t input) {
	return ISODayOfWeekOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct DayOfYearOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractDayOfTheYear(input);
	}
};

template <> int64_t DayOfYearOperator::Operation(timestamp_t input) {
	return DayOfYearOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct WeekOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::ExtractWeekNumber(input);
	}
};

template <> int64_t WeekOperator::Operation(timestamp_t input) {
	return WeekOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
}

struct EpochOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return Date::Epoch(input);
	}
};

template <> int64_t EpochOperator::Operation(timestamp_t input) {
	return Timestamp::GetEpoch(input);
}

struct MicrosecondsOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return 0;
	}
};

template <> int64_t MicrosecondsOperator::Operation(timestamp_t input) {
	return Timestamp::GetMilliseconds(input) * 1000;
}

struct MillisecondsOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return 0;
	}
};

template <> int64_t MillisecondsOperator::Operation(timestamp_t input) {
	return Timestamp::GetMilliseconds(input);
}

struct SecondsOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return 0;
	}
};

template <> int64_t SecondsOperator::Operation(timestamp_t input) {
	return Timestamp::GetSeconds(input);
}

struct MinutesOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return 0;
	}
};

template <> int64_t MinutesOperator::Operation(timestamp_t input) {
	return Timestamp::GetMinutes(input);
}

struct HoursOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return 0;
	}
};

template <> int64_t HoursOperator::Operation(timestamp_t input) {
	return Timestamp::GetHours(input);
}

template <class T> static int64_t extract_element(DatePartSpecifier type, T element) {
	switch (type) {
	case DatePartSpecifier::YEAR:
		return YearOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::MONTH:
		return MonthOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::DAY:
		return DayOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::DECADE:
		return DecadeOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::CENTURY:
		return CenturyOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::MILLENNIUM:
		return MilleniumOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::QUARTER:
		return QuarterOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::DOW:
		return DayOfWeekOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::ISODOW:
		return ISODayOfWeekOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::DOY:
		return DayOfYearOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::WEEK:
		return WeekOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::EPOCH:
		return EpochOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::MICROSECONDS:
		return MicrosecondsOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::MILLISECONDS:
		return MillisecondsOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::SECOND:
		return SecondsOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::MINUTE:
		return MinutesOperator::Operation<T, int64_t>(element);
	case DatePartSpecifier::HOUR:
		return HoursOperator::Operation<T, int64_t>(element);
	default:
		throw NotImplementedException("Specifier type not implemented");
	}
}

struct DatePartOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA specifier, TB date) {
		return extract_element<TB>(GetDatePartSpecifier(specifier.GetString()), date);
	}
};

template <class OP> static void AddDatePartOperator(BuiltinFunctions &set, string name) {
	ScalarFunctionSet operator_set(name);
	operator_set.AddFunction(
	    ScalarFunction({SQLType::DATE}, SQLType::BIGINT, ScalarFunction::UnaryFunction<date_t, int64_t, OP>));
	operator_set.AddFunction(
	    ScalarFunction({SQLType::TIMESTAMP}, SQLType::BIGINT, ScalarFunction::UnaryFunction<timestamp_t, int64_t, OP>));
	set.AddFunction(operator_set);
}

void DatePartFun::RegisterFunction(BuiltinFunctions &set) {
	// register the individual operators
	AddDatePartOperator<YearOperator>(set, "year");
	AddDatePartOperator<MonthOperator>(set, "month");
	AddDatePartOperator<DayOperator>(set, "day");
	AddDatePartOperator<DecadeOperator>(set, "decade");
	AddDatePartOperator<CenturyOperator>(set, "century");
	AddDatePartOperator<MilleniumOperator>(set, "millenium");
	AddDatePartOperator<QuarterOperator>(set, "quarter");
	AddDatePartOperator<DayOfWeekOperator>(set, "dayofweek");
	AddDatePartOperator<ISODayOfWeekOperator>(set, "isodow");
	AddDatePartOperator<DayOfYearOperator>(set, "dayofyear");
	AddDatePartOperator<WeekOperator>(set, "week");
	AddDatePartOperator<EpochOperator>(set, "epoch");
	AddDatePartOperator<MicrosecondsOperator>(set, "microsecond");
	AddDatePartOperator<MillisecondsOperator>(set, "millisecond");
	AddDatePartOperator<SecondsOperator>(set, "second");
	AddDatePartOperator<MinutesOperator>(set, "minute");
	AddDatePartOperator<HoursOperator>(set, "hour");

	// finally the actual date_part function
	ScalarFunctionSet date_part("date_part");
	date_part.AddFunction(
	    ScalarFunction({SQLType::VARCHAR, SQLType::DATE}, SQLType::BIGINT,
	                   ScalarFunction::BinaryFunction<string_t, date_t, int64_t, DatePartOperator, true>));
	date_part.AddFunction(
	    ScalarFunction({SQLType::VARCHAR, SQLType::TIMESTAMP}, SQLType::BIGINT,
	                   ScalarFunction::BinaryFunction<string_t, timestamp_t, int64_t, DatePartOperator, true>));
	set.AddFunction(date_part);
	date_part.name = "datepart";
	set.AddFunction(date_part);
}

} // namespace duckdb








// TODO date_trunc function should also handle interval data type when it is implemented. See
// https://www.postgresql.org/docs/9.1/functions-datetime.html

using namespace std;

namespace duckdb {

struct MillenniumTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(Date::FromDate((Date::ExtractYear(date) / 1000) * 1000, 1, 1), 0);
	}
};
template <> timestamp_t MillenniumTruncOperator::Operation(date_t input) {
	return MillenniumTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct CenturyTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(Date::FromDate((Date::ExtractYear(date) / 100) * 100, 1, 1), 0);
	}
};
template <> timestamp_t CenturyTruncOperator::Operation(date_t input) {
	return CenturyTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct DecadeTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(Date::FromDate((Date::ExtractYear(date) / 10) * 10, 1, 1), 0);
	}
};
template <> timestamp_t DecadeTruncOperator::Operation(date_t input) {
	return DecadeTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct YearTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(Date::FromDate(Date::ExtractYear(date), 1, 1), 0);
	}
};
template <> timestamp_t YearTruncOperator::Operation(date_t input) {
	return YearTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct QuarterTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);

		int32_t month = Date::ExtractMonth(date);
		month = 1 + (((month - 1) / 3) * 3);
		return Timestamp::FromDatetime(Date::FromDate(Date::ExtractYear(date), month, 1), 0);
	}
};
template <> timestamp_t QuarterTruncOperator::Operation(date_t input) {
	return QuarterTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct MonthTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(Date::FromDate(Date::ExtractYear(date), Date::ExtractMonth(date), 1), 0);
	}
};
template <> timestamp_t MonthTruncOperator::Operation(date_t input) {
	return MonthTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct WeekTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);

		return Timestamp::FromDatetime(Date::GetMondayOfCurrentWeek(date), 0);
	}
};
template <> timestamp_t WeekTruncOperator::Operation(date_t input) {
	return WeekTruncOperator::Operation<timestamp_t, timestamp_t>(Timestamp::FromDatetime(input, 0));
}

struct DayTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(date, 0);
	}
};
template <> timestamp_t DayTruncOperator::Operation(date_t input) {
	return Timestamp::FromDatetime(input, 0);
}

struct HourTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(date, Time::FromTime(Timestamp::GetHours(input), 0, 0, 0));
	}
};
template <> timestamp_t HourTruncOperator::Operation(date_t input) {
	return Timestamp::FromDatetime(input, 0);
}

struct MinuteTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(date,
		                               Time::FromTime(Timestamp::GetHours(input), Timestamp::GetMinutes(input), 0, 0));
	}
};
template <> timestamp_t MinuteTruncOperator::Operation(date_t input) {
	return Timestamp::FromDatetime(input, 0);
}

struct SecondsTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		date_t date = Timestamp::GetDate(input);
		return Timestamp::FromDatetime(date, Time::FromTime(Timestamp::GetHours(input), Timestamp::GetMinutes(input),
		                                                    Timestamp::GetSeconds(input), 0));
	}
};
template <> timestamp_t SecondsTruncOperator::Operation(date_t input) {
	return Timestamp::FromDatetime(input, 0);
}

struct MilliSecondsTruncOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return input;
	}
};
template <> timestamp_t MilliSecondsTruncOperator::Operation(date_t input) {
	return Timestamp::FromDatetime(input, 0);
}

template <class TA, class TR> static TR truncate_element(DatePartSpecifier type, TA element) {
	switch (type) {
	case DatePartSpecifier::MILLENNIUM:
		return MillenniumTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::CENTURY:
		return CenturyTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::DECADE:
		return DecadeTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::YEAR:
		return YearTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::QUARTER:
		return QuarterTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::MONTH:
		return MonthTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::WEEK:
		return WeekTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::DAY:
		return DayTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::HOUR:
		return HourTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::MINUTE:
		return MinuteTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::SECOND:
		return SecondsTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::MILLISECONDS:
		return MilliSecondsTruncOperator::Operation<TA, TR>(element);
	case DatePartSpecifier::MICROSECONDS:
		// Since microseconds are not stored truncating to microseconds does the same as to milliseconds.
		return MilliSecondsTruncOperator::Operation<TA, TR>(element);
	default:
		throw NotImplementedException("Specifier type not implemented");
	}
}

struct DateTruncOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA specifier, TB date) {
		return truncate_element<TB, TR>(GetDatePartSpecifier(specifier.GetString()), date);
	}
};

void DateTruncFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet date_trunc("date_trunc");
	date_trunc.AddFunction(
	    ScalarFunction({SQLType::VARCHAR, SQLType::TIMESTAMP}, SQLType::TIMESTAMP,
	                   ScalarFunction::BinaryFunction<string_t, timestamp_t, timestamp_t, DateTruncOperator>));
	date_trunc.AddFunction(
	    ScalarFunction({SQLType::VARCHAR, SQLType::DATE}, SQLType::TIMESTAMP,
	                   ScalarFunction::BinaryFunction<string_t, date_t, timestamp_t, DateTruncOperator>));
	set.AddFunction(date_trunc);
	date_trunc.name = "datetrunc";
	set.AddFunction(date_trunc);
}

} // namespace duckdb


using namespace duckdb;
using namespace std;

void BuiltinFunctions::RegisterDateFunctions() {
	Register<AgeFun>();
	Register<DatePartFun>();
	Register<DateTruncFun>();
	Register<CurrentTimeFun>();
	Register<CurrentDateFun>();
	Register<CurrentTimestampFun>();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/math_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct AbsFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SignFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CeilFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct FloorFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct RoundFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct DegreesFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct RadiansFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct RandomFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SetseedFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CbrtFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct ExpFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct Log2Fun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct Log10Fun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct LnFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct PowFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SqrtFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct PiFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb



#include <algorithm>
#include <cmath>

using namespace duckdb;
using namespace std;

namespace duckdb {

//===--------------------------------------------------------------------===//
// abs
//===--------------------------------------------------------------------===//
struct AbsOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return left < 0 ? left * -1 : left;
	}
};

void AbsFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet abs("abs");
	for (auto &type : SQLType::NUMERIC) {
		abs.AddFunction(ScalarFunction({type}, type, ScalarFunction::GetScalarUnaryFunction<AbsOperator>(type)));
	}
	set.AddFunction(abs);
}

//===--------------------------------------------------------------------===//
// sign
//===--------------------------------------------------------------------===//
struct SignOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		if (left == TA(0))
			return 0;
		else if (left > TA(0))
			return 1;
		else
			return -1;
	}
};

void SignFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet sign("sign");
	for (auto &type : SQLType::NUMERIC) {
		sign.AddFunction(ScalarFunction({type}, SQLType::TINYINT,
		                                ScalarFunction::GetScalarUnaryFunctionFixedReturn<int8_t, SignOperator>(type)));
	}
	set.AddFunction(sign);
}

//===--------------------------------------------------------------------===//
// ceil
//===--------------------------------------------------------------------===//
struct CeilOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return ceil(left);
	}
};

void CeilFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet ceil("ceil");
	for (auto &type : SQLType::NUMERIC) {
		scalar_function_t func;
		if (type.IsIntegral()) {
			// ceil on integral type is a nop
			func = ScalarFunction::NopFunction;
		} else {
			func = ScalarFunction::GetScalarUnaryFunction<CeilOperator>(type);
		}
		ceil.AddFunction(ScalarFunction({type}, type, func));
	}
	set.AddFunction(ceil);
	ceil.name = "ceiling";
	set.AddFunction(ceil);
}

//===--------------------------------------------------------------------===//
// floor
//===--------------------------------------------------------------------===//
struct FloorOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return floor(left);
	}
};

void FloorFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet floor("floor");
	for (auto &type : SQLType::NUMERIC) {
		scalar_function_t func;
		if (type.IsIntegral()) {
			// floor on integral type is a nop
			func = ScalarFunction::NopFunction;
		} else {
			func = ScalarFunction::GetScalarUnaryFunction<FloorOperator>(type);
		}
		floor.AddFunction(ScalarFunction({type}, type, func));
	}
	set.AddFunction(floor);
}

//===--------------------------------------------------------------------===//
// round
//===--------------------------------------------------------------------===//
struct RoundOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA input, TB precision) {
		if (precision < 0) {
			precision = 0;
		}
		TA modifier = pow(10, precision);
		return (round(input * modifier)) / modifier;
	}
};

void RoundFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet round("round");
	for (auto &type : SQLType::NUMERIC) {
		scalar_function_t func;
		if (type.IsIntegral()) {
			// round on integral type is a nop
			func = ScalarFunction::NopFunction;
		} else if (type.id == SQLTypeId::FLOAT) {
			func = ScalarFunction::BinaryFunction<float, int32_t, float, RoundOperator>;
		} else {
			assert(type.id == SQLTypeId::DOUBLE || type.id == SQLTypeId::DECIMAL);
			func = ScalarFunction::BinaryFunction<double, int32_t, double, RoundOperator>;
		}
		round.AddFunction(ScalarFunction({type, SQLType::INTEGER}, type, func));
	}
	set.AddFunction(round);
}

//===--------------------------------------------------------------------===//
// exp
//===--------------------------------------------------------------------===//
struct ExpOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return exp(left);
	}
};

void ExpFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("exp", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, ExpOperator>));
}

//===--------------------------------------------------------------------===//
// pow
//===--------------------------------------------------------------------===//
struct PowOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA base, TB exponent) {
		return pow(base, exponent);
	}
};

void PowFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunction power_function("pow", {SQLType::DOUBLE, SQLType::DOUBLE}, SQLType::DOUBLE,
	                              ScalarFunction::BinaryFunction<double, double, double, PowOperator>);
	set.AddFunction(power_function);
	power_function.name = "power";
	set.AddFunction(power_function);
}

//===--------------------------------------------------------------------===//
// sqrt
//===--------------------------------------------------------------------===//
struct SqrtOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return sqrt(left);
	}
};

void SqrtFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("sqrt", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, SqrtOperator>));
}

//===--------------------------------------------------------------------===//
// ln
//===--------------------------------------------------------------------===//
struct LnOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return log(left);
	}
};

void LnFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("ln", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, LnOperator>));
}

//===--------------------------------------------------------------------===//
// log
//===--------------------------------------------------------------------===//
struct Log10Operator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return log10(left);
	}
};

void Log10Fun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunction log_function("log10", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                            ScalarFunction::UnaryFunction<double, double, Log10Operator>);
	set.AddFunction(log_function);
	// "log" is an alias for "log10"
	log_function.name = "log";
	set.AddFunction(log_function);
}

//===--------------------------------------------------------------------===//
// log2
//===--------------------------------------------------------------------===//
struct Log2Operator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return log2(left);
	}
};

void Log2Fun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("log2", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, Log2Operator>));
}

//===--------------------------------------------------------------------===//
// cbrt
//===--------------------------------------------------------------------===//
struct CbRtOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return cbrt(left);
	}
};

void CbrtFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("cbrt", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, CbRtOperator>));
}

//===--------------------------------------------------------------------===//
// pi
//===--------------------------------------------------------------------===//
Value pi_value = Value::DOUBLE(PI);

static void pi_function(DataChunk &args, ExpressionState &state, Vector &result) {
	assert(args.column_count() == 0);
	result.Reference(pi_value);
}

void PiFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("pi", {}, SQLType::DOUBLE, pi_function));
}

//===--------------------------------------------------------------------===//
// degrees
//===--------------------------------------------------------------------===//
struct DegreesOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return left * (180 / PI);
	}
};

void DegreesFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("degrees", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, DegreesOperator>));
}

//===--------------------------------------------------------------------===//
// radians
//===--------------------------------------------------------------------===//
struct RadiansOperator {
	template <class TA, class TR> static inline TR Operation(TA left) {
		return left * (PI / 180);
	}
};

void RadiansFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("radians", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, RadiansOperator>));
}

} // namespace duckdb





#include <random>

using namespace duckdb;
using namespace std;

struct RandomBindData : public FunctionData {
	ClientContext &context;
	uniform_real_distribution<double> dist;

	RandomBindData(ClientContext &context, uniform_real_distribution<double> dist) : context(context), dist(dist) {
	}

	unique_ptr<FunctionData> Copy() override {
		return make_unique<RandomBindData>(context, dist);
	}
};

static void random_function(DataChunk &args, ExpressionState &state, Vector &result) {
	assert(args.column_count() == 0);
	auto &func_expr = (BoundFunctionExpression &)state.expr;
	auto &info = (RandomBindData &)*func_expr.bind_info;

	result.vector_type = VectorType::FLAT_VECTOR;
	auto result_data = FlatVector::GetData<double>(result);
	for (idx_t i = 0; i < args.size(); i++) {
		result_data[i] = info.dist(info.context.random_engine);
	}
}

unique_ptr<FunctionData> random_bind(BoundFunctionExpression &expr, ClientContext &context) {
	uniform_real_distribution<double> dist(0, 1);
	return make_unique<RandomBindData>(context, move(dist));
}

void RandomFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("random", {}, SQLType::DOUBLE, random_function, true, random_bind));
}







using namespace duckdb;
using namespace std;

struct SetseedBindData : public FunctionData {
	//! The client context for the function call
	ClientContext &context;

	SetseedBindData(ClientContext &context) : context(context) {
	}

	unique_ptr<FunctionData> Copy() override {
		return make_unique<SetseedBindData>(context);
	}
};

static void setseed_function(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &func_expr = (BoundFunctionExpression &)state.expr;
	auto &info = (SetseedBindData &)*func_expr.bind_info;
	auto &input = args.data[0];
	input.Normalify(args.size());

	auto input_seeds = FlatVector::GetData<double>(input);
	uint32_t half_max = numeric_limits<uint32_t>::max() / 2;

	for (idx_t i = 0; i < args.size(); i++) {
		if (input_seeds[i] < -1.0 || input_seeds[i] > 1.0) {
			throw Exception("SETSEED accepts seed values between -1.0 and 1.0, inclusive");
		}
		uint32_t norm_seed = (input_seeds[i] + 1.0) * half_max;
		info.context.random_engine.seed(norm_seed);
	}

	result.vector_type = VectorType::CONSTANT_VECTOR;
	ConstantVector::SetNull(result, true);
}

unique_ptr<FunctionData> setseed_bind(BoundFunctionExpression &expr, ClientContext &context) {
	return make_unique<SetseedBindData>(context);
}

void SetseedFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(
	    ScalarFunction("setseed", {SQLType::DOUBLE}, SQLType::SQLNULL, setseed_function, true, setseed_bind));
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/trigonometric_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct SinFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CosFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct TanFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct AsinFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct AcosFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct AtanFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct CotFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct Atan2Fun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb




#include <algorithm>
#include <cmath>

using namespace std;

namespace duckdb {

//===--------------------------------------------------------------------===//
// sin
//===--------------------------------------------------------------------===//
struct SinOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return sin(input);
	}
};

void SinFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("sin", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, SinOperator>));
}

//===--------------------------------------------------------------------===//
// cos
//===--------------------------------------------------------------------===//
struct CosOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return (double)cos(input);
	}
};

void CosFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("cos", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, CosOperator>));
}

//===--------------------------------------------------------------------===//
// tan
//===--------------------------------------------------------------------===//
struct TanOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return (double)tan(input);
	}
};

void TanFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("tan", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, TanOperator>));
}

//===--------------------------------------------------------------------===//
// asin
//===--------------------------------------------------------------------===//
struct ASinOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		if (input < -1 || input > 1) {
			throw Exception("ASIN is undefined outside [-1,1]");
		}
		return (double)asin(input);
	}
};

void AsinFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("asin", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, ASinOperator>));
}

//===--------------------------------------------------------------------===//
// atan
//===--------------------------------------------------------------------===//
struct ATanOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return (double)atan(input);
	}
};

void AtanFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("atan", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, ATanOperator>));
}

//===--------------------------------------------------------------------===//
// atan2
//===--------------------------------------------------------------------===//
struct ATan2 {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return (double)atan2(left, right);
	}
};

void Atan2Fun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("atan2", {SQLType::DOUBLE, SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::BinaryFunction<double, double, double, ATan2>));
}

//===--------------------------------------------------------------------===//
// acos
//===--------------------------------------------------------------------===//
struct ACos {
	template <class TA, class TR> static inline TR Operation(TA input) {
		if (input < -1 || input > 1) {
			throw Exception("ACOS is undefined outside [-1,1]");
		}
		return (double)acos(input);
	}
};

void AcosFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("acos", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, ACos>));
}

//===--------------------------------------------------------------------===//
// cot
//===--------------------------------------------------------------------===//
struct CotOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		return 1.0 / (double)tan(input);
	}
};

void CotFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("cot", {SQLType::DOUBLE}, SQLType::DOUBLE,
	                               ScalarFunction::UnaryFunction<double, double, CotOperator>));
}

} // namespace duckdb



using namespace duckdb;
using namespace std;

void BuiltinFunctions::RegisterMathFunctions() {
	Register<AbsFun>();
	Register<SignFun>();

	Register<CeilFun>();
	Register<FloorFun>();
	Register<RoundFun>();

	Register<DegreesFun>();
	Register<RadiansFun>();

	Register<CbrtFun>();
	Register<ExpFun>();
	Register<Log2Fun>();
	Register<Log10Fun>();
	Register<LnFun>();
	Register<PowFun>();
	Register<RandomFun>();
	Register<SetseedFun>();
	Register<SqrtFun>();

	Register<PiFun>();
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/nested_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct VariableReturnBindData : public FunctionData {
	SQLType stype;

	VariableReturnBindData(SQLType stype) : stype(stype) {
	}

	unique_ptr<FunctionData> Copy() override {
		return make_unique<VariableReturnBindData>(stype);
	}
};

struct StructPackFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct ListValueFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct StructExtractBindData : public FunctionData {
	string key;
	idx_t index;
	TypeId type;

	StructExtractBindData(string key, idx_t index, TypeId type) : key(key), index(index), type(type) {
	}

	unique_ptr<FunctionData> Copy() override {
		return make_unique<StructExtractBindData>(key, index, type);
	}
};

struct StructExtractFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb




using namespace std;

namespace duckdb {

static void list_value_fun(DataChunk &args, ExpressionState &state, Vector &result) {
	//	auto &func_expr = (BoundFunctionExpression &)state.expr;
	//	auto &info = (VariableReturnBindData &)*func_expr.bind_info;

	assert(result.type == TypeId::LIST);
	auto list_child = make_unique<ChunkCollection>();
	ListVector::SetEntry(result, move(list_child));

	auto &cc = ListVector::GetEntry(result);
	DataChunk append_vals;
	vector<TypeId> types;
	if (args.column_count() > 0) {
		types.push_back(args.GetTypes()[0]);
		append_vals.Initialize(types);
		append_vals.SetCardinality(1);
	}
	result.vector_type = VectorType::CONSTANT_VECTOR;
	for (idx_t i = 0; i < args.column_count(); i++) {
		if (args.data[i].vector_type != VectorType::CONSTANT_VECTOR) {
			result.vector_type = VectorType::FLAT_VECTOR;
		}
	}

	auto result_data = FlatVector::GetData<list_entry_t>(result);
	for (idx_t i = 0; i < args.size(); i++) {
		result_data[i].offset = cc.count;
		for (idx_t col_idx = 0; col_idx < args.column_count(); col_idx++) {
			append_vals.SetValue(0, 0, args.GetValue(col_idx, i).CastAs(types[0])); // FIXME evil pattern
			cc.Append(append_vals);
		}
		result_data[i].length = args.column_count();
	}
	result.Verify(args.size());
}

static unique_ptr<FunctionData> list_value_bind(BoundFunctionExpression &expr, ClientContext &context) {
	SQLType stype(SQLTypeId::LIST);

	// collect names and deconflict, construct return type
	assert(expr.arguments.size() == expr.children.size());

	if (expr.children.size() > 0) {
		stype.child_type.push_back(make_pair("", expr.arguments[0]));
	}

	// this is more for completeness reasons
	expr.sql_return_type = stype;
	return make_unique<VariableReturnBindData>(stype);
}

void ListValueFun::RegisterFunction(BuiltinFunctions &set) {
	// the arguments and return types are actually set in the binder function
	ScalarFunction fun("list_value", {}, SQLType::LIST, list_value_fun, false, list_value_bind);
	fun.varargs = SQLType::ANY;
	set.AddFunction(fun);
}

} // namespace duckdb





using namespace std;

namespace duckdb {

static void struct_extract_fun(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &func_expr = (BoundFunctionExpression &)state.expr;
	auto &info = (StructExtractBindData &)*func_expr.bind_info;

	// this should be guaranteed by the binder
	assert(args.column_count() == 1);
	auto &vec = args.data[0];

	vec.Verify(args.size());
	if (vec.vector_type == VectorType::DICTIONARY_VECTOR) {
		auto &child = DictionaryVector::Child(vec);
		auto &dict_sel = DictionaryVector::SelVector(vec);
		auto &children = StructVector::GetEntries(child);
		if (info.index >= children.size()) {
			throw Exception("Not enough struct entries for struct_extract");
		}
		auto &struct_child = children[info.index];
		if (struct_child.first != info.key || struct_child.second->type != info.type) {
			throw Exception("Struct key or type mismatch");
		}
		result.Slice(*struct_child.second, dict_sel, args.size());
	} else {
		auto &children = StructVector::GetEntries(vec);
		if (info.index >= children.size()) {
			throw Exception("Not enough struct entries for struct_extract");
		}
		auto &struct_child = children[info.index];
		if (struct_child.first != info.key || struct_child.second->type != info.type) {
			throw Exception("Struct key or type mismatch");
		}
		result.Reference(*struct_child.second);
	}
	result.Verify(args.size());
}

static unique_ptr<FunctionData> struct_extract_bind(BoundFunctionExpression &expr, ClientContext &context) {
	// the binder should fix this for us.
	assert(expr.children.size() == 2);
	assert(expr.arguments.size() == expr.children.size());
	assert(expr.arguments[0].id == SQLTypeId::STRUCT);
	assert(expr.children[0]->return_type == TypeId::STRUCT);
	if (expr.arguments[0].child_type.size() < 1) {
		throw Exception("Can't extract something from an empty struct");
	}

	auto &key_child = expr.children[1];

	if (expr.arguments[1].id != SQLTypeId::VARCHAR || key_child->return_type != TypeId::VARCHAR ||
	    !key_child->IsScalar()) {
		throw Exception("Key name for struct_extract needs to be a constant string");
	}
	Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get());
	assert(key_val.type == TypeId::VARCHAR);
	if (key_val.is_null || key_val.str_value.length() < 1) {
		throw Exception("Key name for struct_extract needs to be neither NULL nor empty");
	}
	string key = StringUtil::Lower(key_val.str_value);

	SQLType return_type;
	idx_t key_index = 0;
	bool found_key = false;

	for (size_t i = 0; i < expr.arguments[0].child_type.size(); i++) {
		auto &child = expr.arguments[0].child_type[i];
		if (child.first == key) {
			found_key = true;
			key_index = i;
			return_type = child.second;
			break;
		}
	}
	if (!found_key) {
		throw Exception("Could not find key in struct");
	}

	expr.return_type = GetInternalType(return_type);
	expr.sql_return_type = return_type;
	expr.children.pop_back();
	return make_unique<StructExtractBindData>(key, key_index, GetInternalType(return_type));
}

void StructExtractFun::RegisterFunction(BuiltinFunctions &set) {
	// the arguments and return types are actually set in the binder function
	ScalarFunction fun("struct_extract", {SQLType::STRUCT, SQLType::VARCHAR}, SQLType::ANY, struct_extract_fun, false,
	                   struct_extract_bind);
	set.AddFunction(fun);
}

} // namespace duckdb





#include <set>

using namespace std;

namespace duckdb {

static void struct_pack_fun(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &func_expr = (BoundFunctionExpression &)state.expr;
	auto &info = (VariableReturnBindData &)*func_expr.bind_info;

	// this should never happen if the binder below is sane
	assert(args.column_count() == info.stype.child_type.size());

	bool all_const = true;
	for (size_t i = 0; i < args.column_count(); i++) {
		if (args.data[i].vector_type != VectorType::CONSTANT_VECTOR) {
			all_const = false;
		}
		// same holds for this
		assert(args.data[i].type == GetInternalType(info.stype.child_type[i].second));
		auto new_child = make_unique<Vector>();
		new_child->Reference(args.data[i]);
		StructVector::AddEntry(result, info.stype.child_type[i].first, move(new_child));
	}
	result.vector_type = all_const ? VectorType::CONSTANT_VECTOR : VectorType::FLAT_VECTOR;

	result.Verify(args.size());
}

static unique_ptr<FunctionData> struct_pack_bind(BoundFunctionExpression &expr, ClientContext &context) {
	SQLType stype(SQLTypeId::STRUCT);
	set<string> name_collision_set;

	// collect names and deconflict, construct return type
	assert(expr.arguments.size() == expr.children.size());

	if (expr.arguments.size() == 0) {
		throw Exception("Can't pack nothing into a struct");
	}
	for (idx_t i = 0; i < expr.children.size(); i++) {
		auto &child = expr.children[i];
		if (child->alias.size() == 0) {
			throw Exception("Need named argument for struct pack, e.g. STRUCT_PACK(a := b)");
		}
		if (name_collision_set.find(child->alias) != name_collision_set.end()) {
			throw Exception("Duplicate struct entry name");
		}
		name_collision_set.insert(child->alias);
		stype.child_type.push_back(make_pair(child->alias, expr.arguments[i]));
	}

	// this is more for completeness reasons
	expr.sql_return_type = stype;
	return make_unique<VariableReturnBindData>(stype);
}

void StructPackFun::RegisterFunction(BuiltinFunctions &set) {
	// the arguments and return types are actually set in the binder function
	ScalarFunction fun("struct_pack", {}, SQLType::STRUCT, struct_pack_fun, false, struct_pack_bind);
	fun.varargs = SQLType::ANY;
	set.AddFunction(fun);
}

} // namespace duckdb


using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterNestedFunctions() {
	Register<StructPackFun>();
	Register<StructExtractFun>();
	Register<ListValueFun>();
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/operators.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct AddFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SubtractFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct MultiplyFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct DivideFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct ModFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct LeftShiftFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct RightShiftFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct BitwiseAndFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct BitwiseOrFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct BitwiseXorFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb




using namespace std;

namespace duckdb {

//===--------------------------------------------------------------------===//
// + [add]
//===--------------------------------------------------------------------===//
void AddFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("+");
	// binary add function adds two numbers together
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(
		    ScalarFunction({type, type}, type, ScalarFunction::GetScalarBinaryFunction<AddOperator>(type)));
	}
	// we can add integers to dates
	functions.AddFunction(ScalarFunction({SQLType::DATE, SQLType::INTEGER}, SQLType::DATE,
	                                     ScalarFunction::GetScalarBinaryFunction<AddOperator>(SQLType::INTEGER)));
	functions.AddFunction(ScalarFunction({SQLType::INTEGER, SQLType::DATE}, SQLType::DATE,
	                                     ScalarFunction::GetScalarBinaryFunction<AddOperator>(SQLType::INTEGER)));
	// unary add function is a nop, but only exists for numeric types
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(ScalarFunction({type}, type, ScalarFunction::NopFunction));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// - [subtract]
//===--------------------------------------------------------------------===//
void SubtractFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("-");
	// binary subtract function "a - b", subtracts b from a
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(
		    ScalarFunction({type, type}, type, ScalarFunction::GetScalarBinaryFunction<SubtractOperator>(type)));
	}
	functions.AddFunction(ScalarFunction({SQLType::DATE, SQLType::DATE}, SQLType::INTEGER,
	                                     ScalarFunction::GetScalarBinaryFunction<SubtractOperator>(SQLType::INTEGER)));
	functions.AddFunction(ScalarFunction({SQLType::DATE, SQLType::INTEGER}, SQLType::DATE,
	                                     ScalarFunction::GetScalarBinaryFunction<SubtractOperator>(SQLType::INTEGER)));
	// unary subtract function, negates the input (i.e. multiplies by -1)
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(
		    ScalarFunction({type}, type, ScalarFunction::GetScalarUnaryFunction<NegateOperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// * [multiply]
//===--------------------------------------------------------------------===//
void MultiplyFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("*");
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(
		    ScalarFunction({type, type}, type, ScalarFunction::GetScalarBinaryFunction<MultiplyOperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// / [divide]
//===--------------------------------------------------------------------===//
struct BinaryZeroIsNullWrapper {
	template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
	static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, nullmask_t &nullmask, idx_t idx) {
		if (right == 0) {
			nullmask[idx] = true;
			return 0;
		} else {
			return OP::template Operation<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(left, right);
		}
	}
};

template <class T, class OP>
static void BinaryScalarFunctionIgnoreZero(DataChunk &input, ExpressionState &state, Vector &result) {
	BinaryExecutor::Execute<T, T, T, OP, true, BinaryZeroIsNullWrapper>(input.data[0], input.data[1], result,
	                                                                    input.size());
}

template <class OP> static scalar_function_t GetBinaryFunctionIgnoreZero(SQLType type) {
	switch (type.id) {
	case SQLTypeId::TINYINT:
		return BinaryScalarFunctionIgnoreZero<int8_t, OP>;
	case SQLTypeId::SMALLINT:
		return BinaryScalarFunctionIgnoreZero<int16_t, OP>;
	case SQLTypeId::INTEGER:
		return BinaryScalarFunctionIgnoreZero<int32_t, OP>;
	case SQLTypeId::BIGINT:
		return BinaryScalarFunctionIgnoreZero<int64_t, OP>;
	case SQLTypeId::FLOAT:
		return BinaryScalarFunctionIgnoreZero<float, OP>;
	case SQLTypeId::DOUBLE:
		return BinaryScalarFunctionIgnoreZero<double, OP>;
	case SQLTypeId::DECIMAL:
		return BinaryScalarFunctionIgnoreZero<double, OP>;
	default:
		throw NotImplementedException("Unimplemented type for GetScalarUnaryFunction");
	}
}

void DivideFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("/");
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(ScalarFunction({type, type}, type, GetBinaryFunctionIgnoreZero<DivideOperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// % [modulo]
//===--------------------------------------------------------------------===//
template <> float ModuloOperator::Operation(float left, float right) {
	assert(right != 0);
	return fmod(left, right);
}

template <> double ModuloOperator::Operation(double left, double right) {
	assert(right != 0);
	return fmod(left, right);
}

void ModFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("%");
	for (auto &type : SQLType::NUMERIC) {
		functions.AddFunction(ScalarFunction({type, type}, type, GetBinaryFunctionIgnoreZero<ModuloOperator>(type)));
	}
	set.AddFunction(functions);
	functions.name = "mod";
	set.AddFunction(functions);
}

} // namespace duckdb



using namespace duckdb;
using namespace std;

namespace duckdb {

//===--------------------------------------------------------------------===//
// & [bitwise_and]
//===--------------------------------------------------------------------===//
struct BitwiseANDOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left & right;
	}
};

void BitwiseAndFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("&");
	for (auto &type : SQLType::INTEGRAL) {
		functions.AddFunction(ScalarFunction({type, type}, type,
		                                     ScalarFunction::GetScalarIntegerBinaryFunction<BitwiseANDOperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// | [bitwise_or]
//===--------------------------------------------------------------------===//
struct BitwiseOROperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left | right;
	}
};

void BitwiseOrFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("|");
	for (auto &type : SQLType::INTEGRAL) {
		functions.AddFunction(ScalarFunction({type, type}, type,
		                                     ScalarFunction::GetScalarIntegerBinaryFunction<BitwiseOROperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// # [bitwise_xor]
//===--------------------------------------------------------------------===//
struct BitwiseXOROperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left ^ right;
	}
};

void BitwiseXorFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("#");
	for (auto &type : SQLType::INTEGRAL) {
		functions.AddFunction(ScalarFunction({type, type}, type,
		                                     ScalarFunction::GetScalarIntegerBinaryFunction<BitwiseXOROperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// << [bitwise_left_shift]
//===--------------------------------------------------------------------===//
struct BitwiseShiftLeftOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left << right;
	}
};

void LeftShiftFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions("<<");
	for (auto &type : SQLType::INTEGRAL) {
		functions.AddFunction(ScalarFunction(
		    {type, type}, type, ScalarFunction::GetScalarIntegerBinaryFunction<BitwiseShiftLeftOperator>(type)));
	}
	set.AddFunction(functions);
}

//===--------------------------------------------------------------------===//
// >> [bitwise_right_shift]
//===--------------------------------------------------------------------===//
struct BitwiseShiftRightOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return left >> right;
	}
};

void RightShiftFun::RegisterFunction(BuiltinFunctions &set) {
	ScalarFunctionSet functions(">>");
	for (auto &type : SQLType::INTEGRAL) {
		functions.AddFunction(ScalarFunction(
		    {type, type}, type, ScalarFunction::GetScalarIntegerBinaryFunction<BitwiseShiftRightOperator>(type)));
	}
	set.AddFunction(functions);
}

} // namespace duckdb



using namespace duckdb;
using namespace std;

void BuiltinFunctions::RegisterOperators() {
	Register<AddFun>();
	Register<SubtractFun>();
	Register<MultiplyFun>();
	Register<DivideFun>();
	Register<ModFun>();
	Register<LeftShiftFun>();
	Register<RightShiftFun>();
	Register<BitwiseAndFun>();
	Register<BitwiseOrFun>();
	Register<BitwiseXorFun>();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/sequence_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

struct NextvalFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb












using namespace std;

namespace duckdb {

struct NextvalBindData : public FunctionData {
	//! The client context for the function call
	ClientContext &context;
	//! The sequence to use for the nextval computation; only if
	SequenceCatalogEntry *sequence;

	NextvalBindData(ClientContext &context, SequenceCatalogEntry *sequence) : context(context), sequence(sequence) {
	}

	unique_ptr<FunctionData> Copy() override {
		return make_unique<NextvalBindData>(context, sequence);
	}
};

static int64_t next_sequence_value(Transaction &transaction, SequenceCatalogEntry *seq) {
	lock_guard<mutex> seqlock(seq->lock);
	int64_t result;
	if (seq->cycle) {
		result = seq->counter;
		seq->counter += seq->increment;
		;
		if (result < seq->min_value) {
			result = seq->max_value;
			seq->counter = seq->max_value + seq->increment;
		} else if (result > seq->max_value) {
			result = seq->min_value;
			seq->counter = seq->min_value + seq->increment;
		}
	} else {
		result = seq->counter;
		seq->counter += seq->increment;
		if (result < seq->min_value) {
			throw SequenceException("nextval: reached minimum value of sequence \"%s\" (%lld)", seq->name.c_str(),
			                        seq->min_value);
		}
		if (result > seq->max_value) {
			throw SequenceException("nextval: reached maximum value of sequence \"%s\" (%lld)", seq->name.c_str(),
			                        seq->max_value);
		}
	}
	seq->usage_count++;
	transaction.sequence_usage[seq] = SequenceValue(seq->usage_count, seq->counter);
	return result;
}

static void nextval_function(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &func_expr = (BoundFunctionExpression &)state.expr;
	auto &info = (NextvalBindData &)*func_expr.bind_info;
	assert(args.column_count() == 1 && args.data[0].type == TypeId::VARCHAR);
	auto &input = args.data[0];

	auto &transaction = Transaction::GetTransaction(info.context);
	if (info.sequence) {
		// sequence to use is hard coded
		// increment the sequence
		result.vector_type = VectorType::FLAT_VECTOR;
		auto result_data = FlatVector::GetData<int64_t>(result);
		for (idx_t i = 0; i < args.size(); i++) {
			// get the next value from the sequence
			result_data[i] = next_sequence_value(transaction, info.sequence);
		}
	} else {
		// sequence to use comes from the input
		UnaryExecutor::Execute<string_t, int64_t, true>(input, result, args.size(), [&](string_t value) {
			string schema, seq;
			string seqname = value.GetString();
			Catalog::ParseRangeVar(seqname, schema, seq);
			// fetch the sequence from the catalog
			auto sequence = Catalog::GetCatalog(info.context).GetEntry<SequenceCatalogEntry>(info.context, schema, seq);
			// finally get the next value from the sequence
			return next_sequence_value(transaction, sequence);
		});
	}
}

static unique_ptr<FunctionData> nextval_bind(BoundFunctionExpression &expr, ClientContext &context) {
	SequenceCatalogEntry *sequence = nullptr;
	if (expr.children[0]->IsFoldable()) {
		string schema, seq;
		// parameter to nextval function is a foldable constant
		// evaluate the constant and perform the catalog lookup already
		Value seqname = ExpressionExecutor::EvaluateScalar(*expr.children[0]);
		if (!seqname.is_null) {
			assert(seqname.type == TypeId::VARCHAR);
			Catalog::ParseRangeVar(seqname.str_value, schema, seq);
			sequence = Catalog::GetCatalog(context).GetEntry<SequenceCatalogEntry>(context, schema, seq);
		}
	}
	return make_unique<NextvalBindData>(context, sequence);
}

static void nextval_dependency(BoundFunctionExpression &expr, unordered_set<CatalogEntry *> &dependencies) {
	auto &info = (NextvalBindData &)*expr.bind_info;
	if (info.sequence) {
		dependencies.insert(info.sequence);
	}
}

void NextvalFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("nextval", {SQLType::VARCHAR}, SQLType::BIGINT, nextval_function, true, nextval_bind,
	                               nextval_dependency));
}

} // namespace duckdb


using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterSequenceFunctions() {
	Register<NextvalFun>();
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/scalar/string_functions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace re2 {
class RE2;
}

namespace duckdb {

struct ReverseFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct LowerFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct UpperFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct ConcatFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct ConcatWSFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct LengthFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct LikeFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct RegexpFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SubstringFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct PrintfFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct InstrFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct PrefixFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SuffixFun {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct RegexpMatchesBindData : public FunctionData {
	RegexpMatchesBindData(std::unique_ptr<re2::RE2> constant_pattern, string range_min, string range_max,
	                      bool range_success);
	~RegexpMatchesBindData();

	std::unique_ptr<re2::RE2> constant_pattern;
	string range_min, range_max;
	bool range_success;

	unique_ptr<FunctionData> Copy() override;
};

} // namespace duckdb






#include <string.h>

using namespace std;

namespace duckdb {

// TODO: this does not handle UTF characters yet.
template <class OP> static void strcase(const char *input_data, idx_t input_length, char *output) {
	for (idx_t i = 0; i < input_length; i++) {
		output[i] = OP::Operation(input_data[i]);
	}
	output[input_length] = '\0';
}

template <class OP> static void caseconvert_function(Vector &input, Vector &result, idx_t count) {
	assert(input.type == TypeId::VARCHAR);

	UnaryExecutor::Execute<string_t, string_t, true>(input, result, count, [&](string_t input) {
		auto input_data = input.GetData();
		auto input_length = input.GetSize();

		auto target = StringVector::EmptyString(result, input_length);
		strcase<OP>(input_data, input_length, target.GetData());
		target.Finalize();
		return target;
	});
}

struct StringToUpper {
	static char Operation(char input) {
		return toupper(input);
	}
};

struct StringToLower {
	static char Operation(char input) {
		return tolower(input);
	}
};

static void caseconvert_upper_function(DataChunk &args, ExpressionState &state, Vector &result) {
	assert(args.column_count() == 1);
	caseconvert_function<StringToUpper>(args.data[0], result, args.size());
}

static void caseconvert_lower_function(DataChunk &args, ExpressionState &state, Vector &result) {
	assert(args.column_count() == 1);
	caseconvert_function<StringToLower>(args.data[0], result, args.size());
}

void LowerFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("lower", {SQLType::VARCHAR}, SQLType::VARCHAR, caseconvert_lower_function));
}

void UpperFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("upper", {SQLType::VARCHAR}, SQLType::VARCHAR, caseconvert_upper_function));
}

} // namespace duckdb







#include <string.h>

using namespace std;

namespace duckdb {

static void concat_function(DataChunk &args, ExpressionState &state, Vector &result) {
	result.vector_type = VectorType::CONSTANT_VECTOR;
	// iterate over the vectors to count how large the final string will be
	idx_t constant_lengths = 0;
	vector<idx_t> result_lengths(args.size(), 0);
	for (idx_t col_idx = 0; col_idx < args.column_count(); col_idx++) {
		auto &input = args.data[col_idx];
		assert(input.type == TypeId::VARCHAR);
		if (input.vector_type == VectorType::CONSTANT_VECTOR) {
			if (ConstantVector::IsNull(input)) {
				// constant null, skip
				continue;
			}
			auto input_data = ConstantVector::GetData<string_t>(input);
			constant_lengths += input_data->GetSize();
		} else {
			// non-constant vector: set the result type to a flat vector
			result.vector_type = VectorType::FLAT_VECTOR;
			// now get the lengths of each of the input elements
			VectorData vdata;
			input.Orrify(args.size(), vdata);

			auto input_data = (string_t *)vdata.data;
			// now add the length of each vector to the result length
			for (idx_t i = 0; i < args.size(); i++) {
				auto idx = vdata.sel->get_index(i);
				if ((*vdata.nullmask)[idx]) {
					continue;
				}
				result_lengths[i] += input_data[idx].GetSize();
			}
		}
	}

	// first we allocate the empty strings for each of the values
	auto result_data = FlatVector::GetData<string_t>(result);
	for (idx_t i = 0; i < args.size(); i++) {
		// allocate an empty string of the required size
		idx_t str_length = constant_lengths + result_lengths[i];
		result_data[i] = StringVector::EmptyString(result, str_length);
		// we reuse the result_lengths vector to store the currently appended size
		result_lengths[i] = 0;
	}

	// now that the empty space for the strings has been allocated, perform the concatenation
	for (idx_t col_idx = 0; col_idx < args.column_count(); col_idx++) {
		auto &input = args.data[col_idx];

		// loop over the vector and concat to all results
		if (input.vector_type == VectorType::CONSTANT_VECTOR) {
			// constant vector
			if (ConstantVector::IsNull(input)) {
				// constant null, skip
				continue;
			}
			// append the constant vector to each of the strings
			auto input_data = ConstantVector::GetData<string_t>(input);
			auto input_ptr = input_data->GetData();
			auto input_len = input_data->GetSize();
			for (idx_t i = 0; i < args.size(); i++) {
				memcpy(result_data[i].GetData() + result_lengths[i], input_ptr, input_len);
				result_lengths[i] += input_len;
			}
		} else {
			// standard vector
			VectorData idata;
			input.Orrify(args.size(), idata);

			auto input_data = (string_t *)idata.data;
			for (idx_t i = 0; i < args.size(); i++) {
				auto idx = idata.sel->get_index(i);
				if ((*idata.nullmask)[idx]) {
					continue;
				}
				auto input_ptr = input_data[idx].GetData();
				auto input_len = input_data[idx].GetSize();
				memcpy(result_data[i].GetData() + result_lengths[i], input_ptr, input_len);
				result_lengths[i] += input_len;
			}
		}
	}
	for (idx_t i = 0; i < args.size(); i++) {
		result_data[i].Finalize();
	}
}

static void concat_operator(DataChunk &args, ExpressionState &state, Vector &result) {
	BinaryExecutor::Execute<string_t, string_t, string_t, true>(
	    args.data[0], args.data[1], result, args.size(), [&](string_t a, string_t b) {
		    auto a_data = a.GetData();
		    auto b_data = b.GetData();
		    auto a_length = a.GetSize();
		    auto b_length = b.GetSize();

		    auto target_length = a_length + b_length;
		    auto target = StringVector::EmptyString(result, target_length);
		    auto target_data = target.GetData();

		    memcpy(target_data, a_data, a_length);
		    memcpy(target_data + a_length, b_data, b_length);
		    target.Finalize();
		    return target;
	    });
}

static void templated_concat_ws(DataChunk &args, string_t *sep_data, const SelectionVector &sep_sel,
                                const SelectionVector &rsel, idx_t count, Vector &result) {
	vector<idx_t> result_lengths(args.size(), 0);
	vector<bool> has_results(args.size(), false);
	auto orrified_data = unique_ptr<VectorData[]>(new VectorData[args.column_count() - 1]);
	for (idx_t col_idx = 1; col_idx < args.column_count(); col_idx++) {
		args.data[col_idx].Orrify(args.size(), orrified_data[col_idx - 1]);
	}

	// first figure out the lengths
	for (idx_t col_idx = 1; col_idx < args.column_count(); col_idx++) {
		auto &idata = orrified_data[col_idx - 1];

		auto input_data = (string_t *)idata.data;
		for (idx_t i = 0; i < count; i++) {
			auto ridx = rsel.get_index(i);
			auto sep_idx = sep_sel.get_index(ridx);
			auto idx = idata.sel->get_index(ridx);
			if ((*idata.nullmask)[idx]) {
				continue;
			}
			if (has_results[ridx]) {
				result_lengths[ridx] += sep_data[sep_idx].GetSize();
			}
			result_lengths[ridx] += input_data[idx].GetSize();
			has_results[ridx] = true;
		}
	}

	// first we allocate the empty strings for each of the values
	auto result_data = FlatVector::GetData<string_t>(result);
	for (idx_t i = 0; i < count; i++) {
		auto ridx = rsel.get_index(i);
		// allocate an empty string of the required size
		result_data[ridx] = StringVector::EmptyString(result, result_lengths[ridx]);
		// we reuse the result_lengths vector to store the currently appended size
		result_lengths[ridx] = 0;
		has_results[ridx] = false;
	}

	// now that the empty space for the strings has been allocated, perform the concatenation
	for (idx_t col_idx = 1; col_idx < args.column_count(); col_idx++) {
		auto &idata = orrified_data[col_idx - 1];
		auto input_data = (string_t *)idata.data;
		for (idx_t i = 0; i < count; i++) {
			auto ridx = rsel.get_index(i);
			auto sep_idx = sep_sel.get_index(ridx);
			auto idx = idata.sel->get_index(ridx);
			if ((*idata.nullmask)[idx]) {
				continue;
			}
			if (has_results[ridx]) {
				auto sep_size = sep_data[sep_idx].GetSize();
				auto sep_ptr = sep_data[sep_idx].GetData();
				memcpy(result_data[ridx].GetData() + result_lengths[ridx], sep_ptr, sep_size);
				result_lengths[ridx] += sep_size;
			}
			auto input_ptr = input_data[idx].GetData();
			auto input_len = input_data[idx].GetSize();
			memcpy(result_data[ridx].GetData() + result_lengths[ridx], input_ptr, input_len);
			result_lengths[ridx] += input_len;
			has_results[ridx] = true;
		}
	}
	for (idx_t i = 0; i < count; i++) {
		auto ridx = rsel.get_index(i);
		result_data[ridx].Finalize();
	}
}

static void concat_ws_function(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &separator = args.data[0];
	VectorData vdata;
	separator.Orrify(args.size(), vdata);

	result.vector_type = VectorType::CONSTANT_VECTOR;
	for (idx_t col_idx = 0; col_idx < args.column_count(); col_idx++) {
		if (args.data[col_idx].vector_type != VectorType::CONSTANT_VECTOR) {
			result.vector_type = VectorType::FLAT_VECTOR;
			break;
		}
	}
	switch (separator.vector_type) {
	case VectorType::CONSTANT_VECTOR:
		if (ConstantVector::IsNull(separator)) {
			// constant NULL as separator: return constant NULL vector
			result.vector_type = VectorType::CONSTANT_VECTOR;
			ConstantVector::SetNull(result, true);
			return;
		}
		// no null values
		templated_concat_ws(args, (string_t *)vdata.data, *vdata.sel, FlatVector::IncrementalSelectionVector,
		                    args.size(), result);
		return;
	default: {
		// default case: loop over nullmask and create a non-null selection vector
		idx_t not_null_count = 0;
		SelectionVector not_null_vector(STANDARD_VECTOR_SIZE);
		auto &result_nullmask = FlatVector::Nullmask(result);
		for (idx_t i = 0; i < args.size(); i++) {
			if ((*vdata.nullmask)[vdata.sel->get_index(i)]) {
				result_nullmask[i] = true;
			} else {
				not_null_vector.set_index(not_null_count++, i);
			}
		}
		templated_concat_ws(args, (string_t *)vdata.data, *vdata.sel, not_null_vector, not_null_count, result);
		return;
	}
	}
}

void ConcatFun::RegisterFunction(BuiltinFunctions &set) {
	// the concat operator and concat function have different behavior regarding NULLs
	// this is strange but seems consistent with postgresql and mysql
	// (sqlite does not support the concat function, only the concat operator)

	// the concat operator behaves as one would expect: any NULL value present results in a NULL
	// i.e. NULL || 'hello' = NULL
	// the concat function, however, treats NULL values as an empty string
	// i.e. concat(NULL, 'hello') = 'hello'
	// concat_ws functions similarly to the concat function, except the result is NULL if the separator is NULL
	// if the separator is not NULL, however, NULL values are counted as empty string
	// there is one separate rule: there are no separators added between NULL values
	// so the NULL value and empty string are different!
	// e.g.:
	// concat_ws(',', NULL, NULL) = ""
	// concat_ws(',', '', '') = ","
	ScalarFunction concat = ScalarFunction("concat", {SQLType::VARCHAR}, SQLType::VARCHAR, concat_function);
	concat.varargs = SQLType::VARCHAR;
	set.AddFunction(concat);

	set.AddFunction(ScalarFunction("||", {SQLType::VARCHAR, SQLType::VARCHAR}, SQLType::VARCHAR, concat_operator));

	ScalarFunction concat_ws =
	    ScalarFunction("concat_ws", {SQLType::VARCHAR, SQLType::VARCHAR}, SQLType::VARCHAR, concat_ws_function);
	concat_ws.varargs = SQLType::VARCHAR;
	set.AddFunction(concat_ws);
}

} // namespace duckdb






#include <string.h>
#include <ctype.h>

using namespace std;

namespace duckdb {

static int64_t instr(string_t haystack, string_t needle);

struct InstrOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return instr(left, right);
	}
};

static int64_t instr(string_t haystack, string_t needle) {
	int64_t string_position = 0;

	// Getting information about the needle and the haystack
	auto input_haystack = haystack.GetData();
	auto input_needle = needle.GetData();
	auto size_haystack = haystack.GetSize();
	auto size_needle = needle.GetSize();

	// Needle needs something to proceed
	if (size_needle > 0) {
		// Haystack should be bigger or equal size to the needle
		while (size_haystack >= size_needle) {
			// Increment and check continuation bytes: bit 7 should be set and 6 unset
			string_position += (input_haystack[0] & 0xC0) != 0x80;
			// Compare Needle to the Haystack
			if ((memcmp(input_haystack, input_needle, size_needle) == 0)) {
				return string_position;
			}
			size_haystack--;
			input_haystack++;
		}

		// Did not find the needle
		string_position = 0;
	}
	return string_position;
}

void InstrFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("instr",                              // name of the function
	                               {SQLType::VARCHAR, SQLType::VARCHAR}, // argument list
	                               SQLType::BIGINT,                      // return type
	                               ScalarFunction::BinaryFunction<string_t, string_t, int64_t, InstrOperator, true>));
}

} // namespace duckdb





using namespace std;

namespace duckdb {

struct StringLengthOperator {
	template <class TA, class TR> static inline TR Operation(TA input) {
		int64_t length = 0;
		auto input_data = input.GetData();
		auto input_length = input.GetSize();
		for (idx_t i = 0; i < input_length; i++) {
			length += (input_data[i] & 0xC0) != 0x80;
		}
		return length;
	}
};

void LengthFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("length", {SQLType::VARCHAR}, SQLType::BIGINT,
	                               ScalarFunction::UnaryFunction<string_t, int64_t, StringLengthOperator, true>));
}

} // namespace duckdb





using namespace std;

namespace duckdb {

static bool like_operator(const char *s, const char *pattern, const char *escape);

struct LikeOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return like_operator(left.GetData(), right.GetData(), nullptr);
	}
};

struct NotLikeOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return !like_operator(left.GetData(), right.GetData(), nullptr);
	}
};

bool like_operator(const char *s, const char *pattern, const char *escape) {
	const char *t, *p;

	t = s;
	for (p = pattern; *p && *t; p++) {
		if (escape && *p == *escape) {
			p++;
			if (*p != *t) {
				return false;
			}
			t++;
		} else if (*p == '_') {
			t++;
		} else if (*p == '%') {
			p++;
			while (*p == '%') {
				p++;
			}
			if (*p == 0) {
				return true; /* tail is acceptable */
			}
			for (; *p && *t; t++) {
				if (like_operator(t, p, escape)) {
					return true;
				}
			}
			if (*p == 0 && *t == 0) {
				return true;
			}
			return false;
		} else if (*p == *t) {
			t++;
		} else {
			return false;
		}
	}
	if (*p == '%' && *(p + 1) == 0) {
		return true;
	}
	return *t == 0 && *p == 0;
}

void LikeFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("~~", {SQLType::VARCHAR, SQLType::VARCHAR}, SQLType::BOOLEAN,
	                               ScalarFunction::BinaryFunction<string_t, string_t, bool, LikeOperator, true>));
	set.AddFunction(ScalarFunction("!~~", {SQLType::VARCHAR, SQLType::VARCHAR}, SQLType::BOOLEAN,
	                               ScalarFunction::BinaryFunction<string_t, string_t, bool, NotLikeOperator, true>));
}

} // namespace duckdb





using namespace std;

namespace duckdb {

static bool prefix(const string_t &str, const string_t &pattern);

struct PrefixOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return prefix(left, right);
	}
};
static bool prefix(const string_t &str, const string_t &pattern) {
	auto str_size = str.GetSize();
	auto patt_length = pattern.GetSize();
	if (patt_length > str_size) {
		return false;
	}
	if (patt_length <= string_t::PREFIX_LENGTH) {
		// short prefix
		if (patt_length == 0) {
			// length = 0, return true
			return true;
		}

		// prefix early out
		const char *str_pref = str.GetPrefix();
		const char *patt_pref = pattern.GetPrefix();
		for (idx_t i = 0; i < patt_length; ++i) {
			if (str_pref[i] != patt_pref[i])
				return false;
		}
		return true;
	} else {
		// prefix early out
		const char *str_pref = str.GetPrefix();
		const char *patt_pref = pattern.GetPrefix();
		for (idx_t i = 0; i < string_t::PREFIX_LENGTH; ++i) {
			if (str_pref[i] != patt_pref[i]) {
				// early out
				return false;
			}
		}
		// compare the rest of the prefix
		bool equal;
		uint32_t num_char_equals = string_t::PREFIX_LENGTH;
		const char *str_data = str.GetData();
		const char *patt_data = pattern.GetData();

		for (idx_t i = string_t::PREFIX_LENGTH; i < patt_length; ++i) {
			equal = (str_data[i] == patt_data[i]); // removed branch
			num_char_equals += equal;
		}

		return (num_char_equals == patt_length);
	}
}

void PrefixFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("prefix",                             // name of the function
	                               {SQLType::VARCHAR, SQLType::VARCHAR}, // argument list
	                               SQLType::BOOLEAN,                     // return type
	                               ScalarFunction::BinaryFunction<string_t, string_t, bool, PrefixOperator, true>));
}

} // namespace duckdb


// Formatting library for C++ - legacy printf implementation
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_

#include <algorithm>  // std::max
#include <limits>     // std::numeric_limits

// Formatting library for C++ - std::ostream support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_

#include <ostream>


FMT_BEGIN_NAMESPACE
namespace internal {

template <class Char> class formatbuf : public std::basic_streambuf<Char> {
 private:
  using int_type = typename std::basic_streambuf<Char>::int_type;
  using traits_type = typename std::basic_streambuf<Char>::traits_type;

  buffer<Char>& buffer_;

 public:
  formatbuf(buffer<Char>& buf) : buffer_(buf) {}

 protected:
  // The put-area is actually always empty. This makes the implementation
  // simpler and has the advantage that the streambuf and the buffer are always
  // in sync and sputc never writes into uninitialized memory. The obvious
  // disadvantage is that each call to sputc always results in a (virtual) call
  // to overflow. There is no disadvantage here for sputn since this always
  // results in a call to xsputn.

  int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
    if (!traits_type::eq_int_type(ch, traits_type::eof()))
      buffer_.push_back(static_cast<Char>(ch));
    return ch;
  }

  std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE {
    buffer_.append(s, s + count);
    return count;
  }
};

template <typename Char> struct test_stream : std::basic_ostream<Char> {
 private:
  // Hide all operator<< from std::basic_ostream<Char>.
  void_t<> operator<<(null<>);
  void_t<> operator<<(const Char*);

  template <typename T, FMT_ENABLE_IF(std::is_convertible<T, int>::value &&
                                      !std::is_enum<T>::value)>
  void_t<> operator<<(T);
};

// Checks if T has a user-defined operator<< (e.g. not a member of
// std::ostream).
template <typename T, typename Char> class is_streamable {
 private:
  template <typename U>
  static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
                                              << std::declval<U>()),
                                     void_t<>>::value>
  test(int);

  template <typename> static std::false_type test(...);

  using result = decltype(test<T>(0));

 public:
  static const bool value = result::value;
};

// Write the content of buf to os.
template <typename Char>
void write(std::basic_ostream<Char>& os, buffer<Char>& buf) {
  const Char* buf_data = buf.data();
  using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
  unsigned_streamsize size = buf.size();
  unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
  do {
    unsigned_streamsize n = size <= max_size ? size : max_size;
    os.write(buf_data, static_cast<std::streamsize>(n));
    buf_data += n;
    size -= n;
  } while (size != 0);
}

template <typename Char, typename T>
void format_value(buffer<Char>& buf, const T& value,
                  locale_ref loc = locale_ref()) {
  formatbuf<Char> format_buf(buf);
  std::basic_ostream<Char> output(&format_buf);
  if (loc) output.imbue(loc.get<std::locale>());
  output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
  output << value;
  buf.resize(buf.size());
}

// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
    : formatter<basic_string_view<Char>, Char> {
  template <typename Context>
  auto format(const T& value, Context& ctx) -> decltype(ctx.out()) {
    basic_memory_buffer<Char> buffer;
    format_value(buffer, value, ctx.locale());
    basic_string_view<Char> str(buffer.data(), buffer.size());
    return formatter<basic_string_view<Char>, Char>::format(str, ctx);
  }
};
}  // namespace internal

template <typename Char>
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
            basic_format_args<buffer_context<Char>> args) {
  basic_memory_buffer<Char> buffer;
  internal::vformat_to(buffer, format_str, args);
  internal::write(os, buffer);
}

/**
  \rst
  Prints formatted data to the stream *os*.

  **Example**::

    fmt::print(cerr, "Don't {}!", "panic");
  \endrst
 */
template <typename S, typename... Args,
          typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
  vprint(os, to_string_view(format_str),
         {internal::make_args_checked<Args...>(format_str, args...)});
}
FMT_END_NAMESPACE

#endif  // FMT_OSTREAM_H_


FMT_BEGIN_NAMESPACE
namespace internal {

// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned> struct int_checker {
  template <typename T> static bool fits_in_int(T value) {
    unsigned max = max_value<int>();
    return value <= max;
  }
  static bool fits_in_int(bool) { return true; }
};

template <> struct int_checker<true> {
  template <typename T> static bool fits_in_int(T value) {
    return value >= std::numeric_limits<int>::min() &&
           value <= max_value<int>();
  }
  static bool fits_in_int(int) { return true; }
};

class printf_precision_handler {
 public:
  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
  int operator()(T value) {
    if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
      FMT_THROW(duckdb::Exception("number is too big"));
    return (std::max)(static_cast<int>(value), 0);
  }

  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
  int operator()(T) {
    FMT_THROW(duckdb::Exception("precision is not integer"));
    return 0;
  }
};

// An argument visitor that returns true iff arg is a zero integer.
class is_zero_int {
 public:
  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
  bool operator()(T value) {
    return value == 0;
  }

  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
  bool operator()(T) {
    return false;
  }
};

template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};

template <> struct make_unsigned_or_bool<bool> { using type = bool; };

template <typename T, typename Context> class arg_converter {
 private:
  using char_type = typename Context::char_type;

  basic_format_arg<Context>& arg_;
  char_type type_;

 public:
  arg_converter(basic_format_arg<Context>& arg, char_type type)
      : arg_(arg), type_(type) {}

  void operator()(bool value) {
    if (type_ != 's') operator()<bool>(value);
  }

  template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
  void operator()(U value) {
    bool is_signed = type_ == 'd' || type_ == 'i';
    using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
    if (const_check(sizeof(target_type) <= sizeof(int))) {
      // Extra casts are used to silence warnings.
      if (is_signed) {
        arg_ = internal::make_arg<Context>(
            static_cast<int>(static_cast<target_type>(value)));
      } else {
        using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
        arg_ = internal::make_arg<Context>(
            static_cast<unsigned>(static_cast<unsigned_type>(value)));
      }
    } else {
      if (is_signed) {
        // glibc's printf doesn't sign extend arguments of smaller types:
        //   std::printf("%lld", -42);  // prints "4294967254"
        // but we don't have to do the same because it's a UB.
        arg_ = internal::make_arg<Context>(static_cast<long long>(value));
      } else {
        arg_ = internal::make_arg<Context>(
            static_cast<typename make_unsigned_or_bool<U>::type>(value));
      }
    }
  }

  template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
  void operator()(U) {}  // No conversion needed for non-integral types.
};

// Converts an integer argument to T for printf, if T is an integral type.
// If T is void, the argument is converted to corresponding signed or unsigned
// type depending on the type specifier: 'd' and 'i' - signed, other -
// unsigned).
template <typename T, typename Context, typename Char>
void convert_arg(basic_format_arg<Context>& arg, Char type) {
  visit_format_arg(arg_converter<T, Context>(arg, type), arg);
}

// Converts an integer argument to char for printf.
template <typename Context> class char_converter {
 private:
  basic_format_arg<Context>& arg_;

 public:
  explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}

  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
  void operator()(T value) {
    arg_ = internal::make_arg<Context>(
        static_cast<typename Context::char_type>(value));
  }

  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
  void operator()(T) {}  // No conversion needed for non-integral types.
};

// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char> class printf_width_handler {
 private:
  using format_specs = basic_format_specs<Char>;

  format_specs& specs_;

 public:
  explicit printf_width_handler(format_specs& specs) : specs_(specs) {}

  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
  unsigned operator()(T value) {
    auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
    if (internal::is_negative(value)) {
      specs_.align = align::left;
      width = 0 - width;
    }
    unsigned int_max = max_value<int>();
    if (width > int_max) FMT_THROW(duckdb::Exception("number is too big"));
    return static_cast<unsigned>(width);
  }

  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
  unsigned operator()(T) {
    FMT_THROW(duckdb::Exception("width is not integer"));
    return 0;
  }
};

template <typename Char, typename Context>
void printf(buffer<Char>& buf, basic_string_view<Char> format,
            basic_format_args<Context> args) {
  Context(std::back_inserter(buf), format, args).format();
}

template <typename OutputIt, typename Char, typename Context>
internal::truncating_iterator<OutputIt> printf(
    internal::truncating_iterator<OutputIt> it, basic_string_view<Char> format,
    basic_format_args<Context> args) {
  return Context(it, format, args).format();
}
}  // namespace internal

using internal::printf;  // For printing into memory_buffer.

template <typename Range> class printf_arg_formatter;

template <typename OutputIt, typename Char> class basic_printf_context;

/**
  \rst
  The ``printf`` argument formatter.
  \endrst
 */
template <typename Range>
class printf_arg_formatter : public internal::arg_formatter_base<Range> {
 public:
  using iterator = typename Range::iterator;

 private:
  using char_type = typename Range::value_type;
  using base = internal::arg_formatter_base<Range>;
  using context_type = basic_printf_context<iterator, char_type>;

  context_type& context_;

  void write_null_pointer(char) {
    this->specs()->type = 0;
    this->write("(nil)");
  }

  void write_null_pointer(wchar_t) {
    this->specs()->type = 0;
    this->write(L"(nil)");
  }

 public:
  using format_specs = typename base::format_specs;

  /**
    \rst
    Constructs an argument formatter object.
    *buffer* is a reference to the output buffer and *specs* contains format
    specifier information for standard argument types.
    \endrst
   */
  printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
      : base(Range(iter), &specs, internal::locale_ref()), context_(ctx) {}

  template <typename T, FMT_ENABLE_IF(fmt::internal::is_integral<T>::value)>
  iterator operator()(T value) {
    // MSVC2013 fails to compile separate overloads for bool and char_type so
    // use std::is_same instead.
    if (std::is_same<T, bool>::value) {
      format_specs& fmt_specs = *this->specs();
      if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
      fmt_specs.type = 0;
      this->write(value != 0);
    } else if (std::is_same<T, char_type>::value) {
      format_specs& fmt_specs = *this->specs();
      if (fmt_specs.type && fmt_specs.type != 'c')
        return (*this)(static_cast<int>(value));
      fmt_specs.sign = sign::none;
      fmt_specs.alt = false;
      fmt_specs.align = align::right;
      return base::operator()(value);
    } else {
      return base::operator()(value);
    }
    return this->out();
  }

  template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
  iterator operator()(T value) {
    return base::operator()(value);
  }

  /** Formats a null-terminated C string. */
  iterator operator()(const char* value) {
    if (value)
      base::operator()(value);
    else if (this->specs()->type == 'p')
      write_null_pointer(char_type());
    else
      this->write("(null)");
    return this->out();
  }

  /** Formats a null-terminated wide C string. */
  iterator operator()(const wchar_t* value) {
    if (value)
      base::operator()(value);
    else if (this->specs()->type == 'p')
      write_null_pointer(char_type());
    else
      this->write(L"(null)");
    return this->out();
  }

  iterator operator()(basic_string_view<char_type> value) {
    return base::operator()(value);
  }

  iterator operator()(monostate value) { return base::operator()(value); }

  /** Formats a pointer. */
  iterator operator()(const void* value) {
    if (value) return base::operator()(value);
    this->specs()->type = 0;
    write_null_pointer(char_type());
    return this->out();
  }

  /** Formats an argument of a custom (user-defined) type. */
  iterator operator()(typename basic_format_arg<context_type>::handle handle) {
    handle.format(context_.parse_context(), context_);
    return this->out();
  }
};

template <typename T> struct printf_formatter {
  template <typename ParseContext>
  auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
    internal::format_value(internal::get_container(ctx.out()), value);
    return ctx.out();
  }
};

/** This template formats data and writes the output to a writer. */
template <typename OutputIt, typename Char> class basic_printf_context {
 public:
  /** The character type for the output. */
  using char_type = Char;
  using format_arg = basic_format_arg<basic_printf_context>;
  template <typename T> using formatter_type = printf_formatter<T>;

 private:
  using format_specs = basic_format_specs<char_type>;

  OutputIt out_;
  basic_format_args<basic_printf_context> args_;
  basic_format_parse_context<Char> parse_ctx_;

  static void parse_flags(format_specs& specs, const Char*& it,
                          const Char* end);

  // Returns the argument with specified index or, if arg_index is -1, the next
  // argument.
  format_arg get_arg(int arg_index = -1);

  // Parses argument index, flags and width and returns the argument index.
  int parse_header(const Char*& it, const Char* end, format_specs& specs);

 public:
  /**
   \rst
   Constructs a ``printf_context`` object. References to the arguments and
   the writer are stored in the context object so make sure they have
   appropriate lifetimes.
   \endrst
   */
  basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
                       basic_format_args<basic_printf_context> args)
      : out_(out), args_(args), parse_ctx_(format_str) {}

  OutputIt out() { return out_; }
  void advance_to(OutputIt it) { out_ = it; }

  format_arg arg(int id) const { return args_.get(id); }

  basic_format_parse_context<Char>& parse_context() { return parse_ctx_; }

  FMT_CONSTEXPR void on_error(const char* message) {
    parse_ctx_.on_error(message);
  }

  /** Formats stored arguments and writes the output to the range. */
  template <typename ArgFormatter = printf_arg_formatter<buffer_range<Char>>>
  OutputIt format();
};

template <typename OutputIt, typename Char>
void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
                                                       const Char*& it,
                                                       const Char* end) {
  for (; it != end; ++it) {
    switch (*it) {
    case '-':
      specs.align = align::left;
      break;
    case '+':
      specs.sign = sign::plus;
      break;
    case '0':
      specs.fill[0] = '0';
      break;
    case ' ':
      specs.sign = sign::space;
      break;
    case '#':
      specs.alt = true;
      break;
    default:
      return;
    }
  }
}

template <typename OutputIt, typename Char>
typename basic_printf_context<OutputIt, Char>::format_arg
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
  if (arg_index < 0)
    arg_index = parse_ctx_.next_arg_id();
  else
    parse_ctx_.check_arg_id(--arg_index);
  return internal::get_arg(*this, arg_index);
}

template <typename OutputIt, typename Char>
int basic_printf_context<OutputIt, Char>::parse_header(
    const Char*& it, const Char* end, format_specs& specs) {
  int arg_index = -1;
  char_type c = *it;
  if (c >= '0' && c <= '9') {
    // Parse an argument index (if followed by '$') or a width possibly
    // preceded with '0' flag(s).
    internal::error_handler eh;
    int value = parse_nonnegative_int(it, end, eh);
    if (it != end && *it == '$') {  // value is an argument index
      ++it;
      arg_index = value;
    } else {
      if (c == '0') specs.fill[0] = '0';
      if (value != 0) {
        // Nonzero value means that we parsed width and don't need to
        // parse it or flags again, so return now.
        specs.width = value;
        return arg_index;
      }
    }
  }
  parse_flags(specs, it, end);
  // Parse width.
  if (it != end) {
    if (*it >= '0' && *it <= '9') {
      internal::error_handler eh;
      specs.width = parse_nonnegative_int(it, end, eh);
    } else if (*it == '*') {
      ++it;
      specs.width = static_cast<int>(visit_format_arg(
          internal::printf_width_handler<char_type>(specs), get_arg()));
    }
  }
  return arg_index;
}

template <typename OutputIt, typename Char>
template <typename ArgFormatter>
OutputIt basic_printf_context<OutputIt, Char>::format() {
  auto out = this->out();
  const Char* start = parse_ctx_.begin();
  const Char* end = parse_ctx_.end();
  auto it = start;
  while (it != end) {
    char_type c = *it++;
    if (c != '%') continue;
    if (it != end && *it == c) {
      out = std::copy(start, it, out);
      start = ++it;
      continue;
    }
    out = std::copy(start, it - 1, out);

    format_specs specs;
    specs.align = align::right;

    // Parse argument index, flags and width.
    int arg_index = parse_header(it, end, specs);
    if (arg_index == 0) on_error("argument index out of range");

    // Parse precision.
    if (it != end && *it == '.') {
      ++it;
      c = it != end ? *it : 0;
      if ('0' <= c && c <= '9') {
        internal::error_handler eh;
        specs.precision = parse_nonnegative_int(it, end, eh);
      } else if (c == '*') {
        ++it;
        specs.precision =
            static_cast<int>(visit_format_arg(internal::printf_precision_handler(), get_arg()));
      } else {
        specs.precision = 0;
      }
    }

    format_arg arg = get_arg(arg_index);
    if (specs.alt && visit_format_arg(internal::is_zero_int(), arg))
      specs.alt = false;
    if (specs.fill[0] == '0') {
      if (arg.is_arithmetic())
        specs.align = align::numeric;
      else
        specs.fill[0] = ' ';  // Ignore '0' flag for non-numeric types.
    }

    // Parse length and convert the argument to the required type.
    c = it != end ? *it++ : 0;
    char_type t = it != end ? *it : 0;
    using internal::convert_arg;
    switch (c) {
    case 'h':
      if (t == 'h') {
        ++it;
        t = it != end ? *it : 0;
        convert_arg<signed char>(arg, t);
      } else {
        convert_arg<short>(arg, t);
      }
      break;
    case 'l':
      if (t == 'l') {
        ++it;
        t = it != end ? *it : 0;
        convert_arg<long long>(arg, t);
      } else {
        convert_arg<long>(arg, t);
      }
      break;
    case 'j':
      convert_arg<intmax_t>(arg, t);
      break;
    case 'z':
      convert_arg<std::size_t>(arg, t);
      break;
    case 't':
      convert_arg<std::ptrdiff_t>(arg, t);
      break;
    case 'L':
      // printf produces garbage when 'L' is omitted for long double, no
      // need to do the same.
      break;
    default:
      --it;
      convert_arg<void>(arg, c);
    }

    // Parse type.
    if (it == end) FMT_THROW(duckdb::Exception("invalid format string"));
    specs.type = static_cast<char>(*it++);
    if (arg.is_integral()) {
      // Normalize type.
      switch (specs.type) {
      case 'i':
      case 'u':
        specs.type = 'd';
        break;
      case 'c':
        visit_format_arg(internal::char_converter<basic_printf_context>(arg),
                         arg);
        break;
      }
    }

    start = it;

    // Format argument.
    visit_format_arg(ArgFormatter(out, specs, *this), arg);
  }
  return std::copy(start, it, out);
}

template <typename Char>
using basic_printf_context_t =
    basic_printf_context<std::back_insert_iterator<internal::buffer<Char>>,
                         Char>;

using printf_context = basic_printf_context_t<char>;
using wprintf_context = basic_printf_context_t<wchar_t>;

using printf_args = basic_format_args<printf_context>;
using wprintf_args = basic_format_args<wprintf_context>;

/**
  \rst
  Constructs an `~fmt::format_arg_store` object that contains references to
  arguments and can be implicitly converted to `~fmt::printf_args`.
  \endrst
 */
template <typename... Args>
inline format_arg_store<printf_context, Args...> make_printf_args(
    const Args&... args) {
  return {args...};
}

/**
  \rst
  Constructs an `~fmt::format_arg_store` object that contains references to
  arguments and can be implicitly converted to `~fmt::wprintf_args`.
  \endrst
 */
template <typename... Args>
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
    const Args&... args) {
  return {args...};
}

template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vsprintf(
    const S& format, basic_format_args<basic_printf_context_t<Char>> args) {
  basic_memory_buffer<Char> buffer;
  printf(buffer, to_string_view(format), args);
  return to_string(buffer);
}

/**
  \rst
  Formats arguments and returns the result as a string.

  **Example**::

    std::string message = fmt::sprintf("The answer is %d", 42);
  \endrst
*/
template <typename S, typename... Args,
          typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
  using context = basic_printf_context_t<Char>;
  return vsprintf(to_string_view(format), {make_format_args<context>(args...)});
}

template <typename S, typename Char = char_t<S>>
inline int vfprintf(std::FILE* f, const S& format,
                    basic_format_args<basic_printf_context_t<Char>> args) {
  basic_memory_buffer<Char> buffer;
  printf(buffer, to_string_view(format), args);
  std::size_t size = buffer.size();
  return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
             ? -1
             : static_cast<int>(size);
}

/**
  \rst
  Prints formatted data to the file *f*.

  **Example**::

    fmt::fprintf(stderr, "Don't %s!", "panic");
  \endrst
 */
template <typename S, typename... Args,
          typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
  using context = basic_printf_context_t<Char>;
  return vfprintf(f, to_string_view(format),
                  {make_format_args<context>(args...)});
}

template <typename S, typename Char = char_t<S>>
inline int vprintf(const S& format,
                   basic_format_args<basic_printf_context_t<Char>> args) {
  return vfprintf(stdout, to_string_view(format), args);
}

/**
  \rst
  Prints formatted data to ``stdout``.

  **Example**::

    fmt::printf("Elapsed time: %.2f seconds", 1.23);
  \endrst
 */
template <typename S, typename... Args,
          FMT_ENABLE_IF(internal::is_string<S>::value)>
inline int printf(const S& format_str, const Args&... args) {
  using context = basic_printf_context_t<char_t<S>>;
  return vprintf(to_string_view(format_str),
                 {make_format_args<context>(args...)});
}

template <typename S, typename Char = char_t<S>>
inline int vfprintf(std::basic_ostream<Char>& os, const S& format,
                    basic_format_args<basic_printf_context_t<Char>> args) {
  basic_memory_buffer<Char> buffer;
  printf(buffer, to_string_view(format), args);
  internal::write(os, buffer);
  return static_cast<int>(buffer.size());
}

/** Formats arguments and writes the output to the range. */
template <typename ArgFormatter, typename Char,
          typename Context =
              basic_printf_context<typename ArgFormatter::iterator, Char>>
typename ArgFormatter::iterator vprintf(internal::buffer<Char>& out,
                                        basic_string_view<Char> format_str,
                                        basic_format_args<Context> args) {
  typename ArgFormatter::iterator iter(out);
  Context(iter, format_str, args).template format<ArgFormatter>();
  return iter;
}

/**
  \rst
  Prints formatted data to the stream *os*.

  **Example**::

    fmt::fprintf(cerr, "Don't %s!", "panic");
  \endrst
 */
template <typename S, typename... Args, typename Char = char_t<S>>
inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
                   const Args&... args) {
  using context = basic_printf_context_t<Char>;
  return vfprintf(os, to_string_view(format_str),
                  {make_format_args<context>(args...)});
}
FMT_END_NAMESPACE

#endif  // FMT_PRINTF_H_


using namespace std;

namespace duckdb {

struct FMTPrintf {
	template <class ctx>
	static string OP(const char *format_str, std::vector<fmt::basic_format_arg<ctx>> &format_args) {
		return fmt::vsprintf(format_str,
		                     fmt::basic_format_args<ctx>(format_args.data(), static_cast<int>(format_args.size())));
	}
};

struct FMTFormat {
	template <class ctx>
	static string OP(const char *format_str, std::vector<fmt::basic_format_arg<ctx>> &format_args) {
		return fmt::vformat(format_str,
		                    fmt::basic_format_args<ctx>(format_args.data(), static_cast<int>(format_args.size())));
	}
};

template <class FORMAT_FUN, class ctx>
static void printf_function(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &format_string = args.data[0];
	result.vector_type = VectorType::CONSTANT_VECTOR;
	for (idx_t i = 0; i < args.column_count(); i++) {
		switch (args.data[i].vector_type) {
		case VectorType::CONSTANT_VECTOR:
			if (ConstantVector::IsNull(args.data[i])) {
				// constant null! result is always NULL regardless of other input
				result.vector_type = VectorType::CONSTANT_VECTOR;
				ConstantVector::SetNull(result, true);
				return;
			}
			break;
		default:
			// FLAT VECTOR, we can directly OR the nullmask
			args.data[i].Normalify(args.size());
			result.vector_type = VectorType::FLAT_VECTOR;
			FlatVector::Nullmask(result) |= FlatVector::Nullmask(args.data[i]);
			break;
		}
	}
	idx_t count = result.vector_type == VectorType::CONSTANT_VECTOR ? 1 : args.size();

	auto format_data = FlatVector::GetData<string_t>(format_string);
	auto result_data = FlatVector::GetData<string_t>(result);
	for (idx_t idx = 0; idx < count; idx++) {
		if (result.vector_type == VectorType::FLAT_VECTOR && FlatVector::IsNull(result, idx)) {
			// this entry is NULL: skip it
			continue;
		}

		// first fetch the format string
		auto fmt_idx = format_string.vector_type == VectorType::CONSTANT_VECTOR ? 0 : idx;
		auto format_string = format_data[fmt_idx].GetData();

		// now gather all the format arguments
		std::vector<fmt::basic_format_arg<ctx>> format_args;
		for (idx_t col_idx = 1; col_idx < args.column_count(); col_idx++) {
			auto &col = args.data[col_idx];
			idx_t arg_idx = col.vector_type == VectorType::CONSTANT_VECTOR ? 0 : idx;
			switch (col.type) {
			case TypeId::BOOL: {
				auto arg_data = FlatVector::GetData<bool>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::INT8: {
				auto arg_data = FlatVector::GetData<int8_t>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::INT16: {
				auto arg_data = FlatVector::GetData<int8_t>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::INT32: {
				auto arg_data = FlatVector::GetData<int32_t>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::INT64: {
				auto arg_data = FlatVector::GetData<int64_t>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::FLOAT: {
				auto arg_data = FlatVector::GetData<float>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::DOUBLE: {
				auto arg_data = FlatVector::GetData<double>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx]));
				break;
			}
			case TypeId::VARCHAR: {
				auto arg_data = FlatVector::GetData<string_t>(col);
				format_args.emplace_back(fmt::internal::make_arg<ctx>(arg_data[arg_idx].GetData()));
				break;
			}
			default:
				throw Exception("Unsupported type for format!");
			}
		}
		// finally actually perform the format
		string dynamic_result = FORMAT_FUN::template OP<ctx>(format_string, format_args);
		result_data[idx] = StringVector::AddString(result, dynamic_result);
	}
}

void PrintfFun::RegisterFunction(BuiltinFunctions &set) {
	// fmt::printf_context, fmt::vsprintf
	ScalarFunction printf_fun =
	    ScalarFunction("printf", {SQLType::VARCHAR}, SQLType::VARCHAR, printf_function<FMTPrintf, fmt::printf_context>);
	printf_fun.varargs = SQLType::ANY;
	set.AddFunction(printf_fun);

	// fmt::format_context, fmt::vformat
	ScalarFunction format_fun =
	    ScalarFunction("format", {SQLType::VARCHAR}, SQLType::VARCHAR, printf_function<FMTFormat, fmt::format_context>);
	format_fun.varargs = SQLType::ANY;
	set.AddFunction(format_fun);
}

} // namespace duckdb










// Copyright 2003-2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_RE2_H_
#define RE2_RE2_H_

// C++ interface to the re2 regular-expression library.
// RE2 supports Perl-style regular expressions (with extensions like
// \d, \w, \s, ...).
//
// -----------------------------------------------------------------------
// REGEXP SYNTAX:
//
// This module uses the re2 library and hence supports
// its syntax for regular expressions, which is similar to Perl's with
// some of the more complicated things thrown away.  In particular,
// backreferences and generalized assertions are not available, nor is \Z.
//
// See https://github.com/google/re2/wiki/Syntax for the syntax
// supported by RE2, and a comparison with PCRE and PERL regexps.
//
// For those not familiar with Perl's regular expressions,
// here are some examples of the most commonly used extensions:
//
//   "hello (\\w+) world"  -- \w matches a "word" character
//   "version (\\d+)"      -- \d matches a digit
//   "hello\\s+world"      -- \s matches any whitespace character
//   "\\b(\\w+)\\b"        -- \b matches non-empty string at word boundary
//   "(?i)hello"           -- (?i) turns on case-insensitive matching
//   "/\\*(.*?)\\*/"       -- .*? matches . minimum no. of times possible
//
// -----------------------------------------------------------------------
// MATCHING INTERFACE:
//
// The "FullMatch" operation checks that supplied text matches a
// supplied pattern exactly.
//
// Example: successful match
//    CHECK(RE2::FullMatch("hello", "h.*o"));
//
// Example: unsuccessful match (requires full match):
//    CHECK(!RE2::FullMatch("hello", "e"));
//
// -----------------------------------------------------------------------
// UTF-8 AND THE MATCHING INTERFACE:
//
// By default, the pattern and input text are interpreted as UTF-8.
// The RE2::Latin1 option causes them to be interpreted as Latin-1.
//
// Example:
//    CHECK(RE2::FullMatch(utf8_string, RE2(utf8_pattern)));
//    CHECK(RE2::FullMatch(latin1_string, RE2(latin1_pattern, RE2::Latin1)));
//
// -----------------------------------------------------------------------
// MATCHING WITH SUBSTRING EXTRACTION:
//
// You can supply extra pointer arguments to extract matched substrings.
// On match failure, none of the pointees will have been modified.
// On match success, the substrings will be converted (as necessary) and
// their values will be assigned to their pointees until all conversions
// have succeeded or one conversion has failed.
// On conversion failure, the pointees will be in an indeterminate state
// because the caller has no way of knowing which conversion failed.
// However, conversion cannot fail for types like string and StringPiece
// that do not inspect the substring contents. Hence, in the common case
// where all of the pointees are of such types, failure is always due to
// match failure and thus none of the pointees will have been modified.
//
// Example: extracts "ruby" into "s" and 1234 into "i"
//    int i;
//    std::string s;
//    CHECK(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s, &i));
//
// Example: fails because string cannot be stored in integer
//    CHECK(!RE2::FullMatch("ruby", "(.*)", &i));
//
// Example: fails because there aren't enough sub-patterns
//    CHECK(!RE2::FullMatch("ruby:1234", "\\w+:\\d+", &s));
//
// Example: does not try to extract any extra sub-patterns
//    CHECK(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s));
//
// Example: does not try to extract into NULL
//    CHECK(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", NULL, &i));
//
// Example: integer overflow causes failure
//    CHECK(!RE2::FullMatch("ruby:1234567891234", "\\w+:(\\d+)", &i));
//
// NOTE(rsc): Asking for substrings slows successful matches quite a bit.
// This may get a little faster in the future, but right now is slower
// than PCRE.  On the other hand, failed matches run *very* fast (faster
// than PCRE), as do matches without substring extraction.
//
// -----------------------------------------------------------------------
// PARTIAL MATCHES
//
// You can use the "PartialMatch" operation when you want the pattern
// to match any substring of the text.
//
// Example: simple search for a string:
//      CHECK(RE2::PartialMatch("hello", "ell"));
//
// Example: find first number in a string
//      int number;
//      CHECK(RE2::PartialMatch("x*100 + 20", "(\\d+)", &number));
//      CHECK_EQ(number, 100);
//
// -----------------------------------------------------------------------
// PRE-COMPILED REGULAR EXPRESSIONS
//
// RE2 makes it easy to use any string as a regular expression, without
// requiring a separate compilation step.
//
// If speed is of the essence, you can create a pre-compiled "RE2"
// object from the pattern and use it multiple times.  If you do so,
// you can typically parse text faster than with sscanf.
//
// Example: precompile pattern for faster matching:
//    RE2 pattern("h.*o");
//    while (ReadLine(&str)) {
//      if (RE2::FullMatch(str, pattern)) ...;
//    }
//
// -----------------------------------------------------------------------
// SCANNING TEXT INCREMENTALLY
//
// The "Consume" operation may be useful if you want to repeatedly
// match regular expressions at the front of a string and skip over
// them as they match.  This requires use of the "StringPiece" type,
// which represents a sub-range of a real string.
//
// Example: read lines of the form "var = value" from a string.
//      std::string contents = ...;     // Fill string somehow
//      StringPiece input(contents);    // Wrap a StringPiece around it
//
//      std::string var;
//      int value;
//      while (RE2::Consume(&input, "(\\w+) = (\\d+)\n", &var, &value)) {
//        ...;
//      }
//
// Each successful call to "Consume" will set "var/value", and also
// advance "input" so it points past the matched text.  Note that if the
// regular expression matches an empty string, input will advance
// by 0 bytes.  If the regular expression being used might match
// an empty string, the loop body must check for this case and either
// advance the string or break out of the loop.
//
// The "FindAndConsume" operation is similar to "Consume" but does not
// anchor your match at the beginning of the string.  For example, you
// could extract all words from a string by repeatedly calling
//     RE2::FindAndConsume(&input, "(\\w+)", &word)
//
// -----------------------------------------------------------------------
// USING VARIABLE NUMBER OF ARGUMENTS
//
// The above operations require you to know the number of arguments
// when you write the code.  This is not always possible or easy (for
// example, the regular expression may be calculated at run time).
// You can use the "N" version of the operations when the number of
// match arguments are determined at run time.
//
// Example:
//   const RE2::Arg* args[10];
//   int n;
//   // ... populate args with pointers to RE2::Arg values ...
//   // ... set n to the number of RE2::Arg objects ...
//   bool match = RE2::FullMatchN(input, pattern, args, n);
//
// The last statement is equivalent to
//
//   bool match = RE2::FullMatch(input, pattern,
//                               *args[0], *args[1], ..., *args[n - 1]);
//
// -----------------------------------------------------------------------
// PARSING HEX/OCTAL/C-RADIX NUMBERS
//
// By default, if you pass a pointer to a numeric value, the
// corresponding text is interpreted as a base-10 number.  You can
// instead wrap the pointer with a call to one of the operators Hex(),
// Octal(), or CRadix() to interpret the text in another base.  The
// CRadix operator interprets C-style "0" (base-8) and "0x" (base-16)
// prefixes, but defaults to base-10.
//
// Example:
//   int a, b, c, d;
//   CHECK(RE2::FullMatch("100 40 0100 0x40", "(.*) (.*) (.*) (.*)",
//         RE2::Octal(&a), RE2::Hex(&b), RE2::CRadix(&c), RE2::CRadix(&d));
// will leave 64 in a, b, c, and d.

#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <map>
#include <mutex>
#include <string>

// Copyright 2001-2010 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_STRINGPIECE_H_
#define RE2_STRINGPIECE_H_

// A string-like object that points to a sized piece of memory.
//
// Functions or methods may use const StringPiece& parameters to accept either
// a "const char*" or a "string" value that will be implicitly converted to
// a StringPiece.  The implicit conversion means that it is often appropriate
// to include this .h file in other files rather than forward-declaring
// StringPiece as would be appropriate for most other Google classes.
//
// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
// conversions from "const char*" to "string" and back again.
//
//
// Arghh!  I wish C++ literals were "string".

// Doing this simplifies the logic below.
#ifndef __has_include
#define __has_include(x) 0
#endif

#include <stddef.h>
#include <string.h>
#include <algorithm>
#include <iosfwd>
#include <iterator>
#include <string>
#if __has_include(<string_view>) && __cplusplus >= 201703L
#include <string_view>
#endif

namespace re2 {

class StringPiece {
 public:
  typedef std::char_traits<char> traits_type;
  typedef char value_type;
  typedef char* pointer;
  typedef const char* const_pointer;
  typedef char& reference;
  typedef const char& const_reference;
  typedef const char* const_iterator;
  typedef const_iterator iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  typedef const_reverse_iterator reverse_iterator;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  static const size_type npos = static_cast<size_type>(-1);

  // We provide non-explicit singleton constructors so users can pass
  // in a "const char*" or a "string" wherever a "StringPiece" is
  // expected.
  StringPiece()
      : data_(NULL), size_(0) {}
#if __has_include(<string_view>) && __cplusplus >= 201703L
  StringPiece(const std::string_view& str)
      : data_(str.data()), size_(str.size()) {}
#endif
  StringPiece(const std::string& str)
      : data_(str.data()), size_(str.size()) {}
  StringPiece(const char* str)
      : data_(str), size_(str == NULL ? 0 : strlen(str)) {}
  StringPiece(const char* str, size_type len)
      : data_(str), size_(len) {}

  const_iterator begin() const { return data_; }
  const_iterator end() const { return data_ + size_; }
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(data_ + size_);
  }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(data_);
  }

  size_type size() const { return size_; }
  size_type length() const { return size_; }
  bool empty() const { return size_ == 0; }

  const_reference operator[](size_type i) const { return data_[i]; }
  const_pointer data() const { return data_; }

  void remove_prefix(size_type n) {
    data_ += n;
    size_ -= n;
  }

  void remove_suffix(size_type n) {
    size_ -= n;
  }

  void set(const char* str) {
    data_ = str;
    size_ = str == NULL ? 0 : strlen(str);
  }

  void set(const char* str, size_type len) {
    data_ = str;
    size_ = len;
  }

  // Converts to `std::basic_string`.
  template <typename A>
  explicit operator std::basic_string<char, traits_type, A>() const {
    if (!data_) return {};
    return std::basic_string<char, traits_type, A>(data_, size_);
  }

  std::string as_string() const {
    return std::string(data_, size_);
  }

  // We also define ToString() here, since many other string-like
  // interfaces name the routine that converts to a C++ string
  // "ToString", and it's confusing to have the method that does that
  // for a StringPiece be called "as_string()".  We also leave the
  // "as_string()" method defined here for existing code.
  std::string ToString() const {
    return std::string(data_, size_);
  }

  void CopyToString(std::string* target) const {
    target->assign(data_, size_);
  }

  void AppendToString(std::string* target) const {
    target->append(data_, size_);
  }

  size_type copy(char* buf, size_type n, size_type pos = 0) const;
  StringPiece substr(size_type pos = 0, size_type n = npos) const;

  int compare(const StringPiece& x) const {
    size_type min_size = std::min(size(), x.size());
    if (min_size > 0) {
      int r = memcmp(data(), x.data(), min_size);
      if (r < 0) return -1;
      if (r > 0) return 1;
    }
    if (size() < x.size()) return -1;
    if (size() > x.size()) return 1;
    return 0;
  }

  // Does "this" start with "x"?
  bool starts_with(const StringPiece& x) const {
    return x.empty() ||
           (size() >= x.size() && memcmp(data(), x.data(), x.size()) == 0);
  }

  // Does "this" end with "x"?
  bool ends_with(const StringPiece& x) const {
    return x.empty() ||
           (size() >= x.size() &&
            memcmp(data() + (size() - x.size()), x.data(), x.size()) == 0);
  }

  bool contains(const StringPiece& s) const {
    return find(s) != npos;
  }

  size_type find(const StringPiece& s, size_type pos = 0) const;
  size_type find(char c, size_type pos = 0) const;
  size_type rfind(const StringPiece& s, size_type pos = npos) const;
  size_type rfind(char c, size_type pos = npos) const;

 private:
  const_pointer data_;
  size_type size_;
};

inline bool operator==(const StringPiece& x, const StringPiece& y) {
  StringPiece::size_type len = x.size();
  if (len != y.size()) return false;
  return x.data() == y.data() || len == 0 ||
         memcmp(x.data(), y.data(), len) == 0;
}

inline bool operator!=(const StringPiece& x, const StringPiece& y) {
  return !(x == y);
}

inline bool operator<(const StringPiece& x, const StringPiece& y) {
  StringPiece::size_type min_size = std::min(x.size(), y.size());
  int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size);
  return (r < 0) || (r == 0 && x.size() < y.size());
}

inline bool operator>(const StringPiece& x, const StringPiece& y) {
  return y < x;
}

inline bool operator<=(const StringPiece& x, const StringPiece& y) {
  return !(x > y);
}

inline bool operator>=(const StringPiece& x, const StringPiece& y) {
  return !(x < y);
}

// Allow StringPiece to be logged.
std::ostream& operator<<(std::ostream& o, const StringPiece& p);

}  // namespace re2

#endif  // RE2_STRINGPIECE_H_


namespace re2 {
class Prog;
class Regexp;
}  // namespace re2

namespace re2 {

// Interface for regular expression matching.  Also corresponds to a
// pre-compiled regular expression.  An "RE2" object is safe for
// concurrent use by multiple threads.
class RE2 {
 public:
  // We convert user-passed pointers into special Arg objects
  class Arg;
  class Options;

  // Defined in set.h.
  class Set;

  enum ErrorCode {
    NoError = 0,

    // Unexpected error
    ErrorInternal,

    // Parse errors
    ErrorBadEscape,          // bad escape sequence
    ErrorBadCharClass,       // bad character class
    ErrorBadCharRange,       // bad character class range
    ErrorMissingBracket,     // missing closing ]
    ErrorMissingParen,       // missing closing )
    ErrorTrailingBackslash,  // trailing \ at end of regexp
    ErrorRepeatArgument,     // repeat argument missing, e.g. "*"
    ErrorRepeatSize,         // bad repetition argument
    ErrorRepeatOp,           // bad repetition operator
    ErrorBadPerlOp,          // bad perl operator
    ErrorBadUTF8,            // invalid UTF-8 in regexp
    ErrorBadNamedCapture,    // bad named capture group
    ErrorPatternTooLarge     // pattern too large (compile failed)
  };

  // Predefined common options.
  // If you need more complicated things, instantiate
  // an Option class, possibly passing one of these to
  // the Option constructor, change the settings, and pass that
  // Option class to the RE2 constructor.
  enum CannedOptions {
    DefaultOptions = 0,
    Latin1, // treat input as Latin-1 (default UTF-8)
    POSIX, // POSIX syntax, leftmost-longest match
    Quiet // do not log about regexp parse errors
  };

  // Need to have the const char* and const std::string& forms for implicit
  // conversions when passing string literals to FullMatch and PartialMatch.
  // Otherwise the StringPiece form would be sufficient.
#ifndef SWIG
  RE2(const char* pattern);
  RE2(const std::string& pattern);
#endif
  RE2(const StringPiece& pattern);
  RE2(const StringPiece& pattern, const Options& options);
  ~RE2();

  // Returns whether RE2 was created properly.
  bool ok() const { return error_code() == NoError; }

  // The string specification for this RE2.  E.g.
  //   RE2 re("ab*c?d+");
  //   re.pattern();    // "ab*c?d+"
  const std::string& pattern() const { return pattern_; }

  // If RE2 could not be created properly, returns an error string.
  // Else returns the empty string.
  const std::string& error() const { return *error_; }

  // If RE2 could not be created properly, returns an error code.
  // Else returns RE2::NoError (== 0).
  ErrorCode error_code() const { return error_code_; }

  // If RE2 could not be created properly, returns the offending
  // portion of the regexp.
  const std::string& error_arg() const { return error_arg_; }

  // Returns the program size, a very approximate measure of a regexp's "cost".
  // Larger numbers are more expensive than smaller numbers.
  int ProgramSize() const;
  int ReverseProgramSize() const;

  // EXPERIMENTAL! SUBJECT TO CHANGE!
  // Outputs the program fanout as a histogram bucketed by powers of 2.
  // Returns the number of the largest non-empty bucket.
  int ProgramFanout(std::map<int, int>* histogram) const;
  int ReverseProgramFanout(std::map<int, int>* histogram) const;

  // Returns the underlying Regexp; not for general use.
  // Returns entire_regexp_ so that callers don't need
  // to know about prefix_ and prefix_foldcase_.
  re2::Regexp* Regexp() const { return entire_regexp_; }

  /***** The array-based matching interface ******/

  // The functions here have names ending in 'N' and are used to implement
  // the functions whose names are the prefix before the 'N'. It is sometimes
  // useful to invoke them directly, but the syntax is awkward, so the 'N'-less
  // versions should be preferred.
  static bool FullMatchN(const StringPiece& text, const RE2& re,
                         const Arg* const args[], int n);
  static bool PartialMatchN(const StringPiece& text, const RE2& re,
                            const Arg* const args[], int n);
  static bool ConsumeN(StringPiece* input, const RE2& re,
                       const Arg* const args[], int n);
  static bool FindAndConsumeN(StringPiece* input, const RE2& re,
                              const Arg* const args[], int n);

#ifndef SWIG
 private:
  template <typename F, typename SP>
  static inline bool Apply(F f, SP sp, const RE2& re) {
    return f(sp, re, NULL, 0);
  }

  template <typename F, typename SP, typename... A>
  static inline bool Apply(F f, SP sp, const RE2& re, const A&... a) {
    const Arg* const args[] = {&a...};
    const int n = sizeof...(a);
    return f(sp, re, args, n);
  }

 public:
  // In order to allow FullMatch() et al. to be called with a varying number
  // of arguments of varying types, we use two layers of variadic templates.
  // The first layer constructs the temporary Arg objects. The second layer
  // (above) constructs the array of pointers to the temporary Arg objects.

  /***** The useful part: the matching interface *****/

  // Matches "text" against "re".  If pointer arguments are
  // supplied, copies matched sub-patterns into them.
  //
  // You can pass in a "const char*" or a "std::string" for "text".
  // You can pass in a "const char*" or a "std::string" or a "RE2" for "re".
  //
  // The provided pointer arguments can be pointers to any scalar numeric
  // type, or one of:
  //    std::string     (matched piece is copied to string)
  //    StringPiece     (StringPiece is mutated to point to matched piece)
  //    T               (where "bool T::ParseFrom(const char*, size_t)" exists)
  //    (void*)NULL     (the corresponding matched sub-pattern is not copied)
  //
  // Returns true iff all of the following conditions are satisfied:
  //   a. "text" matches "re" exactly
  //   b. The number of matched sub-patterns is >= number of supplied pointers
  //   c. The "i"th argument has a suitable type for holding the
  //      string captured as the "i"th sub-pattern.  If you pass in
  //      NULL for the "i"th argument, or pass fewer arguments than
  //      number of sub-patterns, "i"th captured sub-pattern is
  //      ignored.
  //
  // CAVEAT: An optional sub-pattern that does not exist in the
  // matched string is assigned the empty string.  Therefore, the
  // following will return false (because the empty string is not a
  // valid number):
  //    int number;
  //    RE2::FullMatch("abc", "[a-z]+(\\d+)?", &number);
  template <typename... A>
  static bool FullMatch(const StringPiece& text, const RE2& re, A&&... a) {
    return Apply(FullMatchN, text, re, Arg(std::forward<A>(a))...);
  }

  // Exactly like FullMatch(), except that "re" is allowed to match
  // a substring of "text".
  template <typename... A>
  static bool PartialMatch(const StringPiece& text, const RE2& re, A&&... a) {
    return Apply(PartialMatchN, text, re, Arg(std::forward<A>(a))...);
  }

  // Like FullMatch() and PartialMatch(), except that "re" has to match
  // a prefix of the text, and "input" is advanced past the matched
  // text.  Note: "input" is modified iff this routine returns true
  // and "re" matched a non-empty substring of "text".
  template <typename... A>
  static bool Consume(StringPiece* input, const RE2& re, A&&... a) {
    return Apply(ConsumeN, input, re, Arg(std::forward<A>(a))...);
  }

  // Like Consume(), but does not anchor the match at the beginning of
  // the text.  That is, "re" need not start its match at the beginning
  // of "input".  For example, "FindAndConsume(s, "(\\w+)", &word)" finds
  // the next word in "s" and stores it in "word".
  template <typename... A>
  static bool FindAndConsume(StringPiece* input, const RE2& re, A&&... a) {
    return Apply(FindAndConsumeN, input, re, Arg(std::forward<A>(a))...);
  }
#endif

  // Replace the first match of "re" in "str" with "rewrite".
  // Within "rewrite", backslash-escaped digits (\1 to \9) can be
  // used to insert text matching corresponding parenthesized group
  // from the pattern.  \0 in "rewrite" refers to the entire matching
  // text.  E.g.,
  //
  //   std::string s = "yabba dabba doo";
  //   CHECK(RE2::Replace(&s, "b+", "d"));
  //
  // will leave "s" containing "yada dabba doo"
  //
  // Returns true if the pattern matches and a replacement occurs,
  // false otherwise.
  static bool Replace(std::string* str,
                      const RE2& re,
                      const StringPiece& rewrite);

  // Like Replace(), except replaces successive non-overlapping occurrences
  // of the pattern in the string with the rewrite. E.g.
  //
  //   std::string s = "yabba dabba doo";
  //   CHECK(RE2::GlobalReplace(&s, "b+", "d"));
  //
  // will leave "s" containing "yada dada doo"
  // Replacements are not subject to re-matching.
  //
  // Because GlobalReplace only replaces non-overlapping matches,
  // replacing "ana" within "banana" makes only one replacement, not two.
  //
  // Returns the number of replacements made.
  static int GlobalReplace(std::string* str,
                           const RE2& re,
                           const StringPiece& rewrite);

  // Like Replace, except that if the pattern matches, "rewrite"
  // is copied into "out" with substitutions.  The non-matching
  // portions of "text" are ignored.
  //
  // Returns true iff a match occurred and the extraction happened
  // successfully;  if no match occurs, the string is left unaffected.
  //
  // REQUIRES: "text" must not alias any part of "*out".
  static bool Extract(const StringPiece& text,
                      const RE2& re,
                      const StringPiece& rewrite,
                      std::string* out);

  // Escapes all potentially meaningful regexp characters in
  // 'unquoted'.  The returned string, used as a regular expression,
  // will exactly match the original string.  For example,
  //           1.5-2.0?
  // may become:
  //           1\.5\-2\.0\?
  static std::string QuoteMeta(const StringPiece& unquoted);

  // Computes range for any strings matching regexp. The min and max can in
  // some cases be arbitrarily precise, so the caller gets to specify the
  // maximum desired length of string returned.
  //
  // Assuming PossibleMatchRange(&min, &max, N) returns successfully, any
  // string s that is an anchored match for this regexp satisfies
  //   min <= s && s <= max.
  //
  // Note that PossibleMatchRange() will only consider the first copy of an
  // infinitely repeated element (i.e., any regexp element followed by a '*' or
  // '+' operator). Regexps with "{N}" constructions are not affected, as those
  // do not compile down to infinite repetitions.
  //
  // Returns true on success, false on error.
  bool PossibleMatchRange(std::string* min, std::string* max,
                          int maxlen) const;

  // Generic matching interface

  // Type of match.
  enum Anchor {
    UNANCHORED,         // No anchoring
    ANCHOR_START,       // Anchor at start only
    ANCHOR_BOTH         // Anchor at start and end
  };

  // Return the number of capturing subpatterns, or -1 if the
  // regexp wasn't valid on construction.  The overall match ($0)
  // does not count: if the regexp is "(a)(b)", returns 2.
  int NumberOfCapturingGroups() const { return num_captures_; }

  // Return a map from names to capturing indices.
  // The map records the index of the leftmost group
  // with the given name.
  // Only valid until the re is deleted.
  const std::map<std::string, int>& NamedCapturingGroups() const;

  // Return a map from capturing indices to names.
  // The map has no entries for unnamed groups.
  // Only valid until the re is deleted.
  const std::map<int, std::string>& CapturingGroupNames() const;

  // General matching routine.
  // Match against text starting at offset startpos
  // and stopping the search at offset endpos.
  // Returns true if match found, false if not.
  // On a successful match, fills in submatch[] (up to nsubmatch entries)
  // with information about submatches.
  // I.e. matching RE2("(foo)|(bar)baz") on "barbazbla" will return true, with
  // submatch[0] = "barbaz", submatch[1].data() = NULL, submatch[2] = "bar",
  // submatch[3].data() = NULL, ..., up to submatch[nsubmatch-1].data() = NULL.
  // Caveat: submatch[] may be clobbered even on match failure.
  //
  // Don't ask for more match information than you will use:
  // runs much faster with nsubmatch == 1 than nsubmatch > 1, and
  // runs even faster if nsubmatch == 0.
  // Doesn't make sense to use nsubmatch > 1 + NumberOfCapturingGroups(),
  // but will be handled correctly.
  //
  // Passing text == StringPiece(NULL, 0) will be handled like any other
  // empty string, but note that on return, it will not be possible to tell
  // whether submatch i matched the empty string or did not match:
  // either way, submatch[i].data() == NULL.
  bool Match(const StringPiece& text,
             size_t startpos,
             size_t endpos,
             Anchor re_anchor,
             StringPiece* submatch,
             int nsubmatch) const;

  // Check that the given rewrite string is suitable for use with this
  // regular expression.  It checks that:
  //   * The regular expression has enough parenthesized subexpressions
  //     to satisfy all of the \N tokens in rewrite
  //   * The rewrite string doesn't have any syntax errors.  E.g.,
  //     '\' followed by anything other than a digit or '\'.
  // A true return value guarantees that Replace() and Extract() won't
  // fail because of a bad rewrite string.
  bool CheckRewriteString(const StringPiece& rewrite,
                          std::string* error) const;

  // Returns the maximum submatch needed for the rewrite to be done by
  // Replace(). E.g. if rewrite == "foo \\2,\\1", returns 2.
  static int MaxSubmatch(const StringPiece& rewrite);

  // Append the "rewrite" string, with backslash subsitutions from "vec",
  // to string "out".
  // Returns true on success.  This method can fail because of a malformed
  // rewrite string.  CheckRewriteString guarantees that the rewrite will
  // be sucessful.
  bool Rewrite(std::string* out,
               const StringPiece& rewrite,
               const StringPiece* vec,
               int veclen) const;

  // Constructor options
  class Options {
   public:
    // The options are (defaults in parentheses):
    //
    //   utf8             (true)  text and pattern are UTF-8; otherwise Latin-1
    //   posix_syntax     (false) restrict regexps to POSIX egrep syntax
    //   longest_match    (false) search for longest match, not first match
    //   log_errors       (true)  log syntax and execution errors to ERROR
    //   max_mem          (see below)  approx. max memory footprint of RE2
    //   literal          (false) interpret string as literal, not regexp
    //   never_nl         (false) never match \n, even if it is in regexp
    //   dot_nl           (false) dot matches everything including new line
    //   never_capture    (false) parse all parens as non-capturing
    //   case_sensitive   (true)  match is case-sensitive (regexp can override
    //                              with (?i) unless in posix_syntax mode)
    //
    // The following options are only consulted when posix_syntax == true.
    // When posix_syntax == false, these features are always enabled and
    // cannot be turned off; to perform multi-line matching in that case,
    // begin the regexp with (?m).
    //   perl_classes     (false) allow Perl's \d \s \w \D \S \W
    //   word_boundary    (false) allow Perl's \b \B (word boundary and not)
    //   one_line         (false) ^ and $ only match beginning and end of text
    //
    // The max_mem option controls how much memory can be used
    // to hold the compiled form of the regexp (the Prog) and
    // its cached DFA graphs.  Code Search placed limits on the number
    // of Prog instructions and DFA states: 10,000 for both.
    // In RE2, those limits would translate to about 240 KB per Prog
    // and perhaps 2.5 MB per DFA (DFA state sizes vary by regexp; RE2 does a
    // better job of keeping them small than Code Search did).
    // Each RE2 has two Progs (one forward, one reverse), and each Prog
    // can have two DFAs (one first match, one longest match).
    // That makes 4 DFAs:
    //
    //   forward, first-match    - used for UNANCHORED or ANCHOR_START searches
    //                               if opt.longest_match() == false
    //   forward, longest-match  - used for all ANCHOR_BOTH searches,
    //                               and the other two kinds if
    //                               opt.longest_match() == true
    //   reverse, first-match    - never used
    //   reverse, longest-match  - used as second phase for unanchored searches
    //
    // The RE2 memory budget is statically divided between the two
    // Progs and then the DFAs: two thirds to the forward Prog
    // and one third to the reverse Prog.  The forward Prog gives half
    // of what it has left over to each of its DFAs.  The reverse Prog
    // gives it all to its longest-match DFA.
    //
    // Once a DFA fills its budget, it flushes its cache and starts over.
    // If this happens too often, RE2 falls back on the NFA implementation.

    // For now, make the default budget something close to Code Search.
    static const int kDefaultMaxMem = 8<<20;

    enum Encoding {
      EncodingUTF8 = 1,
      EncodingLatin1
    };

    Options() :
      encoding_(EncodingUTF8),
      posix_syntax_(false),
      longest_match_(false),
      log_errors_(true),
      max_mem_(kDefaultMaxMem),
      literal_(false),
      never_nl_(false),
      dot_nl_(false),
      never_capture_(false),
      case_sensitive_(true),
      perl_classes_(false),
      word_boundary_(false),
      one_line_(false) {
    }

    /*implicit*/ Options(CannedOptions);

    Encoding encoding() const { return encoding_; }
    void set_encoding(Encoding encoding) { encoding_ = encoding; }

    // Legacy interface to encoding.
    // TODO(rsc): Remove once clients have been converted.
    bool utf8() const { return encoding_ == EncodingUTF8; }
    void set_utf8(bool b) {
      if (b) {
        encoding_ = EncodingUTF8;
      } else {
        encoding_ = EncodingLatin1;
      }
    }

    bool posix_syntax() const { return posix_syntax_; }
    void set_posix_syntax(bool b) { posix_syntax_ = b; }

    bool longest_match() const { return longest_match_; }
    void set_longest_match(bool b) { longest_match_ = b; }

    bool log_errors() const { return log_errors_; }
    void set_log_errors(bool b) { log_errors_ = b; }

    int64_t max_mem() const { return max_mem_; }
    void set_max_mem(int64_t m) { max_mem_ = m; }

    bool literal() const { return literal_; }
    void set_literal(bool b) { literal_ = b; }

    bool never_nl() const { return never_nl_; }
    void set_never_nl(bool b) { never_nl_ = b; }

    bool dot_nl() const { return dot_nl_; }
    void set_dot_nl(bool b) { dot_nl_ = b; }

    bool never_capture() const { return never_capture_; }
    void set_never_capture(bool b) { never_capture_ = b; }

    bool case_sensitive() const { return case_sensitive_; }
    void set_case_sensitive(bool b) { case_sensitive_ = b; }

    bool perl_classes() const { return perl_classes_; }
    void set_perl_classes(bool b) { perl_classes_ = b; }

    bool word_boundary() const { return word_boundary_; }
    void set_word_boundary(bool b) { word_boundary_ = b; }

    bool one_line() const { return one_line_; }
    void set_one_line(bool b) { one_line_ = b; }

    void Copy(const Options& src) {
      *this = src;
    }

    int ParseFlags() const;

   private:
    Encoding encoding_;
    bool posix_syntax_;
    bool longest_match_;
    bool log_errors_;
    int64_t max_mem_;
    bool literal_;
    bool never_nl_;
    bool dot_nl_;
    bool never_capture_;
    bool case_sensitive_;
    bool perl_classes_;
    bool word_boundary_;
    bool one_line_;
  };

  // Returns the options set in the constructor.
  const Options& options() const { return options_; }

  // Argument converters; see below.
  static inline Arg CRadix(short* x);
  static inline Arg CRadix(unsigned short* x);
  static inline Arg CRadix(int* x);
  static inline Arg CRadix(unsigned int* x);
  static inline Arg CRadix(long* x);
  static inline Arg CRadix(unsigned long* x);
  static inline Arg CRadix(long long* x);
  static inline Arg CRadix(unsigned long long* x);

  static inline Arg Hex(short* x);
  static inline Arg Hex(unsigned short* x);
  static inline Arg Hex(int* x);
  static inline Arg Hex(unsigned int* x);
  static inline Arg Hex(long* x);
  static inline Arg Hex(unsigned long* x);
  static inline Arg Hex(long long* x);
  static inline Arg Hex(unsigned long long* x);

  static inline Arg Octal(short* x);
  static inline Arg Octal(unsigned short* x);
  static inline Arg Octal(int* x);
  static inline Arg Octal(unsigned int* x);
  static inline Arg Octal(long* x);
  static inline Arg Octal(unsigned long* x);
  static inline Arg Octal(long long* x);
  static inline Arg Octal(unsigned long long* x);

 private:
  void Init(const StringPiece& pattern, const Options& options);

  bool DoMatch(const StringPiece& text,
               Anchor re_anchor,
               size_t* consumed,
               const Arg* const args[],
               int n) const;

  re2::Prog* ReverseProg() const;

  std::string   pattern_;          // string regular expression
  Options       options_;          // option flags
  std::string   prefix_;           // required prefix (before regexp_)
  bool          prefix_foldcase_;  // prefix is ASCII case-insensitive
  re2::Regexp*  entire_regexp_;    // parsed regular expression
  re2::Regexp*  suffix_regexp_;    // parsed regular expression, prefix removed
  re2::Prog*    prog_;             // compiled program for regexp
  int           num_captures_;     // Number of capturing groups
  bool          is_one_pass_;      // can use prog_->SearchOnePass?

  mutable re2::Prog*          rprog_;    // reverse program for regexp
  mutable const std::string*  error_;    // Error indicator
                                         // (or points to empty string)
  mutable ErrorCode      error_code_;    // Error code
  mutable std::string    error_arg_;     // Fragment of regexp showing error

  // Map from capture names to indices
  mutable const std::map<std::string, int>* named_groups_;

  // Map from capture indices to names
  mutable const std::map<int, std::string>* group_names_;

  // Onces for lazy computations.
  mutable std::once_flag rprog_once_;
  mutable std::once_flag named_groups_once_;
  mutable std::once_flag group_names_once_;

  RE2(const RE2&) = delete;
  RE2& operator=(const RE2&) = delete;
};

/***** Implementation details *****/

// Hex/Octal/Binary?

// Special class for parsing into objects that define a ParseFrom() method
template <class T>
class _RE2_MatchObject {
 public:
  static inline bool Parse(const char* str, size_t n, void* dest) {
    if (dest == NULL) return true;
    T* object = reinterpret_cast<T*>(dest);
    return object->ParseFrom(str, n);
  }
};

class RE2::Arg {
 public:
  // Empty constructor so we can declare arrays of RE2::Arg
  Arg();

  // Constructor specially designed for NULL arguments
  Arg(void*);
  Arg(std::nullptr_t);

  typedef bool (*Parser)(const char* str, size_t n, void* dest);

// Type-specific parsers
#define MAKE_PARSER(type, name)            \
  Arg(type* p) : arg_(p), parser_(name) {} \
  Arg(type* p, Parser parser) : arg_(p), parser_(parser) {}

  MAKE_PARSER(char,               parse_char)
  MAKE_PARSER(signed char,        parse_schar)
  MAKE_PARSER(unsigned char,      parse_uchar)
  MAKE_PARSER(float,              parse_float)
  MAKE_PARSER(double,             parse_double)
  MAKE_PARSER(std::string,        parse_string)
  MAKE_PARSER(StringPiece,        parse_stringpiece)

  MAKE_PARSER(short,              parse_short)
  MAKE_PARSER(unsigned short,     parse_ushort)
  MAKE_PARSER(int,                parse_int)
  MAKE_PARSER(unsigned int,       parse_uint)
  MAKE_PARSER(long,               parse_long)
  MAKE_PARSER(unsigned long,      parse_ulong)
  MAKE_PARSER(long long,          parse_longlong)
  MAKE_PARSER(unsigned long long, parse_ulonglong)

#undef MAKE_PARSER

  // Generic constructor templates
  template <class T> Arg(T* p)
      : arg_(p), parser_(_RE2_MatchObject<T>::Parse) { }
  template <class T> Arg(T* p, Parser parser)
      : arg_(p), parser_(parser) { }

  // Parse the data
  bool Parse(const char* str, size_t n) const;

 private:
  void*         arg_;
  Parser        parser_;

  static bool parse_null          (const char* str, size_t n, void* dest);
  static bool parse_char          (const char* str, size_t n, void* dest);
  static bool parse_schar         (const char* str, size_t n, void* dest);
  static bool parse_uchar         (const char* str, size_t n, void* dest);
  static bool parse_float         (const char* str, size_t n, void* dest);
  static bool parse_double        (const char* str, size_t n, void* dest);
  static bool parse_string        (const char* str, size_t n, void* dest);
  static bool parse_stringpiece   (const char* str, size_t n, void* dest);

#define DECLARE_INTEGER_PARSER(name)                                       \
 private:                                                                  \
  static bool parse_##name(const char* str, size_t n, void* dest);         \
  static bool parse_##name##_radix(const char* str, size_t n, void* dest,  \
                                   int radix);                             \
                                                                           \
 public:                                                                   \
  static bool parse_##name##_hex(const char* str, size_t n, void* dest);   \
  static bool parse_##name##_octal(const char* str, size_t n, void* dest); \
  static bool parse_##name##_cradix(const char* str, size_t n, void* dest);

  DECLARE_INTEGER_PARSER(short)
  DECLARE_INTEGER_PARSER(ushort)
  DECLARE_INTEGER_PARSER(int)
  DECLARE_INTEGER_PARSER(uint)
  DECLARE_INTEGER_PARSER(long)
  DECLARE_INTEGER_PARSER(ulong)
  DECLARE_INTEGER_PARSER(longlong)
  DECLARE_INTEGER_PARSER(ulonglong)

#undef DECLARE_INTEGER_PARSER

};

inline RE2::Arg::Arg() : arg_(NULL), parser_(parse_null) { }
inline RE2::Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
inline RE2::Arg::Arg(std::nullptr_t p) : arg_(p), parser_(parse_null) { }

inline bool RE2::Arg::Parse(const char* str, size_t n) const {
  return (*parser_)(str, n, arg_);
}

// This part of the parser, appropriate only for ints, deals with bases
#define MAKE_INTEGER_PARSER(type, name)                    \
  inline RE2::Arg RE2::Hex(type* ptr) {                    \
    return RE2::Arg(ptr, RE2::Arg::parse_##name##_hex);    \
  }                                                        \
  inline RE2::Arg RE2::Octal(type* ptr) {                  \
    return RE2::Arg(ptr, RE2::Arg::parse_##name##_octal);  \
  }                                                        \
  inline RE2::Arg RE2::CRadix(type* ptr) {                 \
    return RE2::Arg(ptr, RE2::Arg::parse_##name##_cradix); \
  }

MAKE_INTEGER_PARSER(short,              short)
MAKE_INTEGER_PARSER(unsigned short,     ushort)
MAKE_INTEGER_PARSER(int,                int)
MAKE_INTEGER_PARSER(unsigned int,       uint)
MAKE_INTEGER_PARSER(long,               long)
MAKE_INTEGER_PARSER(unsigned long,      ulong)
MAKE_INTEGER_PARSER(long long,          longlong)
MAKE_INTEGER_PARSER(unsigned long long, ulonglong)

#undef MAKE_INTEGER_PARSER

#ifndef SWIG

// Silence warnings about missing initializers for members of LazyRE2.
// Note that we test for Clang first because it defines __GNUC__ as well.
#if defined(__clang__)
#elif defined(__GNUC__) && __GNUC__ >= 6
//#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif

// Helper for writing global or static RE2s safely.
// Write
//     static LazyRE2 re = {".*"};
// and then use *re instead of writing
//     static RE2 re(".*");
// The former is more careful about multithreaded
// situations than the latter.
//
// N.B. This class never deletes the RE2 object that
// it constructs: that's a feature, so that it can be used
// for global and function static variables.
class LazyRE2 {
 private:
  struct NoArg {};

 public:
  typedef RE2 element_type;  // support std::pointer_traits

  // Constructor omitted to preserve braced initialization in C++98.

  // Pretend to be a pointer to Type (never NULL due to on-demand creation):
  RE2& operator*() const { return *get(); }
  RE2* operator->() const { return get(); }

  // Named accessor/initializer:
  RE2* get() const {
    std::call_once(once_, &LazyRE2::Init, this);
    return ptr_;
  }

  // All data fields must be public to support {"foo"} initialization.
  const char* pattern_;
  RE2::CannedOptions options_;
  NoArg barrier_against_excess_initializers_;

  mutable RE2* ptr_;
  mutable std::once_flag once_;

 private:
  static void Init(const LazyRE2* lazy_re2) {
    lazy_re2->ptr_ = new RE2(lazy_re2->pattern_, lazy_re2->options_);
  }

  void operator=(const LazyRE2&);  // disallowed
};
#endif  // SWIG

}  // namespace re2

using re2::RE2;
using re2::LazyRE2;

#endif  // RE2_RE2_H_


using namespace std;

namespace duckdb {

RegexpMatchesBindData::RegexpMatchesBindData(unique_ptr<RE2> constant_pattern, string range_min, string range_max,
                                             bool range_success)
    : constant_pattern(std::move(constant_pattern)), range_min(range_min), range_max(range_max),
      range_success(range_success) {
}

RegexpMatchesBindData::~RegexpMatchesBindData() {
}

unique_ptr<FunctionData> RegexpMatchesBindData::Copy() {
	return make_unique<RegexpMatchesBindData>(move(constant_pattern), range_min, range_max, range_success);
}

static inline re2::StringPiece CreateStringPiece(string_t &input) {
	return re2::StringPiece(input.GetData(), input.GetSize());
}

static void regexp_matches_function(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &strings = args.data[0];
	auto &patterns = args.data[1];

	auto &func_expr = (BoundFunctionExpression &)state.expr;
	auto &info = (RegexpMatchesBindData &)*func_expr.bind_info;

	RE2::Options options;
	options.set_log_errors(false);

	if (info.constant_pattern) {
		// FIXME: this should be a unary loop
		UnaryExecutor::Execute<string_t, bool, true>(strings, result, args.size(), [&](string_t input) {
			return RE2::PartialMatch(CreateStringPiece(input), *info.constant_pattern);
		});
	} else {
		BinaryExecutor::Execute<string_t, string_t, bool, true>(
		    strings, patterns, result, args.size(), [&](string_t input, string_t pattern) {
			    RE2 re(CreateStringPiece(pattern), options);
			    if (!re.ok()) {
				    throw Exception(re.error());
			    }
			    return RE2::PartialMatch(CreateStringPiece(input), re);
		    });
	}
}

static unique_ptr<FunctionData> regexp_matches_get_bind_function(BoundFunctionExpression &expr,
                                                                 ClientContext &context) {
	// pattern is the second argument. If its constant, we can already prepare the pattern and store it for later.
	assert(expr.children.size() == 2);
	if (expr.children[1]->IsScalar()) {
		Value pattern_str = ExpressionExecutor::EvaluateScalar(*expr.children[1]);
		if (!pattern_str.is_null && pattern_str.type == TypeId::VARCHAR) {
			RE2::Options options;
			options.set_log_errors(false);
			auto re = make_unique<RE2>(pattern_str.str_value, options);
			if (!re->ok()) {
				throw Exception(re->error());
			}

			string range_min, range_max;
			auto range_success = re->PossibleMatchRange(&range_min, &range_max, 1000);
			// range_min and range_max might produce non-valid UTF8 strings, e.g. in the case of 'a.*'
			// in this case we don't push a range filter
			if (range_success && (Utf8Proc::Analyze(range_min) == UnicodeType::INVALID ||
			                      Utf8Proc::Analyze(range_max) == UnicodeType::INVALID)) {
				range_success = false;
			}

			return make_unique<RegexpMatchesBindData>(move(re), range_min, range_max, range_success);
		}
	}
	return make_unique<RegexpMatchesBindData>(nullptr, "", "", false);
}

static void regexp_replace_function(DataChunk &args, ExpressionState &state, Vector &result) {
	auto &strings = args.data[0];
	auto &patterns = args.data[1];
	auto &replaces = args.data[2];

	RE2::Options options;
	options.set_log_errors(false);

	TernaryExecutor::Execute<string_t, string_t, string_t, string_t>(
	    strings, patterns, replaces, result, args.size(), [&](string_t input, string_t pattern, string_t replace) {
		    RE2 re(CreateStringPiece(pattern), options);
		    std::string sstring(input.GetData(), input.GetSize());
		    RE2::Replace(&sstring, re, CreateStringPiece(replace));
		    return StringVector::AddString(result, sstring);
	    });
}

void RegexpFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("regexp_matches", {SQLType::VARCHAR, SQLType::VARCHAR}, SQLType::BOOLEAN,
	                               regexp_matches_function, false, regexp_matches_get_bind_function));
	set.AddFunction(ScalarFunction("regexp_replace", {SQLType::VARCHAR, SQLType::VARCHAR, SQLType::VARCHAR},
	                               SQLType::VARCHAR, regexp_replace_function));
}

} // namespace duckdb






#include <string.h>

using namespace std;

namespace duckdb {

static void strreverse(const char *input, idx_t n, char *output) {
	idx_t bytes = 0;

	output[n] = 0;

	while (*input) {
		if (!(*input & 0x80)) { // !*input & 0b10000000
			bytes = 1;
		} else if ((*input & 0xe0) == 0xc0) { // (*input & 0b1110_0000 == 0b1100_0000)
			bytes = 2;
		} else if ((*input & 0xf0) == 0xe0) { // (*input & 0b1111_0000 == 0b1110_0000)
			bytes = 3;
		} else if ((*input & 0xf8) == 0xf0) { // (*input & 0b1111_1000 == 0b1111_0000)
			bytes = 4;
		} else {
			assert(false);
		}

		memcpy(&output[n - bytes], input, bytes);
		input += bytes;
		n -= bytes;
	}
}

static void reverse_chunk_function(DataChunk &args, ExpressionState &state, Vector &result) {
	assert(args.column_count() == 1);
	assert(args.data[0].type == TypeId::VARCHAR);

	UnaryExecutor::Execute<string_t, string_t, true>(args.data[0], result, args.size(), [&](string_t input) {
		auto input_data = input.GetData();
		auto input_length = input.GetSize();

		auto target = StringVector::EmptyString(result, input_length);
		strreverse(input_data, input_length, target.GetData());
		return target;
	});
}

void ReverseFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("reverse", {SQLType::VARCHAR}, SQLType::VARCHAR, reverse_chunk_function));
}

} // namespace duckdb






using namespace std;

namespace duckdb {

static string_t substring_scalar_function(string_t input, int offset, int length, unique_ptr<char[]> &output,
                                          idx_t &current_len) {
	// reduce offset by one because SQL starts counting at 1
	offset--;

	if (offset < 0 || length < 0) {
		throw Exception("SUBSTRING cannot handle negative offsets");
	}

	idx_t required_len = input.GetSize() + 1;
	if (required_len > current_len) {
		// need a resize
		current_len = required_len;
		output = unique_ptr<char[]>{new char[required_len]};
	}

	// UTF8 chars can use more than one byte
	idx_t input_char_offset = 0;
	idx_t input_byte_offset = 0;
	idx_t output_byte_offset = 0;

	auto input_string = input.GetData();

	while (input_string[input_byte_offset]) {
		char b = input_string[input_byte_offset++];
		input_char_offset += (b & 0xC0) != 0x80;
		if (input_char_offset > (idx_t)(offset + length)) {
			break;
		}
		if (input_char_offset > (idx_t)offset) {
			output[output_byte_offset++] = b;
		}
	}
	// terminate output
	output[output_byte_offset] = '\0';
	return string_t(output.get(), output_byte_offset);
}

static void substring_function(DataChunk &args, ExpressionState &state, Vector &result) {
	assert(args.column_count() == 3 && args.data[0].type == TypeId::VARCHAR && args.data[1].type == TypeId::INT32 &&
	       args.data[2].type == TypeId::INT32);
	auto &input_vector = args.data[0];
	auto &offset_vector = args.data[1];
	auto &length_vector = args.data[2];

	idx_t current_len = 0;
	unique_ptr<char[]> output;
	TernaryExecutor::Execute<string_t, int, int, string_t>(
	    input_vector, offset_vector, length_vector, result, args.size(),
	    [&](string_t input_string, int offset, int length) {
		    return StringVector::AddString(
		        result, substring_scalar_function(input_string, offset, length, output, current_len));
	    });
}

void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("substring",       // name of function
	                               {SQLType::VARCHAR, // argument list
	                                SQLType::INTEGER, SQLType::INTEGER},
	                               SQLType::VARCHAR,     // return type
	                               substring_function)); // pointer to function implementation
}

} // namespace duckdb





using namespace std;

namespace duckdb {

static bool suffix(const string_t &str, const string_t &suffix);

struct SuffixOperator {
	template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
		return suffix(left, right);
	}
};

static bool suffix(const string_t &str, const string_t &suffix) {
	auto suffix_size = suffix.GetSize();
	auto str_size = str.GetSize();
	if (suffix_size > str_size) {
		return false;
	}

	auto suffix_data = suffix.GetData();
	auto str_data = str.GetData();
	int32_t suf_idx = suffix_size - 1;
	idx_t str_idx = str_size - 1;
	for (; suf_idx >= 0; --suf_idx, --str_idx) {
		if (suffix_data[suf_idx] != str_data[str_idx]) {
			return false;
		}
	}
	return true;
}

void SuffixFun::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(ScalarFunction("suffix",                             // name of the function
	                               {SQLType::VARCHAR, SQLType::VARCHAR}, // argument list
	                               SQLType::BOOLEAN,                     // return type
	                               ScalarFunction::BinaryFunction<string_t, string_t, bool, SuffixOperator, true>));
}

} // namespace duckdb


using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterStringFunctions() {
	Register<ReverseFun>();
	Register<LowerFun>();
	Register<UpperFun>();
	Register<ConcatFun>();
	Register<LengthFun>();
	Register<LikeFun>();
	Register<PrintfFun>();
	Register<RegexpFun>();
	Register<SubstringFun>();
	Register<InstrFun>();
	Register<PrefixFun>();
	Register<SuffixFun>();
}

} // namespace duckdb




using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterTrigonometricsFunctions() {
	Register<SinFun>();
	Register<CosFun>();
	Register<TanFun>();
	Register<AsinFun>();
	Register<AcosFun>();
	Register<AtanFun>();
	Register<CotFun>();
	Register<Atan2Fun>();
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/table/read_csv.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct ReadCSVTableFunction {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb



using namespace std;

namespace duckdb {

struct ReadCSVData : public TableFunctionData {
	ReadCSVData() {
	}

	CopyInfo info;
	//! The CSV reader
	unique_ptr<BufferedCSVReader> csv_reader;
};

static unique_ptr<FunctionData> read_csv_bind(ClientContext &context, vector<Value> inputs,
                                              vector<SQLType> &return_types, vector<string> &names) {
	for (auto &val : inputs[2].struct_value) {
		names.push_back(val.first);
		if (val.second.type != TypeId::VARCHAR) {
			throw BinderException("read_csv requires a type specification as string");
		}
		return_types.push_back(TransformStringToSQLType(val.second.str_value.c_str()));
	}
	if (names.size() == 0) {
		throw BinderException("read_csv requires at least a single column as input!");
	}
	auto result = make_unique<ReadCSVData>();

	result->info.file_path = inputs[0].str_value;
	result->info.header = false;
	result->info.delimiter = inputs[1].str_value;

	result->csv_reader = make_unique<BufferedCSVReader>(context, result->info, return_types);
	return move(result);
}

static void read_csv_info(ClientContext &context, vector<Value> &input, DataChunk &output, FunctionData *dataptr) {
	auto &data = ((ReadCSVData &)*dataptr);
	data.csv_reader->ParseCSV(output);
}

void ReadCSVTableFunction::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(TableFunction("read_csv", {SQLType::VARCHAR, SQLType::VARCHAR, SQLType::STRUCT}, read_csv_bind,
	                              read_csv_info, nullptr));
}

void BuiltinFunctions::RegisterReadFunctions() {
	ReadCSVTableFunction::RegisterFunction(*this);
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/function/table/sqlite_functions.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

struct PragmaTableInfo {
	static void RegisterFunction(BuiltinFunctions &set);
};

struct SQLiteMaster {
	static void RegisterFunction(BuiltinFunctions &set);
};

} // namespace duckdb







#include <algorithm>

using namespace std;

namespace duckdb {

struct PragmaTableFunctionData : public TableFunctionData {
	PragmaTableFunctionData() : entry(nullptr), offset(0) {
	}

	TableCatalogEntry *entry;
	idx_t offset;
};

static unique_ptr<FunctionData> pragma_table_info_bind(ClientContext &context, vector<Value> inputs,
                                                       vector<SQLType> &return_types, vector<string> &names) {
	names.push_back("cid");
	return_types.push_back(SQLType::INTEGER);

	names.push_back("name");
	return_types.push_back(SQLType::VARCHAR);

	names.push_back("type");
	return_types.push_back(SQLType::VARCHAR);

	names.push_back("notnull");
	return_types.push_back(SQLType::BOOLEAN);

	names.push_back("dflt_value");
	return_types.push_back(SQLType::VARCHAR);

	names.push_back("pk");
	return_types.push_back(SQLType::BOOLEAN);

	return make_unique<PragmaTableFunctionData>();
}

static void pragma_table_info(ClientContext &context, vector<Value> &input, DataChunk &output, FunctionData *dataptr) {
	auto &data = *((PragmaTableFunctionData *)dataptr);
	if (!data.entry) {
		// first call: load the entry from the catalog
		assert(input.size() == 1);

		auto table_name = input[0].GetValue<string>();
		// look up the table name in the catalog
		auto &catalog = Catalog::GetCatalog(context);
		data.entry = catalog.GetEntry<TableCatalogEntry>(context, DEFAULT_SCHEMA, table_name);
	}

	if (data.offset >= data.entry->columns.size()) {
		// finished returning values
		return;
	}
	// start returning values
	// either fill up the chunk or return all the remaining columns
	idx_t next = min(data.offset + STANDARD_VECTOR_SIZE, (idx_t)data.entry->columns.size());
	output.SetCardinality(next - data.offset);

	for (idx_t i = data.offset; i < next; i++) {
		auto index = i - data.offset;
		auto &column = data.entry->columns[i];
		// return values:
		// "cid", TypeId::INT32
		assert(column.oid < (idx_t)std::numeric_limits<int32_t>::max());

		output.SetValue(0, index, Value::INTEGER((int32_t)column.oid));
		// "name", TypeId::VARCHAR
		output.SetValue(1, index, Value(column.name));
		// "type", TypeId::VARCHAR
		output.SetValue(2, index, Value(SQLTypeToString(column.type)));
		// "notnull", TypeId::BOOL
		// FIXME: look at constraints
		output.SetValue(3, index, Value::BOOLEAN(false));
		// "dflt_value", TypeId::VARCHAR
		string def_value = column.default_value ? column.default_value->ToString() : "NULL";
		output.SetValue(4, index, Value(def_value));
		// "pk", TypeId::BOOL
		// FIXME: look at constraints
		output.SetValue(5, index, Value::BOOLEAN(false));
	}
	data.offset = next;
}

void PragmaTableInfo::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(
	    TableFunction("pragma_table_info", {SQLType::VARCHAR}, pragma_table_info_bind, pragma_table_info, nullptr));
}

} // namespace duckdb








#include <algorithm>

using namespace std;

namespace duckdb {

struct SQLiteMasterData : public TableFunctionData {
	SQLiteMasterData() : initialized(false), offset(0) {
	}

	bool initialized;
	vector<CatalogEntry *> entries;
	idx_t offset;
};

string GenerateQuery(CatalogEntry *entry) {
	// generate a query from a catalog entry
	if (entry->type == CatalogType::TABLE) {
		// FIXME: constraints
		stringstream ss;
		auto table = (TableCatalogEntry *)entry;
		ss << "CREATE TABLE " << table->name << "(";

		for (idx_t i = 0; i < table->columns.size(); i++) {
			auto &column = table->columns[i];
			ss << column.name << " " << SQLTypeToString(column.type);
			if (i + 1 < table->columns.size()) {
				ss << ", ";
			}
		}

		ss << ");";
		return ss.str();
	} else {
		return "[Unknown]";
	}
}

static unique_ptr<FunctionData> sqlite_master_bind(ClientContext &context, vector<Value> inputs,
                                                   vector<SQLType> &return_types, vector<string> &names) {
	names.push_back("type");
	return_types.push_back(SQLType::VARCHAR);

	names.push_back("name");
	return_types.push_back(SQLType::VARCHAR);

	names.push_back("tbl_name");
	return_types.push_back(SQLType::VARCHAR);

	names.push_back("rootpage");
	return_types.push_back(SQLType::INTEGER);

	names.push_back("sql");
	return_types.push_back(SQLType::VARCHAR);

	// initialize the function data structure
	return make_unique<SQLiteMasterData>();
}

void sqlite_master(ClientContext &context, vector<Value> &input, DataChunk &output, FunctionData *dataptr) {
	auto &data = *((SQLiteMasterData *)dataptr);
	assert(input.size() == 0);
	if (!data.initialized) {
		// scan all the schemas
		auto &transaction = Transaction::GetTransaction(context);
		Catalog::GetCatalog(context).schemas.Scan(transaction, [&](CatalogEntry *entry) {
			auto schema = (SchemaCatalogEntry *)entry;
			schema->tables.Scan(transaction, [&](CatalogEntry *entry) { data.entries.push_back(entry); });
		});
		data.initialized = true;
	}

	if (data.offset >= data.entries.size()) {
		// finished returning values
		return;
	}
	idx_t next = min(data.offset + STANDARD_VECTOR_SIZE, (idx_t)data.entries.size());
	output.SetCardinality(next - data.offset);

	// start returning values
	// either fill up the chunk or return all the remaining columns
	for (idx_t i = data.offset; i < next; i++) {
		auto index = i - data.offset;
		auto &entry = data.entries[i];

		// return values:
		// "type", TypeId::VARCHAR
		const char *type_str;
		switch (entry->type) {
		case CatalogType::TABLE:
			type_str = "table";
			break;
		case CatalogType::SCHEMA:
			type_str = "schema";
			break;
		case CatalogType::TABLE_FUNCTION:
			type_str = "function";
			break;
		case CatalogType::VIEW:
			type_str = "view";
			break;
		default:
			type_str = "unknown";
		}
		output.SetValue(0, index, Value(type_str));
		// "name", TypeId::VARCHAR
		output.SetValue(1, index, Value(entry->name));
		// "tbl_name", TypeId::VARCHAR
		output.SetValue(2, index, Value(entry->name));
		// "rootpage", TypeId::INT32
		output.SetValue(3, index, Value::INTEGER(0));
		// "sql", TypeId::VARCHAR
		output.SetValue(4, index, Value(GenerateQuery(entry)));
	}
	data.offset = next;
}

void SQLiteMaster::RegisterFunction(BuiltinFunctions &set) {
	set.AddFunction(TableFunction("sqlite_master", {}, sqlite_master_bind, sqlite_master, nullptr));
}

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/star_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a * expression in the SELECT clause
class StarExpression : public ParsedExpression {
public:
	StarExpression();

public:
	string ToString() const override;

	unique_ptr<ParsedExpression> Copy() const override;

	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/table_function_ref.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Represents a Table producing function
class TableFunctionRef : public TableRef {
public:
	TableFunctionRef() : TableRef(TableReferenceType::TABLE_FUNCTION) {
	}

	unique_ptr<ParsedExpression> function;

public:
	string ToString() const override {
		return function->ToString();
	}

	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a BaseTableRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a BaseTableRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb




using namespace std;

namespace duckdb {

void BuiltinFunctions::RegisterSQLiteFunctions() {
	PragmaTableInfo::RegisterFunction(*this);
	SQLiteMaster::RegisterFunction(*this);

	CreateViewInfo info;
	info.schema = DEFAULT_SCHEMA;
	info.view_name = "sqlite_master";
	info.on_conflict = OnCreateConflict::REPLACE;

	auto select = make_unique<SelectNode>();
	select->select_list.push_back(make_unique<StarExpression>());
	vector<unique_ptr<ParsedExpression>> children;

	auto function = make_unique<FunctionExpression>(DEFAULT_SCHEMA, "sqlite_master", children);
	auto function_expr = make_unique<TableFunctionRef>();
	function_expr->function = move(function);
	select->from_table = move(function_expr);
	info.query = move(select);
	//	catalog.CreateView(transaction, &info);
}

} // namespace duckdb











using namespace duckdb;
using namespace std;

Appender::Appender(Connection &con, string schema_name, string table_name) : con(con), column(0) {
	description = con.TableInfo(schema_name, table_name);
	if (!description) {
		// table could not be found
		throw CatalogException(
		    StringUtil::Format("Table \"%s.%s\" could not be found", schema_name.c_str(), table_name.c_str()));
	} else {
		vector<TypeId> types;
		for (auto &column : description->columns) {
			types.push_back(GetInternalType(column.type));
		}
		chunk.Initialize(types);
		con.context->RegisterAppender(this);
	}
}

Appender::Appender(Connection &con, string table_name) : Appender(con, DEFAULT_SCHEMA, table_name) {
}

Appender::~Appender() {
	Close();
}

void Appender::CheckInvalidated() {
	if (!invalidated_msg.empty()) {
		throw Exception("Invalid appender: " + invalidated_msg);
	}
}

void Appender::BeginRow() {
	CheckInvalidated();
}

void Appender::EndRow() {
	CheckInvalidated();
	// check that all rows have been appended to
	if (column != chunk.column_count()) {
		InvalidateException("Call to EndRow before all rows have been appended to!");
	}
	column = 0;
	chunk.SetCardinality(chunk.size() + 1);
	if (chunk.size() >= STANDARD_VECTOR_SIZE) {
		Flush();
	}
}

template <class SRC, class DST> void Appender::AppendValueInternal(Vector &col, SRC input) {
	FlatVector::GetData<DST>(col)[chunk.size()] = Cast::Operation<SRC, DST>(input);
}

void Appender::InvalidateException(string msg) {
	Invalidate(msg);
	throw Exception(msg);
}

template <class T> void Appender::AppendValueInternal(T input) {
	CheckInvalidated();
	if (column >= chunk.column_count()) {
		InvalidateException("Too many appends for chunk!");
	}
	auto &col = chunk.data[column];
	switch (col.type) {
	case TypeId::BOOL:
		AppendValueInternal<T, bool>(col, input);
		break;
	case TypeId::INT8:
		AppendValueInternal<T, int8_t>(col, input);
		break;
	case TypeId::INT16:
		AppendValueInternal<T, int16_t>(col, input);
		break;
	case TypeId::INT32:
		AppendValueInternal<T, int32_t>(col, input);
		break;
	case TypeId::INT64:
		AppendValueInternal<T, int64_t>(col, input);
		break;
	case TypeId::FLOAT:
		AppendValueInternal<T, float>(col, input);
		break;
	case TypeId::DOUBLE:
		AppendValueInternal<T, double>(col, input);
		break;
	default:
		AppendValue(Value::CreateValue<T>(input));
		return;
	}
	column++;
}

template <> void Appender::Append(bool value) {
	AppendValueInternal<bool>(value);
}

template <> void Appender::Append(int8_t value) {
	AppendValueInternal<int8_t>(value);
}

template <> void Appender::Append(int16_t value) {
	AppendValueInternal<int16_t>(value);
}

template <> void Appender::Append(int32_t value) {
	AppendValueInternal<int32_t>(value);
}

template <> void Appender::Append(int64_t value) {
	AppendValueInternal<int64_t>(value);
}

template <> void Appender::Append(const char *value) {
	AppendValueInternal<string_t>(string_t(value));
}

template <> void Appender::Append(double value) {
	AppendValueInternal<double>(value);
}

template <> void Appender::Append(Value value) {
	if (column >= chunk.column_count()) {
		InvalidateException("Too many appends for chunk!");
	}
	AppendValue(move(value));
}

template <> void Appender::Append(nullptr_t value) {
	if (column >= chunk.column_count()) {
		InvalidateException("Too many appends for chunk!");
	}
	auto &col = chunk.data[column++];
	FlatVector::SetNull(col, chunk.size(), true);
}

void Appender::AppendValue(Value value) {
	chunk.SetValue(column, chunk.size(), value);
	column++;
}

void Appender::Flush() {
	CheckInvalidated();
	try {
		// check that all vectors have the same length before appending
		if (column != 0) {
			throw Exception("Failed to Flush appender: incomplete append to row!");
		}

		if (chunk.size() == 0) {
			return;
		}
		con.Append(*description, chunk);
	} catch (Exception &ex) {
		Invalidate(ex.what());
		throw ex;
	}
	chunk.Reset();
	column = 0;
}

void Appender::Close() {
	if (!invalidated_msg.empty()) {
		return;
	}
	if (column == 0 || column == chunk.column_count()) {
		Flush();
	}
	Invalidate("The appender has been closed!");
}

void Appender::Invalidate(string msg, bool close) {
	if (!invalidated_msg.empty()) {
		return;
	}
	if (close) {
		con.context->RemoveAppender(this);
	}
	assert(!msg.empty());
	invalidated_msg = msg;
}










//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/optimizer.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/expression_rewriter.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/matcher/logical_operator_matcher.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The LogicalOperatorMatcher class contains a set of matchers that can be used to match LogicalOperators
class LogicalOperatorMatcher {
public:
	virtual ~LogicalOperatorMatcher() {
	}

	virtual bool Match(LogicalOperatorType type) = 0;
};

//! The SpecificLogicalTypeMatcher class matches only a single specified LogicalOperatorType
class SpecificLogicalTypeMatcher : public LogicalOperatorMatcher {
public:
	SpecificLogicalTypeMatcher(LogicalOperatorType type) : type(type) {
	}

	bool Match(LogicalOperatorType type) override {
		return type == this->type;
	}

private:
	LogicalOperatorType type;
};

} // namespace duckdb


namespace duckdb {
class ExpressionRewriter;

class Rule {
public:
	Rule(ExpressionRewriter &rewriter) : rewriter(rewriter) {
	}
	virtual ~Rule() {
	}

	//! The expression rewriter this rule belongs to
	ExpressionRewriter &rewriter;
	//! The root
	unique_ptr<LogicalOperatorMatcher> logical_root;
	//! The expression matcher of the rule
	unique_ptr<ExpressionMatcher> root;

	virtual unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &fixed_point) = 0;
};

} // namespace duckdb


namespace duckdb {
class ClientContext;

//! The ExpressionRewriter performs a set of fixed rewrite rules on the expressions that occur in a SQL statement
class ExpressionRewriter {
public:
	ExpressionRewriter(ClientContext &context) : context(context) {
	}
	//! The set of rules as known by the Expression Rewriter
	vector<unique_ptr<Rule>> rules;

	//! Apply the rules to a specific LogicalOperator
	void Apply(LogicalOperator &root);

	ClientContext &context;

private:
	//! Apply a set of rules to a specific expression
	static unique_ptr<Expression> ApplyRules(LogicalOperator &op, const vector<Rule *> &rules,
	                                         unique_ptr<Expression> expr, bool &changes_made);
};

} // namespace duckdb




namespace duckdb {
class Binder;

class Optimizer {
public:
	Optimizer(Binder &binder, ClientContext &context);

	unique_ptr<LogicalOperator> Optimize(unique_ptr<LogicalOperator> plan);

	ClientContext &context;
	Binder &binder;
	ExpressionRewriter rewriter;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parser.hpp
//
//
//===----------------------------------------------------------------------===//





struct PGNode;
struct PGList;

namespace duckdb {
//! The parser is responsible for parsing the query and converting it into a set
//! of parsed statements. The parsed statements can then be converted into a
//! plan and executed.
class Parser {
public:
	Parser();

	//! Attempts to parse a query into a series of SQL statements. Returns
	//! whether or not the parsing was successful. If the parsing was
	//! successful, the parsed statements will be stored in the statements
	//! variable.
	void ParseQuery(string query);

	//! The parsed SQL statements from an invocation to ParseQuery.
	vector<unique_ptr<SQLStatement>> statements;

	idx_t n_prepared_parameters = 0;

private:
	//! Transform a Postgres parse tree into a set of SQL Statements
	bool TransformList(PGList *tree);
	//! Transform a single Postgres parse node into a SQL Statement.
	unique_ptr<SQLStatement> TransformNode(PGNode *stmt);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/constant_expression.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! ConstantExpression represents a constant value in the query
class ConstantExpression : public ParsedExpression {
public:
	ConstantExpression(SQLType sql_type, Value val);

	//! The constant value referenced
	Value value;
	//! The SQL Type of the value
	SQLType sql_type;

public:
	string ToString() const override;

	static bool Equals(const ConstantExpression *a, const ConstantExpression *b);
	hash_t Hash() const override;

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/drop_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class DropStatement : public SQLStatement {
public:
	DropStatement() : SQLStatement(StatementType::DROP), info(make_unique<DropInfo>()){};

	unique_ptr<DropInfo> info;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/execute_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class ExecuteStatement : public SQLStatement {
public:
	ExecuteStatement() : SQLStatement(StatementType::EXECUTE){};

	string name;
	vector<unique_ptr<ParsedExpression>> values;
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/explain_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class ExplainStatement : public SQLStatement {
public:
	ExplainStatement(unique_ptr<SQLStatement> stmt) : SQLStatement(StatementType::EXPLAIN), stmt(move(stmt)){};

	unique_ptr<SQLStatement> stmt;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/prepare_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class PrepareStatement : public SQLStatement {
public:
	PrepareStatement() : SQLStatement(StatementType::PREPARE), statement(nullptr), name("") {
	}

	unique_ptr<SQLStatement> statement;
	string name;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/planner.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
class ClientContext;

//! The planner creates a logical query plan from the parsed SQL statements
//! using the Binder and LogicalPlanGenerator.
class Planner {
public:
	Planner(ClientContext &context);

	void CreatePlan(unique_ptr<SQLStatement> statement);

	unique_ptr<LogicalOperator> plan;
	vector<string> names;
	vector<SQLType> sql_types;
	unordered_map<idx_t, PreparedValueEntry> value_map;

	Binder binder;
	ClientContext &context;

	bool read_only;
	bool requires_valid_transaction;

private:
	void CreatePlan(SQLStatement &statement);

	void VerifyQuery(BoundSQLStatement &statement);
	void VerifyNode(BoundQueryNode &statement);
	void VerifyExpression(Expression &expr, vector<unique_ptr<Expression>> &copies);

	bool StatementRequiresValidTransaction(BoundSQLStatement &statement);
};
} // namespace duckdb






using namespace duckdb;
using namespace std;

ClientContext::ClientContext(DuckDB &database)
    : db(database), transaction(*database.transaction_manager), interrupted(false), catalog(*database.catalog),
      temporary_objects(make_unique<SchemaCatalogEntry>(db.catalog.get(), TEMP_SCHEMA)),
      prepared_statements(make_unique<CatalogSet>(*db.catalog)), open_result(nullptr) {
	random_device rd;
	random_engine.seed(rd());
}

void ClientContext::Cleanup() {
	lock_guard<mutex> client_guard(context_lock);
	if (is_invalidated || !prepared_statements) {
		return;
	}
	if (transaction.HasActiveTransaction()) {
		ActiveTransaction().active_query = MAXIMUM_QUERY_ID;
		if (!transaction.IsAutoCommit()) {
			transaction.Rollback();
		}
	}
	assert(prepared_statements);
	db.transaction_manager->AddCatalogSet(*this, move(prepared_statements));
	// invalidate any prepared statements
	for (auto &statement : prepared_statement_objects) {
		statement->is_invalidated = true;
	}
	for (auto &appender : appenders) {
		appender->Invalidate("Connection has been closed!", false);
	}
	CleanupInternal();
}

void ClientContext::RegisterAppender(Appender *appender) {
	lock_guard<mutex> client_guard(context_lock);
	if (is_invalidated) {
		throw Exception("Database that this connection belongs to has been closed!");
	}
	appenders.insert(appender);
}

void ClientContext::RemoveAppender(Appender *appender) {
	lock_guard<mutex> client_guard(context_lock);
	if (is_invalidated) {
		return;
	}
	appenders.erase(appender);
}

unique_ptr<DataChunk> ClientContext::Fetch() {
	lock_guard<mutex> client_guard(context_lock);
	if (!open_result) {
		// no result to fetch from
		return nullptr;
	}
	if (is_invalidated) {
		// ClientContext is invalidated: database has been closed
		open_result->error = "Database that this connection belongs to has been closed!";
		open_result->success = false;
		return nullptr;
	}
	try {
		// fetch the chunk and return it
		auto chunk = FetchInternal();
		return chunk;
	} catch (Exception &ex) {
		open_result->error = ex.what();
	} catch (...) {
		open_result->error = "Unhandled exception in Fetch";
	}
	open_result->success = false;
	CleanupInternal();
	return nullptr;
}

string ClientContext::FinalizeQuery(bool success) {
	profiler.EndQuery();

	execution_context.Reset();

	string error;
	if (transaction.HasActiveTransaction()) {
		ActiveTransaction().active_query = MAXIMUM_QUERY_ID;
		try {
			if (transaction.IsAutoCommit()) {
				if (success) {
					// query was successful: commit
					transaction.Commit();
				} else {
					// query was unsuccessful: rollback
					transaction.Rollback();
				}
			}
		} catch (Exception &ex) {
			error = ex.what();
		} catch (...) {
			error = "Unhandled exception!";
		}
	}
	return error;
}

void ClientContext::CleanupInternal() {
	if (!open_result) {
		// no result currently open
		return;
	}

	auto error = FinalizeQuery(open_result->success);
	if (open_result->success) {
		// if an error occurred while committing report it in the result
		open_result->error = error;
		open_result->success = error.empty();
	}

	open_result->is_open = false;
	open_result = nullptr;
}

unique_ptr<DataChunk> ClientContext::FetchInternal() {
	assert(execution_context.physical_plan);
	auto chunk = make_unique<DataChunk>();
	// run the plan to get the next chunks
	execution_context.physical_plan->InitializeChunk(*chunk);
	execution_context.physical_plan->GetChunk(*this, *chunk, execution_context.physical_state.get());
	return chunk;
}

unique_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(const string &query,
                                                                         unique_ptr<SQLStatement> statement) {
	StatementType statement_type = statement->type;
	auto result = make_unique<PreparedStatementData>(statement_type);

	profiler.StartPhase("planner");
	Planner planner(*this);
	planner.CreatePlan(move(statement));
	assert(planner.plan);
	profiler.EndPhase();

	auto plan = move(planner.plan);
	// extract the result column names from the plan
	result->read_only = planner.read_only;
	result->requires_valid_transaction = planner.requires_valid_transaction;
	result->names = planner.names;
	result->sql_types = planner.sql_types;
	result->value_map = move(planner.value_map);

#ifdef DEBUG
	if (enable_optimizer) {
#endif
		profiler.StartPhase("optimizer");
		Optimizer optimizer(planner.binder, *this);
		plan = optimizer.Optimize(move(plan));
		assert(plan);
		profiler.EndPhase();
#ifdef DEBUG
	}
#endif

	profiler.StartPhase("physical_planner");
	// now convert logical query plan into a physical query plan
	PhysicalPlanGenerator physical_planner(*this);
	auto physical_plan = physical_planner.CreatePlan(move(plan));
	profiler.EndPhase();

	result->dependencies = move(physical_planner.dependencies);
	result->types = physical_plan->types;
	result->plan = move(physical_plan);
	return result;
}

unique_ptr<QueryResult> ClientContext::ExecutePreparedStatement(const string &query, PreparedStatementData &statement,
                                                                vector<Value> bound_values, bool allow_stream_result) {
	if (ActiveTransaction().is_invalidated && statement.requires_valid_transaction) {
		throw Exception("Current transaction is aborted (please ROLLBACK)");
	}
	if (db.access_mode == AccessMode::READ_ONLY && !statement.read_only) {
		throw Exception(StringUtil::Format("Cannot execute statement of type \"%s\" in read-only mode!",
		                                   StatementTypeToString(statement.statement_type).c_str()));
	}

	// bind the bound values before execution
	statement.Bind(move(bound_values));

	bool create_stream_result = statement.statement_type == StatementType::SELECT && allow_stream_result;

	// store the physical plan in the context for calls to Fetch()
	execution_context.physical_plan = move(statement.plan);
	execution_context.physical_state = execution_context.physical_plan->GetOperatorState();

	auto types = execution_context.physical_plan->GetTypes();
	assert(types.size() == statement.sql_types.size());

	if (create_stream_result) {
		// successfully compiled SELECT clause and it is the last statement
		// return a StreamQueryResult so the client can call Fetch() on it and stream the result
		return make_unique<StreamQueryResult>(statement.statement_type, *this, statement.sql_types, types,
		                                      statement.names);
	}
	// create a materialized result by continuously fetching
	auto result =
	    make_unique<MaterializedQueryResult>(statement.statement_type, statement.sql_types, types, statement.names);
	while (true) {
		auto chunk = FetchInternal();
		if (chunk->size() == 0) {
			break;
		}
		result->collection.Append(*chunk);
	}
	return move(result);
}

void ClientContext::InitialCleanup() {
	if (is_invalidated) {
		throw Exception("Database that this connection belongs to has been closed!");
	}
	//! Cleanup any open results and reset the interrupted flag
	CleanupInternal();
	interrupted = false;
}

unique_ptr<PreparedStatement> ClientContext::Prepare(string query) {
	lock_guard<mutex> client_guard(context_lock);
	// prepare the query
	try {
		InitialCleanup();

		// first parse the query
		Parser parser;
		parser.ParseQuery(query.c_str());
		if (parser.statements.size() == 0) {
			throw Exception("No statement to prepare!");
		}
		if (parser.statements.size() > 1) {
			throw Exception("Cannot prepare multiple statements at once!");
		}
		// now write the prepared statement data into the catalog
		string prepare_name = "____duckdb_internal_prepare_" + to_string(prepare_count);
		prepare_count++;
		// create a prepare statement out of the underlying statement
		auto prepare = make_unique<PrepareStatement>();
		prepare->name = prepare_name;
		prepare->statement = move(parser.statements[0]);

		// now perform the actual PREPARE query
		auto result = RunStatement(query, move(prepare), false);
		if (!result->success) {
			throw Exception(result->error);
		}
		auto prepared_catalog = (PreparedStatementCatalogEntry *)prepared_statements->GetRootEntry(prepare_name);
		auto prepared_object = make_unique<PreparedStatement>(this, prepare_name, query, *prepared_catalog->prepared,
		                                                      parser.n_prepared_parameters);
		prepared_statement_objects.insert(prepared_object.get());
		return prepared_object;
	} catch (Exception &ex) {
		return make_unique<PreparedStatement>(ex.what());
	}
}

unique_ptr<QueryResult> ClientContext::Execute(string name, vector<Value> &values, bool allow_stream_result,
                                               string query) {
	lock_guard<mutex> client_guard(context_lock);
	try {
		InitialCleanup();
	} catch (std::exception &ex) {
		return make_unique<MaterializedQueryResult>(ex.what());
	}

	// create the execute statement
	auto execute = make_unique<ExecuteStatement>();
	execute->name = name;
	for (auto &val : values) {
		execute->values.push_back(make_unique<ConstantExpression>(SQLTypeFromInternalType(val.type), val));
	}

	return RunStatement(query, move(execute), allow_stream_result);
}
void ClientContext::RemovePreparedStatement(PreparedStatement *statement) {
	lock_guard<mutex> client_guard(context_lock);
	if (!statement->success || statement->is_invalidated || is_invalidated) {
		return;
	}
	try {
		InitialCleanup();
	} catch (...) {
		return;
	}
	// erase the object from the list of prepared statements
	prepared_statement_objects.erase(statement);
	// drop it from the catalog
	auto deallocate_statement = make_unique<DropStatement>();
	deallocate_statement->info->type = CatalogType::PREPARED_STATEMENT;
	deallocate_statement->info->name = statement->name;
	string query = "DEALLOCATE " + statement->name;
	RunStatement(query, move(deallocate_statement), false);
}

unique_ptr<QueryResult> ClientContext::RunStatementInternal(const string &query, unique_ptr<SQLStatement> statement,
                                                            bool allow_stream_result) {
	// prepare the query for execution
	auto prepared = CreatePreparedStatement(query, move(statement));
	// by default, no values are bound
	vector<Value> bound_values;
	// execute the prepared statement
	return ExecutePreparedStatement(query, *prepared, move(bound_values), allow_stream_result);
}

unique_ptr<QueryResult> ClientContext::RunStatement(const string &query, unique_ptr<SQLStatement> statement,
                                                    bool allow_stream_result) {
	unique_ptr<QueryResult> result;
	// check if we are on AutoCommit. In this case we should start a transaction.
	if (transaction.IsAutoCommit()) {
		transaction.BeginTransaction();
	}
	ActiveTransaction().active_query = db.transaction_manager->GetQueryNumber();
	if (statement->type == StatementType::SELECT && query_verification_enabled) {
		// query verification is enabled:
		// create a copy of the statement and verify the original statement
		auto copied_statement = ((SelectStatement &)*statement).Copy();
		string error = VerifyQuery(query, move(statement));
		if (!error.empty()) {
			// query failed: abort now
			FinalizeQuery(false);
			// error in verifying query
			return make_unique<MaterializedQueryResult>(error);
		}
		statement = move(copied_statement);
	}
	// start the profiler
	profiler.StartQuery(query, *statement);
	try {
		result = RunStatementInternal(query, move(statement), allow_stream_result);
	} catch (StandardException &ex) {
		// standard exceptions do not invalidate the current transaction
		result = make_unique<MaterializedQueryResult>(ex.what());
	} catch (std::exception &ex) {
		// other types of exceptions do invalidate the current transaction
		if (transaction.HasActiveTransaction()) {
			ActiveTransaction().is_invalidated = true;
		}
		result = make_unique<MaterializedQueryResult>(ex.what());
	}
	if (!result->success) {
		// initial failures should always be reported as MaterializedResult
		assert(result->type != QueryResultType::STREAM_RESULT);
		// query failed: abort now
		FinalizeQuery(false);
		return result;
	}
	// query succeeded, append to list of results
	if (result->type == QueryResultType::STREAM_RESULT) {
		// store as currently open result if it is a stream result
		this->open_result = (StreamQueryResult *)result.get();
	} else {
		// finalize the query if it is not a stream result
		string error = FinalizeQuery(true);
		if (!error.empty()) {
			// failure in committing transaction
			return make_unique<MaterializedQueryResult>(error);
		}
	}
	return result;
}

unique_ptr<QueryResult> ClientContext::RunStatements(const string &query, vector<unique_ptr<SQLStatement>> &statements,
                                                     bool allow_stream_result) {
	// now we have a list of statements
	// iterate over them and execute them one by one
	unique_ptr<QueryResult> result;
	QueryResult *last_result = nullptr;
	for (idx_t i = 0; i < statements.size(); i++) {
		auto &statement = statements[i];
		bool is_last_statement = i + 1 == statements.size();
		auto current_result = RunStatement(query, move(statement), allow_stream_result && is_last_statement);
		// now append the result to the list of results
		if (!last_result) {
			// first result of the query
			result = move(current_result);
			last_result = result.get();
		} else {
			// later results; attach to the result chain
			last_result->next = move(current_result);
			last_result = last_result->next.get();
		}
	}
	return result;
}

unique_ptr<QueryResult> ClientContext::Query(string query, bool allow_stream_result) {
	lock_guard<mutex> client_guard(context_lock);

	Parser parser;
	try {
		InitialCleanup();
		// parse the query and transform it into a set of statements
		parser.ParseQuery(query.c_str());
	} catch (std::exception &ex) {
		return make_unique<MaterializedQueryResult>(ex.what());
	}

	if (parser.statements.size() == 0) {
		// no statements, return empty successful result
		return make_unique<MaterializedQueryResult>(StatementType::INVALID);
	}

	return RunStatements(query, parser.statements, allow_stream_result);
}

void ClientContext::Interrupt() {
	interrupted = true;
}

void ClientContext::EnableProfiling() {
	lock_guard<mutex> client_guard(context_lock);
	profiler.Enable();
}

void ClientContext::DisableProfiling() {
	lock_guard<mutex> client_guard(context_lock);
	profiler.Disable();
}

void ClientContext::Invalidate() {
	// interrupt any running query before attempting to obtain the lock
	// this way we don't have to wait for the entire query to finish
	Interrupt();
	// now obtain the context lock
	lock_guard<mutex> client_guard(context_lock);
	// invalidate this context and the TransactionManager
	is_invalidated = true;
	transaction.Invalidate();
	// also close any open result
	if (open_result) {
		open_result->is_open = false;
	}
	// and close any open appenders and prepared statements
	for (auto &statement : prepared_statement_objects) {
		statement->is_invalidated = true;
	}
	for (auto &appender : appenders) {
		appender->Invalidate("Database that this appender belongs to has been closed!", false);
	}
	appenders.clear();
}

string ClientContext::VerifyQuery(string query, unique_ptr<SQLStatement> statement) {
	assert(statement->type == StatementType::SELECT);
	// aggressive query verification

	// the purpose of this function is to test correctness of otherwise hard to test features:
	// Copy() of statements and expressions
	// Serialize()/Deserialize() of expressions
	// Hash() of expressions
	// Equality() of statements and expressions
	// Correctness of plans both with and without optimizers

	// copy the statement
	auto select_stmt = (SelectStatement *)statement.get();
	auto copied_stmt = select_stmt->Copy();
	auto unoptimized_stmt = select_stmt->Copy();

	BufferedSerializer serializer;
	select_stmt->Serialize(serializer);
	BufferedDeserializer source(serializer);
	auto deserialized_stmt = SelectStatement::Deserialize(source);
	// all the statements should be equal
	assert(copied_stmt->Equals(statement.get()));
	assert(deserialized_stmt->Equals(statement.get()));
	assert(copied_stmt->Equals(deserialized_stmt.get()));

	// now perform checking on the expressions
#ifdef DEBUG
	auto &orig_expr_list = select_stmt->node->GetSelectList();
	auto &de_expr_list = deserialized_stmt->node->GetSelectList();
	auto &cp_expr_list = copied_stmt->node->GetSelectList();
	assert(orig_expr_list.size() == de_expr_list.size() && cp_expr_list.size() == de_expr_list.size());
	for (idx_t i = 0; i < orig_expr_list.size(); i++) {
		// check that the expressions are equivalent
		assert(orig_expr_list[i]->Equals(de_expr_list[i].get()));
		assert(orig_expr_list[i]->Equals(cp_expr_list[i].get()));
		assert(de_expr_list[i]->Equals(cp_expr_list[i].get()));
		// check that the hashes are equivalent too
		assert(orig_expr_list[i]->Hash() == de_expr_list[i]->Hash());
		assert(orig_expr_list[i]->Hash() == cp_expr_list[i]->Hash());
	}
	// now perform additional checking within the expressions
	for (idx_t outer_idx = 0; outer_idx < orig_expr_list.size(); outer_idx++) {
		auto hash = orig_expr_list[outer_idx]->Hash();
		for (idx_t inner_idx = 0; inner_idx < orig_expr_list.size(); inner_idx++) {
			auto hash2 = orig_expr_list[inner_idx]->Hash();
			if (hash != hash2) {
				// if the hashes are not equivalent, the expressions should not be equivalent
				assert(!orig_expr_list[outer_idx]->Equals(orig_expr_list[inner_idx].get()));
			}
		}
	}
#endif

	// disable profiling if it is enabled
	bool profiling_is_enabled = profiler.IsEnabled();
	if (profiling_is_enabled) {
		profiler.Disable();
	}

	// see below
	auto statement_copy_for_explain = select_stmt->Copy();

	auto original_result = make_unique<MaterializedQueryResult>(StatementType::SELECT),
	     copied_result = make_unique<MaterializedQueryResult>(StatementType::SELECT),
	     deserialized_result = make_unique<MaterializedQueryResult>(StatementType::SELECT),
	     unoptimized_result = make_unique<MaterializedQueryResult>(StatementType::SELECT);
	// execute the original statement
	try {
		auto result = RunStatementInternal(query, move(statement), false);
		original_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
	} catch (Exception &ex) {
		original_result->error = ex.what();
		original_result->success = false;
	}

	// check explain, only if q does not already contain EXPLAIN
	if (original_result->success) {
		auto explain_q = "EXPLAIN " + query;
		auto explain_stmt = make_unique<ExplainStatement>(move(statement_copy_for_explain));
		try {
			RunStatementInternal(explain_q, move(explain_stmt), false);
		} catch (std::exception &ex) {
			return "EXPLAIN failed but query did not (" + string(ex.what()) + ")";
		}
	}

	// now execute the copied statement
	try {
		auto result = RunStatementInternal(query, move(copied_stmt), false);
		copied_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
	} catch (Exception &ex) {
		copied_result->error = ex.what();
	}
	// now execute the deserialized statement
	try {
		auto result = RunStatementInternal(query, move(deserialized_stmt), false);
		deserialized_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
	} catch (Exception &ex) {
		deserialized_result->error = ex.what();
	}
	// now execute the unoptimized statement
	enable_optimizer = false;
	try {
		auto result = RunStatementInternal(query, move(unoptimized_stmt), false);
		unoptimized_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
	} catch (Exception &ex) {
		unoptimized_result->error = ex.what();
	}

	enable_optimizer = true;
	if (profiling_is_enabled) {
		profiler.Enable();
	}

	// now compare the results
	// the results of all four runs should be identical
	if (!original_result->collection.Equals(copied_result->collection)) {
		string result = "Copied result differs from original result!\n";
		result += "Original Result:\n" + original_result->ToString();
		result += "Copied Result\n" + copied_result->ToString();
		return result;
	}
	if (!original_result->collection.Equals(deserialized_result->collection)) {
		string result = "Deserialized result differs from original result!\n";
		result += "Original Result:\n" + original_result->ToString();
		result += "Deserialized Result\n" + deserialized_result->ToString();
		return result;
	}
	if (!original_result->collection.Equals(unoptimized_result->collection)) {
		string result = "Unoptimized result differs from original result!\n";
		result += "Original Result:\n" + original_result->ToString();
		result += "Unoptimized Result\n" + unoptimized_result->ToString();
		return result;
	}

	return "";
}

unique_ptr<TableDescription> ClientContext::TableInfo(string schema_name, string table_name) {
	lock_guard<mutex> client_guard(context_lock);
	if (is_invalidated || (transaction.HasActiveTransaction() && transaction.ActiveTransaction().is_invalidated)) {
		return nullptr;
	}
	// check if we are on AutoCommit. In this case we should start a transaction
	if (transaction.IsAutoCommit()) {
		transaction.BeginTransaction();
	}
	unique_ptr<TableDescription> result;
	try {
		// obtain the table info
		auto table = db.catalog->GetEntry<TableCatalogEntry>(*this, schema_name, table_name);
		// write the table info to the result
		result = make_unique<TableDescription>();
		result->schema = schema_name;
		result->table = table_name;
		for (auto &column : table->columns) {
			result->columns.push_back(ColumnDefinition(column.name, column.type));
		}
	} catch (...) {
		// table not found!
		result = nullptr;
	}

	if (transaction.IsAutoCommit()) {
		transaction.Commit();
	}
	return result;
}

void ClientContext::Append(TableDescription &description, DataChunk &chunk) {
	lock_guard<mutex> client_guard(context_lock);
	if (is_invalidated) {
		throw Exception("Failed to append: database has been closed!");
	}
	if (transaction.HasActiveTransaction() && transaction.ActiveTransaction().is_invalidated) {
		throw Exception("Failed to append: transaction has been invalidated!");
	}
	// check if we are on AutoCommit. In this case we should start a transaction
	if (transaction.IsAutoCommit()) {
		transaction.BeginTransaction();
	}
	try {
		auto table_entry = db.catalog->GetEntry<TableCatalogEntry>(*this, description.schema, description.table);
		// verify that the table columns and types match up
		if (description.columns.size() != table_entry->columns.size()) {
			throw Exception("Failed to append: table entry has different number of columns!");
		}
		for (idx_t i = 0; i < description.columns.size(); i++) {
			if (description.columns[i].type != table_entry->columns[i].type) {
				throw Exception("Failed to append: table entry has different number of columns!");
			}
		}
		table_entry->storage->Append(*table_entry, *this, chunk);
	} catch (Exception &ex) {
		if (transaction.IsAutoCommit()) {
			transaction.Rollback();
		} else {
			transaction.Invalidate();
		}
		throw ex;
	}
	if (transaction.IsAutoCommit()) {
		transaction.Commit();
	}
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/main/connection_manager.hpp
//
//
//===----------------------------------------------------------------------===//






#include <mutex>

namespace duckdb {

class DuckDB;
class Connection;

class ConnectionManager {
public:
	~ConnectionManager();

	void AddConnection(Connection *conn);
	void RemoveConnection(Connection *conn);

	template <class T> void Scan(T &&callback) {
		// lock the catalog set
		std::lock_guard<std::mutex> lock(connections_lock);
		for (auto &conn : connections) {
			callback(conn);
		}
	}

private:
	std::mutex connections_lock;
	unordered_set<Connection *> connections;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

Connection::Connection(DuckDB &database) : db(database), context(make_unique<ClientContext>(database)) {
	db.connection_manager->AddConnection(this);
#ifdef DEBUG
	EnableProfiling();
#endif
}

Connection::~Connection() {
	if (!context->is_invalidated) {
		context->Cleanup();
		db.connection_manager->RemoveConnection(this);
	}
}

string Connection::GetProfilingInformation(ProfilerPrintFormat format) {
	if (context->is_invalidated) {
		return "Context is invalidated.";
	}
	if (format == ProfilerPrintFormat::JSON) {
		return context->profiler.ToJSON();
	} else {
		return context->profiler.ToString();
	}
}

void Connection::Interrupt() {
	context->Interrupt();
}

void Connection::EnableProfiling() {
	context->EnableProfiling();
}

void Connection::DisableProfiling() {
	context->DisableProfiling();
}

void Connection::EnableQueryVerification() {
#ifdef DEBUG
	context->query_verification_enabled = true;
#endif
}

unique_ptr<QueryResult> Connection::SendQuery(string query) {
	return context->Query(query, true);
}

unique_ptr<MaterializedQueryResult> Connection::Query(string query) {
	auto result = context->Query(query, false);
	assert(result->type == QueryResultType::MATERIALIZED_RESULT);
	return unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
}

unique_ptr<PreparedStatement> Connection::Prepare(string query) {
	return context->Prepare(query);
}

unique_ptr<QueryResult> Connection::QueryParamsRecursive(string query, vector<Value> &values) {
	auto statement = Prepare(query);
	if (!statement->success) {
		return make_unique<MaterializedQueryResult>(statement->error);
	}
	return statement->Execute(values);
}

unique_ptr<TableDescription> Connection::TableInfo(string table_name) {
	return TableInfo(DEFAULT_SCHEMA, table_name);
}

unique_ptr<TableDescription> Connection::TableInfo(string schema_name, string table_name) {
	return context->TableInfo(schema_name, table_name);
}

vector<unique_ptr<SQLStatement>> Connection::ExtractStatements(string query) {
	Parser parser;
	parser.ParseQuery(query);
	return move(parser.statements);
}

void Connection::Append(TableDescription &description, DataChunk &chunk) {
	context->Append(description, chunk);
}





using namespace duckdb;
using namespace std;

ConnectionManager::~ConnectionManager() {
	std::lock_guard<std::mutex> lock(connections_lock);
	for (auto &conn : connections) {
		conn->context->Invalidate();
	}
}

void ConnectionManager::AddConnection(Connection *conn) {
	assert(conn);
	std::lock_guard<std::mutex> lock(connections_lock);
	connections.insert(conn);
}

void ConnectionManager::RemoveConnection(Connection *conn) {
	assert(conn);
	std::lock_guard<std::mutex> lock(connections_lock);
	connections.erase(conn);
}








using namespace duckdb;
using namespace std;

DBConfig::~DBConfig() {
}

DuckDB::DuckDB(const char *path, DBConfig *config) {
	if (config) {
		// user-supplied configuration
		Configure(*config);
	} else {
		// default configuration
		DBConfig config;
		Configure(config);
	}
	if (temporary_directory.empty() && path) {
		// no directory specified: use default temp path
		temporary_directory = string(path) + ".tmp";

		// special treatment for in-memory mode
		if (strcmp(path, ":memory:") == 0) {
			temporary_directory = ".tmp";
		}
	}
	if (config && !config->use_temporary_directory) {
		// temporary directories explicitly disabled
		temporary_directory = string();
	}

	storage = make_unique<StorageManager>(*this, path ? string(path) : string(), access_mode == AccessMode::READ_ONLY);
	catalog = make_unique<Catalog>(*storage);
	transaction_manager = make_unique<TransactionManager>(*storage);
	connection_manager = make_unique<ConnectionManager>();
	// initialize the database
	storage->Initialize();
}

DuckDB::DuckDB(const string &path, DBConfig *config) : DuckDB(path.c_str(), config) {
}

DuckDB::~DuckDB() {
}

void DuckDB::Configure(DBConfig &config) {
	if (config.access_mode != AccessMode::UNDEFINED) {
		access_mode = config.access_mode;
	} else {
		access_mode = AccessMode::READ_WRITE;
	}
	if (config.file_system) {
		file_system = move(config.file_system);
	} else {
		file_system = make_unique<FileSystem>();
	}
	checkpoint_only = config.checkpoint_only;
	checkpoint_wal_size = config.checkpoint_wal_size;
	use_direct_io = config.use_direct_io;
	maximum_memory = config.maximum_memory;
	temporary_directory = config.temporary_directory;
}







#include <cstring>

#ifdef _WIN32
#define strdup _strdup
#endif

using namespace duckdb;

static SQLType ConvertCTypeToCPP(duckdb_type type);
static duckdb_type ConvertCPPTypeToC(SQLType type);
static idx_t GetCTypeSize(duckdb_type type);

struct DatabaseData {
	DatabaseData() : database(nullptr) {
	}
	~DatabaseData() {
		if (database) {
			delete database;
		}
	}

	DuckDB *database;
};

duckdb_state duckdb_open(const char *path, duckdb_database *out) {
	auto wrapper = new DatabaseData();
	try {
		wrapper->database = new DuckDB(path);
	} catch (...) {
		delete wrapper;
		return DuckDBError;
	}
	*out = (duckdb_database)wrapper;
	return DuckDBSuccess;
}

void duckdb_close(duckdb_database *database) {
	if (*database) {
		auto wrapper = (DatabaseData *)*database;
		delete wrapper;
		*database = nullptr;
	}
}

duckdb_state duckdb_connect(duckdb_database database, duckdb_connection *out) {
	auto wrapper = (DatabaseData *)database;
	Connection *connection;
	try {
		connection = new Connection(*wrapper->database);
	} catch (...) {
		return DuckDBError;
	}
	*out = (duckdb_connection)connection;
	return DuckDBSuccess;
}

void duckdb_disconnect(duckdb_connection *connection) {
	if (*connection) {
		Connection *conn = (Connection *)*connection;
		delete conn;
		*connection = nullptr;
	}
}

template <class T> void WriteData(duckdb_result *out, ChunkCollection &source, idx_t col) {
	idx_t row = 0;
	auto target = (T *)out->columns[col].data;
	for (auto &chunk : source.chunks) {
		auto source = FlatVector::GetData<T>(chunk->data[col]);
		for (idx_t k = 0; k < chunk->size(); k++) {
			target[row++] = source[k];
		}
	}
}

static duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_result *out) {
	assert(result);
	if (!out) {
		// no result to write to, only return the status
		return result->success ? DuckDBSuccess : DuckDBError;
	}
	out->error_message = NULL;
	if (!result->success) {
		// write the error message
		out->error_message = strdup(result->error.c_str());
		return DuckDBError;
	}
	// copy the data
	// first write the meta data
	out->column_count = result->types.size();
	out->row_count = result->collection.count;
	out->columns = (duckdb_column *)malloc(sizeof(duckdb_column) * out->column_count);
	if (!out->columns) {
		return DuckDBError;
	}
	// zero initialize the columns (so we can cleanly delete it in case a malloc fails)
	memset(out->columns, 0, sizeof(duckdb_column) * out->column_count);
	for (idx_t i = 0; i < out->column_count; i++) {
		out->columns[i].type = ConvertCPPTypeToC(result->sql_types[i]);
		out->columns[i].name = strdup(result->names[i].c_str());
		out->columns[i].nullmask = (bool *)malloc(sizeof(bool) * out->row_count);
		out->columns[i].data = malloc(GetCTypeSize(out->columns[i].type) * out->row_count);
		if (!out->columns[i].nullmask || !out->columns[i].name || !out->columns[i].data) {
			// malloc failure
			return DuckDBError;
		}
		// memset data to 0 for VARCHAR columns for safe deletion later
		if (result->types[i] == TypeId::VARCHAR) {
			memset(out->columns[i].data, 0, GetCTypeSize(out->columns[i].type) * out->row_count);
		}
	}
	// now write the data
	for (idx_t col = 0; col < out->column_count; col++) {
		// first set the nullmask
		idx_t row = 0;
		for (auto &chunk : result->collection.chunks) {
			for (idx_t k = 0; k < chunk->size(); k++) {
				out->columns[col].nullmask[row++] = FlatVector::IsNull(chunk->data[col], k);
			}
		}
		// then write the data
		switch (result->sql_types[col].id) {
		case SQLTypeId::BOOLEAN:
			WriteData<bool>(out, result->collection, col);
			break;
		case SQLTypeId::TINYINT:
			WriteData<int8_t>(out, result->collection, col);
			break;
		case SQLTypeId::SMALLINT:
			WriteData<int16_t>(out, result->collection, col);
			break;
		case SQLTypeId::INTEGER:
			WriteData<int32_t>(out, result->collection, col);
			break;
		case SQLTypeId::BIGINT:
			WriteData<int64_t>(out, result->collection, col);
			break;
		case SQLTypeId::FLOAT:
			WriteData<float>(out, result->collection, col);
			break;
		case SQLTypeId::DECIMAL:
		case SQLTypeId::DOUBLE:
			WriteData<double>(out, result->collection, col);
			break;
		case SQLTypeId::VARCHAR: {
			idx_t row = 0;
			auto target = (const char **)out->columns[col].data;
			for (auto &chunk : result->collection.chunks) {
				auto source = FlatVector::GetData<string_t>(chunk->data[col]);
				for (idx_t k = 0; k < chunk->size(); k++) {
					if (!FlatVector::IsNull(chunk->data[col], k)) {
						target[row] = strdup(source[k].GetData());
					}
					row++;
				}
			}
			break;
		}
		case SQLTypeId::DATE: {
			idx_t row = 0;
			auto target = (duckdb_date *)out->columns[col].data;
			for (auto &chunk : result->collection.chunks) {
				auto source = FlatVector::GetData<date_t>(chunk->data[col]);
				for (idx_t k = 0; k < chunk->size(); k++) {
					if (!FlatVector::IsNull(chunk->data[col], k)) {
						int32_t year, month, day;
						Date::Convert(source[k], year, month, day);
						target[row].year = year;
						target[row].month = month;
						target[row].day = day;
					}
					row++;
				}
			}
			break;
		}
		case SQLTypeId::TIME: {
			idx_t row = 0;
			auto target = (duckdb_time *)out->columns[col].data;
			for (auto &chunk : result->collection.chunks) {
				auto source = FlatVector::GetData<dtime_t>(chunk->data[col]);
				for (idx_t k = 0; k < chunk->size(); k++) {
					if (!FlatVector::IsNull(chunk->data[col], k)) {
						int32_t hour, min, sec, msec;
						Time::Convert(source[k], hour, min, sec, msec);
						target[row].hour = hour;
						target[row].min = min;
						target[row].sec = sec;
						target[row].msec = msec;
					}
					row++;
				}
			}
			break;
		}
		case SQLTypeId::TIMESTAMP: {
			idx_t row = 0;
			auto target = (duckdb_timestamp *)out->columns[col].data;
			for (auto &chunk : result->collection.chunks) {
				auto source = FlatVector::GetData<timestamp_t>(chunk->data[col]);
				for (idx_t k = 0; k < chunk->size(); k++) {
					if (!FlatVector::IsNull(chunk->data[col], k)) {
						date_t date;
						dtime_t time;
						Timestamp::Convert(source[k], date, time);

						int32_t year, month, day;
						Date::Convert(date, year, month, day);

						int32_t hour, min, sec, msec;
						Time::Convert(time, hour, min, sec, msec);

						target[row].date.year = year;
						target[row].date.month = month;
						target[row].date.day = day;
						target[row].time.hour = hour;
						target[row].time.min = min;
						target[row].time.sec = sec;
						target[row].time.msec = msec;
					}
					row++;
				}
			}
			break;
		}
		default:
			// unsupported type for C API
			assert(0);
			return DuckDBError;
		}
	}
	return DuckDBSuccess;
}

duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out) {
	Connection *conn = (Connection *)connection;
	auto result = conn->Query(query);
	return duckdb_translate_result(result.get(), out);
}

static void duckdb_destroy_column(duckdb_column column, idx_t count) {
	if (column.data) {
		if (column.type == DUCKDB_TYPE_VARCHAR) {
			// varchar, delete individual strings
			auto data = (char **)column.data;
			for (idx_t i = 0; i < count; i++) {
				if (data[i]) {
					free(data[i]);
				}
			}
		}
		free(column.data);
	}
	if (column.nullmask) {
		free(column.nullmask);
	}
	if (column.name) {
		free(column.name);
	}
}

void duckdb_destroy_result(duckdb_result *result) {
	if (result->error_message) {
		free(result->error_message);
	}
	if (result->columns) {
		for (idx_t i = 0; i < result->column_count; i++) {
			duckdb_destroy_column(result->columns[i], result->row_count);
		}
		free(result->columns);
	}
	memset(result, 0, sizeof(duckdb_result));
}

struct PreparedStatementWrapper {
	PreparedStatementWrapper() : statement(nullptr) {
	}
	~PreparedStatementWrapper() {
	}
	unique_ptr<PreparedStatement> statement;
	vector<Value> values;
};

duckdb_state duckdb_prepare(duckdb_connection connection, const char *query,
                            duckdb_prepared_statement *out_prepared_statement) {
	if (!connection || !query) {
		return DuckDBError;
	}
	auto wrapper = new PreparedStatementWrapper();
	Connection *conn = (Connection *)connection;
	wrapper->statement = conn->Prepare(query);
	*out_prepared_statement = (duckdb_prepared_statement)wrapper;
	return wrapper->statement->success ? DuckDBSuccess : DuckDBError;
}

duckdb_state duckdb_nparams(duckdb_prepared_statement prepared_statement, idx_t *nparams_out) {
	auto wrapper = (PreparedStatementWrapper *)prepared_statement;
	if (!wrapper || !wrapper->statement || !wrapper->statement->success || wrapper->statement->is_invalidated) {
		return DuckDBError;
	}
	*nparams_out = wrapper->statement->n_param;
	return DuckDBSuccess;
}

static duckdb_state duckdb_bind_value(duckdb_prepared_statement prepared_statement, idx_t param_idx, Value val) {
	auto wrapper = (PreparedStatementWrapper *)prepared_statement;
	if (!wrapper || !wrapper->statement || !wrapper->statement->success || wrapper->statement->is_invalidated) {
		return DuckDBError;
	}
	if (param_idx > wrapper->statement->n_param) {
		return DuckDBError;
	}
	if (param_idx > wrapper->values.size()) {
		wrapper->values.resize(param_idx);
	}
	wrapper->values[param_idx - 1] = val;
	return DuckDBSuccess;
}

duckdb_state duckdb_bind_boolean(duckdb_prepared_statement prepared_statement, idx_t param_idx, bool val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value::BOOLEAN(val));
}

duckdb_state duckdb_bind_int8(duckdb_prepared_statement prepared_statement, idx_t param_idx, int8_t val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value::TINYINT(val));
}

duckdb_state duckdb_bind_int16(duckdb_prepared_statement prepared_statement, idx_t param_idx, int16_t val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value::SMALLINT(val));
}

duckdb_state duckdb_bind_int32(duckdb_prepared_statement prepared_statement, idx_t param_idx, int32_t val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value::INTEGER(val));
}

duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx_t param_idx, int64_t val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value::BIGINT(val));
}

duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value(val));
}

duckdb_state duckdb_bind_double(duckdb_prepared_statement prepared_statement, idx_t param_idx, double val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value(val));
}

duckdb_state duckdb_bind_varchar(duckdb_prepared_statement prepared_statement, idx_t param_idx, const char *val) {
	return duckdb_bind_value(prepared_statement, param_idx, Value(val));
}

duckdb_state duckdb_bind_null(duckdb_prepared_statement prepared_statement, idx_t param_idx) {
	return duckdb_bind_value(prepared_statement, param_idx, Value());
}

duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statement, duckdb_result *out_result) {
	auto wrapper = (PreparedStatementWrapper *)prepared_statement;
	if (!wrapper || !wrapper->statement || !wrapper->statement->success || wrapper->statement->is_invalidated) {
		return DuckDBError;
	}
	auto result = wrapper->statement->Execute(wrapper->values, false);
	assert(result->type == QueryResultType::MATERIALIZED_RESULT);
	auto mat_res = (MaterializedQueryResult *)result.get();
	return duckdb_translate_result(mat_res, out_result);
}

void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement) {
	if (!prepared_statement) {
		return;
	}
	auto wrapper = (PreparedStatementWrapper *)*prepared_statement;
	if (wrapper) {
		delete wrapper;
	}
	*prepared_statement = nullptr;
}

duckdb_type ConvertCPPTypeToC(SQLType sql_type) {
	switch (sql_type.id) {
	case SQLTypeId::BOOLEAN:
		return DUCKDB_TYPE_BOOLEAN;
	case SQLTypeId::TINYINT:
		return DUCKDB_TYPE_TINYINT;
	case SQLTypeId::SMALLINT:
		return DUCKDB_TYPE_SMALLINT;
	case SQLTypeId::INTEGER:
		return DUCKDB_TYPE_INTEGER;
	case SQLTypeId::BIGINT:
		return DUCKDB_TYPE_BIGINT;
	case SQLTypeId::FLOAT:
		return DUCKDB_TYPE_FLOAT;
	case SQLTypeId::DECIMAL:
	case SQLTypeId::DOUBLE:
		return DUCKDB_TYPE_DOUBLE;
	case SQLTypeId::TIMESTAMP:
		return DUCKDB_TYPE_TIMESTAMP;
	case SQLTypeId::DATE:
		return DUCKDB_TYPE_DATE;
	case SQLTypeId::TIME:
		return DUCKDB_TYPE_TIME;
	case SQLTypeId::VARCHAR:
		return DUCKDB_TYPE_VARCHAR;
	default:
		return DUCKDB_TYPE_INVALID;
	}
}

SQLType ConvertCTypeToCPP(duckdb_type type) {
	switch (type) {
	case DUCKDB_TYPE_BOOLEAN:
		return SQLType(SQLTypeId::BOOLEAN);
	case DUCKDB_TYPE_TINYINT:
		return SQLType::TINYINT;
	case DUCKDB_TYPE_SMALLINT:
		return SQLType::SMALLINT;
	case DUCKDB_TYPE_INTEGER:
		return SQLType::INTEGER;
	case DUCKDB_TYPE_BIGINT:
		return SQLType::BIGINT;
	case DUCKDB_TYPE_FLOAT:
		return SQLType::FLOAT;
	case DUCKDB_TYPE_DOUBLE:
		return SQLType::DOUBLE;
	case DUCKDB_TYPE_TIMESTAMP:
		return SQLType::TIMESTAMP;
	case DUCKDB_TYPE_DATE:
		return SQLType::DATE;
	case DUCKDB_TYPE_TIME:
		return SQLType::TIME;
	case DUCKDB_TYPE_VARCHAR:
		return SQLType::VARCHAR;
	default:
		return SQLType(SQLTypeId::INVALID);
	}
}

idx_t GetCTypeSize(duckdb_type type) {
	switch (type) {
	case DUCKDB_TYPE_BOOLEAN:
		return sizeof(bool);
	case DUCKDB_TYPE_TINYINT:
		return sizeof(int8_t);
	case DUCKDB_TYPE_SMALLINT:
		return sizeof(int16_t);
	case DUCKDB_TYPE_INTEGER:
		return sizeof(int32_t);
	case DUCKDB_TYPE_BIGINT:
		return sizeof(int64_t);
	case DUCKDB_TYPE_FLOAT:
		return sizeof(float);
	case DUCKDB_TYPE_DOUBLE:
		return sizeof(double);
	case DUCKDB_TYPE_DATE:
		return sizeof(duckdb_date);
	case DUCKDB_TYPE_TIME:
		return sizeof(duckdb_time);
	case DUCKDB_TYPE_TIMESTAMP:
		return sizeof(duckdb_timestamp);
	case DUCKDB_TYPE_VARCHAR:
		return sizeof(const char *);
	default:
		// unsupported type
		assert(0);
		return sizeof(const char *);
	}
}

template <class T> T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) {
	assert(row < result->row_count);
	return ((T *)result->columns[col].data)[row];
}

static Value GetCValue(duckdb_result *result, idx_t col, idx_t row) {
	if (col >= result->column_count) {
		return Value();
	}
	if (row >= result->row_count) {
		return Value();
	}
	if (result->columns[col].nullmask[row]) {
		return Value();
	}
	switch (result->columns[col].type) {
	case DUCKDB_TYPE_BOOLEAN:
		return Value::BOOLEAN(UnsafeFetch<bool>(result, col, row));
	case DUCKDB_TYPE_TINYINT:
		return Value::TINYINT(UnsafeFetch<int8_t>(result, col, row));
	case DUCKDB_TYPE_SMALLINT:
		return Value::SMALLINT(UnsafeFetch<int16_t>(result, col, row));
	case DUCKDB_TYPE_INTEGER:
		return Value::INTEGER(UnsafeFetch<int32_t>(result, col, row));
	case DUCKDB_TYPE_BIGINT:
		return Value::BIGINT(UnsafeFetch<int64_t>(result, col, row));
	case DUCKDB_TYPE_FLOAT:
		return Value(UnsafeFetch<float>(result, col, row));
	case DUCKDB_TYPE_DOUBLE:
		return Value(UnsafeFetch<double>(result, col, row));
	case DUCKDB_TYPE_DATE: {
		auto date = UnsafeFetch<duckdb_date>(result, col, row);
		return Value::DATE(date.year, date.month, date.day);
	}
	case DUCKDB_TYPE_TIME: {
		auto time = UnsafeFetch<duckdb_time>(result, col, row);
		return Value::TIME(time.hour, time.min, time.sec, time.msec);
	}
	case DUCKDB_TYPE_TIMESTAMP: {
		auto timestamp = UnsafeFetch<duckdb_timestamp>(result, col, row);
		return Value::TIMESTAMP(timestamp.date.year, timestamp.date.month, timestamp.date.day, timestamp.time.hour,
		                        timestamp.time.min, timestamp.time.sec, timestamp.time.msec);
	}
	case DUCKDB_TYPE_VARCHAR:
		return Value(string(UnsafeFetch<const char *>(result, col, row)));
	default:
		// invalid type for C to C++ conversion
		assert(0);
		return Value();
	}
}

bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return false;
	} else {
		return val.CastAs(TypeId::BOOL).value_.boolean;
	}
}

int8_t duckdb_value_int8(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return 0;
	} else {
		return val.CastAs(TypeId::INT8).value_.tinyint;
	}
}

int16_t duckdb_value_int16(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return 0;
	} else {
		return val.CastAs(TypeId::INT16).value_.smallint;
	}
}

int32_t duckdb_value_int32(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return 0;
	} else {
		return val.CastAs(TypeId::INT32).value_.integer;
	}
}

int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return 0;
	} else {
		return val.CastAs(TypeId::INT64).value_.bigint;
	}
}

float duckdb_value_float(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return 0.0;
	} else {
		return val.CastAs(TypeId::FLOAT).value_.float_;
	}
}

double duckdb_value_double(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	if (val.is_null) {
		return 0.0;
	} else {
		return val.CastAs(TypeId::DOUBLE).value_.double_;
	}
}

char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row) {
	Value val = GetCValue(result, col, row);
	return strdup(val.ToString(ConvertCTypeToCPP(result->columns[col].type)).c_str());
}


using namespace duckdb;
using namespace std;

MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type)
    : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type) {
}

MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type, vector<SQLType> sql_types,
                                                 vector<TypeId> types, vector<string> names)
    : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, sql_types, types, names) {
}

MaterializedQueryResult::MaterializedQueryResult(string error)
    : QueryResult(QueryResultType::MATERIALIZED_RESULT, error) {
}

Value MaterializedQueryResult::GetValue(idx_t column, idx_t index) {
	auto &data = collection.GetChunk(index).data[column];
	auto offset_in_chunk = index % STANDARD_VECTOR_SIZE;
	return data.GetValue(offset_in_chunk);
}

string MaterializedQueryResult::ToString() {
	string result;
	if (success) {
		result = HeaderToString();
		result += "[ Rows: " + to_string(collection.count) + "]\n";
		for (idx_t j = 0; j < collection.count; j++) {
			for (idx_t i = 0; i < collection.column_count(); i++) {
				auto val = collection.GetValue(i, j);
				result += val.is_null ? "NULL" : val.ToString(sql_types[i]);
				result += "\t";
			}
			result += "\n";
		}
		result += "\n";
	} else {
		result = "Query Error: " + error + "\n";
	}
	return result;
}

unique_ptr<DataChunk> MaterializedQueryResult::Fetch() {
	if (!success) {
		return nullptr;
	}
	if (collection.chunks.size() == 0) {
		return make_unique<DataChunk>();
	}
	auto chunk = move(collection.chunks[0]);
	collection.chunks.erase(collection.chunks.begin() + 0);
	return chunk;
}





using namespace duckdb;
using namespace std;

PreparedStatement::PreparedStatement(ClientContext *context, string name, string query, PreparedStatementData &data,
                                     idx_t n_param)
    : context(context), name(name), query(query), success(true), is_invalidated(false), n_param(n_param) {
	this->type = data.statement_type;
	this->types = data.sql_types;
	this->names = data.names;
}

PreparedStatement::PreparedStatement(string error)
    : context(nullptr), success(false), error(error), is_invalidated(false) {
}

PreparedStatement::~PreparedStatement() {
	if (!is_invalidated && success) {
		assert(context);
		context->RemovePreparedStatement(this);
	}
}

unique_ptr<QueryResult> PreparedStatement::Execute(vector<Value> &values, bool allow_stream_result) {
	if (!success) {
		return make_unique<MaterializedQueryResult>("Attempting to execute an unsuccessfully prepared statement!");
	}
	if (is_invalidated) {
		return make_unique<MaterializedQueryResult>(
		    "Cannot execute prepared statement: underlying database or connection has been destroyed");
	}
	assert(context);
	return context->Execute(name, values, allow_stream_result, query);
}



using namespace duckdb;
using namespace std;

PreparedStatementData::PreparedStatementData(StatementType type)
    : statement_type(type), read_only(true), requires_valid_transaction(true) {
}

PreparedStatementData::~PreparedStatementData() {
}

void PreparedStatementData::Bind(vector<Value> values) {
	// set parameters
	if (values.size() != value_map.size()) {
		throw BinderException("Parameter/argument count mismatch for prepared statement");
	}
	// bind the values
	for (idx_t i = 0; i < values.size(); i++) {
		auto it = value_map.find(i + 1);
		if (it == value_map.end()) {
			throw BinderException("Could not find parameter with index %llu", i + 1);
		}
		if (values[i].type != GetInternalType(it->second.target_type)) {
			throw BinderException(
			    "Type mismatch for binding parameter with index %llu, expected type %s but got type %s", i + 1,
			    TypeIdToString(values[i].type).c_str(),
			    TypeIdToString(GetInternalType(it->second.target_type)).c_str());
		}
		auto &target = it->second;
		*target.value = values[i];
	}
}

SQLType PreparedStatementData::GetType(idx_t param_idx) {
	auto it = value_map.find(param_idx);
	if (it == value_map.end()) {
		throw BinderException("Could not find parameter with index %llu", param_idx);
	}
	return it->second.target_type;
}








#include <iostream>
#include <utility>

using namespace duckdb;
using namespace std;

constexpr idx_t TREE_RENDER_WIDTH = 20;
constexpr idx_t REMAINING_RENDER_WIDTH = TREE_RENDER_WIDTH - 2;
constexpr idx_t MAX_EXTRA_LINES = 10;

void QueryProfiler::StartQuery(string query, SQLStatement &statement) {
	if (!enabled) {
		return;
	}
	if (statement.type != StatementType::SELECT && statement.type != StatementType::EXECUTE) {
		return;
	}
	this->running = true;
	this->query = query;
	tree_map.clear();
	execution_stack = stack<PhysicalOperator *>();
	root = nullptr;
	phase_timings.clear();
	phase_stack.clear();

	main_query.Start();
	op.Start();
}

void QueryProfiler::EndQuery() {
	if (!enabled || !running) {
		return;
	}

	main_query.End();
	this->running = false;
	// print the query after termination, if this is enabled
	if (automatic_print_format != ProfilerPrintFormat::NONE) {
		string query_info;
		if (automatic_print_format == ProfilerPrintFormat::JSON) {
			query_info = ToJSON();
		} else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE) {
			query_info = ToString();
		}

		if (save_location.empty()) {
			cout << query_info << "\n";
		} else {
			WriteToFile(save_location.c_str(), query_info);
		}
	}
}

void QueryProfiler::StartPhase(string new_phase) {
	if (!enabled || !running) {
		return;
	}

	if (!phase_stack.empty()) {
		// there are active phases
		phase_profiler.End();
		// add the timing to all phases prior to this one
		string prefix = "";
		for (auto &phase : phase_stack) {
			phase_timings[phase] += phase_profiler.Elapsed();
			prefix += phase + " > ";
		}
		// when there are previous phases, we prefix the current phase with those phases
		new_phase = prefix + new_phase;
	}

	// start a new phase
	phase_stack.push_back(new_phase);
	// restart the timer
	phase_profiler.Start();
}

void QueryProfiler::EndPhase() {
	if (!enabled || !running) {
		return;
	}
	assert(phase_stack.size() > 0);

	// end the timer
	phase_profiler.End();
	// add the timing to all currently active phases
	for (auto &phase : phase_stack) {
		phase_timings[phase] += phase_profiler.Elapsed();
	}
	// now remove the last added phase
	phase_stack.pop_back();

	if (phase_stack.size() > 0) {
		phase_profiler.Start();
	}
}

void QueryProfiler::StartOperator(PhysicalOperator *phys_op) {
	if (!enabled || !running) {
		return;
	}

	if (!root) {
		// start of execution: create operator tree
		root = CreateTree(phys_op);
	}
	if (!execution_stack.empty()) {
		// add timing for the previous element
		op.End();
		assert(tree_map.count(execution_stack.top()) > 0);
		auto &info = tree_map[execution_stack.top()]->info;
		info.time += op.Elapsed();
	}
	if (tree_map.count(phys_op) == 0) {
		// element does not exist in the tree! this only happens with a subquery
		// create a new tree
		assert(execution_stack.size() > 0);
		auto node = tree_map[execution_stack.top()];
		auto new_tree = CreateTree(phys_op, node->depth + 1);
		// add it to the current node
		node->children.push_back(move(new_tree));
	}
	execution_stack.push(phys_op);

	// start timing for current element
	op.Start();
}

void QueryProfiler::EndOperator(DataChunk &chunk) {
	if (!enabled || !running) {
		return;
	}

	// finish timing for the current element
	op.End();
	auto &info = tree_map[execution_stack.top()]->info;
	info.time += op.Elapsed();
	info.elements += chunk.size();

	assert(!execution_stack.empty());
	execution_stack.pop();

	// start timing again for the previous element, if any
	if (!execution_stack.empty()) {
		op.Start();
	}
}

string QueryProfiler::ToString() const {
	if (!enabled) {
		return "Query profiling is disabled. Call "
		       "Connection::EnableProfiling() to enable profiling!";
	}

	if (query.empty()) {
		return "<<Empty Profiling Information>>";
	}
	string result = "<<Query Profiling Information>>\n";
	result += StringUtil::Replace(query, "\n", " ") + "\n";
	result += "<<Timing>>\n";
	result += "Total Time: " + to_string(main_query.Elapsed()) + "s\n";
	// print phase timings
	for (const auto &entry : GetOrderedPhaseTimings()) {
		result += entry.first + ": " + to_string(entry.second) + "s\n";
	}
	// render the main operator tree
	result += "<<Operator Tree>>\n";
	if (!root) {
		result += "<<ERROR RENDERING ROOT>";
	} else {
		result += RenderTree(*root);
	}
	return result;
}

static string ToJSONRecursive(QueryProfiler::TreeNode &node) {
	string result = "{ \"name\": \"" + node.name + "\",\n";
	result += "\"timing\":" + StringUtil::Format("%.2f", node.info.time) + ",\n";
	result += "\"cardinality\":" + to_string(node.info.elements) + ",\n";
	result += "\"extra_info\": \"" + StringUtil::Replace(node.extra_info, "\n", "\\n") + "\",\n";
	result += "\"children\": [";
	result +=
	    StringUtil::Join(node.children, node.children.size(), ",\n",
	                     [](const unique_ptr<QueryProfiler::TreeNode> &child) { return ToJSONRecursive(*child); });
	result += "]\n}\n";
	return result;
}

string QueryProfiler::ToJSON() const {
	if (!enabled) {
		return "{ \"result\": \"disabled\" }\n";
	}
	if (query.empty()) {
		return "{ \"result\": \"empty\" }\n";
	}
	if (!root) {
		return "{ \"result\": \"error\" }\n";
	}
	string result = "{ \"result\": " + to_string(main_query.Elapsed()) + ",\n";
	// print the phase timings
	result += "\"timings\": {\n";
	const auto &ordered_phase_timings = GetOrderedPhaseTimings();
	result +=
	    StringUtil::Join(ordered_phase_timings, ordered_phase_timings.size(), ",\n", [](const PhaseTimingItem &entry) {
		    return "\"" + entry.first + "\": " + to_string(entry.second);
	    });
	result += "},\n";
	// recursively print the physical operator tree
	result += "\"tree\": ";
	result += ToJSONRecursive(*root);
	return result + "}";
}

void QueryProfiler::WriteToFile(const char *path, string &info) const {
	ofstream out(path);
	out << info;
	out.close();
}

static bool is_non_split_char(char l) {
	return (l >= 65 && l <= 90) || (l >= 97 && l <= 122) || l == 95 || l == ']' || l == ')';
}

static bool is_padding(char l) {
	return l == ' ' || l == '(' || l == ')';
}

static string remove_padding(string l) {
	idx_t start = 0, end = l.size();
	while (start < l.size() && is_padding(l[start])) {
		start++;
	}
	while (end > 0 && is_padding(l[end - 1])) {
		end--;
	}
	return l.substr(start, end - start);
}

unique_ptr<QueryProfiler::TreeNode> QueryProfiler::CreateTree(PhysicalOperator *root, idx_t depth) {
	auto node = make_unique<QueryProfiler::TreeNode>();
	node->name = PhysicalOperatorToString(root->type);
	node->extra_info = root->ExtraRenderInformation();
	if (!node->extra_info.empty()) {
		auto splits = StringUtil::Split(node->extra_info, '\n');
		for (auto &split : splits) {
			string str = remove_padding(split);
			constexpr idx_t max_segment_size = REMAINING_RENDER_WIDTH - 2;
			idx_t location = 0;
			while (location < str.size() && node->split_extra_info.size() < MAX_EXTRA_LINES) {
				bool has_to_split = (str.size() - location) > max_segment_size;
				if (has_to_split) {
					// look for a split character
					idx_t i;
					for (i = 8; i < max_segment_size; i++) {
						if (!is_non_split_char(str[location + i])) {
							// split here
							break;
						}
					}
					node->split_extra_info.push_back(str.substr(location, i));
					location += i;
				} else {
					node->split_extra_info.push_back(str.substr(location));
					break;
				}
			}
		}
	}
	node->depth = depth;
	tree_map[root] = node.get();
	for (auto &child : root->children) {
		auto child_node = CreateTree(child.get(), depth + 1);
		node->children.push_back(move(child_node));
	}
	return node;
}

static string DrawPadded(string text, char padding_character = ' ') {
	auto remaining_width = REMAINING_RENDER_WIDTH;
	if (text.size() > remaining_width) {
		text = text.substr(0, remaining_width);
	}
	assert(text.size() <= (idx_t)numeric_limits<int32_t>::max());

	auto right_padding = (remaining_width - text.size()) / 2;
	auto left_padding = remaining_width - text.size() - right_padding;
	return "|" + string(left_padding, padding_character) + text + string(right_padding, padding_character) + "|";
}

idx_t QueryProfiler::RenderTreeRecursive(QueryProfiler::TreeNode &node, vector<string> &render,
                                         vector<idx_t> &render_heights, idx_t base_render_x, idx_t start_depth,
                                         idx_t depth) {
	auto render_height = render_heights[depth];
	auto width = base_render_x;
	// render this node
	// first add any padding to render at this location
	auto start_position = width * TREE_RENDER_WIDTH;
	for (idx_t i = 0; i < render_height; i++) {
		if (render[start_depth + i].size() > start_position) {
			// something has already been rendered here!
			throw Exception("Tree rendering error, overlapping nodes!");
		} else {
			// add the padding
			render[start_depth + i] += string(start_position - render[start_depth + i].size(), ' ');
		}
	}

	// draw the boundaries of the box
	render[start_depth] += string(TREE_RENDER_WIDTH, '-');
	render[start_depth + render_height - 1] += string(TREE_RENDER_WIDTH, '-');

	// draw the name
	string name = node.name;
	render[start_depth + 1] += DrawPadded(name);
	// draw extra information
	for (idx_t i = 2; i < render_height - 3; i++) {
		auto split_index = i - 2;
		string string = split_index < node.split_extra_info.size() ? node.split_extra_info[split_index] : "";
		render[start_depth + i] += DrawPadded(string);
	}
	// draw the timing information
	string timing = StringUtil::Format("%.2f", node.info.time);
	render[start_depth + render_height - 3] += DrawPadded("(" + timing + "s)");
	// draw the intermediate count
	render[start_depth + render_height - 2] += DrawPadded(to_string(node.info.elements));

	for (auto &child : node.children) {
		// render all the children
		width =
		    RenderTreeRecursive(*child, render, render_heights, width, start_depth + render_heights[depth], depth + 1);
		width++;
	}
	if (node.children.size() > 0) {
		width--;
	}
	return width;
}

idx_t QueryProfiler::GetDepth(QueryProfiler::TreeNode &node) {
	idx_t depth = 0;
	for (auto &child : node.children) {
		depth = max(depth, GetDepth(*child));
	}
	return depth + 1;
}

static void GetRenderHeight(QueryProfiler::TreeNode &node, vector<idx_t> &render_heights, int depth = 0) {
	render_heights[depth] = max(render_heights[depth], (5 + (idx_t)node.split_extra_info.size()));
	for (auto &child : node.children) {
		GetRenderHeight(*child, render_heights, depth + 1);
	}
}

string QueryProfiler::RenderTree(QueryProfiler::TreeNode &node) {
	vector<idx_t> render_heights;
	// compute the height of each level
	auto depth = GetDepth(node);

	// compute the render height
	render_heights.resize(depth);
	GetRenderHeight(node, render_heights);
	int32_t total_height = 0;
	for (auto height : render_heights) {
		total_height += height;
	}

	// now actually render the tree
	vector<string> render;
	render.resize(total_height);

	RenderTreeRecursive(node, render, render_heights);
	string text;
	for (auto &str : render) {
		text += str + "\n";
	}
	return text;
}

void QueryProfiler::Print() {
	Printer::Print(ToString());
}

vector<QueryProfiler::PhaseTimingItem> QueryProfiler::GetOrderedPhaseTimings() const {
	vector<PhaseTimingItem> result;
	// first sort the phases alphabetically
	vector<string> phases;
	for (auto &entry : phase_timings) {
		phases.push_back(entry.first);
	}
	std::sort(phases.begin(), phases.end());
	for (const auto &phase : phases) {
		auto entry = phase_timings.find(phase);
		assert(entry != phase_timings.end());
		result.emplace_back(entry->first, entry->second);
	}
	return result;
}


using namespace duckdb;
using namespace std;

QueryResult::QueryResult(QueryResultType type, StatementType statement_type)
    : type(type), statement_type(statement_type), success(true) {
}

QueryResult::QueryResult(QueryResultType type, StatementType statement_type, vector<SQLType> sql_types,
                         vector<TypeId> types, vector<string> names)
    : type(type), statement_type(statement_type), sql_types(sql_types), types(types), names(names), success(true) {
	assert(types.size() == names.size());
}

QueryResult::QueryResult(QueryResultType type, string error) : type(type), success(false), error(error) {
}

bool QueryResult::Equals(QueryResult &other) {
	// first compare the success state of the results
	if (success != other.success) {
		return false;
	}
	if (!success) {
		return error == other.error;
	}
	// compare names
	if (names != other.names) {
		return false;
	}
	// compare types
	if (sql_types != other.sql_types || types != other.types) {
		return false;
	}
	// now compare the actual values
	// fetch chunks
	while (true) {
		auto lchunk = Fetch();
		auto rchunk = other.Fetch();
		if (lchunk->size() == 0 && rchunk->size() == 0) {
			return true;
		}
		if (lchunk->size() != rchunk->size()) {
			return false;
		}
		assert(lchunk->column_count() == rchunk->column_count());
		for (idx_t col = 0; col < rchunk->column_count(); col++) {
			for (idx_t row = 0; row < rchunk->size(); row++) {
				auto lvalue = lchunk->GetValue(col, row);
				auto rvalue = rchunk->GetValue(col, row);
				if (lvalue != rvalue) {
					return false;
				}
			}
		}
	}
}

void QueryResult::Print() {
	fprintf(stderr, "%s\n", ToString().c_str());
}

string QueryResult::HeaderToString() {
	string result;
	for (auto &name : names) {
		result += name + "\t";
	}
	result += "\n";
	for (auto &type : sql_types) {
		result += SQLTypeToString(type) + "\t";
	}
	result += "\n";
	return result;
}





using namespace duckdb;
using namespace std;

StreamQueryResult::StreamQueryResult(StatementType statement_type, ClientContext &context, vector<SQLType> sql_types,
                                     vector<TypeId> types, vector<string> names)
    : QueryResult(QueryResultType::STREAM_RESULT, statement_type, sql_types, types, names), is_open(true),
      context(context) {
}

StreamQueryResult::~StreamQueryResult() {
	Close();
}

string StreamQueryResult::ToString() {
	string result;
	if (success) {
		result = HeaderToString();
		result += "[[STREAM RESULT]]";
	} else {
		result = "Query Error: " + error + "\n";
	}
	return result;
}

unique_ptr<DataChunk> StreamQueryResult::Fetch() {
	if (!success || !is_open) {
		return nullptr;
	}
	auto chunk = context.Fetch();
	if (!chunk || chunk->column_count() == 0 || chunk->size() == 0) {
		Close();
	}
	return chunk;
}

unique_ptr<MaterializedQueryResult> StreamQueryResult::Materialize() {
	if (!success) {
		return make_unique<MaterializedQueryResult>(error);
	}
	auto result = make_unique<MaterializedQueryResult>(statement_type, sql_types, types, names);
	while (true) {
		auto chunk = Fetch();
		if (!chunk || chunk->size() == 0) {
			return result;
		}
		result->collection.Append(*chunk);
	}
}

void StreamQueryResult::Close() {
	if (!is_open) {
		return;
	}
	context.Cleanup();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/column_lifetime_optimizer.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class BoundColumnRefExpression;

//! The ColumnLifetimeAnalyzer optimizer traverses the logical operator tree and ensures that columns are removed from
//! the plan when no longer required
class ColumnLifetimeAnalyzer : public LogicalOperatorVisitor {
public:
	ColumnLifetimeAnalyzer(bool is_root = false) : everything_referenced(is_root) {
	}

	void VisitOperator(LogicalOperator &op) override;

protected:
	unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr) override;
	unique_ptr<Expression> VisitReplace(BoundReferenceExpression &expr, unique_ptr<Expression> *expr_ptr) override;

private:
	//! Whether or not all the columns are referenced. This happens in the case of the root expression (because the
	//! output implicitly refers all the columns below it)
	bool everything_referenced;
	//! The set of column references
	column_binding_set_t column_references;

private:
	void StandardVisitOperator(LogicalOperator &op);

	void ExtractUnusedColumnBindings(vector<ColumnBinding> bindings, column_binding_set_t &unused_bindings);
	void GenerateProjectionMap(vector<ColumnBinding> bindings, column_binding_set_t &unused_bindings,
	                           vector<idx_t> &map);
};
} // namespace duckdb








using namespace duckdb;
using namespace std;

void ColumnLifetimeAnalyzer::ExtractUnusedColumnBindings(vector<ColumnBinding> bindings,
                                                         column_binding_set_t &unused_bindings) {
	for (idx_t i = 0; i < bindings.size(); i++) {
		if (column_references.find(bindings[i]) == column_references.end()) {
			unused_bindings.insert(bindings[i]);
		}
	}
}

void ColumnLifetimeAnalyzer::GenerateProjectionMap(vector<ColumnBinding> bindings,
                                                   column_binding_set_t &unused_bindings,
                                                   vector<idx_t> &projection_map) {
	if (unused_bindings.size() == 0) {
		return;
	}
	// now iterate over the result bindings of the child
	for (idx_t i = 0; i < bindings.size(); i++) {
		// if this binding does not belong to the unused bindings, add it to the projection map
		if (unused_bindings.find(bindings[i]) == unused_bindings.end()) {
			projection_map.push_back(i);
		}
	}
	if (projection_map.size() == bindings.size()) {
		projection_map.clear();
	}
}

void ColumnLifetimeAnalyzer::StandardVisitOperator(LogicalOperator &op) {
	LogicalOperatorVisitor::VisitOperatorExpressions(op);
	if (op.type == LogicalOperatorType::DELIM_JOIN) {
		// visit the duplicate eliminated columns on the LHS, if any
		auto &delim_join = (LogicalDelimJoin &)op;
		for (auto &expr : delim_join.duplicate_eliminated_columns) {
			VisitExpression(&expr);
		}
	}
	LogicalOperatorVisitor::VisitOperatorChildren(op);
}

void ColumnLifetimeAnalyzer::VisitOperator(LogicalOperator &op) {
	switch (op.type) {
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY: {
		// FIXME: groups that are not referenced can be removed from projection
		// recurse into the children of the aggregate
		ColumnLifetimeAnalyzer analyzer;
		analyzer.VisitOperatorExpressions(op);
		analyzer.VisitOperator(*op.children[0]);
		return;
	}
	case LogicalOperatorType::DELIM_JOIN:
	case LogicalOperatorType::COMPARISON_JOIN: {
		if (everything_referenced) {
			break;
		}
		auto &comp_join = (LogicalComparisonJoin &)op;
		if (comp_join.join_type == JoinType::MARK || comp_join.join_type == JoinType::SEMI ||
		    comp_join.join_type == JoinType::ANTI) {
			break;
		}
		// FIXME for now, we only push into the projection map for equality (hash) joins
		// FIXME: add projection to LHS as well
		bool has_equality = false;
		for (auto &cond : comp_join.conditions) {
			if (cond.comparison == ExpressionType::COMPARE_EQUAL) {
				has_equality = true;
			}
		}
		if (!has_equality) {
			break;
		}
		// now, for each of the columns of the RHS, check which columns need to be projected
		column_binding_set_t unused_bindings;
		ExtractUnusedColumnBindings(op.children[1]->GetColumnBindings(), unused_bindings);

		// now recurse into the filter and its children
		StandardVisitOperator(op);

		// then generate the projection map
		GenerateProjectionMap(op.children[1]->GetColumnBindings(), unused_bindings, comp_join.right_projection_map);
		return;
	}
	case LogicalOperatorType::UNION:
	case LogicalOperatorType::EXCEPT:
	case LogicalOperatorType::INTERSECT:
		// for set operations we don't remove anything, just recursively visit the children
		// FIXME: for UNION we can remove unreferenced columns as long as everything_referenced is false (i.e. we
		// encounter a UNION node that is not preceded by a DISTINCT)
		for (auto &child : op.children) {
			ColumnLifetimeAnalyzer analyzer(true);
			analyzer.VisitOperator(*child);
		}
		return;
	case LogicalOperatorType::PROJECTION: {
		// then recurse into the children of this projection
		ColumnLifetimeAnalyzer analyzer;
		analyzer.VisitOperatorExpressions(op);
		analyzer.VisitOperator(*op.children[0]);
		return;
	}
	case LogicalOperatorType::DISTINCT: {
		// distinct, all projected columns are used for the DISTINCT computation
		// mark all columns as used and continue to the children
		// FIXME: DISTINCT with expression list does not implicitly reference everything
		everything_referenced = true;
		break;
	}
	case LogicalOperatorType::FILTER: {
		auto &filter = (LogicalFilter &)op;
		if (everything_referenced) {
			break;
		}
		// filter, figure out which columns are not needed after the filter
		column_binding_set_t unused_bindings;
		ExtractUnusedColumnBindings(op.children[0]->GetColumnBindings(), unused_bindings);

		// now recurse into the filter and its children
		StandardVisitOperator(op);

		// then generate the projection map
		GenerateProjectionMap(op.children[0]->GetColumnBindings(), unused_bindings, filter.projection_map);
		return;
	}
	default:
		break;
	}
	StandardVisitOperator(op);
}

unique_ptr<Expression> ColumnLifetimeAnalyzer::VisitReplace(BoundColumnRefExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	column_references.insert(expr.binding);
	return nullptr;
}

unique_ptr<Expression> ColumnLifetimeAnalyzer::VisitReplace(BoundReferenceExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	// BoundReferenceExpression should not be used here yet, they only belong in the physical plan
	throw InternalException("BoundReferenceExpression should not be used here yet!");
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/cse_optimizer.hpp
//
//
//===----------------------------------------------------------------------===//




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression_map.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class Expression;

struct ExpressionHashFunction {
	uint64_t operator()(const BaseExpression *const &expr) const {
		return (uint64_t)expr->Hash();
	}
};

struct ExpressionEquality {
	bool operator()(const BaseExpression *const &a, const BaseExpression *const &b) const {
		return a->Equals(b);
	}
};

template <typename T>
using expression_map_t = unordered_map<BaseExpression *, T, ExpressionHashFunction, ExpressionEquality>;

using expression_set_t = unordered_set<BaseExpression *, ExpressionHashFunction, ExpressionEquality>;

} // namespace duckdb



namespace duckdb {
//! The CommonSubExpression optimizer traverses the expressions of a LogicalOperator to look for duplicate expressions,
//! and moves duplicate expressions into a shared CommonSubExpression.
class CommonSubExpressionOptimizer : public LogicalOperatorVisitor {
private:
	struct CSENode {
		idx_t count;
		Expression *expr;

		CSENode(idx_t count = 1, Expression *expr = nullptr) : count(count), expr(expr) {
		}
	};

	//! First iteration: count how many times each expression occurs
	void CountExpressions(Expression &expr, expression_map_t<CSENode> &expression_count);
	//! Second iteration: perform the actual replacement of the duplicate expressions with common subexpressions nodes
	void PerformCSEReplacement(unique_ptr<Expression> *expr, expression_map_t<CSENode> &expression_count);

	//! Main method to extract common subexpressions
	void ExtractCommonSubExpresions(LogicalOperator &op);

public:
	void VisitOperator(LogicalOperator &op) override;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/common_subexpression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents a CommonSubExpression, this is only generated by the optimizers. CSEs cannot be serialized, deserialized
//! or copied.
class CommonSubExpression : public Expression {
public:
	CommonSubExpression(unique_ptr<Expression> child, string alias);
	CommonSubExpression(Expression *child, string alias);

	//! The child of the CSE
	Expression *child;
	//! The owned child of the CSE (if any)
	unique_ptr<Expression> owned_child;

public:
	bool IsScalar() const override {
		return false;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb





using namespace duckdb;
using namespace std;

void CommonSubExpressionOptimizer::VisitOperator(LogicalOperator &op) {
	switch (op.type) {
	case LogicalOperatorType::FILTER:
	case LogicalOperatorType::PROJECTION:
		ExtractCommonSubExpresions(op);
		break;
	default:
		break;
	}
	LogicalOperatorVisitor::VisitOperator(op);
}

void CommonSubExpressionOptimizer::CountExpressions(Expression &expr, expression_map_t<CSENode> &expression_count) {
	// we only consider expressions with children for CSE elimination
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_COLUMN_REF:
	case ExpressionClass::BOUND_CONSTANT:
	case ExpressionClass::BOUND_PARAMETER:
	case ExpressionClass::COMMON_SUBEXPRESSION:
		return;
	default:
		break;
	}
	auto node = expression_count.find(&expr);
	if (node == expression_count.end()) {
		// first time we encounter this expression, insert this node with [count = 1]
		expression_count[&expr] = CSENode(1);
	} else {
		// we encountered this expression before, increment the occurrence count
		node->second.count++;
	}
	// recursively count the children
	ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { CountExpressions(child, expression_count); });
}

void CommonSubExpressionOptimizer::PerformCSEReplacement(unique_ptr<Expression> *expr_ptr,
                                                         expression_map_t<CSENode> &expression_count) {
	Expression &expr = **expr_ptr;
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_COLUMN_REF:
	case ExpressionClass::BOUND_CONSTANT:
	case ExpressionClass::BOUND_PARAMETER:
	case ExpressionClass::COMMON_SUBEXPRESSION:
		return;
	default:
		break;
	}
	// check if this child is eligible for CSE elimination
	if (expression_count.find(&expr) == expression_count.end()) {
		// no occurrence: skip the node
		return;
	}
	auto &node = expression_count[&expr];
	if (node.count > 1) {
		// this expression occurs more than once! replace it with a CSE
		// check if it has already been replaced with a CSE before
		auto alias = expr.alias.empty() ? expr.GetName() : expr.alias;
		if (!node.expr) {
			// the CSE does not exist yet: create the CSE with the ownership of this node
			node.expr = &expr;
			*expr_ptr = make_unique<CommonSubExpression>(move(*expr_ptr), alias);
		} else {
			// the CSE already exists: create a CSE referring to the existing node
			*expr_ptr = make_unique<CommonSubExpression>(node.expr, alias);
		}
		return;
	}
	// this expression only occurs once, we can't perform CSE elimination
	// look into the children to see if we can replace them
	ExpressionIterator::EnumerateChildren(expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		PerformCSEReplacement(&child, expression_count);
		return move(child);
	});
}

void CommonSubExpressionOptimizer::ExtractCommonSubExpresions(LogicalOperator &op) {
	// first we count for each expression with children how many types it occurs
	expression_map_t<CSENode> expression_count;
	for (auto &expr : op.expressions) {
		CountExpressions(*expr, expression_count);
	}
	// now we iterate over all the expressions and perform the actual CSE elimination
	for (idx_t i = 0; i < op.expressions.size(); i++) {
		PerformCSEReplacement(&op.expressions[i], expression_count);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/expression_heuristics.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class ExpressionHeuristics : public LogicalOperatorVisitor {
public:
	ExpressionHeuristics(Optimizer &optimizer) : optimizer(optimizer) {
	}

	Optimizer &optimizer;
	unique_ptr<LogicalOperator> root;

public:
	//! Search for filters to be reordered
	unique_ptr<LogicalOperator> Rewrite(unique_ptr<LogicalOperator> op);
	//! Reorder the expressions of a filter
	void ReorderExpressions(vector<unique_ptr<Expression>> &expressions);
	//! Return the cost of an expression
	idx_t Cost(Expression &expr);

	unique_ptr<Expression> VisitReplace(BoundConjunctionExpression &expr, unique_ptr<Expression> *expr_ptr) override;
	//! Override this function to search for filter operators
	void VisitOperator(LogicalOperator &op) override;

private:
	std::unordered_map<std::string, idx_t> function_costs = {
	    {"+", 5},       {"-", 5},    {"&", 5},          {"#", 5},
	    {">>", 5},      {"<<", 5},   {"abs", 5},        {"*", 10},
	    {"%", 10},      {"/", 15},   {"date_part", 20}, {"year", 20},
	    {"round", 100}, {"~~", 200}, {"!~~", 200},      {"regexp_matches", 200},
	    {"||", 200}};

	idx_t ExpressionCost(BoundBetweenExpression &expr);
	idx_t ExpressionCost(BoundCaseExpression &expr);
	idx_t ExpressionCost(BoundCastExpression &expr);
	idx_t ExpressionCost(BoundComparisonExpression &expr);
	idx_t ExpressionCost(BoundConjunctionExpression &expr);
	idx_t ExpressionCost(BoundFunctionExpression &expr);
	idx_t ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type);
	idx_t ExpressionCost(TypeId &return_type, idx_t multiplier);
};
} // namespace duckdb









//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_default_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundDefaultExpression : public Expression {
public:
	BoundDefaultExpression(TypeId type = TypeId::INVALID, SQLType sql_type = SQLType())
	    : Expression(ExpressionType::VALUE_DEFAULT, ExpressionClass::BOUND_DEFAULT, type), sql_type(sql_type) {
	}

	SQLType sql_type;

public:
	bool IsScalar() const override {
		return false;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override {
		return "DEFAULT";
	}

	unique_ptr<Expression> Copy() override {
		return make_unique<BoundDefaultExpression>(return_type, sql_type);
	}
};
} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression/bound_subquery_expression.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/subquery_type.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//===--------------------------------------------------------------------===//
// Subquery Types
//===--------------------------------------------------------------------===//
enum class SubqueryType : uint8_t {
	INVALID = 0,
	SCALAR = 1,     // Regular scalar subquery
	EXISTS = 2,     // EXISTS (SELECT...)
	NOT_EXISTS = 3, // NOT EXISTS(SELECT...)
	ANY = 4,        // x = ANY(SELECT...) OR x IN (SELECT...)
};

} // namespace duckdb





namespace duckdb {

class BoundSubqueryExpression : public Expression {
public:
	BoundSubqueryExpression(TypeId return_type);

	bool IsCorrelated() {
		return binder->correlated_columns.size() > 0;
	}

	//! The binder used to bind the subquery node
	unique_ptr<Binder> binder;
	//! The bound subquery node
	unique_ptr<BoundQueryNode> subquery;
	//! The subquery type
	SubqueryType subquery_type;
	//! the child expression to compare with (in case of IN, ANY, ALL operators)
	unique_ptr<Expression> child;
	//! The comparison type of the child expression with the subquery (in case of ANY, ALL operators)
	ExpressionType comparison_type;
	//! The SQLType of the subquery result. Only used for ANY expressions.
	SQLType child_type;
	//! The target SQLType of the subquery result (i.e. to which type it should be casted, if child_type <>
	//! child_target). Only used for ANY expressions.
	SQLType child_target;

public:
	bool HasSubquery() const override {
		return true;
	}
	bool IsScalar() const override {
		return false;
	}
	bool IsFoldable() const override {
		return false;
	}

	string ToString() const override;

	bool Equals(const BaseExpression *other) const override;

	unique_ptr<Expression> Copy() override;
};
} // namespace duckdb






using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> ExpressionHeuristics::Rewrite(unique_ptr<LogicalOperator> op) {
	VisitOperator(*op);
	return op;
}

void ExpressionHeuristics::VisitOperator(LogicalOperator &op) {
	if (op.type == LogicalOperatorType::FILTER) {
		// reorder all filter expressions
		if (op.expressions.size() > 1) {
			ReorderExpressions(op.expressions);
		}
	}

	// traverse recursively through the operator tree
	VisitOperatorChildren(op);
	VisitOperatorExpressions(op);
}

unique_ptr<Expression> ExpressionHeuristics::VisitReplace(BoundConjunctionExpression &expr,
                                                          unique_ptr<Expression> *expr_ptr) {
	ReorderExpressions(expr.children);
	return nullptr;
}

void ExpressionHeuristics::ReorderExpressions(vector<unique_ptr<Expression>> &expressions) {

	struct ExpressionCosts {
		unique_ptr<Expression> expr;
		idx_t cost;

		bool operator==(const ExpressionCosts &p) const {
			return cost == p.cost;
		}
		bool operator<(const ExpressionCosts &p) const {
			return cost < p.cost;
		}
	};

	vector<ExpressionCosts> expression_costs;
	// iterate expressions, get cost for each one
	for (idx_t i = 0; i < expressions.size(); i++) {
		idx_t cost = Cost(*expressions[i]);
		expression_costs.push_back({move(expressions[i]), cost});
	}

	// sort by cost and put back in place
	sort(expression_costs.begin(), expression_costs.end());
	for (idx_t i = 0; i < expression_costs.size(); i++) {
		expressions[i] = move(expression_costs[i].expr);
	}
}

idx_t ExpressionHeuristics::ExpressionCost(BoundBetweenExpression &expr) {
	return Cost(*expr.input) + Cost(*expr.lower) + Cost(*expr.upper) + 10;
}

idx_t ExpressionHeuristics::ExpressionCost(BoundCaseExpression &expr) {
	// CASE WHEN check THEN result_if_true ELSE result_if_false END
	return Cost(*expr.check) + Cost(*expr.result_if_true) + Cost(*expr.result_if_false) + 5;
}

idx_t ExpressionHeuristics::ExpressionCost(BoundCastExpression &expr) {
	// OPERATOR_CAST
	// determine cast cost by comparing cast_expr.source_type and cast_expr_target_type
	idx_t cast_cost = 0;
	if (expr.target_type != expr.source_type) {
		// if cast from or to varchar
		// TODO: we might want to add more cases
		if (expr.target_type == SQLType::VARCHAR || expr.source_type == SQLType::VARCHAR) {
			cast_cost = 200;
		} else {
			cast_cost = 5;
		}
	}
	return Cost(*expr.child) + cast_cost;
}

idx_t ExpressionHeuristics::ExpressionCost(BoundComparisonExpression &expr) {
	// COMPARE_EQUAL, COMPARE_NOTEQUAL, COMPARE_GREATERTHAN, COMPARE_GREATERTHANOREQUALTO, COMPARE_LESSTHAN,
	// COMPARE_LESSTHANOREQUALTO
	return Cost(*expr.left) + 5 + Cost(*expr.right);
}

idx_t ExpressionHeuristics::ExpressionCost(BoundConjunctionExpression &expr) {
	// CONJUNCTION_AND, CONJUNCTION_OR
	idx_t cost = 5;
	for (auto &child : expr.children) {
		cost += Cost(*child);
	}
	return cost;
}

idx_t ExpressionHeuristics::ExpressionCost(BoundFunctionExpression &expr) {
	idx_t cost_children = 0;
	for (auto &child : expr.children) {
		cost_children += Cost(*child);
	}

	auto cost_function = function_costs.find(expr.function.name);
	if (cost_function != function_costs.end()) {
		return cost_children + cost_function->second;
	} else {
		return cost_children + 1000;
	}
}

idx_t ExpressionHeuristics::ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type) {
	idx_t sum = 0;
	for (auto &child : expr.children) {
		sum += Cost(*child);
	}

	// OPERATOR_IS_NULL, OPERATOR_IS_NOT_NULL
	if (expr_type == ExpressionType::OPERATOR_IS_NULL || expr_type == ExpressionType::OPERATOR_IS_NOT_NULL) {
		return sum + 5;
	} else if (expr_type == ExpressionType::COMPARE_IN || expr_type == ExpressionType::COMPARE_NOT_IN) {
		// COMPARE_IN, COMPARE_NOT_IN
		return sum + (expr.children.size() - 1) * 100;
	} else if (expr_type == ExpressionType::OPERATOR_NOT) {
		// OPERATOR_NOT
		return sum + 10; // TODO: evaluate via measured runtimes
	} else {
		return sum + 1000;
	}
}

idx_t ExpressionHeuristics::ExpressionCost(TypeId &return_type, idx_t multiplier) {
	// TODO: ajust values according to benchmark results
	switch (return_type) {
	case TypeId::VARCHAR:
		return 5 * multiplier;
	case TypeId::FLOAT:
		return 2 * multiplier;
	case TypeId::DOUBLE:
		return 2 * multiplier;
	default:
		return 1 * multiplier;
	}
}

idx_t ExpressionHeuristics::Cost(Expression &expr) {
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_CASE: {
		auto &case_expr = (BoundCaseExpression &)expr;
		return ExpressionCost(case_expr);
	}
	case ExpressionClass::BOUND_BETWEEN: {
		auto &between_expr = (BoundBetweenExpression &)expr;
		return ExpressionCost(between_expr);
	}
	case ExpressionClass::BOUND_CAST: {
		auto &cast_expr = (BoundCastExpression &)expr;
		return ExpressionCost(cast_expr);
	}
	case ExpressionClass::BOUND_COMPARISON: {
		auto &comp_expr = (BoundComparisonExpression &)expr;
		return ExpressionCost(comp_expr);
	}
	case ExpressionClass::BOUND_CONJUNCTION: {
		auto &conj_expr = (BoundConjunctionExpression &)expr;
		return ExpressionCost(conj_expr);
	}
	case ExpressionClass::BOUND_FUNCTION: {
		auto &func_expr = (BoundFunctionExpression &)expr;
		return ExpressionCost(func_expr);
	}
	case ExpressionClass::BOUND_OPERATOR: {
		auto &op_expr = (BoundOperatorExpression &)expr;
		return ExpressionCost(op_expr, expr.type);
	}
	case ExpressionClass::BOUND_COLUMN_REF: {
		auto &col_expr = (BoundColumnRefExpression &)expr;
		return ExpressionCost(col_expr.return_type, 8);
	}
	case ExpressionClass::BOUND_CONSTANT: {
		auto &const_expr = (BoundConstantExpression &)expr;
		return ExpressionCost(const_expr.return_type, 1);
	}
	case ExpressionClass::BOUND_PARAMETER: {
		auto &const_expr = (BoundConstantExpression &)expr;
		return ExpressionCost(const_expr.return_type, 1);
	}
	case ExpressionClass::BOUND_REF: {
		auto &col_expr = (BoundColumnRefExpression &)expr;
		return ExpressionCost(col_expr.return_type, 8);
	}
	default: {
		break;
	}
	}

	// return a very high value if nothing matches
	return 1000;
}






using namespace duckdb;
using namespace std;

unique_ptr<Expression> ExpressionRewriter::ApplyRules(LogicalOperator &op, const vector<Rule *> &rules,
                                                      unique_ptr<Expression> expr, bool &changes_made) {
	for (auto &rule : rules) {
		vector<Expression *> bindings;
		if (rule->root->Match(expr.get(), bindings)) {
			// the rule matches! try to apply it
			bool rule_made_change = false;
			auto result = rule->Apply(op, bindings, rule_made_change);
			if (result) {
				changes_made = true;
				// the base node changed: the rule applied changes
				// rerun on the new node
				return ExpressionRewriter::ApplyRules(op, rules, move(result), changes_made);
			} else if (rule_made_change) {
				changes_made = true;
				// the base node didn't change, but changes were made, rerun
				return expr;
			}
			// else nothing changed, continue to the next rule
			continue;
		}
	}
	// no changes could be made to this node
	// recursively run on the children of this node
	ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		return ExpressionRewriter::ApplyRules(op, rules, move(child), changes_made);
	});
	return expr;
}

void ExpressionRewriter::Apply(LogicalOperator &root) {
	// first apply the rules to child operators of this node (if any)
	for (auto &child : root.children) {
		Apply(*child);
	}
	// apply the rules to this node
	if (root.expressions.size() == 0) {
		// no expressions to apply rules on: return
		return;
	}
	vector<Rule *> to_apply_rules;
	for (auto &rule : rules) {
		if (rule->logical_root && !rule->logical_root->Match(root.type)) {
			// this rule does not apply to this type of LogicalOperator
			continue;
		}
		to_apply_rules.push_back(rule.get());
	}
	if (to_apply_rules.size() == 0) {
		// no rules to apply on this node
		return;
	}
	for (idx_t i = 0; i < root.expressions.size(); i++) {
		bool changes_made;
		do {
			changes_made = false;
			root.expressions[i] =
			    ExpressionRewriter::ApplyRules(root, to_apply_rules, move(root.expressions[i]), changes_made);
		} while (changes_made);
	}

	// if it is a LogicalFilter, we split up filter conjunctions again
	if (root.type == LogicalOperatorType::FILTER) {
		auto &filter = (LogicalFilter &)root;
		filter.SplitPredicates();
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/filter_combiner.hpp
//
//
//===----------------------------------------------------------------------===//









#include <functional>

namespace duckdb {

enum class ValueComparisonResult { PRUNE_LEFT, PRUNE_RIGHT, UNSATISFIABLE_CONDITION, PRUNE_NOTHING };
enum class FilterResult { UNSATISFIABLE, SUCCESS, UNSUPPORTED };

//! The FilterCombiner combines several filters and generates a logically equivalent set that is more efficient
//! Amongst others:
//! (1) it prunes obsolete filter conditions: i.e. [X > 5 and X > 7] => [X > 7]
//! (2) it generates new filters for expressions in the same equivalence set: i.e. [X = Y and X = 500] => [Y = 500]
//! (3) it prunes branches that have unsatisfiable filters: i.e. [X = 5 AND X > 6] => FALSE, prune branch
class FilterCombiner {
public:
	struct ExpressionValueInformation {
		Value constant;
		ExpressionType comparison_type;
	};

	FilterResult AddFilter(unique_ptr<Expression> expr);

	void GenerateFilters(std::function<void(unique_ptr<Expression> filter)> callback);
	bool HasFilters();
	vector<TableFilter> GenerateTableScanFilters(std::function<void(unique_ptr<Expression> filter)> callback,
	                                             vector<idx_t> &column_ids);

private:
	FilterResult AddFilter(Expression *expr);

	Expression *GetNode(Expression *expr);
	idx_t GetEquivalenceSet(Expression *expr);
	FilterResult AddConstantComparison(vector<ExpressionValueInformation> &info_list, ExpressionValueInformation info);

	vector<unique_ptr<Expression>> remaining_filters;

	expression_map_t<unique_ptr<Expression>> stored_expressions;
	unordered_map<Expression *, idx_t> equivalence_set_map;
	unordered_map<idx_t, vector<ExpressionValueInformation>> constant_values;
	unordered_map<idx_t, vector<Expression *>> equivalence_map;
	idx_t set_index = 0;
};

} // namespace duckdb










using namespace duckdb;
using namespace std;

using ExpressionValueInformation = FilterCombiner::ExpressionValueInformation;

ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, ExpressionValueInformation &right);

Expression *FilterCombiner::GetNode(Expression *expr) {
	auto entry = stored_expressions.find(expr);
	if (entry != stored_expressions.end()) {
		// expression already exists: return a reference to the stored expression
		return entry->second.get();
	}
	// expression does not exist yet: create a copy and store it
	auto copy = expr->Copy();
	auto pointer_copy = copy.get();
	stored_expressions.insert(make_pair(pointer_copy, move(copy)));
	return pointer_copy;
}

idx_t FilterCombiner::GetEquivalenceSet(Expression *expr) {
	assert(stored_expressions.find(expr) != stored_expressions.end());
	assert(stored_expressions.find(expr)->second.get() == expr);

	auto entry = equivalence_set_map.find(expr);
	if (entry == equivalence_set_map.end()) {
		idx_t index = set_index++;
		equivalence_set_map[expr] = index;
		equivalence_map[index].push_back(expr);
		constant_values.insert(make_pair(index, vector<ExpressionValueInformation>()));
		return index;
	} else {
		return entry->second;
	}
}

FilterResult FilterCombiner::AddConstantComparison(vector<ExpressionValueInformation> &info_list,
                                                   ExpressionValueInformation info) {
	for (idx_t i = 0; i < info_list.size(); i++) {
		auto comparison = CompareValueInformation(info_list[i], info);
		switch (comparison) {
		case ValueComparisonResult::PRUNE_LEFT:
			// prune the entry from the info list
			info_list.erase(info_list.begin() + i);
			i--;
			break;
		case ValueComparisonResult::PRUNE_RIGHT:
			// prune the current info
			return FilterResult::SUCCESS;
		case ValueComparisonResult::UNSATISFIABLE_CONDITION:
			// combination of filters is unsatisfiable: prune the entire branch
			return FilterResult::UNSATISFIABLE;
		default:
			// prune nothing, move to the next condition
			break;
		}
	}
	// finally add the entry to the list
	info_list.push_back(info);
	return FilterResult::SUCCESS;
}

FilterResult FilterCombiner::AddFilter(unique_ptr<Expression> expr) {
	// try to push the filter into the combiner
	auto result = AddFilter(expr.get());
	if (result == FilterResult::UNSUPPORTED) {
		// unsupported filter, push into remaining filters
		remaining_filters.push_back(move(expr));
		return FilterResult::SUCCESS;
	}
	return result;
}

void FilterCombiner::GenerateFilters(std::function<void(unique_ptr<Expression> filter)> callback) {
	// first loop over the remaining filters
	for (auto &filter : remaining_filters) {
		callback(move(filter));
	}
	remaining_filters.clear();
	// now loop over the equivalence sets
	for (auto &entry : equivalence_map) {
		auto equivalence_set = entry.first;
		auto &entries = entry.second;
		auto &constant_list = constant_values.find(equivalence_set)->second;
		// for each entry generate an equality expression comparing to each other
		for (idx_t i = 0; i < entries.size(); i++) {
			for (idx_t k = i + 1; k < entries.size(); k++) {
				auto comparison = make_unique<BoundComparisonExpression>(ExpressionType::COMPARE_EQUAL,
				                                                         entries[i]->Copy(), entries[k]->Copy());
				callback(move(comparison));
			}
			// for each entry also create a comparison with each constant
			int lower_index = -1, upper_index = -1;
			bool lower_inclusive, upper_inclusive;
			for (idx_t k = 0; k < constant_list.size(); k++) {
				auto &info = constant_list[k];
				if (info.comparison_type == ExpressionType::COMPARE_GREATERTHAN ||
				    info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) {
					lower_index = k;
					lower_inclusive = info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO;
				} else if (info.comparison_type == ExpressionType::COMPARE_LESSTHAN ||
				           info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) {
					upper_index = k;
					upper_inclusive = info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO;
				} else {
					auto constant = make_unique<BoundConstantExpression>(info.constant);
					auto comparison = make_unique<BoundComparisonExpression>(info.comparison_type, entries[i]->Copy(),
					                                                         move(constant));
					callback(move(comparison));
				}
			}
			if (lower_index >= 0 && upper_index >= 0) {
				// found both lower and upper index, create a BETWEEN expression
				auto lower_constant = make_unique<BoundConstantExpression>(constant_list[lower_index].constant);
				auto upper_constant = make_unique<BoundConstantExpression>(constant_list[upper_index].constant);
				auto between = make_unique<BoundBetweenExpression>(
				    entries[i]->Copy(), move(lower_constant), move(upper_constant), lower_inclusive, upper_inclusive);
				callback(move(between));
			} else if (lower_index >= 0) {
				// only lower index found, create simple comparison expression
				auto constant = make_unique<BoundConstantExpression>(constant_list[lower_index].constant);
				auto comparison = make_unique<BoundComparisonExpression>(constant_list[lower_index].comparison_type,
				                                                         entries[i]->Copy(), move(constant));
				callback(move(comparison));
			} else if (upper_index >= 0) {
				// only upper index found, create simple comparison expression
				auto constant = make_unique<BoundConstantExpression>(constant_list[upper_index].constant);
				auto comparison = make_unique<BoundComparisonExpression>(constant_list[upper_index].comparison_type,
				                                                         entries[i]->Copy(), move(constant));
				callback(move(comparison));
			}
		}
	}
	stored_expressions.clear();
	equivalence_set_map.clear();
	constant_values.clear();
	equivalence_map.clear();
}

bool FilterCombiner::HasFilters() {
	bool has_filters = false;
	GenerateFilters([&](unique_ptr<Expression> child) { has_filters = true; });
	return has_filters;
}

vector<TableFilter>
FilterCombiner::GenerateTableScanFilters(std::function<void(unique_ptr<Expression> filter)> callback,
                                         vector<idx_t> &column_ids) {
	vector<TableFilter> tableFilters;
	//! First, we figure the filters that have constant expressions that we can push down to the table scan
	for (auto &constant_value : constant_values) {
		if (constant_value.second.size() > 0) {
			for (idx_t i = 0; i < constant_value.second.size(); ++i) {
				if ((constant_value.second[i].comparison_type == ExpressionType::COMPARE_EQUAL ||
				     constant_value.second[i].comparison_type == ExpressionType::COMPARE_GREATERTHAN ||
				     constant_value.second[i].comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO ||
				     constant_value.second[i].comparison_type == ExpressionType::COMPARE_LESSTHAN ||
				     constant_value.second[i].comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) &&
				    TypeIsNumeric(constant_value.second[i].constant.type)) {
					//! Here we check if these filters are column references
					auto filter_exp = equivalence_map.find(constant_value.first);
					if (filter_exp->second.size() == 1 &&
					    filter_exp->second[0]->type == ExpressionType::BOUND_COLUMN_REF) {
						auto filter_col_exp = static_cast<BoundColumnRefExpression *>(filter_exp->second[0]);
						if (column_ids[filter_col_exp->binding.column_index] == COLUMN_IDENTIFIER_ROW_ID) {
							break;
						}
						tableFilters.push_back(TableFilter(constant_value.second[i].constant,
						                                   constant_value.second[i].comparison_type,
						                                   filter_col_exp->binding.column_index));
						auto equivalence_set = filter_exp->first;
						auto &entries = filter_exp->second;
						auto &constant_list = constant_values.find(equivalence_set)->second;
						// for each entry generate an equality expression comparing to each other
						for (idx_t i = 0; i < entries.size(); i++) {
							for (idx_t k = i + 1; k < entries.size(); k++) {
								auto comparison = make_unique<BoundComparisonExpression>(
								    ExpressionType::COMPARE_EQUAL, entries[i]->Copy(), entries[k]->Copy());
								callback(move(comparison));
							}
							// for each entry also create a comparison with each constant
							int lower_index = -1, upper_index = -1;
							bool lower_inclusive, upper_inclusive;
							for (idx_t k = 0; k < constant_list.size(); k++) {
								auto &info = constant_list[k];
								if (info.comparison_type == ExpressionType::COMPARE_GREATERTHAN ||
								    info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) {
									lower_index = k;
									lower_inclusive =
									    info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO;
								} else if (info.comparison_type == ExpressionType::COMPARE_LESSTHAN ||
								           info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) {
									upper_index = k;
									upper_inclusive = info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO;
								} else {
									auto constant = make_unique<BoundConstantExpression>(info.constant);
									auto comparison = make_unique<BoundComparisonExpression>(
									    info.comparison_type, entries[i]->Copy(), move(constant));
									callback(move(comparison));
								}
							}
							if (lower_index >= 0 && upper_index >= 0) {
								// found both lower and upper index, create a BETWEEN expression
								auto lower_constant =
								    make_unique<BoundConstantExpression>(constant_list[lower_index].constant);
								auto upper_constant =
								    make_unique<BoundConstantExpression>(constant_list[upper_index].constant);
								auto between = make_unique<BoundBetweenExpression>(
								    entries[i]->Copy(), move(lower_constant), move(upper_constant), lower_inclusive,
								    upper_inclusive);
								callback(move(between));
							} else if (lower_index >= 0) {
								// only lower index found, create simple comparison expression
								auto constant =
								    make_unique<BoundConstantExpression>(constant_list[lower_index].constant);
								auto comparison = make_unique<BoundComparisonExpression>(
								    constant_list[lower_index].comparison_type, entries[i]->Copy(), move(constant));
								callback(move(comparison));
							} else if (upper_index >= 0) {
								// only upper index found, create simple comparison expression
								auto constant =
								    make_unique<BoundConstantExpression>(constant_list[upper_index].constant);
								auto comparison = make_unique<BoundComparisonExpression>(
								    constant_list[upper_index].comparison_type, entries[i]->Copy(), move(constant));
								callback(move(comparison));
							}
						}
						equivalence_map.erase(filter_exp);
					}
				}
			}
		}
	}
	return tableFilters;
}

FilterResult FilterCombiner::AddFilter(Expression *expr) {
	if (expr->HasParameter()) {
		return FilterResult::UNSUPPORTED;
	}
	if (expr->IsFoldable()) {
		// scalar condition, evaluate it
		auto result = ExpressionExecutor::EvaluateScalar(*expr).CastAs(TypeId::BOOL);
		// check if the filter passes
		if (result.is_null || !result.value_.boolean) {
			// the filter does not pass the scalar test, create an empty result
			return FilterResult::UNSATISFIABLE;
		} else {
			// the filter passes the scalar test, just remove the condition
			return FilterResult::SUCCESS;
		}
	}
	assert(!expr->IsFoldable());
	if (expr->GetExpressionClass() != ExpressionClass::BOUND_COMPARISON) {
		// only comparisons supported for now
		return FilterResult::UNSUPPORTED;
	}
	auto &comparison = (BoundComparisonExpression &)*expr;
	if (comparison.type != ExpressionType::COMPARE_LESSTHAN &&
	    comparison.type != ExpressionType::COMPARE_LESSTHANOREQUALTO &&
	    comparison.type != ExpressionType::COMPARE_GREATERTHAN &&
	    comparison.type != ExpressionType::COMPARE_GREATERTHANOREQUALTO &&
	    comparison.type != ExpressionType::COMPARE_EQUAL && comparison.type != ExpressionType::COMPARE_NOTEQUAL) {
		// only support [>, >=, <, <=, ==] expressions
		return FilterResult::UNSUPPORTED;
	}
	// check if one of the sides is a scalar value
	bool left_is_scalar = comparison.left->IsFoldable();
	bool right_is_scalar = comparison.right->IsFoldable();
	if (left_is_scalar || right_is_scalar) {
		// comparison with scalar
		auto node = GetNode(left_is_scalar ? comparison.right.get() : comparison.left.get());
		idx_t equivalence_set = GetEquivalenceSet(node);
		auto scalar = left_is_scalar ? comparison.left.get() : comparison.right.get();
		auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar);

		// create the ExpressionValueInformation
		ExpressionValueInformation info;
		info.comparison_type = left_is_scalar ? FlipComparisionExpression(comparison.type) : comparison.type;
		info.constant = constant_value;

		// get the current bucket of constant values
		assert(constant_values.find(equivalence_set) != constant_values.end());
		auto &info_list = constant_values.find(equivalence_set)->second;
		// check the existing constant comparisons to see if we can do any pruning
		return AddConstantComparison(info_list, info);
	} else {
		// comparison between two non-scalars
		// only handle comparisons for now
		if (expr->type != ExpressionType::COMPARE_EQUAL) {
			return FilterResult::UNSUPPORTED;
		}
		// get the LHS and RHS nodes
		auto left_node = GetNode(comparison.left.get());
		auto right_node = GetNode(comparison.right.get());
		// get the equivalence sets of the LHS and RHS
		auto left_equivalence_set = GetEquivalenceSet(left_node);
		auto right_equivalence_set = GetEquivalenceSet(right_node);
		if (left_equivalence_set == right_equivalence_set) {
			// this equality filter already exists, prune it
			return FilterResult::SUCCESS;
		}
		// add the right bucket into the left bucket
		assert(equivalence_map.find(left_equivalence_set) != equivalence_map.end());
		assert(equivalence_map.find(right_equivalence_set) != equivalence_map.end());

		auto &left_bucket = equivalence_map.find(left_equivalence_set)->second;
		auto &right_bucket = equivalence_map.find(right_equivalence_set)->second;
		for (idx_t i = 0; i < right_bucket.size(); i++) {
			// rewrite the equivalence set mapping for this node
			equivalence_set_map[right_bucket[i]] = left_equivalence_set;
			// add the node to the left bucket
			left_bucket.push_back(right_bucket[i]);
		}
		// now add all constant values from the right bucket to the left bucket
		assert(constant_values.find(left_equivalence_set) != constant_values.end());
		assert(constant_values.find(right_equivalence_set) != constant_values.end());
		auto &left_constant_bucket = constant_values.find(left_equivalence_set)->second;
		auto &right_constant_bucket = constant_values.find(right_equivalence_set)->second;
		for (idx_t i = 0; i < right_constant_bucket.size(); i++) {
			if (AddConstantComparison(left_constant_bucket, right_constant_bucket[i]) == FilterResult::UNSATISFIABLE) {
				return FilterResult::UNSATISFIABLE;
			}
		}
	}
	return FilterResult::SUCCESS;
}

static bool IsGreaterThan(ExpressionType type) {
	return type == ExpressionType::COMPARE_GREATERTHAN || type == ExpressionType::COMPARE_GREATERTHANOREQUALTO;
}

static bool IsLessThan(ExpressionType type) {
	return type == ExpressionType::COMPARE_LESSTHAN || type == ExpressionType::COMPARE_LESSTHANOREQUALTO;
}

ValueComparisonResult InvertValueComparisonResult(ValueComparisonResult result) {
	if (result == ValueComparisonResult::PRUNE_RIGHT) {
		return ValueComparisonResult::PRUNE_LEFT;
	}
	if (result == ValueComparisonResult::PRUNE_LEFT) {
		return ValueComparisonResult::PRUNE_RIGHT;
	}
	return result;
}

ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, ExpressionValueInformation &right) {
	if (left.comparison_type == ExpressionType::COMPARE_EQUAL) {
		// left is COMPARE_EQUAL, we can either
		// (1) prune the right side or
		// (2) return UNSATISFIABLE
		bool prune_right_side = false;
		switch (right.comparison_type) {
		case ExpressionType::COMPARE_LESSTHAN:
			prune_right_side = left.constant < right.constant;
			break;
		case ExpressionType::COMPARE_LESSTHANOREQUALTO:
			prune_right_side = left.constant <= right.constant;
			break;
		case ExpressionType::COMPARE_GREATERTHAN:
			prune_right_side = left.constant > right.constant;
			break;
		case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
			prune_right_side = left.constant >= right.constant;
			break;
		case ExpressionType::COMPARE_NOTEQUAL:
			prune_right_side = left.constant != right.constant;
			break;
		default:
			assert(right.comparison_type == ExpressionType::COMPARE_EQUAL);
			prune_right_side = left.constant == right.constant;
			break;
		}
		if (prune_right_side) {
			return ValueComparisonResult::PRUNE_RIGHT;
		} else {
			return ValueComparisonResult::UNSATISFIABLE_CONDITION;
		}
	} else if (right.comparison_type == ExpressionType::COMPARE_EQUAL) {
		// right is COMPARE_EQUAL
		return InvertValueComparisonResult(CompareValueInformation(right, left));
	} else if (left.comparison_type == ExpressionType::COMPARE_NOTEQUAL) {
		// left is COMPARE_NOTEQUAL, we can either
		// (1) prune the left side or
		// (2) not prune anything
		bool prune_left_side = false;
		switch (right.comparison_type) {
		case ExpressionType::COMPARE_LESSTHAN:
			prune_left_side = left.constant >= right.constant;
			break;
		case ExpressionType::COMPARE_LESSTHANOREQUALTO:
			prune_left_side = left.constant > right.constant;
			break;
		case ExpressionType::COMPARE_GREATERTHAN:
			prune_left_side = left.constant <= right.constant;
			break;
		case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
			prune_left_side = left.constant < right.constant;
			break;
		default:
			assert(right.comparison_type == ExpressionType::COMPARE_NOTEQUAL);
			prune_left_side = left.constant == right.constant;
			break;
		}
		if (prune_left_side) {
			return ValueComparisonResult::PRUNE_LEFT;
		} else {
			return ValueComparisonResult::PRUNE_NOTHING;
		}
	} else if (right.comparison_type == ExpressionType::COMPARE_NOTEQUAL) {
		return InvertValueComparisonResult(CompareValueInformation(right, left));
	} else if (IsGreaterThan(left.comparison_type) && IsGreaterThan(right.comparison_type)) {
		// both comparisons are [>], we can either
		// (1) prune the left side or
		// (2) prune the right side
		if (left.constant > right.constant) {
			// left constant is more selective, prune right
			return ValueComparisonResult::PRUNE_RIGHT;
		} else if (left.constant < right.constant) {
			// right constant is more selective, prune left
			return ValueComparisonResult::PRUNE_LEFT;
		} else {
			// constants are equivalent
			// however we can still have the scenario where one is [>=] and the other is [>]
			// we want to prune the [>=] because [>] is more selective
			// if left is [>=] we prune the left, else we prune the right
			if (left.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) {
				return ValueComparisonResult::PRUNE_LEFT;
			} else {
				return ValueComparisonResult::PRUNE_RIGHT;
			}
		}
	} else if (IsLessThan(left.comparison_type) && IsLessThan(right.comparison_type)) {
		// both comparisons are [<], we can either
		// (1) prune the left side or
		// (2) prune the right side
		if (left.constant < right.constant) {
			// left constant is more selective, prune right
			return ValueComparisonResult::PRUNE_RIGHT;
		} else if (left.constant > right.constant) {
			// right constant is more selective, prune left
			return ValueComparisonResult::PRUNE_LEFT;
		} else {
			// constants are equivalent
			// however we can still have the scenario where one is [<=] and the other is [<]
			// we want to prune the [<=] because [<] is more selective
			// if left is [<=] we prune the left, else we prune the right
			if (left.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) {
				return ValueComparisonResult::PRUNE_LEFT;
			} else {
				return ValueComparisonResult::PRUNE_RIGHT;
			}
		}
	} else if (IsLessThan(left.comparison_type)) {
		assert(IsGreaterThan(right.comparison_type));
		// left is [<] and right is [>], in this case we can either
		// (1) prune nothing or
		// (2) return UNSATISFIABLE
		// the SMALLER THAN constant has to be greater than the BIGGER THAN constant
		if (left.constant >= right.constant) {
			return ValueComparisonResult::PRUNE_NOTHING;
		} else {
			return ValueComparisonResult::UNSATISFIABLE_CONDITION;
		}
	} else {
		// left is [>] and right is [<] or [!=]
		assert(IsLessThan(right.comparison_type) && IsGreaterThan(left.comparison_type));
		return InvertValueComparisonResult(CompareValueInformation(right, left));
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/filter_pushdown.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class Optimizer;

class FilterPushdown {
public:
	FilterPushdown(Optimizer &optimizer) : optimizer(optimizer) {
	}
	//! Perform filter pushdown
	unique_ptr<LogicalOperator> Rewrite(unique_ptr<LogicalOperator> node);

	struct Filter {
		unordered_set<idx_t> bindings;
		unique_ptr<Expression> filter;

		Filter() {
		}
		Filter(unique_ptr<Expression> filter) : filter(move(filter)) {
		}

		void ExtractBindings();
	};

private:
	vector<unique_ptr<Filter>> filters;
	Optimizer &optimizer;

	//! Push down a LogicalAggregate op
	unique_ptr<LogicalOperator> PushdownAggregate(unique_ptr<LogicalOperator> op);
	//! Push down a LogicalFilter op
	unique_ptr<LogicalOperator> PushdownFilter(unique_ptr<LogicalOperator> op);
	//! Push down a LogicalCrossProduct op
	unique_ptr<LogicalOperator> PushdownCrossProduct(unique_ptr<LogicalOperator> op);
	//! Push down a join operator
	unique_ptr<LogicalOperator> PushdownJoin(unique_ptr<LogicalOperator> op);
	//! Push down a LogicalProjection op
	unique_ptr<LogicalOperator> PushdownProjection(unique_ptr<LogicalOperator> op);
	//! Push down a LogicalSetOperation op
	unique_ptr<LogicalOperator> PushdownSetOperation(unique_ptr<LogicalOperator> op);
	//! Push down a LogicalGet op
	unique_ptr<LogicalOperator> PushdownGet(unique_ptr<LogicalOperator> op);
	// Pushdown an inner join
	unique_ptr<LogicalOperator> PushdownInnerJoin(unique_ptr<LogicalOperator> op, unordered_set<idx_t> &left_bindings,
	                                              unordered_set<idx_t> &right_bindings);
	// Pushdown a left join
	unique_ptr<LogicalOperator> PushdownLeftJoin(unique_ptr<LogicalOperator> op, unordered_set<idx_t> &left_bindings,
	                                             unordered_set<idx_t> &right_bindings);
	// Pushdown a mark join
	unique_ptr<LogicalOperator> PushdownMarkJoin(unique_ptr<LogicalOperator> op, unordered_set<idx_t> &left_bindings,
	                                             unordered_set<idx_t> &right_bindings);
	// Pushdown a single join
	unique_ptr<LogicalOperator> PushdownSingleJoin(unique_ptr<LogicalOperator> op, unordered_set<idx_t> &left_bindings,
	                                               unordered_set<idx_t> &right_bindings);

	// Finish pushing down at this operator, creating a LogicalFilter to store any of the stored filters and recursively
	// pushing down into its children (if any)
	unique_ptr<LogicalOperator> FinishPushdown(unique_ptr<LogicalOperator> op);
	//! Adds a filter to the set of filters. Returns FilterResult::UNSATISFIABLE if the subtree should be stripped, or
	//! FilterResult::SUCCESS otherwise
	FilterResult AddFilter(unique_ptr<Expression> expr);
	//! Generate filters from the current set of filters stored in the FilterCombiner
	void GenerateFilters();
	//! if there are filters in this FilterPushdown node, push them into the combiner
	void PushFilters();

	FilterCombiner combiner;
};

} // namespace duckdb






using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

unique_ptr<LogicalOperator> FilterPushdown::Rewrite(unique_ptr<LogicalOperator> op) {
	assert(!combiner.HasFilters());
	switch (op->type) {
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY:
		return PushdownAggregate(move(op));
	case LogicalOperatorType::FILTER:
		return PushdownFilter(move(op));
	case LogicalOperatorType::CROSS_PRODUCT:
		return PushdownCrossProduct(move(op));
	case LogicalOperatorType::COMPARISON_JOIN:
	case LogicalOperatorType::ANY_JOIN:
	case LogicalOperatorType::DELIM_JOIN:
		return PushdownJoin(move(op));
	case LogicalOperatorType::PROJECTION:
		return PushdownProjection(move(op));
	case LogicalOperatorType::INTERSECT:
	case LogicalOperatorType::EXCEPT:
	case LogicalOperatorType::UNION:
		return PushdownSetOperation(move(op));
	case LogicalOperatorType::DISTINCT:
	case LogicalOperatorType::ORDER_BY:
	case LogicalOperatorType::PRUNE_COLUMNS: {
		// we can just push directly through these operations without any rewriting
		op->children[0] = Rewrite(move(op->children[0]));
		return op;
	}
	case LogicalOperatorType::GET:
		return PushdownGet(move(op));
	default:
		return FinishPushdown(move(op));
	}
}

unique_ptr<LogicalOperator> FilterPushdown::PushdownJoin(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::COMPARISON_JOIN || op->type == LogicalOperatorType::ANY_JOIN ||
	       op->type == LogicalOperatorType::DELIM_JOIN);
	auto &join = (LogicalJoin &)*op;
	unordered_set<idx_t> left_bindings, right_bindings;
	LogicalJoin::GetTableReferences(*op->children[0], left_bindings);
	LogicalJoin::GetTableReferences(*op->children[1], right_bindings);

	switch (join.join_type) {
	case JoinType::INNER:
		return PushdownInnerJoin(move(op), left_bindings, right_bindings);
	case JoinType::LEFT:
		return PushdownLeftJoin(move(op), left_bindings, right_bindings);
	case JoinType::MARK:
		return PushdownMarkJoin(move(op), left_bindings, right_bindings);
	case JoinType::SINGLE:
		return PushdownSingleJoin(move(op), left_bindings, right_bindings);
	default:
		// unsupported join type: stop pushing down
		return FinishPushdown(move(op));
	}
}
void FilterPushdown::PushFilters() {
	for (auto &f : filters) {
		auto result = combiner.AddFilter(move(f->filter));
		assert(result == FilterResult::SUCCESS);
	}
	filters.clear();
}
FilterResult FilterPushdown::AddFilter(unique_ptr<Expression> expr) {
	PushFilters();
	// split up the filters by AND predicate
	vector<unique_ptr<Expression>> expressions;
	expressions.push_back(move(expr));
	LogicalFilter::SplitPredicates(expressions);
	// push the filters into the combiner
	for (auto &expr : expressions) {
		if (combiner.AddFilter(move(expr)) == FilterResult::UNSATISFIABLE) {
			return FilterResult::UNSATISFIABLE;
		}
	}
	return FilterResult::SUCCESS;
}

void FilterPushdown::GenerateFilters() {
	if (filters.size() > 0) {
		assert(!combiner.HasFilters());
		return;
	}
	combiner.GenerateFilters([&](unique_ptr<Expression> filter) {
		auto f = make_unique<Filter>();
		f->filter = move(filter);
		f->ExtractBindings();
		filters.push_back(move(f));
	});
}

unique_ptr<LogicalOperator> FilterPushdown::FinishPushdown(unique_ptr<LogicalOperator> op) {
	// unhandled type, first perform filter pushdown in its children
	for (idx_t i = 0; i < op->children.size(); i++) {
		FilterPushdown pushdown(optimizer);
		op->children[i] = pushdown.Rewrite(move(op->children[i]));
	}
	// now push any existing filters
	if (filters.size() == 0) {
		// no filters to push
		return op;
	}
	auto filter = make_unique<LogicalFilter>();
	for (auto &f : filters) {
		filter->expressions.push_back(move(f->filter));
	}
	filter->children.push_back(move(op));
	return move(filter);
}

void FilterPushdown::Filter::ExtractBindings() {
	bindings.clear();
	LogicalJoin::GetExpressionBindings(*filter, bindings);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/in_clause_rewriter.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class Optimizer;

class InClauseRewriter : public LogicalOperatorVisitor {
public:
	InClauseRewriter(Optimizer &optimizer) : optimizer(optimizer) {
	}

	Optimizer &optimizer;
	unique_ptr<LogicalOperator> root;

public:
	unique_ptr<LogicalOperator> Rewrite(unique_ptr<LogicalOperator> op);

	unique_ptr<Expression> VisitReplace(BoundOperatorExpression &expr, unique_ptr<Expression> *expr_ptr) override;
};

} // namespace duckdb










namespace duckdb {

unique_ptr<LogicalOperator> InClauseRewriter::Rewrite(unique_ptr<LogicalOperator> op) {
	if (op->children.size() == 1) {
		root = move(op->children[0]);
		VisitOperatorExpressions(*op);
		op->children[0] = move(root);
	}

	for (auto &child : op->children) {
		child = Rewrite(move(child));
	}
	return op;
}

unique_ptr<Expression> InClauseRewriter::VisitReplace(BoundOperatorExpression &expr, unique_ptr<Expression> *expr_ptr) {
	if (expr.type != ExpressionType::COMPARE_IN && expr.type != ExpressionType::COMPARE_NOT_IN) {
		return nullptr;
	}
	assert(root);
	auto in_type = expr.children[0]->return_type;
	bool is_regular_in = expr.type == ExpressionType::COMPARE_IN;
	bool all_scalar = true;
	// IN clause with many children: try to generate a mark join that replaces this IN expression
	// we can only do this if the expressions in the expression list are scalar
	for (idx_t i = 1; i < expr.children.size(); i++) {
		assert(expr.children[i]->return_type == in_type);
		if (!expr.children[i]->IsFoldable()) {
			// non-scalar expression
			all_scalar = false;
		}
	}
	if (expr.children.size() == 2) {
		// only one child
		// IN: turn into X = 1
		// NOT IN: turn into X <> 1
		return make_unique<BoundComparisonExpression>(is_regular_in ? ExpressionType::COMPARE_EQUAL
		                                                            : ExpressionType::COMPARE_NOTEQUAL,
		                                              move(expr.children[0]), move(expr.children[1]));
	}
	if (expr.children.size() < 6 || !all_scalar) {
		// low amount of children or not all scalar
		// IN: turn into (X = 1 OR X = 2 OR X = 3...)
		// NOT IN: turn into (X <> 1 AND X <> 2 AND X <> 3 ...)
		auto conjunction = make_unique<BoundConjunctionExpression>(is_regular_in ? ExpressionType::CONJUNCTION_OR
		                                                                         : ExpressionType::CONJUNCTION_AND);
		for (idx_t i = 1; i < expr.children.size(); i++) {
			conjunction->children.push_back(make_unique<BoundComparisonExpression>(
			    is_regular_in ? ExpressionType::COMPARE_EQUAL : ExpressionType::COMPARE_NOTEQUAL,
			    expr.children[0]->Copy(), move(expr.children[i])));
		}
		return move(conjunction);
	}
	// IN clause with many constant children
	// generate a mark join that replaces this IN expression
	// first generate a ChunkCollection from the set of expressions
	vector<TypeId> types = {in_type};
	auto collection = make_unique<ChunkCollection>();
	DataChunk chunk;
	chunk.Initialize(types);
	for (idx_t i = 1; i < expr.children.size(); i++) {
		// reoslve this expression to a constant
		auto value = ExpressionExecutor::EvaluateScalar(*expr.children[i]);
		idx_t index = chunk.size();
		chunk.SetCardinality(chunk.size() + 1);
		chunk.SetValue(0, index, value);
		if (chunk.size() == STANDARD_VECTOR_SIZE || i + 1 == expr.children.size()) {
			// chunk full: append to chunk collection
			collection->Append(chunk);
			chunk.Reset();
		}
	}
	// now generate a ChunkGet that scans this collection
	auto chunk_index = optimizer.binder.GenerateTableIndex();
	auto chunk_scan = make_unique<LogicalChunkGet>(chunk_index, types, move(collection));

	// then we generate the MARK join with the chunk scan on the RHS
	auto join = make_unique<LogicalComparisonJoin>(JoinType::MARK);
	join->mark_index = chunk_index;
	join->AddChild(move(root));
	join->AddChild(move(chunk_scan));
	// create the JOIN condition
	JoinCondition cond;
	cond.left = move(expr.children[0]);

	cond.right = make_unique<BoundColumnRefExpression>(in_type, ColumnBinding(chunk_index, 0));
	cond.comparison = ExpressionType::COMPARE_EQUAL;
	join->conditions.push_back(move(cond));
	root = move(join);

	// we replace the original subquery with a BoundColumnRefExpression refering to the mark column
	unique_ptr<Expression> result =
	    make_unique<BoundColumnRefExpression>("IN (...)", TypeId::BOOL, ColumnBinding(chunk_index, 0));
	if (!is_regular_in) {
		// NOT IN: invert
		auto invert = make_unique<BoundOperatorExpression>(ExpressionType::OPERATOR_NOT, TypeId::BOOL);
		invert->children.push_back(move(result));
		result = move(invert);
	}
	return result;
}

} // namespace duckdb
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/index_scan.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class Optimizer;

class IndexScan {
public:
	//! Optimize Filters in Index Scans
	unique_ptr<LogicalOperator> Optimize(unique_ptr<LogicalOperator> node);

private:
	//! Transform a Filter in an index scan
	unique_ptr<LogicalOperator> TransformFilterToIndexScan(unique_ptr<LogicalOperator> op);
};

} // namespace duckdb














using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> IndexScan::Optimize(unique_ptr<LogicalOperator> op) {
	if (op->type == LogicalOperatorType::FILTER && op->children[0]->type == LogicalOperatorType::GET) {
		return TransformFilterToIndexScan(move(op));
	}
	for (auto &child : op->children) {
		child = Optimize(move(child));
	}
	return op;
}

static void RewriteIndexExpression(Index &index, LogicalGet &get, Expression &expr, bool &rewrite_possible) {
	if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
		auto &bound_colref = (BoundColumnRefExpression &)expr;
		// bound column ref: rewrite to fit in the current set of bound column ids
		bound_colref.binding.table_index = get.table_index;
		column_t referenced_column = index.column_ids[bound_colref.binding.column_index];
		// search for the referenced column in the set of column_ids
		for (idx_t i = 0; i < get.column_ids.size(); i++) {
			if (get.column_ids[i] == referenced_column) {
				bound_colref.binding.column_index = i;
				return;
			}
		}
		// column id not found in bound columns in the LogicalGet: rewrite not possible
		rewrite_possible = false;
	}
	ExpressionIterator::EnumerateChildren(
	    expr, [&](Expression &child) { RewriteIndexExpression(index, get, child, rewrite_possible); });
}

unique_ptr<LogicalOperator> IndexScan::TransformFilterToIndexScan(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::FILTER);
	auto &filter = (LogicalFilter &)*op;
	auto get = (LogicalGet *)op->children[0].get();

	if (!get->table) {
		return op;
	}

	auto &storage = *get->table->storage;

	if (storage.indexes.size() == 0) {
		// no indexes on the table, can't rewrite
		return op;
	}

	// check all the indexes
	for (size_t j = 0; j < storage.indexes.size(); j++) {
		auto &index = storage.indexes[j];

		//		assert(index->unbound_expressions.size() == 1);
		// first rewrite the index expression so the ColumnBindings align with the column bindings of the current table
		if (index->unbound_expressions.size() > 1)
			continue;
		auto index_expression = index->unbound_expressions[0]->Copy();
		bool rewrite_possible = true;
		RewriteIndexExpression(*index, *get, *index_expression, rewrite_possible);
		if (!rewrite_possible) {
			// could not rewrite!
			continue;
		}

		Value low_value, high_value, equal_value;
		// try to find a matching index for any of the filter expressions
		auto expr = filter.expressions[0].get();
		auto low_comparison_type = expr->type;
		auto high_comparison_type = expr->type;
		for (idx_t i = 0; i < filter.expressions.size(); i++) {
			expr = filter.expressions[i].get();
			// create a matcher for a comparison with a constant
			ComparisonExpressionMatcher matcher;
			// match on a comparison type
			matcher.expr_type = make_unique<ComparisonExpressionTypeMatcher>();
			// match on a constant comparison with the indexed expression
			matcher.matchers.push_back(make_unique<ExpressionEqualityMatcher>(index_expression.get()));
			matcher.matchers.push_back(make_unique<ConstantExpressionMatcher>());

			matcher.policy = SetMatcher::Policy::UNORDERED;

			vector<Expression *> bindings;
			if (matcher.Match(expr, bindings)) {
				// range or equality comparison with constant value
				// we can use our index here
				// bindings[0] = the expression
				// bindings[1] = the index expression
				// bindings[2] = the constant
				auto comparison = (BoundComparisonExpression *)bindings[0];
				assert(bindings[0]->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON);
				assert(bindings[2]->type == ExpressionType::VALUE_CONSTANT);

				auto constant_value = ((BoundConstantExpression *)bindings[2])->value;
				auto comparison_type = comparison->type;
				if (comparison->left->type == ExpressionType::VALUE_CONSTANT) {
					// the expression is on the right side, we flip them around
					comparison_type = FlipComparisionExpression(comparison_type);
				}
				if (comparison_type == ExpressionType::COMPARE_EQUAL) {
					// equality value
					// equality overrides any other bounds so we just break here
					equal_value = constant_value;
					break;
				} else if (comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO ||
				           comparison_type == ExpressionType::COMPARE_GREATERTHAN) {
					// greater than means this is a lower bound
					low_value = constant_value;
					low_comparison_type = comparison_type;
				} else {
					// smaller than means this is an upper bound
					high_value = constant_value;
					high_comparison_type = comparison_type;
				}
			}
		}
		if (!equal_value.is_null || !low_value.is_null || !high_value.is_null) {
			auto logical_index_scan = make_unique<LogicalIndexScan>(*get->table, *get->table->storage, *index,
			                                                        get->column_ids, get->table_index);
			if (!equal_value.is_null) {
				logical_index_scan->equal_value = equal_value;
				logical_index_scan->equal_index = true;
			}
			if (!low_value.is_null) {
				logical_index_scan->low_value = low_value;
				logical_index_scan->low_index = true;
				logical_index_scan->low_expression_type = low_comparison_type;
			}
			if (!high_value.is_null) {
				logical_index_scan->high_value = high_value;
				logical_index_scan->high_index = true;
				logical_index_scan->high_expression_type = high_comparison_type;
			}
			op->children[0] = move(logical_index_scan);
			break;
		}
	}
	return op;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/join_order/query_graph.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/join_order/relation.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class LogicalOperator;

//! Represents a single relation and any metadata accompanying that relation
struct Relation {
	LogicalOperator *op;
	LogicalOperator *parent;

	Relation() {
	}
	Relation(LogicalOperator *op, LogicalOperator *parent) : op(op), parent(parent) {
	}
};

//! Set of relations, used in the join graph.
struct RelationSet {
	RelationSet(unique_ptr<idx_t[]> relations, idx_t count) : relations(move(relations)), count(count) {
	}

	string ToString() const;

	unique_ptr<idx_t[]> relations;
	idx_t count;

	static bool IsSubset(RelationSet *super, RelationSet *sub);
};

//! The RelationTree is a structure holding all the created RelationSet objects and allowing fast lookup on to them
class RelationSetManager {
public:
	//! Contains a node with a RelationSet and child relations
	// FIXME: this structure is inefficient, could use a bitmap for lookup instead (todo: profile)
	struct RelationTreeNode {
		unique_ptr<RelationSet> relation;
		unordered_map<idx_t, unique_ptr<RelationTreeNode>> children;
	};

public:
	//! Create or get a RelationSet from a single node with the given index
	RelationSet *GetRelation(idx_t index);
	//! Create or get a RelationSet from a set of relation bindings
	RelationSet *GetRelation(unordered_set<idx_t> &bindings);
	//! Create or get a RelationSet from a (sorted, duplicate-free!) list of relations
	RelationSet *GetRelation(unique_ptr<idx_t[]> relations, idx_t count);
	//! Union two sets of relations together and create a new relation set
	RelationSet *Union(RelationSet *left, RelationSet *right);
	//! Create the set difference of left \ right (i.e. all elements in left that are not in right)
	RelationSet *Difference(RelationSet *left, RelationSet *right);

private:
	RelationTreeNode root;
};

} // namespace duckdb


#include <functional>

namespace duckdb {
class Expression;
class LogicalOperator;

struct FilterInfo {
	idx_t filter_index;
	RelationSet *left_set = nullptr;
	RelationSet *right_set = nullptr;
	RelationSet *set = nullptr;
};

struct FilterNode {
	vector<FilterInfo *> filters;
	unordered_map<idx_t, unique_ptr<FilterNode>> children;
};

struct NeighborInfo {
	RelationSet *neighbor;
	vector<FilterInfo *> filters;
};

//! The QueryGraph contains edges between relations and allows edges to be created/queried
class QueryGraph {
public:
	//! Contains a node with info about neighboring relations and child edge infos
	struct QueryEdge {
		vector<unique_ptr<NeighborInfo>> neighbors;
		unordered_map<idx_t, unique_ptr<QueryEdge>> children;
	};

public:
	string ToString() const;
	void Print();

	//! Create an edge in the edge_set
	void CreateEdge(RelationSet *left, RelationSet *right, FilterInfo *info);
	//! Returns a connection if there is an edge that connects these two sets, or nullptr otherwise
	NeighborInfo *GetConnection(RelationSet *node, RelationSet *other);
	//! Enumerate the neighbors of a specific node that do not belong to any of the exclusion_set. Note that if a
	//! neighbor has multiple nodes, this function will return the lowest entry in that set.
	vector<idx_t> GetNeighbors(RelationSet *node, unordered_set<idx_t> &exclusion_set);
	//! Enumerate all neighbors of a given RelationSet node
	void EnumerateNeighbors(RelationSet *node, std::function<bool(NeighborInfo *)> callback);

private:
	//! Get the QueryEdge of a specific node
	QueryEdge *GetQueryEdge(RelationSet *left);

	QueryEdge root;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

using QueryEdge = QueryGraph::QueryEdge;

static string QueryEdgeToString(const QueryEdge *info, vector<idx_t> prefix) {
	string result = "";
	string source = "[";
	for (idx_t i = 0; i < prefix.size(); i++) {
		source += to_string(prefix[i]) + (i < prefix.size() - 1 ? ", " : "");
	}
	source += "]";
	for (auto &entry : info->neighbors) {
		result += StringUtil::Format("%s -> %s\n", source.c_str(), entry->neighbor->ToString().c_str());
	}
	for (auto &entry : info->children) {
		vector<idx_t> new_prefix = prefix;
		new_prefix.push_back(entry.first);
		result += QueryEdgeToString(entry.second.get(), new_prefix);
	}
	return result;
}

string QueryGraph::ToString() const {
	return QueryEdgeToString(&root, {});
}

QueryEdge *QueryGraph::GetQueryEdge(RelationSet *left) {
	assert(left && left->count > 0);
	// find the EdgeInfo corresponding to the left set
	QueryEdge *info = &root;
	for (idx_t i = 0; i < left->count; i++) {
		auto entry = info->children.find(left->relations[i]);
		if (entry == info->children.end()) {
			// node not found, create it
			auto insert_it = info->children.insert(make_pair(left->relations[i], make_unique<QueryEdge>()));
			entry = insert_it.first;
		}
		// move to the next node
		info = entry->second.get();
	}
	return info;
}

void QueryGraph::CreateEdge(RelationSet *left, RelationSet *right, FilterInfo *filter_info) {
	assert(left && right && left->count > 0 && right->count > 0);
	// find the EdgeInfo corresponding to the left set
	auto info = GetQueryEdge(left);
	// now insert the edge to the right relation, if it does not exist
	for (idx_t i = 0; i < info->neighbors.size(); i++) {
		if (info->neighbors[i]->neighbor == right) {
			if (filter_info) {
				// neighbor already exists just add the filter, if we have any
				info->neighbors[i]->filters.push_back(filter_info);
			}
			return;
		}
	}
	// neighbor does not exist, create it
	auto n = make_unique<NeighborInfo>();
	if (filter_info) {
		n->filters.push_back(filter_info);
	}
	n->neighbor = right;
	info->neighbors.push_back(move(n));
}

void QueryGraph::EnumerateNeighbors(RelationSet *node, function<bool(NeighborInfo *)> callback) {
	for (idx_t j = 0; j < node->count; j++) {
		QueryEdge *info = &root;
		for (idx_t i = j; i < node->count; i++) {
			auto entry = info->children.find(node->relations[i]);
			if (entry == info->children.end()) {
				// node not found
				break;
			}
			// check if any subset of the other set is in this sets neighbors
			info = entry->second.get();
			for (auto &neighbor : info->neighbors) {
				if (callback(neighbor.get())) {
					return;
				}
			}
		}
	}
}

//! Returns true if a RelationSet is banned by the list of exclusion_set, false otherwise
static bool RelationSetIsExcluded(RelationSet *node, unordered_set<idx_t> &exclusion_set) {
	return exclusion_set.find(node->relations[0]) != exclusion_set.end();
}

vector<idx_t> QueryGraph::GetNeighbors(RelationSet *node, unordered_set<idx_t> &exclusion_set) {
	unordered_set<idx_t> result;
	EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool {
		if (!RelationSetIsExcluded(info->neighbor, exclusion_set)) {
			// add the smallest node of the neighbor to the set
			result.insert(info->neighbor->relations[0]);
		}
		return false;
	});
	vector<idx_t> neighbors;
	neighbors.insert(neighbors.end(), result.begin(), result.end());
	return neighbors;
}

NeighborInfo *QueryGraph::GetConnection(RelationSet *node, RelationSet *other) {
	NeighborInfo *connection = nullptr;
	EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool {
		if (RelationSet::IsSubset(other, info->neighbor)) {
			connection = info;
			return true;
		}
		return false;
	});
	return connection;
}

void QueryGraph::Print() {
	Printer::Print(ToString());
}



#include <algorithm>
#include <string>

using namespace duckdb;
using namespace std;

using RelationTreeNode = RelationSetManager::RelationTreeNode;

string RelationSet::ToString() const {
	string result = "[";
	result += StringUtil::Join(relations, count, ", ", [](const idx_t &relation) { return to_string(relation); });
	result += "]";
	return result;
}

//! Returns true if sub is a subset of super
bool RelationSet::IsSubset(RelationSet *super, RelationSet *sub) {
	if (sub->count == 0) {
		return false;
	}
	if (sub->count > super->count) {
		return false;
	}
	idx_t j = 0;
	for (idx_t i = 0; i < super->count; i++) {
		if (sub->relations[j] == super->relations[i]) {
			j++;
			if (j == sub->count) {
				return true;
			}
		}
	}
	return false;
}

RelationSet *RelationSetManager::GetRelation(unique_ptr<idx_t[]> relations, idx_t count) {
	// now look it up in the tree
	RelationTreeNode *info = &root;
	for (idx_t i = 0; i < count; i++) {
		auto entry = info->children.find(relations[i]);
		if (entry == info->children.end()) {
			// node not found, create it
			auto insert_it = info->children.insert(make_pair(relations[i], make_unique<RelationTreeNode>()));
			entry = insert_it.first;
		}
		// move to the next node
		info = entry->second.get();
	}
	// now check if the RelationSet has already been created
	if (!info->relation) {
		// if it hasn't we need to create it
		info->relation = make_unique<RelationSet>(move(relations), count);
	}
	return info->relation.get();
}

//! Create or get a RelationSet from a single node with the given index
RelationSet *RelationSetManager::GetRelation(idx_t index) {
	// create a sorted vector of the relations
	auto relations = unique_ptr<idx_t[]>(new idx_t[1]);
	relations[0] = index;
	idx_t count = 1;
	return GetRelation(move(relations), count);
}

RelationSet *RelationSetManager::GetRelation(unordered_set<idx_t> &bindings) {
	// create a sorted vector of the relations
	unique_ptr<idx_t[]> relations = bindings.size() == 0 ? nullptr : unique_ptr<idx_t[]>(new idx_t[bindings.size()]);
	idx_t count = 0;
	for (auto &entry : bindings) {
		relations[count++] = entry;
	}
	sort(relations.get(), relations.get() + count);
	return GetRelation(move(relations), count);
}

RelationSet *RelationSetManager::Union(RelationSet *left, RelationSet *right) {
	auto relations = unique_ptr<idx_t[]>(new idx_t[left->count + right->count]);
	idx_t count = 0;
	// move through the left and right relations, eliminating duplicates
	idx_t i = 0, j = 0;
	while (true) {
		if (i == left->count) {
			// exhausted left relation, add remaining of right relation
			for (; j < right->count; j++) {
				relations[count++] = right->relations[j];
			}
			break;
		} else if (j == right->count) {
			// exhausted right relation, add remaining of left
			for (; i < left->count; i++) {
				relations[count++] = left->relations[i];
			}
			break;
		} else if (left->relations[i] == right->relations[j]) {
			// equivalent, add only one of the two pairs
			relations[count++] = left->relations[i];
			i++;
			j++;
		} else if (left->relations[i] < right->relations[j]) {
			// left is smaller, progress left and add it to the set
			relations[count++] = left->relations[i];
			i++;
		} else {
			// right is smaller, progress right and add it to the set
			relations[count++] = right->relations[j];
			j++;
		}
	}
	return GetRelation(move(relations), count);
}

RelationSet *RelationSetManager::Difference(RelationSet *left, RelationSet *right) {
	auto relations = unique_ptr<idx_t[]>(new idx_t[left->count]);
	idx_t count = 0;
	// move through the left and right relations
	idx_t i = 0, j = 0;
	while (true) {
		if (i == left->count) {
			// exhausted left relation, we are done
			break;
		} else if (j == right->count) {
			// exhausted right relation, add remaining of left
			for (; i < left->count; i++) {
				relations[count++] = left->relations[i];
			}
			break;
		} else if (left->relations[i] == right->relations[j]) {
			// equivalent, add nothing
			i++;
			j++;
		} else if (left->relations[i] < right->relations[j]) {
			// left is smaller, progress left and add it to the set
			relations[count++] = left->relations[i];
			i++;
		} else {
			// right is smaller, progress right
			j++;
		}
	}
	return GetRelation(move(relations), count);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/join_order_optimizer.hpp
//
//
//===----------------------------------------------------------------------===//











#include <functional>

namespace duckdb {

class JoinOrderOptimizer {
public:
	//! Represents a node in the join plan
	struct JoinNode {
		RelationSet *set;
		NeighborInfo *info;
		idx_t cardinality;
		idx_t cost;
		JoinNode *left;
		JoinNode *right;

		//! Create a leaf node in the join tree
		JoinNode(RelationSet *set, idx_t cardinality)
		    : set(set), info(nullptr), cardinality(cardinality), cost(cardinality), left(nullptr), right(nullptr) {
		}
		//! Create an intermediate node in the join tree
		JoinNode(RelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right, idx_t cardinality, idx_t cost)
		    : set(set), info(info), cardinality(cardinality), cost(cost), left(left), right(right) {
		}
	};

public:
	//! Perform join reordering inside a plan
	unique_ptr<LogicalOperator> Optimize(unique_ptr<LogicalOperator> plan);

private:
	//! The total amount of join pairs that have been considered
	idx_t pairs = 0;
	//! Set of all relations considered in the join optimizer
	vector<unique_ptr<Relation>> relations;
	//! A mapping of base table index -> index into relations array (relation number)
	unordered_map<idx_t, idx_t> relation_mapping;
	//! A structure holding all the created RelationSet objects
	RelationSetManager set_manager;
	//! The set of edges used in the join optimizer
	QueryGraph query_graph;
	//! The optimal join plan found for the specific RelationSet*
	unordered_map<RelationSet *, unique_ptr<JoinNode>> plans;
	//! The set of filters extracted from the query graph
	vector<unique_ptr<Expression>> filters;
	//! The set of filter infos created from the extracted filters
	vector<unique_ptr<FilterInfo>> filter_infos;
	//! A map of all expressions a given expression has to be equivalent to. This is used to add "implied join edges".
	//! i.e. in the join A=B AND B=C, the equivalence set of {B} is {A, C}, thus we can add an implied join edge {A <->
	//! C}
	expression_map_t<vector<FilterInfo *>> equivalence_sets;

	//! Extract the bindings referred to by an Expression
	bool ExtractBindings(Expression &expression, unordered_set<idx_t> &bindings);
	//! Traverse the query tree to find (1) base relations, (2) existing join conditions and (3) filters that can be
	//! rewritten into joins. Returns true if there are joins in the tree that can be reordered, false otherwise.
	bool ExtractJoinRelations(LogicalOperator &input_op, vector<LogicalOperator *> &filter_operators,
	                          LogicalOperator *parent = nullptr);
	//! Emit a pair as a potential join candidate. Returns the best plan found for the (left, right) connection (either
	//! the newly created plan, or an existing plan)
	JoinNode *EmitPair(RelationSet *left, RelationSet *right, NeighborInfo *info);
	//! Tries to emit a potential join candidate pair. Returns false if too many pairs have already been emitted,
	//! cancelling the dynamic programming step.
	bool TryEmitPair(RelationSet *left, RelationSet *right, NeighborInfo *info);

	bool EnumerateCmpRecursive(RelationSet *left, RelationSet *right, unordered_set<idx_t> exclusion_set);
	//! Emit a relation set node
	bool EmitCSG(RelationSet *node);
	//! Enumerate the possible connected subgraphs that can be joined together in the join graph
	bool EnumerateCSGRecursive(RelationSet *node, unordered_set<idx_t> &exclusion_set);
	//! Rewrite a logical query plan given the join plan
	unique_ptr<LogicalOperator> RewritePlan(unique_ptr<LogicalOperator> plan, JoinNode *node);
	//! Generate cross product edges inside the side
	void GenerateCrossProducts();
	//! Perform the join order solving
	void SolveJoinOrder();
	//! Solve the join order exactly using dynamic programming. Returns true if it was completed successfully (i.e. did
	//! not time-out)
	bool SolveJoinOrderExactly();
	//! Solve the join order approximately using a greedy algorithm
	void SolveJoinOrderApproximately();

	unique_ptr<LogicalOperator> ResolveJoinConditions(unique_ptr<LogicalOperator> op);
	std::pair<RelationSet *, unique_ptr<LogicalOperator>>
	GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted_relations, JoinNode *node);
};

} // namespace duckdb











































using namespace duckdb;
using namespace std;

using JoinNode = JoinOrderOptimizer::JoinNode;

//! Returns true if A and B are disjoint, false otherwise
template <class T> static bool Disjoint(unordered_set<T> &a, unordered_set<T> &b) {
	for (auto &entry : a) {
		if (b.find(entry) != b.end()) {
			return false;
		}
	}
	return true;
}

//! Extract the set of relations referred to inside an expression
bool JoinOrderOptimizer::ExtractBindings(Expression &expression, unordered_set<idx_t> &bindings) {
	if (expression.type == ExpressionType::BOUND_COLUMN_REF) {
		auto &colref = (BoundColumnRefExpression &)expression;
		assert(colref.depth == 0);
		assert(colref.binding.table_index != INVALID_INDEX);
		// map the base table index to the relation index used by the JoinOrderOptimizer
		assert(relation_mapping.find(colref.binding.table_index) != relation_mapping.end());
		bindings.insert(relation_mapping[colref.binding.table_index]);
	}
	if (expression.type == ExpressionType::BOUND_REF) {
		// bound expression
		bindings.clear();
		return false;
	}
	assert(expression.type != ExpressionType::SUBQUERY);
	bool can_reorder = true;
	ExpressionIterator::EnumerateChildren(expression, [&](Expression &expr) {
		if (!ExtractBindings(expr, bindings)) {
			can_reorder = false;
			return;
		}
	});
	return can_reorder;
}

static unique_ptr<LogicalOperator> PushFilter(unique_ptr<LogicalOperator> node, unique_ptr<Expression> expr) {
	// push an expression into a filter
	// first check if we have any filter to push it into
	if (node->type != LogicalOperatorType::FILTER) {
		// we don't, we need to create one
		auto filter = make_unique<LogicalFilter>();
		filter->children.push_back(move(node));
		node = move(filter);
	}
	// push the filter into the LogicalFilter
	assert(node->type == LogicalOperatorType::FILTER);
	auto filter = (LogicalFilter *)node.get();
	filter->expressions.push_back(move(expr));
	return node;
}

bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<LogicalOperator *> &filter_operators,
                                              LogicalOperator *parent) {
	LogicalOperator *op = &input_op;
	while (op->children.size() == 1 && op->type != LogicalOperatorType::PROJECTION) {
		if (op->type == LogicalOperatorType::FILTER) {
			// extract join conditions from filter
			filter_operators.push_back(op);
		}
		if (op->type == LogicalOperatorType::AGGREGATE_AND_GROUP_BY || op->type == LogicalOperatorType::WINDOW) {
			// don't push filters through projection or aggregate and group by
			JoinOrderOptimizer optimizer;
			op->children[0] = optimizer.Optimize(move(op->children[0]));
			return false;
		}
		op = op->children[0].get();
	}
	bool non_reorderable_operation = false;
	if (op->type == LogicalOperatorType::UNION || op->type == LogicalOperatorType::EXCEPT ||
	    op->type == LogicalOperatorType::INTERSECT || op->type == LogicalOperatorType::DELIM_JOIN ||
	    op->type == LogicalOperatorType::ANY_JOIN) {
		// set operation, optimize separately in children
		non_reorderable_operation = true;
	}

	if (op->type == LogicalOperatorType::COMPARISON_JOIN) {
		LogicalJoin *join = (LogicalJoin *)op;
		if (join->join_type == JoinType::INNER) {
			// extract join conditions from inner join
			filter_operators.push_back(op);
		} else {
			// non-inner join, not reordarable yet
			non_reorderable_operation = true;
		}
	}
	if (non_reorderable_operation) {
		// we encountered a non-reordable operation (setop or non-inner join)
		// we do not reorder non-inner joins yet, however we do want to expand the potential join graph around them
		// non-inner joins are also tricky because we can't freely make conditions through them
		// e.g. suppose we have (left LEFT OUTER JOIN right WHERE right IS NOT NULL), the join can generate
		// new NULL values in the right side, so pushing this condition through the join leads to incorrect results
		// for this reason, we just start a new JoinOptimizer pass in each of the children of the join
		for (idx_t i = 0; i < op->children.size(); i++) {
			JoinOrderOptimizer optimizer;
			op->children[i] = optimizer.Optimize(move(op->children[i]));
		}
		// after this we want to treat this node as one  "end node" (like e.g. a base relation)
		// however the join refers to multiple base relations
		// enumerate all base relations obtained from this join and add them to the relation mapping
		// also, we have to resolve the join conditions for the joins here
		// get the left and right bindings
		unordered_set<idx_t> bindings;
		LogicalJoin::GetTableReferences(*op, bindings);
		// now create the relation that refers to all these bindings
		auto relation = make_unique<Relation>(&input_op, parent);
		for (idx_t it : bindings) {
			relation_mapping[it] = relations.size();
		}
		relations.push_back(move(relation));
		return true;
	}
	if (op->type == LogicalOperatorType::COMPARISON_JOIN || op->type == LogicalOperatorType::CROSS_PRODUCT) {
		// inner join or cross product
		bool can_reorder_left = ExtractJoinRelations(*op->children[0], filter_operators, op);
		bool can_reorder_right = ExtractJoinRelations(*op->children[1], filter_operators, op);
		return can_reorder_left && can_reorder_right;
	} else if (op->type == LogicalOperatorType::GET) {
		// base table scan, add to set of relations
		auto get = (LogicalGet *)op;
		auto relation = make_unique<Relation>(&input_op, parent);
		relation_mapping[get->table_index] = relations.size();
		relations.push_back(move(relation));
		return true;
	} else if (op->type == LogicalOperatorType::TABLE_FUNCTION) {
		// table function call, add to set of relations
		auto table_function = (LogicalTableFunction *)op;
		auto relation = make_unique<Relation>(&input_op, parent);
		relation_mapping[table_function->table_index] = relations.size();
		relations.push_back(move(relation));
		return true;
	} else if (op->type == LogicalOperatorType::PROJECTION) {
		auto proj = (LogicalProjection *)op;
		// we run the join order optimizer witin the subquery as well
		JoinOrderOptimizer optimizer;
		op->children[0] = optimizer.Optimize(move(op->children[0]));
		// projection, add to the set of relations
		auto relation = make_unique<Relation>(&input_op, parent);
		relation_mapping[proj->table_index] = relations.size();
		relations.push_back(move(relation));
		return true;
	}
	return false;
}

//! Update the exclusion set with all entries in the subgraph
static void UpdateExclusionSet(RelationSet *node, unordered_set<idx_t> &exclusion_set) {
	for (idx_t i = 0; i < node->count; i++) {
		exclusion_set.insert(node->relations[i]);
	}
}

//! Create a new JoinTree node by joining together two previous JoinTree nodes
static unique_ptr<JoinNode> CreateJoinTree(RelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right) {
	// for the hash join we want the right side (build side) to have the smallest cardinality
	// also just a heuristic but for now...
	// FIXME: we should probably actually benchmark that as well
	// FIXME: should consider different join algorithms, should we pick a join algorithm here as well? (probably)
	if (left->cardinality < right->cardinality) {
		return CreateJoinTree(set, info, right, left);
	}
	// the expected cardinality is the max of the child cardinalities
	// FIXME: we should obviously use better cardinality estimation here
	// but for now we just assume foreign key joins only
	idx_t expected_cardinality;
	if (info->filters.size() == 0) {
		// cross product
		expected_cardinality = left->cardinality * right->cardinality;
	} else {
		// normal join, expect foreign key join
		expected_cardinality = std::max(left->cardinality, right->cardinality);
	}
	// cost is expected_cardinality plus the cost of the previous plans
	idx_t cost = expected_cardinality;
	return make_unique<JoinNode>(set, info, left, right, expected_cardinality, cost);
}

JoinNode *JoinOrderOptimizer::EmitPair(RelationSet *left, RelationSet *right, NeighborInfo *info) {
	// get the left and right join plans
	auto &left_plan = plans[left];
	auto &right_plan = plans[right];
	auto new_set = set_manager.Union(left, right);
	// create the join tree based on combining the two plans
	auto new_plan = CreateJoinTree(new_set, info, left_plan.get(), right_plan.get());
	// check if this plan is the optimal plan we found for this set of relations
	auto entry = plans.find(new_set);
	if (entry == plans.end() || new_plan->cost < entry->second->cost) {
		// the plan is the optimal plan, move it into the dynamic programming tree
		auto result = new_plan.get();
		plans[new_set] = move(new_plan);
		return result;
	}
	return entry->second.get();
}

bool JoinOrderOptimizer::TryEmitPair(RelationSet *left, RelationSet *right, NeighborInfo *info) {
	pairs++;
	if (pairs >= 2000) {
		// when the amount of pairs gets too large we exit the dynamic programming and resort to a greedy algorithm
		// FIXME: simple heuristic currently
		// at 10K pairs stop searching exactly and switch to heuristic
		return false;
	}
	EmitPair(left, right, info);
	return true;
}

bool JoinOrderOptimizer::EmitCSG(RelationSet *node) {
	// create the exclusion set as everything inside the subgraph AND anything with members BELOW it
	unordered_set<idx_t> exclusion_set;
	for (idx_t i = 0; i < node->relations[0]; i++) {
		exclusion_set.insert(i);
	}
	UpdateExclusionSet(node, exclusion_set);
	// find the neighbors given this exclusion set
	auto neighbors = query_graph.GetNeighbors(node, exclusion_set);
	if (neighbors.size() == 0) {
		return true;
	}
	// we iterate over the neighbors ordered by their first node
	sort(neighbors.begin(), neighbors.end());
	for (auto neighbor : neighbors) {
		// since the GetNeighbors only returns the smallest element in a list, the entry might not be connected to
		// (only!) this neighbor,  hence we have to do a connectedness check before we can emit it
		auto neighbor_relation = set_manager.GetRelation(neighbor);
		auto connection = query_graph.GetConnection(node, neighbor_relation);
		if (connection) {
			if (!TryEmitPair(node, neighbor_relation, connection)) {
				return false;
			}
		}
		if (!EnumerateCmpRecursive(node, neighbor_relation, exclusion_set)) {
			return false;
		}
	}
	return true;
}

bool JoinOrderOptimizer::EnumerateCmpRecursive(RelationSet *left, RelationSet *right,
                                               unordered_set<idx_t> exclusion_set) {
	// get the neighbors of the second relation under the exclusion set
	auto neighbors = query_graph.GetNeighbors(right, exclusion_set);
	if (neighbors.size() == 0) {
		return true;
	}
	vector<RelationSet *> union_sets;
	union_sets.resize(neighbors.size());
	for (idx_t i = 0; i < neighbors.size(); i++) {
		auto neighbor = set_manager.GetRelation(neighbors[i]);
		// emit the combinations of this node and its neighbors
		auto combined_set = set_manager.Union(right, neighbor);
		if (plans.find(combined_set) != plans.end()) {
			auto connection = query_graph.GetConnection(left, combined_set);
			if (connection) {
				if (!TryEmitPair(left, combined_set, connection)) {
					return false;
				}
			}
		}
		union_sets[i] = combined_set;
	}
	// recursively enumerate the sets
	for (idx_t i = 0; i < neighbors.size(); i++) {
		// updated the set of excluded entries with this neighbor
		unordered_set<idx_t> new_exclusion_set = exclusion_set;
		new_exclusion_set.insert(neighbors[i]);
		if (!EnumerateCmpRecursive(left, union_sets[i], new_exclusion_set)) {
			return false;
		}
	}
	return true;
}

bool JoinOrderOptimizer::EnumerateCSGRecursive(RelationSet *node, unordered_set<idx_t> &exclusion_set) {
	// find neighbors of S under the exlusion set
	auto neighbors = query_graph.GetNeighbors(node, exclusion_set);
	if (neighbors.size() == 0) {
		return true;
	}
	// now first emit the connected subgraphs of the neighbors
	vector<RelationSet *> union_sets;
	union_sets.resize(neighbors.size());
	for (idx_t i = 0; i < neighbors.size(); i++) {
		auto neighbor = set_manager.GetRelation(neighbors[i]);
		// emit the combinations of this node and its neighbors
		auto new_set = set_manager.Union(node, neighbor);
		if (plans.find(new_set) != plans.end()) {
			if (!EmitCSG(new_set)) {
				return false;
			}
		}
		union_sets[i] = new_set;
	}
	// recursively enumerate the sets
	for (idx_t i = 0; i < neighbors.size(); i++) {
		// updated the set of excluded entries with this neighbor
		unordered_set<idx_t> new_exclusion_set = exclusion_set;
		new_exclusion_set.insert(neighbors[i]);
		if (!EnumerateCSGRecursive(union_sets[i], new_exclusion_set)) {
			return false;
		}
	}
	return true;
}

bool JoinOrderOptimizer::SolveJoinOrderExactly() {
	// now we perform the actual dynamic programming to compute the final result
	// we enumerate over all the possible pairs in the neighborhood
	for (idx_t i = relations.size(); i > 0; i--) {
		// for every node in the set, we consider it as the start node once
		auto start_node = set_manager.GetRelation(i - 1);
		// emit the start node
		if (!EmitCSG(start_node)) {
			return false;
		}
		// initialize the set of exclusion_set as all the nodes with a number below this
		unordered_set<idx_t> exclusion_set;
		for (idx_t j = 0; j < i - 1; j++) {
			exclusion_set.insert(j);
		}
		// then we recursively search for neighbors that do not belong to the banned entries
		if (!EnumerateCSGRecursive(start_node, exclusion_set)) {
			return false;
		}
	}
	return true;
}

void JoinOrderOptimizer::SolveJoinOrderApproximately() {
	// at this point, we exited the dynamic programming but did not compute the final join order because it took too
	// long instead, we use a greedy heuristic to obtain a join ordering now we use Greedy Operator Ordering to
	// construct the result tree first we start out with all the base relations (the to-be-joined relations)
	vector<RelationSet *> T;
	for (idx_t i = 0; i < relations.size(); i++) {
		T.push_back(set_manager.GetRelation(i));
	}
	while (T.size() > 1) {
		// now in every step of the algorithm, we greedily pick the join between the to-be-joined relations that has the
		// smallest cost. This is O(r^2) per step, and every step will reduce the total amount of relations to-be-joined
		// by 1, so the total cost is O(r^3) in the amount of relations
		idx_t best_left = 0, best_right = 0;
		JoinNode *best_connection = nullptr;
		for (idx_t i = 0; i < T.size(); i++) {
			auto left = T[i];
			for (idx_t j = i + 1; j < T.size(); j++) {
				auto right = T[j];
				// check if we can connect these two relations
				auto connection = query_graph.GetConnection(left, right);
				if (connection) {
					// we can! check the cost of this connection
					auto node = EmitPair(left, right, connection);
					if (!best_connection || node->cost < best_connection->cost) {
						// best pair found so far
						best_connection = node;
						best_left = i;
						best_right = j;
					}
				}
			}
		}
		if (!best_connection) {
			// could not find a connection, but we were not done with finding a completed plan
			// we have to add a cross product; we add it between the two smallest relations
			JoinNode *smallest_plans[2] = {nullptr};
			idx_t smallest_index[2];
			for (idx_t i = 0; i < T.size(); i++) {
				// get the plan for this relation
				auto current_plan = plans[T[i]].get();
				// check if the cardinality is smaller than the smallest two found so far
				for (idx_t j = 0; j < 2; j++) {
					if (!smallest_plans[j] || smallest_plans[j]->cardinality > current_plan->cardinality) {
						smallest_plans[j] = current_plan;
						smallest_index[j] = i;
						break;
					}
				}
			}
			assert(smallest_plans[0] && smallest_plans[1]);
			assert(smallest_index[0] != smallest_index[1]);
			auto left = smallest_plans[0]->set, right = smallest_plans[1]->set;
			// create a cross product edge (i.e. edge with empty filter) between these two sets in the query graph
			query_graph.CreateEdge(left, right, nullptr);
			// now emit the pair and continue with the algorithm
			auto connection = query_graph.GetConnection(left, right);
			assert(connection);

			best_connection = EmitPair(left, right, connection);
			best_left = smallest_index[0];
			best_right = smallest_index[1];
			// the code below assumes best_right > best_left
			if (best_left > best_right) {
				swap(best_left, best_right);
			}
		}
		// now update the to-be-checked pairs
		// remove left and right, and add the combination

		// important to erase the biggest element first
		// if we erase the smallest element first the index of the biggest element changes
		assert(best_right > best_left);
		T.erase(T.begin() + best_right);
		T.erase(T.begin() + best_left);
		T.push_back(best_connection->set);
	}
}

void JoinOrderOptimizer::SolveJoinOrder() {
	// first try to solve the join order exactly
	if (!SolveJoinOrderExactly()) {
		// otherwise, if that times out we resort to a greedy algorithm
		SolveJoinOrderApproximately();
	}
}

void JoinOrderOptimizer::GenerateCrossProducts() {
	// generate a set of cross products to combine the currently available plans into a full join plan
	// we create edges between every relation with a high cost
	for (idx_t i = 0; i < relations.size(); i++) {
		auto left = set_manager.GetRelation(i);
		for (idx_t j = 0; j < relations.size(); j++) {
			if (i != j) {
				auto right = set_manager.GetRelation(j);
				query_graph.CreateEdge(left, right, nullptr);
				query_graph.CreateEdge(right, left, nullptr);
			}
		}
	}
}

static unique_ptr<LogicalOperator> ExtractRelation(Relation &rel) {
	auto &children = rel.parent->children;
	for (idx_t i = 0; i < children.size(); i++) {
		if (children[i].get() == rel.op) {
			// found it! take ownership of it from the parent
			auto result = move(children[i]);
			children.erase(children.begin() + i);
			return result;
		}
	}
	throw Exception("Could not find relation in parent node (?)");
}

pair<RelationSet *, unique_ptr<LogicalOperator>>
JoinOrderOptimizer::GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted_relations, JoinNode *node) {
	RelationSet *left_node = nullptr, *right_node = nullptr;
	RelationSet *result_relation;
	unique_ptr<LogicalOperator> result_operator;
	if (node->left && node->right) {
		// generate the left and right children
		auto left = GenerateJoins(extracted_relations, node->left);
		auto right = GenerateJoins(extracted_relations, node->right);

		if (node->info->filters.size() == 0) {
			// no filters, create a cross product
			auto join = make_unique<LogicalCrossProduct>();
			join->children.push_back(move(left.second));
			join->children.push_back(move(right.second));
			result_operator = move(join);
		} else {
			// we have filters, create a join node
			auto join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
			join->children.push_back(move(left.second));
			join->children.push_back(move(right.second));
			// set the join conditions from the join node
			for (auto &f : node->info->filters) {
				// extract the filter from the operator it originally belonged to
				assert(filters[f->filter_index]);
				auto condition = move(filters[f->filter_index]);
				// now create the actual join condition
				assert((RelationSet::IsSubset(left.first, f->left_set) &&
				        RelationSet::IsSubset(right.first, f->right_set)) ||
				       (RelationSet::IsSubset(left.first, f->right_set) &&
				        RelationSet::IsSubset(right.first, f->left_set)));
				JoinCondition cond;
				assert(condition->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON);
				auto &comparison = (BoundComparisonExpression &)*condition;
				// we need to figure out which side is which by looking at the relations available to us
				bool invert = RelationSet::IsSubset(left.first, f->left_set) ? false : true;
				cond.left = !invert ? move(comparison.left) : move(comparison.right);
				cond.right = !invert ? move(comparison.right) : move(comparison.left);
				cond.comparison = condition->type;
				if (invert) {
					// reverse comparison expression if we reverse the order of the children
					cond.comparison = FlipComparisionExpression(cond.comparison);
				}
				join->conditions.push_back(move(cond));
			}
			assert(join->conditions.size() > 0);
			result_operator = move(join);
		}
		left_node = left.first;
		right_node = right.first;
		result_relation = set_manager.Union(left_node, right_node);
	} else {
		// base node, get the entry from the list of extracted relations
		assert(node->set->count == 1);
		assert(extracted_relations[node->set->relations[0]]);
		result_relation = node->set;
		result_operator = move(extracted_relations[node->set->relations[0]]);
	}
	// check if we should do a pushdown on this node
	// basically, any remaining filter that is a subset of the current relation will no longer be used in joins
	// hence we should push it here
	for (idx_t i = 0; i < filter_infos.size(); i++) {
		// check if the filter has already been extracted
		auto info = filter_infos[i].get();
		if (filters[info->filter_index]) {
			// now check if the filter is a subset of the current relation
			// note that infos with an empty relation set are a special case and we do not push them down
			if (info->set->count > 0 && RelationSet::IsSubset(result_relation, info->set)) {
				auto filter = move(filters[info->filter_index]);
				// if it is, we can push the filter
				// we can push it either into a join or as a filter
				// check if we are in a join or in a base table
				if (!left_node || !info->left_set) {
					// base table or non-comparison expression, push it as a filter
					result_operator = PushFilter(move(result_operator), move(filter));
					continue;
				}
				// the node below us is a join or cross product and the expression is a comparison
				// check if the nodes can be split up into left/right
				bool found_subset = false;
				bool invert = false;
				if (RelationSet::IsSubset(left_node, info->left_set) &&
				    RelationSet::IsSubset(right_node, info->right_set)) {
					found_subset = true;
				} else if (RelationSet::IsSubset(right_node, info->left_set) &&
				           RelationSet::IsSubset(left_node, info->right_set)) {
					invert = true;
					found_subset = true;
				}
				if (!found_subset) {
					// could not be split up into left/right
					result_operator = PushFilter(move(result_operator), move(filter));
					continue;
				}
				// create the join condition
				JoinCondition cond;
				assert(filter->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON);
				auto &comparison = (BoundComparisonExpression &)*filter;
				// we need to figure out which side is which by looking at the relations available to us
				cond.left = !invert ? move(comparison.left) : move(comparison.right);
				cond.right = !invert ? move(comparison.right) : move(comparison.left);
				cond.comparison = comparison.type;
				if (invert) {
					// reverse comparison expression if we reverse the order of the children
					cond.comparison = FlipComparisionExpression(comparison.type);
				}
				// now find the join to push it into
				auto node = result_operator.get();
				if (node->type == LogicalOperatorType::FILTER) {
					node = node->children[0].get();
				}
				if (node->type == LogicalOperatorType::CROSS_PRODUCT) {
					// turn into comparison join
					auto comp_join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
					comp_join->children.push_back(move(node->children[0]));
					comp_join->children.push_back(move(node->children[1]));
					comp_join->conditions.push_back(move(cond));
					if (node == result_operator.get()) {
						result_operator = move(comp_join);
					} else {
						assert(result_operator->type == LogicalOperatorType::FILTER);
						result_operator->children[0] = move(comp_join);
					}
				} else {
					assert(node->type == LogicalOperatorType::COMPARISON_JOIN);
					auto &comp_join = (LogicalComparisonJoin &)*node;
					comp_join.conditions.push_back(move(cond));
				}
			}
		}
	}
	return make_pair(result_relation, move(result_operator));
}

unique_ptr<LogicalOperator> JoinOrderOptimizer::RewritePlan(unique_ptr<LogicalOperator> plan, JoinNode *node) {
	// now we have to rewrite the plan
	bool root_is_join = plan->children.size() > 1;

	// first we will extract all relations from the main plan
	vector<unique_ptr<LogicalOperator>> extracted_relations;
	for (idx_t i = 0; i < relations.size(); i++) {
		extracted_relations.push_back(ExtractRelation(*relations[i]));
	}
	// now we generate the actual joins
	auto join_tree = GenerateJoins(extracted_relations, node);
	// perform the final pushdown of remaining filters
	for (idx_t i = 0; i < filters.size(); i++) {
		// check if the filter has already been extracted
		if (filters[i]) {
			// if not we need to push it
			join_tree.second = PushFilter(move(join_tree.second), move(filters[i]));
		}
	}

	// find the first join in the relation to know where to place this node
	if (root_is_join) {
		// first node is the join, return it immediately
		return move(join_tree.second);
	}
	assert(plan->children.size() == 1);
	// have to move up through the relations
	auto op = plan.get();
	auto parent = plan.get();
	while (op->type != LogicalOperatorType::CROSS_PRODUCT && op->type != LogicalOperatorType::COMPARISON_JOIN) {
		assert(op->children.size() == 1);
		parent = op;
		op = op->children[0].get();
	}
	// have to replace at this node
	parent->children[0] = move(join_tree.second);
	return plan;
}

// the join ordering is pretty much a straight implementation of the paper "Dynamic Programming Strikes Back" by Guido
// Moerkotte and Thomas Neumannn, see that paper for additional info/documentation bonus slides:
// https://db.in.tum.de/teaching/ws1415/queryopt/chapter3.pdf?lang=de
// FIXME: incorporate cardinality estimation into the plans, possibly by pushing samples?
unique_ptr<LogicalOperator> JoinOrderOptimizer::Optimize(unique_ptr<LogicalOperator> plan) {
	assert(filters.size() == 0 && relations.size() == 0); // assert that the JoinOrderOptimizer has not been used before
	LogicalOperator *op = plan.get();
	// now we optimize the current plan
	// we skip past until we find the first projection, we do this because the HAVING clause inserts a Filter AFTER the
	// group by and this filter cannot be reordered
	// extract a list of all relations that have to be joined together
	// and a list of all conditions that is applied to them
	vector<LogicalOperator *> filter_operators;
	if (!ExtractJoinRelations(*op, filter_operators)) {
		// do not support reordering this type of plan
		return plan;
	}
	if (relations.size() <= 1) {
		// at most one relation, nothing to reorder
		return plan;
	}
	// now that we know we are going to perform join ordering we actually extract the filters, eliminating duplicate
	// filters in the process
	expression_set_t filter_set;
	for (auto &op : filter_operators) {
		if (op->type == LogicalOperatorType::COMPARISON_JOIN) {
			auto &join = (LogicalComparisonJoin &)*op;
			assert(join.join_type == JoinType::INNER);
			assert(join.expressions.size() == 0);
			for (auto &cond : join.conditions) {
				auto comparison =
				    make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
				if (filter_set.find(comparison.get()) == filter_set.end()) {
					filter_set.insert(comparison.get());
					filters.push_back(move(comparison));
				}
			}
			join.conditions.clear();
		} else {
			for (idx_t i = 0; i < op->expressions.size(); i++) {
				if (filter_set.find(op->expressions[i].get()) == filter_set.end()) {
					filter_set.insert(op->expressions[i].get());
					filters.push_back(move(op->expressions[i]));
				}
			}
			op->expressions.clear();
		}
	}
	// create potential edges from the comparisons
	for (idx_t i = 0; i < filters.size(); i++) {
		auto &filter = filters[i];
		auto info = make_unique<FilterInfo>();
		auto filter_info = info.get();
		filter_infos.push_back(move(info));
		// first extract the relation set for the entire filter
		unordered_set<idx_t> bindings;
		ExtractBindings(*filter, bindings);
		filter_info->set = set_manager.GetRelation(bindings);
		filter_info->filter_index = i;
		// now check if it can be used as a join predicate
		if (filter->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) {
			auto comparison = (BoundComparisonExpression *)filter.get();
			// extract the bindings that are required for the left and right side of the comparison
			unordered_set<idx_t> left_bindings, right_bindings;
			ExtractBindings(*comparison->left, left_bindings);
			ExtractBindings(*comparison->right, right_bindings);
			if (left_bindings.size() > 0 && right_bindings.size() > 0) {
				// both the left and the right side have bindings
				// first create the relation sets, if they do not exist
				filter_info->left_set = set_manager.GetRelation(left_bindings);
				filter_info->right_set = set_manager.GetRelation(right_bindings);
				// we can only create a meaningful edge if the sets are not exactly the same
				if (filter_info->left_set != filter_info->right_set) {
					// check if the sets are disjoint
					if (Disjoint(left_bindings, right_bindings)) {
						// they are disjoint, we only need to create one set of edges in the join graph
						query_graph.CreateEdge(filter_info->left_set, filter_info->right_set, filter_info);
						query_graph.CreateEdge(filter_info->right_set, filter_info->left_set, filter_info);
					} else {
						// the sets are not disjoint, we create two sets of edges
						auto left_difference = set_manager.Difference(filter_info->left_set, filter_info->right_set);
						auto right_difference = set_manager.Difference(filter_info->right_set, filter_info->left_set);
						// -> LEFT <-> RIGHT \ LEFT
						query_graph.CreateEdge(filter_info->left_set, right_difference, filter_info);
						query_graph.CreateEdge(right_difference, filter_info->left_set, filter_info);
						// -> RIGHT <-> LEFT \ RIGHT
						query_graph.CreateEdge(left_difference, filter_info->right_set, filter_info);
						query_graph.CreateEdge(filter_info->right_set, left_difference, filter_info);
					}
					continue;
				}
			}
		}
	}
	// now use dynamic programming to figure out the optimal join order
	// First we initialize each of the single-node plans with themselves and with their cardinalities these are the leaf
	// nodes of the join tree NOTE: we can just use pointers to RelationSet* here because the GetRelation function
	// ensures that a unique combination of relations will have a unique RelationSet object.
	for (idx_t i = 0; i < relations.size(); i++) {
		auto &rel = *relations[i];
		auto node = set_manager.GetRelation(i);
		plans[node] = make_unique<JoinNode>(node, rel.op->EstimateCardinality());
	}
	// now we perform the actual dynamic programming to compute the final result
	SolveJoinOrder();
	// now the optimal join path should have been found
	// get it from the node
	unordered_set<idx_t> bindings;
	for (idx_t i = 0; i < relations.size(); i++) {
		bindings.insert(i);
	}
	auto total_relation = set_manager.GetRelation(bindings);
	auto final_plan = plans.find(total_relation);
	if (final_plan == plans.end()) {
		// could not find the final plan
		// this should only happen in case the sets are actually disjunct
		// in this case we need to generate cross product to connect the disjoint sets
		GenerateCrossProducts();
		//! solve the join order again
		SolveJoinOrder();
		// now we can obtain the final plan!
		final_plan = plans.find(total_relation);
		assert(final_plan != plans.end());
	}
	// now perform the actual reordering
	return RewritePlan(move(plan), final_plan->second.get());
}




using namespace duckdb;
using namespace std;

bool ExpressionMatcher::Match(Expression *expr, vector<Expression *> &bindings) {
	if (type && !type->Match(expr->return_type)) {
		return false;
	}
	if (expr_type && !expr_type->Match(expr->type)) {
		return false;
	}
	if (expr_class != ExpressionClass::INVALID && expr_class != expr->GetExpressionClass()) {
		return false;
	}
	bindings.push_back(expr);
	return true;
}

bool ExpressionEqualityMatcher::Match(Expression *expr, vector<Expression *> &bindings) {
	if (!Expression::Equals(expression, expr)) {
		return false;
	}
	bindings.push_back(expr);
	return true;
}

bool CaseExpressionMatcher::Match(Expression *expr_, vector<Expression *> &bindings) {
	if (!ExpressionMatcher::Match(expr_, bindings)) {
		return false;
	}
	auto expr = (BoundCaseExpression *)expr_;
	if (check && !check->Match(expr->check.get(), bindings)) {
		return false;
	}
	if (result_if_true && !result_if_true->Match(expr->result_if_true.get(), bindings)) {
		return false;
	}
	if (result_if_false && !result_if_false->Match(expr->result_if_false.get(), bindings)) {
		return false;
	}
	return true;
}

bool CastExpressionMatcher::Match(Expression *expr_, vector<Expression *> &bindings) {
	if (!ExpressionMatcher::Match(expr_, bindings)) {
		return false;
	}
	auto expr = (BoundCastExpression *)expr_;
	if (child && !child->Match(expr->child.get(), bindings)) {
		return false;
	}
	return true;
}

bool ComparisonExpressionMatcher::Match(Expression *expr_, vector<Expression *> &bindings) {
	if (!ExpressionMatcher::Match(expr_, bindings)) {
		return false;
	}
	auto expr = (BoundComparisonExpression *)expr_;
	vector<Expression *> expressions = {expr->left.get(), expr->right.get()};
	return SetMatcher::Match(matchers, expressions, bindings, policy);
}

bool ConjunctionExpressionMatcher::Match(Expression *expr_, vector<Expression *> &bindings) {
	if (!ExpressionMatcher::Match(expr_, bindings)) {
		return false;
	}
	auto expr = (BoundConjunctionExpression *)expr_;
	if (!SetMatcher::Match(matchers, expr->children, bindings, policy)) {
		return false;
	}
	return true;
}

bool OperatorExpressionMatcher::Match(Expression *expr_, vector<Expression *> &bindings) {
	if (!ExpressionMatcher::Match(expr_, bindings)) {
		return false;
	}
	auto expr = (BoundOperatorExpression *)expr_;
	return SetMatcher::Match(matchers, expr->children, bindings, policy);
}

bool FunctionExpressionMatcher::Match(Expression *expr_, vector<Expression *> &bindings) {
	if (!ExpressionMatcher::Match(expr_, bindings)) {
		return false;
	}
	auto expr = (BoundFunctionExpression *)expr_;
	if (!FunctionMatcher::Match(function, expr->function.name)) {
		return false;
	}
	if (!SetMatcher::Match(matchers, expr->children, bindings, policy)) {
		return false;
	}
	return true;
}

bool FoldableConstantMatcher::Match(Expression *expr, vector<Expression *> &bindings) {
	// we match on ANY expression that is a scalar expression
	if (!expr->IsFoldable()) {
		return false;
	}
	bindings.push_back(expr);
	return true;
}











//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/regex_range_filter.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class Optimizer;

class RegexRangeFilter {
public:
	RegexRangeFilter() {
	}
	//! Perform filter pushdown
	unique_ptr<LogicalOperator> Rewrite(unique_ptr<LogicalOperator> node);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/remove_unused_columns.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class BoundColumnRefExpression;

//! The RemoveUnusedColumns optimizer traverses the logical operator tree and removes any columns that are not required
class RemoveUnusedColumns : public LogicalOperatorVisitor {
public:
	RemoveUnusedColumns(bool is_root = false) : everything_referenced(is_root) {
	}

	void VisitOperator(LogicalOperator &op) override;

protected:
	unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr) override;
	unique_ptr<Expression> VisitReplace(BoundReferenceExpression &expr, unique_ptr<Expression> *expr_ptr) override;

private:
	//! Whether or not all the columns are referenced. This happens in the case of the root expression (because the
	//! output implicitly refers all the columns below it)
	bool everything_referenced;
	//! The map of column references
	column_binding_map_t<vector<BoundColumnRefExpression *>> column_references;

private:
	template <class T> void ClearUnusedExpressions(vector<T> &list, idx_t table_idx);

	//! Perform a replacement of the ColumnBinding, iterating over all the currently found column references and
	//! replacing the bindings
	void ReplaceBinding(ColumnBinding current_binding, ColumnBinding new_binding);
};
} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/arithmetic_simplification.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// The Arithmetic Simplification rule applies arithmetic expressions to which the answer is known (e.g. X + 0 => X, X *
// 0 => 0)
class ArithmeticSimplificationRule : public Rule {
public:
	ArithmeticSimplificationRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/case_simplification.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// The Case Simplification rule rewrites cases with a constant check (i.e. [CASE WHEN 1=1 THEN x ELSE y END] => x)
class CaseSimplificationRule : public Rule {
public:
	CaseSimplificationRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/comparison_simplification.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// The Comparison Simplification rule rewrites comparisons with a constant NULL (i.e. [x = NULL] => [NULL])
class ComparisonSimplificationRule : public Rule {
public:
	ComparisonSimplificationRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/conjunction_simplification.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// The Conjunction Simplification rule rewrites conjunctions with a constant
class ConjunctionSimplificationRule : public Rule {
public:
	ConjunctionSimplificationRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;

	unique_ptr<Expression> RemoveExpression(BoundConjunctionExpression &conj, Expression *expr);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/constant_folding.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// Fold any constant scalar expressions into a single constant (i.e. [2 + 2] => [4], [2 = 2] => [True], etc...)
class ConstantFoldingRule : public Rule {
public:
	ConstantFoldingRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/date_part_simplification.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// The DatePart Simplification rule rewrites date_part with a constant specifier into a specialized funciton (e.g.
// date_part('year', x) => year(x))
class DatePartSimplificationRule : public Rule {
public:
	DatePartSimplificationRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/distributivity.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

// (X AND B) OR (X AND C) OR (X AND D) = X AND (B OR C OR D)
class DistributivityRule : public Rule {
public:
	DistributivityRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;

private:
	void AddExpressionSet(Expression &expr, expression_set_t &set);
	unique_ptr<Expression> ExtractExpression(BoundConjunctionExpression &conj, idx_t idx, Expression &expr);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/rule/move_constants.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

// The MoveConstantsRule moves constants to the same side of an expression, e.g. if we have an expression x + 1 = 5000
// then this will turn it into x = 4999.
class MoveConstantsRule : public Rule {
public:
	MoveConstantsRule(ExpressionRewriter &rewriter);

	unique_ptr<Expression> Apply(LogicalOperator &op, vector<Expression *> &bindings, bool &changes_made) override;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/optimizer/topn_optimizer.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class LogicalOperator;
class Optimizer;

class TopN {
public:
	//! Optimize ORDER BY + LIMIT to TopN
	unique_ptr<LogicalOperator> Optimize(unique_ptr<LogicalOperator> node);
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

Optimizer::Optimizer(Binder &binder, ClientContext &context) : context(context), binder(binder), rewriter(context) {
	rewriter.rules.push_back(make_unique<ConstantFoldingRule>(rewriter));
	rewriter.rules.push_back(make_unique<DistributivityRule>(rewriter));
	rewriter.rules.push_back(make_unique<ArithmeticSimplificationRule>(rewriter));
	rewriter.rules.push_back(make_unique<CaseSimplificationRule>(rewriter));
	rewriter.rules.push_back(make_unique<ConjunctionSimplificationRule>(rewriter));
	rewriter.rules.push_back(make_unique<ComparisonSimplificationRule>(rewriter));
	rewriter.rules.push_back(make_unique<DatePartSimplificationRule>(rewriter));
	rewriter.rules.push_back(make_unique<MoveConstantsRule>(rewriter));

#ifdef DEBUG
	for (auto &rule : rewriter.rules) {
		// root not defined in rule
		assert(rule->root);
	}
#endif
}

unique_ptr<LogicalOperator> Optimizer::Optimize(unique_ptr<LogicalOperator> plan) {
	// first we perform expression rewrites using the ExpressionRewriter
	// this does not change the logical plan structure, but only simplifies the expression trees
	context.profiler.StartPhase("expression_rewriter");
	rewriter.Apply(*plan);
	context.profiler.EndPhase();

	// perform filter pushdown
	context.profiler.StartPhase("filter_pushdown");
	FilterPushdown filter_pushdown(*this);
	plan = filter_pushdown.Rewrite(move(plan));
	context.profiler.EndPhase();

	// check if filters match with existing indexes, if true transforms filters to index scans
	context.profiler.StartPhase("index_scan");
	IndexScan index_scan;
	plan = index_scan.Optimize(move(plan));
	context.profiler.EndPhase();

	context.profiler.StartPhase("regex_range");
	RegexRangeFilter regex_opt;
	plan = regex_opt.Rewrite(move(plan));
	context.profiler.EndPhase();

	context.profiler.StartPhase("in_clause");
	InClauseRewriter rewriter(*this);
	plan = rewriter.Rewrite(move(plan));
	context.profiler.EndPhase();

	// then we perform the join ordering optimization
	// this also rewrites cross products + filters into joins and performs filter pushdowns
	context.profiler.StartPhase("join_order");
	JoinOrderOptimizer optimizer;
	plan = optimizer.Optimize(move(plan));
	context.profiler.EndPhase();

	// then we extract common subexpressions inside the different operators
	// context.profiler.StartPhase("common_subexpressions");
	// CommonSubExpressionOptimizer cse_optimizer;
	// cse_optimizer.VisitOperator(*plan);
	// context.profiler.EndPhase();

	context.profiler.StartPhase("unused_columns");
	RemoveUnusedColumns unused(true);
	unused.VisitOperator(*plan);
	context.profiler.EndPhase();

	context.profiler.StartPhase("column_lifetime");
	ColumnLifetimeAnalyzer column_lifetime(true);
	column_lifetime.VisitOperator(*plan);
	context.profiler.EndPhase();

	// transform ORDER BY + LIMIT to TopN
	context.profiler.StartPhase("top_n");
	TopN topn;
	plan = topn.Optimize(move(plan));
	context.profiler.EndPhase();

	// apply simple expression heuristics to get an initial reordering
	context.profiler.StartPhase("reorder_filter_expressions");
	ExpressionHeuristics expression_heuristics(*this);
	plan = expression_heuristics.Rewrite(move(plan));
	context.profiler.EndPhase();

	return plan;
}







using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

static unique_ptr<Expression> ReplaceGroupBindings(LogicalAggregate &proj, unique_ptr<Expression> expr) {
	if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
		auto &colref = (BoundColumnRefExpression &)*expr;
		assert(colref.binding.table_index == proj.group_index);
		assert(colref.binding.column_index < proj.groups.size());
		assert(colref.depth == 0);
		// replace the binding with a copy to the expression at the referenced index
		return proj.groups[colref.binding.column_index]->Copy();
	}
	ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		return ReplaceGroupBindings(proj, move(child));
	});
	return expr;
}

unique_ptr<LogicalOperator> FilterPushdown::PushdownAggregate(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::AGGREGATE_AND_GROUP_BY);
	auto &aggr = (LogicalAggregate &)*op;

	// pushdown into AGGREGATE and GROUP BY
	// we cannot push expressions that refer to the aggregate
	FilterPushdown child_pushdown(optimizer);
	for (idx_t i = 0; i < filters.size(); i++) {
		auto &f = *filters[i];
		// check if the aggregate is in the set
		if (f.bindings.find(aggr.aggregate_index) == f.bindings.end()) {
			// no aggregate! we can push this down
			// rewrite any group bindings within the filter
			f.filter = ReplaceGroupBindings(aggr, move(f.filter));
			// add the filter to the child node
			if (child_pushdown.AddFilter(move(f.filter)) == FilterResult::UNSATISFIABLE) {
				// filter statically evaluates to false, strip tree
				return make_unique<LogicalEmptyResult>(move(op));
			}
			// erase the filter from here
			filters.erase(filters.begin() + i);
			i--;
		}
	}
	child_pushdown.GenerateFilters();

	op->children[0] = child_pushdown.Rewrite(move(op->children[0]));
	return FinishPushdown(move(op));
}




using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

unique_ptr<LogicalOperator> FilterPushdown::PushdownCrossProduct(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::CROSS_PRODUCT);
	FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer);
	vector<unique_ptr<Expression>> join_conditions;
	unordered_set<idx_t> left_bindings, right_bindings;
	if (filters.size() > 0) {
		// check to see into which side we should push the filters
		// first get the LHS and RHS bindings
		LogicalJoin::GetTableReferences(*op->children[0], left_bindings);
		LogicalJoin::GetTableReferences(*op->children[1], right_bindings);
		// now check the set of filters
		for (auto &f : filters) {
			auto side = JoinSide::GetJoinSide(f->bindings, left_bindings, right_bindings);
			if (side == JoinSide::LEFT) {
				// bindings match left side: push into left
				left_pushdown.filters.push_back(move(f));
			} else if (side == JoinSide::RIGHT) {
				// bindings match right side: push into right
				right_pushdown.filters.push_back(move(f));
			} else {
				assert(side == JoinSide::BOTH);
				// bindings match both: turn into join condition
				join_conditions.push_back(move(f->filter));
			}
		}
	}
	op->children[0] = left_pushdown.Rewrite(move(op->children[0]));
	op->children[1] = right_pushdown.Rewrite(move(op->children[1]));

	if (join_conditions.size() > 0) {
		// join conditions found: turn into inner join
		return LogicalComparisonJoin::CreateJoin(JoinType::INNER, move(op->children[0]), move(op->children[1]),
		                                         left_bindings, right_bindings, join_conditions);
	} else {
		// no join conditions found: keep as cross product
		return op;
	}
}




using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

unique_ptr<LogicalOperator> FilterPushdown::PushdownFilter(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::FILTER);
	auto &filter = (LogicalFilter &)*op;
	// filter: gather the filters and remove the filter from the set of operations
	for (idx_t i = 0; i < filter.expressions.size(); i++) {
		if (AddFilter(move(filter.expressions[i])) == FilterResult::UNSATISFIABLE) {
			// filter statically evaluates to false, strip tree
			return make_unique<LogicalEmptyResult>(move(op));
		}
	}
	GenerateFilters();
	return Rewrite(move(filter.children[0]));
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> FilterPushdown::PushdownGet(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::GET);
	auto &get = (LogicalGet &)*op;
	if (!get.tableFilters.empty()) {
        if (!filters.empty()) {
            //! We didn't managed to push down all filters to table scan
            auto logicalFilter = make_unique<LogicalFilter>();
            for (auto &f : filters) {
                logicalFilter->expressions.push_back(move(f->filter));
            }
            logicalFilter->children.push_back(move(op));
            return move(logicalFilter);
        }
    else{
            return op;

        }
	}
	//! FIXME: We only need to skip if the index is in the column being filtered
	if (!get.table || !get.table->storage->indexes.empty()) {
		//! now push any existing filters
		if (filters.empty()) {
			//! no filters to push
			return op;
		}
		auto filter = make_unique<LogicalFilter>();
		for (auto &f : filters) {
			filter->expressions.push_back(move(f->filter));
		}
		filter->children.push_back(move(op));
		return move(filter);
	}
	PushFilters();

	vector<unique_ptr<Filter>> filtersToPushDown;
	get.tableFilters = combiner.GenerateTableScanFilters(
	    [&](unique_ptr<Expression> filter) {
		    auto f = make_unique<Filter>();
		    f->filter = move(filter);
		    f->ExtractBindings();
		    filtersToPushDown.push_back(move(f));
	    },
	    get.column_ids);
	for (auto &f : get.tableFilters) {
		f.column_index = get.column_ids[f.column_index];
	}

	GenerateFilters();
	for (auto &f : filtersToPushDown) {
		get.expressions.push_back(move(f->filter));
	}

	if (!filters.empty()) {
		//! We didn't managed to push down all filters to table scan
		auto logicalFilter = make_unique<LogicalFilter>();
		for (auto &f : filters) {
			logicalFilter->expressions.push_back(move(f->filter));
		}
		logicalFilter->children.push_back(move(op));
		return move(logicalFilter);
	}
	return op;
}






using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

unique_ptr<LogicalOperator> FilterPushdown::PushdownInnerJoin(unique_ptr<LogicalOperator> op,
                                                              unordered_set<idx_t> &left_bindings,
                                                              unordered_set<idx_t> &right_bindings) {
	auto &join = (LogicalJoin &)*op;
	assert(join.join_type == JoinType::INNER);
	assert(op->type != LogicalOperatorType::DELIM_JOIN);
	// inner join: gather all the conditions of the inner join and add to the filter list
	if (op->type == LogicalOperatorType::ANY_JOIN) {
		auto &any_join = (LogicalAnyJoin &)join;
		// any join: only one filter to add
		if (AddFilter(move(any_join.condition)) == FilterResult::UNSATISFIABLE) {
			// filter statically evaluates to false, strip tree
			return make_unique<LogicalEmptyResult>(move(op));
		}
	} else {
		// comparison join
		assert(op->type == LogicalOperatorType::COMPARISON_JOIN);
		auto &comp_join = (LogicalComparisonJoin &)join;
		// turn the conditions into filters
		for (idx_t i = 0; i < comp_join.conditions.size(); i++) {
			auto condition = JoinCondition::CreateExpression(move(comp_join.conditions[i]));
			if (AddFilter(move(condition)) == FilterResult::UNSATISFIABLE) {
				// filter statically evaluates to false, strip tree
				return make_unique<LogicalEmptyResult>(move(op));
			}
		}
	}
	GenerateFilters();

	// turn the inner join into a cross product
	auto cross_product = make_unique<LogicalCrossProduct>();
	cross_product->children.push_back(move(op->children[0]));
	cross_product->children.push_back(move(op->children[1]));
	// then push down cross product
	return PushdownCrossProduct(move(cross_product));
}










using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

static unique_ptr<Expression> ReplaceColRefWithNull(unique_ptr<Expression> expr, unordered_set<idx_t> &right_bindings) {
	if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
		auto &bound_colref = (BoundColumnRefExpression &)*expr;
		if (right_bindings.find(bound_colref.binding.table_index) != right_bindings.end()) {
			// bound colref belongs to RHS
			// replace it with a constant NULL
			return make_unique<BoundConstantExpression>(Value(expr->return_type));
		}
		return expr;
	}
	ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		return ReplaceColRefWithNull(move(child), right_bindings);
	});
	return expr;
}

static bool FilterRemovesNull(ExpressionRewriter &rewriter, Expression *expr, unordered_set<idx_t> &right_bindings) {
	// make a copy of the expression
	auto copy = expr->Copy();
	// replace all BoundColumnRef expressions frmo the RHS with NULL constants in the copied expression
	copy = ReplaceColRefWithNull(move(copy), right_bindings);

	// attempt to flatten the expression by running the expression rewriter on it
	auto filter = make_unique<LogicalFilter>();
	filter->expressions.push_back(move(copy));
	rewriter.Apply(*filter);
	assert(filter->expressions.size() == 1);

	if (filter->expressions[0]->type != ExpressionType::VALUE_CONSTANT) {
		// could not flatten the result
		assert(!filter->expressions[0]->IsFoldable());
		return false;
	}
	// we flattened the result into a scalar, check if it is FALSE or NULL
	auto val = ((BoundConstantExpression &)*filter->expressions[0]).value.CastAs(TypeId::BOOL);
	// if the result of the expression with all expressions replaced with NULL is "NULL" or "false"
	// then any extra entries generated by the LEFT OUTER JOIN will be filtered out!
	// hence the LEFT OUTER JOIN is equivalent to an inner join
	return val.is_null || !val.value_.boolean;
}

unique_ptr<LogicalOperator> FilterPushdown::PushdownLeftJoin(unique_ptr<LogicalOperator> op,
                                                             unordered_set<idx_t> &left_bindings,
                                                             unordered_set<idx_t> &right_bindings) {
	auto &join = (LogicalJoin &)*op;
	assert(join.join_type == JoinType::LEFT);
	assert(op->type != LogicalOperatorType::DELIM_JOIN);
	FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer);
	// for a comparison join we create a FilterCombiner that checks if we can push conditions on LHS join conditions
	// into the RHS of the join
	FilterCombiner filter_combiner;
	if (op->type == LogicalOperatorType::COMPARISON_JOIN) {
		// add all comparison conditions
		auto &comparison_join = (LogicalComparisonJoin &)*op;
		for (auto &cond : comparison_join.conditions) {
			filter_combiner.AddFilter(
			    make_unique<BoundComparisonExpression>(cond.comparison, cond.left->Copy(), cond.right->Copy()));
		}
	}
	// now check the set of filters
	for (idx_t i = 0; i < filters.size(); i++) {
		auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings);
		if (side == JoinSide::LEFT) {
			// bindings match left side
			// we can push the filter into the left side
			if (op->type == LogicalOperatorType::COMPARISON_JOIN) {
				// we MIGHT be able to push it down the RHS as well, but only if it is a comparison that matches the
				// join predicates we use the FilterCombiner to figure this out add the expression to the FilterCombiner
				filter_combiner.AddFilter(filters[i]->filter->Copy());
			}
			left_pushdown.filters.push_back(move(filters[i]));
			// erase the filter from the list of filters
			filters.erase(filters.begin() + i);
			i--;
		} else {
			// bindings match right side or both sides: we cannot directly push it into the right
			// however, if the filter removes rows with null values from the RHS we can turn the left outer join
			// in an inner join, and then push down as we would push down an inner join
			if (FilterRemovesNull(optimizer.rewriter, filters[i]->filter.get(), right_bindings)) {
				// the filter removes NULL values, turn it into an inner join
				join.join_type = JoinType::INNER;
				// now we can do more pushdown
				// move all filters we added to the left_pushdown back into the filter list
				for (auto &left_filter : left_pushdown.filters) {
					filters.push_back(move(left_filter));
				}
				// now push down the inner join
				return PushdownInnerJoin(move(op), left_bindings, right_bindings);
			}
		}
	}
	// finally we check the FilterCombiner to see if there are any predicates we can push into the RHS
	// we only added (1) predicates that have JoinSide::BOTH from the conditions, and
	// (2) predicates that have JoinSide::LEFT from the filters
	// we check now if this combination generated any new filters that are only on JoinSide::RIGHT
	// this happens if, e.g. a join condition is (i=a) and there is a filter (i=500), we can then push the filter
	// (a=500) into the RHS
	filter_combiner.GenerateFilters([&](unique_ptr<Expression> filter) {
		if (JoinSide::GetJoinSide(*filter, left_bindings, right_bindings) == JoinSide::RIGHT) {
			right_pushdown.AddFilter(move(filter));
		}
	});
	right_pushdown.GenerateFilters();
	op->children[0] = left_pushdown.Rewrite(move(op->children[0]));
	op->children[1] = right_pushdown.Rewrite(move(op->children[1]));
	return FinishPushdown(move(op));
}




using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

unique_ptr<LogicalOperator> FilterPushdown::PushdownMarkJoin(unique_ptr<LogicalOperator> op,
                                                             unordered_set<idx_t> &left_bindings,
                                                             unordered_set<idx_t> &right_bindings) {
	auto &join = (LogicalJoin &)*op;
	auto &comp_join = (LogicalComparisonJoin &)*op;
	assert(join.join_type == JoinType::MARK);
	assert(op->type == LogicalOperatorType::COMPARISON_JOIN || op->type == LogicalOperatorType::DELIM_JOIN);

	right_bindings.insert(comp_join.mark_index);
	FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer);
	bool found_mark_reference = false;
	// now check the set of filters
	for (idx_t i = 0; i < filters.size(); i++) {
		auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings);
		if (side == JoinSide::LEFT) {
			// bindings match left side: push into left
			left_pushdown.filters.push_back(move(filters[i]));
			// erase the filter from the list of filters
			filters.erase(filters.begin() + i);
			i--;
		} else if (side == JoinSide::RIGHT) {
			// there can only be at most one filter referencing the marker
			assert(!found_mark_reference);
			found_mark_reference = true;
			// this filter references the marker
			// we can turn this into a SEMI join if the filter is on only the marker
			if (filters[i]->filter->type == ExpressionType::BOUND_COLUMN_REF) {
				// filter just references the marker: turn into semi join
				join.join_type = JoinType::SEMI;
				filters.erase(filters.begin() + i);
				i--;
				continue;
			}
			// if the filter is on NOT(marker) AND the join conditions are all set to "null_values_are_equal" we can
			// turn this into an ANTI join if all join conditions have null_values_are_equal=true, then the result of
			// the MARK join is always TRUE or FALSE, and never NULL this happens in the case of a correlated EXISTS
			// clause
			if (filters[i]->filter->type == ExpressionType::OPERATOR_NOT) {
				auto &op_expr = (BoundOperatorExpression &)*filters[i]->filter;
				if (op_expr.children[0]->type == ExpressionType::BOUND_COLUMN_REF) {
					// the filter is NOT(marker), check the join conditions
					bool all_null_values_are_equal = true;
					for (auto &cond : comp_join.conditions) {
						if (!cond.null_values_are_equal) {
							all_null_values_are_equal = false;
							break;
						}
					}
					if (all_null_values_are_equal) {
						// all null values are equal, convert to ANTI join
						join.join_type = JoinType::ANTI;
						filters.erase(filters.begin() + i);
						i--;
						continue;
					}
				}
			}
		}
	}
	op->children[0] = left_pushdown.Rewrite(move(op->children[0]));
	op->children[1] = right_pushdown.Rewrite(move(op->children[1]));
	return FinishPushdown(move(op));
}






using namespace duckdb;
using namespace std;

static unique_ptr<Expression> ReplaceProjectionBindings(LogicalProjection &proj, unique_ptr<Expression> expr) {
	if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
		auto &colref = (BoundColumnRefExpression &)*expr;
		assert(colref.binding.table_index == proj.table_index);
		assert(colref.binding.column_index < proj.expressions.size());
		assert(colref.depth == 0);
		// replace the binding with a copy to the expression at the referenced index
		return proj.expressions[colref.binding.column_index]->Copy();
	}
	ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		return ReplaceProjectionBindings(proj, move(child));
	});
	return expr;
}

unique_ptr<LogicalOperator> FilterPushdown::PushdownProjection(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::PROJECTION);
	auto &proj = (LogicalProjection &)*op;
	// push filter through logical projection
	// all the BoundColumnRefExpressions in the filter should refer to the LogicalProjection
	// we can rewrite them by replacing those references with the expression of the LogicalProjection node
	FilterPushdown child_pushdown(optimizer);
	for (idx_t i = 0; i < filters.size(); i++) {
		auto &f = *filters[i];
		assert(f.bindings.size() <= 1);
		// rewrite the bindings within this subquery
		f.filter = ReplaceProjectionBindings(proj, move(f.filter));
		// add the filter to the child pushdown
		if (child_pushdown.AddFilter(move(f.filter)) == FilterResult::UNSATISFIABLE) {
			// filter statically evaluates to false, strip tree
			return make_unique<LogicalEmptyResult>(move(op));
		}
	}
	child_pushdown.GenerateFilters();
	// now push into children
	op->children[0] = child_pushdown.Rewrite(move(op->children[0]));
	return op;
}







using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

static void ReplaceSetOpBindings(vector<ColumnBinding> &bindings, Filter &filter, Expression &expr,
                                 LogicalSetOperation &setop) {
	if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
		auto &colref = (BoundColumnRefExpression &)expr;
		assert(colref.binding.table_index == setop.table_index);
		assert(colref.depth == 0);

		// rewrite the binding by looking into the bound_tables list of the subquery
		colref.binding = bindings[colref.binding.column_index];
		filter.bindings.insert(colref.binding.table_index);
		return;
	}
	ExpressionIterator::EnumerateChildren(
	    expr, [&](Expression &child) { ReplaceSetOpBindings(bindings, filter, child, setop); });
}

unique_ptr<LogicalOperator> FilterPushdown::PushdownSetOperation(unique_ptr<LogicalOperator> op) {
	assert(op->type == LogicalOperatorType::UNION || op->type == LogicalOperatorType::EXCEPT ||
	       op->type == LogicalOperatorType::INTERSECT);
	auto &setop = (LogicalSetOperation &)*op;

	assert(op->children.size() == 2);
	auto left_bindings = op->children[0]->GetColumnBindings();
	auto right_bindings = op->children[1]->GetColumnBindings();

	// pushdown into set operation, we can duplicate the condition and pushdown the expressions into both sides
	FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer);
	for (idx_t i = 0; i < filters.size(); i++) {
		// first create a copy of the filter
		auto right_filter = make_unique<Filter>();
		right_filter->filter = filters[i]->filter->Copy();

		// in the original filter, rewrite references to the result of the union into references to the left_index
		ReplaceSetOpBindings(left_bindings, *filters[i], *filters[i]->filter, setop);
		// in the copied filter, rewrite references to the result of the union into references to the right_index
		ReplaceSetOpBindings(right_bindings, *right_filter, *right_filter->filter, setop);

		// extract bindings again
		filters[i]->ExtractBindings();
		right_filter->ExtractBindings();

		// move the filters into the child pushdown nodes
		left_pushdown.filters.push_back(move(filters[i]));
		right_pushdown.filters.push_back(move(right_filter));
	}

	op->children[0] = left_pushdown.Rewrite(move(op->children[0]));
	op->children[1] = right_pushdown.Rewrite(move(op->children[1]));
	return op;
}



using namespace duckdb;
using namespace std;

using Filter = FilterPushdown::Filter;

unique_ptr<LogicalOperator> FilterPushdown::PushdownSingleJoin(unique_ptr<LogicalOperator> op,
                                                               unordered_set<idx_t> &left_bindings,
                                                               unordered_set<idx_t> &right_bindings) {
	assert(((LogicalJoin &)*op).join_type == JoinType::SINGLE);
	FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer);
	// now check the set of filters
	for (idx_t i = 0; i < filters.size(); i++) {
		auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings);
		if (side == JoinSide::LEFT) {
			// bindings match left side: push into left
			left_pushdown.filters.push_back(move(filters[i]));
			// erase the filter from the list of filters
			filters.erase(filters.begin() + i);
			i--;
		}
	}
	op->children[0] = left_pushdown.Rewrite(move(op->children[0]));
	op->children[1] = right_pushdown.Rewrite(move(op->children[1]));
	return FinishPushdown(move(op));
}













using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> RegexRangeFilter::Rewrite(unique_ptr<LogicalOperator> op) {

	for (idx_t child_idx = 0; child_idx < op->children.size(); child_idx++) {
		op->children[child_idx] = Rewrite(move(op->children[child_idx]));
	}

	if (op->type != LogicalOperatorType::FILTER) {
		return op;
	}

	auto new_filter = make_unique<LogicalFilter>();

	for (auto &expr : op->expressions) {
		if (expr->type == ExpressionType::BOUND_FUNCTION) {
			auto &func = (BoundFunctionExpression &)*expr.get();
			if (func.function.name != "regexp_matches" || func.children.size() != 2) {
				continue;
			}
			auto &info = (RegexpMatchesBindData &)*func.bind_info;
			if (!info.range_success) {
				continue;
			}
			auto filter_left = make_unique<BoundComparisonExpression>(
			    ExpressionType::COMPARE_GREATERTHANOREQUALTO, func.children[0]->Copy(),
			    make_unique<BoundConstantExpression>(Value(info.range_min)));
			auto filter_right = make_unique<BoundComparisonExpression>(
			    ExpressionType::COMPARE_LESSTHANOREQUALTO, func.children[0]->Copy(),
			    make_unique<BoundConstantExpression>(Value(info.range_max)));
			auto filter_expr = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_AND,
			                                                           move(filter_left), move(filter_right));

			new_filter->expressions.push_back(move(filter_expr));
		}
	}

	if (new_filter->expressions.size() > 0) {
		new_filter->children = move(op->children);
		op->children.clear();
		op->children.push_back(move(new_filter));
	}

	return op;
}

















using namespace duckdb;
using namespace std;

void RemoveUnusedColumns::ReplaceBinding(ColumnBinding current_binding, ColumnBinding new_binding) {
	auto colrefs = column_references.find(current_binding);
	if (colrefs != column_references.end()) {
		for (auto &colref : colrefs->second) {
			assert(colref->binding == current_binding);
			colref->binding = new_binding;
		}
	}
}

template <class T> void RemoveUnusedColumns::ClearUnusedExpressions(vector<T> &list, idx_t table_idx) {
	idx_t offset = 0;
	for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) {
		auto current_binding = ColumnBinding(table_idx, col_idx + offset);
		auto entry = column_references.find(current_binding);
		if (entry == column_references.end()) {
			// this entry is not referred to, erase it from the set of expresisons
			list.erase(list.begin() + col_idx);
			offset++;
			col_idx--;
		} else if (offset > 0) {
			// column is used but the ColumnBinding has changed because of removed columns
			ReplaceBinding(current_binding, ColumnBinding(table_idx, col_idx));
		}
	}
}

void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
	switch (op.type) {
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY: {
		// aggregate
		if (!everything_referenced) {
			// FIXME: groups that are not referenced need to stay -> but they don't need to be scanned and output!
			auto &aggr = (LogicalAggregate &)op;
			ClearUnusedExpressions(aggr.expressions, aggr.aggregate_index);

			if (aggr.expressions.size() == 0 && aggr.groups.size() == 0) {
				// removed all expressions from the aggregate: push a COUNT(*)
				aggr.expressions.push_back(
				    make_unique<BoundAggregateExpression>(TypeId::INT64, CountStarFun::GetFunction(), false));
			}
		}

		// then recurse into the children of the aggregate
		RemoveUnusedColumns remove;
		remove.VisitOperatorExpressions(op);
		remove.VisitOperator(*op.children[0]);
		return;
	}
	case LogicalOperatorType::DELIM_JOIN:
	case LogicalOperatorType::COMPARISON_JOIN: {
		if (!everything_referenced) {
			auto &comp_join = (LogicalComparisonJoin &)op;

			if (comp_join.join_type != JoinType::INNER) {
				break;
			}
			// for inner joins with equality predicates in the form of (X=Y)
			// we can replace any references to the RHS (Y) to references to the LHS (X)
			// this reduces the amount of columns we need to extract from the join hash table
			for (auto &cond : comp_join.conditions) {
				if (cond.comparison == ExpressionType::COMPARE_EQUAL) {
					if (cond.left->expression_class == ExpressionClass::BOUND_COLUMN_REF &&
					    cond.right->expression_class == ExpressionClass::BOUND_COLUMN_REF) {
						// comparison join between two bound column refs
						// we can replace any reference to the RHS (build-side) with a reference to the LHS (probe-side)
						auto &lhs_col = (BoundColumnRefExpression &)*cond.left;
						auto &rhs_col = (BoundColumnRefExpression &)*cond.right;
						// if there are any columns that refer to the RHS,
						auto colrefs = column_references.find(rhs_col.binding);
						if (colrefs != column_references.end()) {
							for (auto &entry : colrefs->second) {
								entry->binding = lhs_col.binding;
								column_references[lhs_col.binding].push_back(entry);
							}
							column_references.erase(rhs_col.binding);
						}
					}
				}
			}
		}
		break;
	}
	case LogicalOperatorType::ANY_JOIN:
		break;
	case LogicalOperatorType::UNION:
	case LogicalOperatorType::EXCEPT:
	case LogicalOperatorType::INTERSECT:
		// for set operations we don't remove anything, just recursively visit the children
		// FIXME: for UNION we can remove unreferenced columns as long as everything_referenced is false (i.e. we
		// encounter a UNION node that is not preceded by a DISTINCT)
		for (auto &child : op.children) {
			RemoveUnusedColumns remove(true);
			remove.VisitOperator(*child);
		}
		return;
	case LogicalOperatorType::PROJECTION: {
		if (!everything_referenced) {
			auto &proj = (LogicalProjection &)op;
			ClearUnusedExpressions(proj.expressions, proj.table_index);

			if (proj.expressions.size() == 0) {
				// nothing references the projected expressions
				// this happens in the case of e.g. EXISTS(SELECT * FROM ...)
				// in this case we only need to project a single constant
				proj.expressions.push_back(make_unique<BoundConstantExpression>(Value::INTEGER(42)));
			}
		}
		// then recurse into the children of this projection
		RemoveUnusedColumns remove;
		remove.VisitOperatorExpressions(op);
		remove.VisitOperator(*op.children[0]);
		return;
	}
	case LogicalOperatorType::GET:
		LogicalOperatorVisitor::VisitOperatorExpressions(op);
		if (!everything_referenced) {
			auto &get = (LogicalGet &)op;
			// table scan: figure out which columns are referenced
			ClearUnusedExpressions(get.column_ids, get.table_index);

			if (get.column_ids.size() == 0) {
				// this generally means we are only interested in whether or not anything exists in the table (e.g.
				// EXISTS(SELECT * FROM tbl)) in this case, we just scan the row identifier column as it means we do not
				// need to read any of the columns
				get.column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
			}
		}
		return;
	case LogicalOperatorType::DISTINCT: {
		// distinct, all projected columns are used for the DISTINCT computation
		// mark all columns as used and continue to the children
		// FIXME: DISTINCT with expression list does not implicitly reference everything
		everything_referenced = true;
		break;
	}
	case LogicalOperatorType::RECURSIVE_CTE: {
		everything_referenced = true;
		break;
	}
	case LogicalOperatorType::CTE_REF: {
		everything_referenced = true;
		break;
	}
	default:
		break;
	}
	LogicalOperatorVisitor::VisitOperatorExpressions(op);
	LogicalOperatorVisitor::VisitOperatorChildren(op);
}

unique_ptr<Expression> RemoveUnusedColumns::VisitReplace(BoundColumnRefExpression &expr,
                                                         unique_ptr<Expression> *expr_ptr) {
	// add a column reference
	column_references[expr.binding].push_back(&expr);
	return nullptr;
}

unique_ptr<Expression> RemoveUnusedColumns::VisitReplace(BoundReferenceExpression &expr,
                                                         unique_ptr<Expression> *expr_ptr) {
	// BoundReferenceExpression should not be used here yet, they only belong in the physical plan
	throw InternalException("BoundReferenceExpression should not be used here yet!");
}






using namespace duckdb;
using namespace std;

ArithmeticSimplificationRule::ArithmeticSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	// match on an OperatorExpression that has a ConstantExpression as child
	auto op = make_unique<FunctionExpressionMatcher>();
	op->matchers.push_back(make_unique<ConstantExpressionMatcher>());
	op->matchers.push_back(make_unique<ExpressionMatcher>());
	op->policy = SetMatcher::Policy::SOME;
	// we only match on simple arithmetic expressions (+, -, *, /)
	op->function = make_unique<ManyFunctionMatcher>(unordered_set<string>{"+", "-", "*", "/"});
	// and only with numeric results
	op->type = make_unique<IntegerTypeMatcher>();
	root = move(op);
}

unique_ptr<Expression> ArithmeticSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                           bool &changes_made) {
	auto root = (BoundFunctionExpression *)bindings[0];
	auto constant = (BoundConstantExpression *)bindings[1];
	int constant_child = root->children[0].get() == constant ? 0 : 1;
	assert(root->children.size() == 2);
	// any arithmetic operator involving NULL is always NULL
	if (constant->value.is_null) {
		return make_unique<BoundConstantExpression>(Value(root->return_type));
	}
	auto &func_name = root->function.name;
	if (func_name == "+") {
		if (constant->value == 0) {
			// addition with 0
			// we can remove the entire operator and replace it with the non-constant child
			return move(root->children[1 - constant_child]);
		}
	} else if (func_name == "-") {
		if (constant_child == 1 && constant->value == 0) {
			// subtraction by 0
			// we can remove the entire operator and replace it with the non-constant child
			return move(root->children[1 - constant_child]);
		}
	} else if (func_name == "*") {
		if (constant->value == 1) {
			// multiply with 1, replace with non-constant child
			return move(root->children[1 - constant_child]);
		}
	} else {
		assert(func_name == "/");
		if (constant_child == 1) {
			if (constant->value == 1) {
				// divide by 1, replace with non-constant child
				return move(root->children[1 - constant_child]);
			} else if (constant->value == 0) {
				// divide by 0, replace with NULL
				return make_unique<BoundConstantExpression>(Value(root->return_type));
			}
		}
	}
	return nullptr;
}





using namespace duckdb;
using namespace std;

CaseSimplificationRule::CaseSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	// match on a CaseExpression that has a ConstantExpression as a check
	auto op = make_unique<CaseExpressionMatcher>();
	op->check = make_unique<FoldableConstantMatcher>();
	root = move(op);
}

unique_ptr<Expression> CaseSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                     bool &changes_made) {
	auto root = (BoundCaseExpression *)bindings[0];
	auto constant_expr = bindings[1];
	// the constant_expr is a scalar expression that we have to fold
	assert(constant_expr->IsFoldable());

	// use an ExpressionExecutor to execute the expression
	auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr);

	// fold based on the constant condition
	auto condition = constant_value.CastAs(TypeId::BOOL);
	if (condition.is_null || !condition.value_.boolean) {
		return move(root->result_if_false);
	} else {
		return move(root->result_if_true);
	}
}





using namespace duckdb;
using namespace std;

ComparisonSimplificationRule::ComparisonSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	// match on a ComparisonExpression that has a ConstantExpression as a check
	auto op = make_unique<ComparisonExpressionMatcher>();
	op->matchers.push_back(make_unique<FoldableConstantMatcher>());
	op->policy = SetMatcher::Policy::SOME;
	root = move(op);
}

unique_ptr<Expression> ComparisonSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                           bool &changes_made) {
	auto constant_expr = bindings[1];
	// the constant_expr is a scalar expression that we have to fold
	// use an ExpressionExecutor to execute the expression
	assert(constant_expr->IsFoldable());
	auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr);
	if (constant_value.is_null) {
		// comparison with constant NULL, return NULL
		return make_unique<BoundConstantExpression>(Value(TypeId::BOOL));
	}
	return nullptr;
}






using namespace duckdb;
using namespace std;

ConjunctionSimplificationRule::ConjunctionSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	// match on a ComparisonExpression that has a ConstantExpression as a check
	auto op = make_unique<ConjunctionExpressionMatcher>();
	op->matchers.push_back(make_unique<FoldableConstantMatcher>());
	op->policy = SetMatcher::Policy::SOME;
	root = move(op);
}

unique_ptr<Expression> ConjunctionSimplificationRule::RemoveExpression(BoundConjunctionExpression &conj,
                                                                       Expression *expr) {
	for (idx_t i = 0; i < conj.children.size(); i++) {
		if (conj.children[i].get() == expr) {
			// erase the expression
			conj.children.erase(conj.children.begin() + i);
			break;
		}
	}
	if (conj.children.size() == 1) {
		// one expression remaining: simply return that expression and erase the conjunction
		return move(conj.children[0]);
	}
	return nullptr;
}

unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                            bool &changes_made) {
	auto conjunction = (BoundConjunctionExpression *)bindings[0];
	auto constant_expr = bindings[1];
	// the constant_expr is a scalar expression that we have to fold
	// use an ExpressionExecutor to execute the expression
	assert(constant_expr->IsFoldable());
	auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr).CastAs(TypeId::BOOL);
	if (constant_value.is_null) {
		// we can't simplify conjunctions with a constant NULL
		return nullptr;
	}
	if (conjunction->type == ExpressionType::CONJUNCTION_AND) {
		if (!constant_value.value_.boolean) {
			// FALSE in AND, result of expression is false
			return make_unique<BoundConstantExpression>(Value::BOOLEAN(false));
		} else {
			// TRUE in AND, remove the expression from the set
			return RemoveExpression(*conjunction, constant_expr);
		}
	} else {
		assert(conjunction->type == ExpressionType::CONJUNCTION_OR);
		if (!constant_value.value_.boolean) {
			// FALSE in OR, remove the expression from the set
			return RemoveExpression(*conjunction, constant_expr);
		} else {
			// TRUE in OR, result of expression is true
			return make_unique<BoundConstantExpression>(Value::BOOLEAN(true));
		}
	}
}







using namespace duckdb;
using namespace std;

namespace duckdb {

//! The ConstantFoldingExpressionMatcher matches on any scalar expression (i.e. Expression::IsFoldable is true)
class ConstantFoldingExpressionMatcher : public FoldableConstantMatcher {
public:
	bool Match(Expression *expr, vector<Expression *> &bindings) override {
		// we also do not match on ConstantExpressions, because we cannot fold those any further
		if (expr->type == ExpressionType::VALUE_CONSTANT) {
			return false;
		}
		return FoldableConstantMatcher::Match(expr, bindings);
	}
};
} // namespace duckdb

ConstantFoldingRule::ConstantFoldingRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	auto op = make_unique<ConstantFoldingExpressionMatcher>();
	root = move(op);
}

unique_ptr<Expression> ConstantFoldingRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                  bool &changes_made) {
	auto root = bindings[0];
	// the root is a scalar expression that we have to fold
	assert(root->IsFoldable() && root->type != ExpressionType::VALUE_CONSTANT);

	// use an ExpressionExecutor to execute the expression
	auto result_value = ExpressionExecutor::EvaluateScalar(*root);
	assert(result_value.type == root->return_type);
	// now get the value from the result vector and insert it back into the plan as a constant expression
	return make_unique<BoundConstantExpression>(result_value);
}










using namespace duckdb;
using namespace std;

DatePartSimplificationRule::DatePartSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	auto func = make_unique<FunctionExpressionMatcher>();
	func->function = make_unique<SpecificFunctionMatcher>("date_part");
	func->matchers.push_back(make_unique<ConstantExpressionMatcher>());
	func->matchers.push_back(make_unique<ExpressionMatcher>());
	func->policy = SetMatcher::Policy::ORDERED;
	root = move(func);
}

unique_ptr<Expression> DatePartSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                         bool &changes_made) {
	auto &date_part = (BoundFunctionExpression &)*bindings[0];
	auto &constant_expr = (BoundConstantExpression &)*bindings[1];
	auto &constant = constant_expr.value;

	if (constant.is_null) {
		// NULL specifier: return constant NULL
		return make_unique<BoundConstantExpression>(Value(date_part.return_type));
	}
	// otherwise check the specifier
	auto specifier = GetDatePartSpecifier(constant.str_value);
	string new_function_name;
	switch (specifier) {
	case DatePartSpecifier::YEAR:
		new_function_name = "year";
		break;
	case DatePartSpecifier::MONTH:
		new_function_name = "month";
		break;
	case DatePartSpecifier::DAY:
		new_function_name = "day";
		break;
	case DatePartSpecifier::DECADE:
		new_function_name = "decade";
		break;
	case DatePartSpecifier::CENTURY:
		new_function_name = "century";
		break;
	case DatePartSpecifier::MILLENNIUM:
		new_function_name = "millenium";
		break;
	case DatePartSpecifier::QUARTER:
		new_function_name = "quarter";
		break;
	case DatePartSpecifier::WEEK:
		new_function_name = "week";
		break;
	case DatePartSpecifier::DOW:
		new_function_name = "dayofweek";
		break;
	case DatePartSpecifier::ISODOW:
		new_function_name = "isodow";
		break;
	case DatePartSpecifier::DOY:
		new_function_name = "dayofyear";
		break;
	case DatePartSpecifier::EPOCH:
		new_function_name = "epoch";
		break;
	case DatePartSpecifier::MICROSECONDS:
		new_function_name = "microsecond";
		break;
	case DatePartSpecifier::MILLISECONDS:
		new_function_name = "millisecond";
		break;
	case DatePartSpecifier::SECOND:
		new_function_name = "second";
		break;
	case DatePartSpecifier::MINUTE:
		new_function_name = "minute";
		break;
	case DatePartSpecifier::HOUR:
		new_function_name = "hour";
		break;
	default:
		return nullptr;
	}
	// found a replacement function: bind it
	vector<SQLType> arguments{date_part.function.arguments[1]};
	vector<unique_ptr<Expression>> children;
	children.push_back(move(date_part.children[1]));

	return ScalarFunction::BindScalarFunction(rewriter.context, DEFAULT_SCHEMA, new_function_name, arguments,
	                                          move(children), false);
}








using namespace duckdb;
using namespace std;

DistributivityRule::DistributivityRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	// we match on an OR expression within a LogicalFilter node
	root = make_unique<ExpressionMatcher>();
	root->expr_type = make_unique<SpecificExpressionTypeMatcher>(ExpressionType::CONJUNCTION_OR);
}

void DistributivityRule::AddExpressionSet(Expression &expr, expression_set_t &set) {
	if (expr.type == ExpressionType::CONJUNCTION_AND) {
		auto &and_expr = (BoundConjunctionExpression &)expr;
		for (auto &child : and_expr.children) {
			set.insert(child.get());
		}
	} else {
		set.insert(&expr);
	}
}

unique_ptr<Expression> DistributivityRule::ExtractExpression(BoundConjunctionExpression &conj, idx_t idx,
                                                             Expression &expr) {
	auto &child = conj.children[idx];
	unique_ptr<Expression> result;
	if (child->type == ExpressionType::CONJUNCTION_AND) {
		// AND, remove expression from the list
		auto &and_expr = (BoundConjunctionExpression &)*child;
		for (idx_t i = 0; i < and_expr.children.size(); i++) {
			if (Expression::Equals(and_expr.children[i].get(), &expr)) {
				result = move(and_expr.children[i]);
				and_expr.children.erase(and_expr.children.begin() + i);
				break;
			}
		}
		if (and_expr.children.size() == 1) {
			conj.children[idx] = move(and_expr.children[0]);
		}
	} else {
		// not an AND node! remove the entire expression
		// this happens in the case of e.g. (X AND B) OR X
		assert(Expression::Equals(child.get(), &expr));
		result = move(child);
		conj.children[idx] = nullptr;
	}
	assert(result);
	return result;
}

unique_ptr<Expression> DistributivityRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                 bool &changes_made) {
	auto initial_or = (BoundConjunctionExpression *)bindings[0];

	// we want to find expressions that occur in each of the children of the OR
	// i.e. (X AND A) OR (X AND B) => X occurs in all branches
	// first, for the initial child, we create an expression set of which expressions occur
	// this is our initial candidate set (in the example: [X, A])
	expression_set_t candidate_set;
	AddExpressionSet(*initial_or->children[0], candidate_set);
	// now for each of the remaining children, we create a set again and intersect them
	// in our example: the second set would be [X, B]
	// the intersection would leave [X]
	for (idx_t i = 1; i < initial_or->children.size(); i++) {
		expression_set_t next_set;
		AddExpressionSet(*initial_or->children[i], next_set);
		expression_set_t intersect_result;
		for (auto &expr : candidate_set) {
			if (next_set.find(expr) != next_set.end()) {
				intersect_result.insert(expr);
			}
		}
		candidate_set = intersect_result;
	}
	if (candidate_set.size() == 0) {
		// nothing found: abort
		return nullptr;
	}
	// now for each of the remaining expressions in the candidate set we know that it is contained in all branches of
	// the OR
	auto new_root = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_AND);
	for (auto &expr : candidate_set) {
		assert(initial_or->children.size() > 0);

		// extract the expression from the first child of the OR
		auto result = ExtractExpression(*initial_or, 0, (Expression &)*expr);
		// now for the subsequent expressions, simply remove the expression
		for (idx_t i = 1; i < initial_or->children.size(); i++) {
			ExtractExpression(*initial_or, i, *result);
		}
		// now we add the expression to the new root
		new_root->children.push_back(move(result));
		// remove any expressions that were set to nullptr
		for (idx_t i = 0; i < initial_or->children.size(); i++) {
			if (!initial_or->children[i]) {
				initial_or->children.erase(initial_or->children.begin() + i);
				i--;
			}
		}
	}
	// finally we need to add the remaining expressions in the OR to the new root
	if (initial_or->children.size() == 1) {
		// one child: skip the OR entirely and only add the single child
		new_root->children.push_back(move(initial_or->children[0]));
	} else if (initial_or->children.size() > 1) {
		// multiple children still remain: push them into a new OR and add that to the new root
		auto new_or = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_OR);
		for (auto &child : initial_or->children) {
			new_or->children.push_back(move(child));
		}
		new_root->children.push_back(move(new_or));
	}
	// finally return the new root
	if (new_root->children.size() == 1) {
		return move(new_root->children[0]);
	}
	return move(new_root);
}








using namespace duckdb;
using namespace std;

MoveConstantsRule::MoveConstantsRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
	auto op = make_unique<ComparisonExpressionMatcher>();
	op->matchers.push_back(make_unique<ConstantExpressionMatcher>());
	op->policy = SetMatcher::Policy::UNORDERED;

	auto arithmetic = make_unique<FunctionExpressionMatcher>();
	// we handle multiplication, addition and subtraction because those are "easy"
	// integer division makes the division case difficult
	// e.g. [x / 2 = 3] means [x = 6 OR x = 7] because of truncation -> no clean rewrite rules
	arithmetic->function = make_unique<ManyFunctionMatcher>(unordered_set<string>{"+", "-", "*"});
	// we match only on integral numeric types
	arithmetic->type = make_unique<IntegerTypeMatcher>();
	arithmetic->matchers.push_back(make_unique<ConstantExpressionMatcher>());
	arithmetic->matchers.push_back(make_unique<ExpressionMatcher>());
	arithmetic->policy = SetMatcher::Policy::SOME;
	op->matchers.push_back(move(arithmetic));
	root = move(op);
}

unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
                                                bool &changes_made) {
	auto comparison = (BoundComparisonExpression *)bindings[0];
	auto outer_constant = (BoundConstantExpression *)bindings[1];
	auto arithmetic = (BoundFunctionExpression *)bindings[2];
	auto inner_constant = (BoundConstantExpression *)bindings[3];

	int arithmetic_child_index = arithmetic->children[0].get() == inner_constant ? 1 : 0;
	auto &op_type = arithmetic->function.name;
	if (op_type == "+") {
		// [x + 1 COMP 10] OR [1 + x COMP 10]
		// order does not matter in addition:
		// simply change right side to 10-1 (outer_constant - inner_constant)
		outer_constant->value = outer_constant->value - inner_constant->value;
	} else if (op_type == "-") {
		// [x - 1 COMP 10] O R [1 - x COMP 10]
		// order matters in subtraction:
		if (arithmetic_child_index == 0) {
			// [x - 1 COMP 10]
			// change right side to 10+1 (outer_constant + inner_constant)
			outer_constant->value = outer_constant->value + inner_constant->value;
		} else {
			// [1 - x COMP 10]
			// change right side to 1-10=-9
			outer_constant->value = inner_constant->value - outer_constant->value;
			// in this case, we should also flip the comparison
			// e.g. if we have [4 - x < 2] then we should have [x > 2]
			comparison->type = FlipComparisionExpression(comparison->type);
		}
	} else {
		assert(op_type == "*");
		// [x * 2 COMP 10] OR [2 * x COMP 10]
		// order does not matter in multiplication:
		// change right side to 10/2 (outer_constant / inner_constant)
		// but ONLY if outer_constant is cleanly divisible by the inner_constant
		if (inner_constant->value == 0) {
			// x * 0, the result is either 0 or NULL
			// thus the final result will be either [TRUE, FALSE] or [NULL], depending
			// on if 0 matches the comparison criteria with the RHS
			// for now we don't fold, but we can fold to "ConstantOrNull"
			return nullptr;
		}
		if (ValueOperations::Modulo(outer_constant->value, inner_constant->value) != 0) {
			// not cleanly divisible, the result will be either FALSE or NULL
			// for now, we don't do anything
			return nullptr;
		}
		if (inner_constant->value < 0) {
			// multiply by negative value, need to flip expression
			comparison->type = FlipComparisionExpression(comparison->type);
		}
		// else divide the RHS by the LHS
		outer_constant->value = outer_constant->value / inner_constant->value;
	}
	// replace left side with x
	// first extract x from the arithmetic expression
	auto arithmetic_child = move(arithmetic->children[arithmetic_child_index]);
	// then place in the comparison
	if (comparison->left.get() == outer_constant) {
		comparison->right = move(arithmetic_child);
	} else {
		comparison->left = move(arithmetic_child);
	}
	changes_made = true;
	return nullptr;
}





using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> TopN::Optimize(unique_ptr<LogicalOperator> op) {
	if (op->type == LogicalOperatorType::LIMIT && op->children[0]->type == LogicalOperatorType::ORDER_BY) {
		auto &limit = (LogicalLimit &)*op;
		auto &order_by = (LogicalOrder &)*(op->children[0]);

		// This optimization doesn't apply when OFFSET is present without LIMIT
		if (limit.limit != std::numeric_limits<int64_t>::max()) {
			auto topn = make_unique<LogicalTopN>(move(order_by.orders), limit.limit, limit.offset);
			topn->AddChild(move(order_by.children[0]));
			op = move(topn);
		}
	} else {
		for (auto &child : op->children) {
			child = Optimize(move(child));
		}
	}
	return op;
}




using namespace duckdb;
using namespace std;

void BaseExpression::Print() {
	Printer::Print(ToString());
}

bool BaseExpression::Equals(const BaseExpression *other) const {
	if (!other) {
		return false;
	}
	if (this->expression_class != other->expression_class || this->type != other->type) {
		return false;
	}
	return true;
}






using namespace duckdb;
using namespace std;

void Constraint::Serialize(Serializer &serializer) {
	serializer.Write<ConstraintType>(type);
}

unique_ptr<Constraint> Constraint::Deserialize(Deserializer &source) {
	auto type = source.Read<ConstraintType>();
	switch (type) {
	case ConstraintType::NOT_NULL:
		return NotNullConstraint::Deserialize(source);
	case ConstraintType::CHECK:
		return CheckConstraint::Deserialize(source);
	case ConstraintType::UNIQUE:
		return UniqueConstraint::Deserialize(source);
	default:
		// don't know how to serialize this constraint type
		return nullptr;
	}
}

void Constraint::Print() {
	Printer::Print(ToString());
}




using namespace std;
using namespace duckdb;

string CheckConstraint::ToString() const {
	return "CHECK(" + expression->ToString() + ")";
}

unique_ptr<Constraint> CheckConstraint::Copy() {
	return make_unique<CheckConstraint>(expression->Copy());
}

void CheckConstraint::Serialize(Serializer &serializer) {
	Constraint::Serialize(serializer);
	expression->Serialize(serializer);
}

unique_ptr<Constraint> CheckConstraint::Deserialize(Deserializer &source) {
	auto expression = ParsedExpression::Deserialize(source);
	return make_unique<CheckConstraint>(move(expression));
}




using namespace std;
using namespace duckdb;

string NotNullConstraint::ToString() const {
	return "NOT NULL Constraint";
}

unique_ptr<Constraint> NotNullConstraint::Copy() {
	return make_unique<NotNullConstraint>(index);
}

void NotNullConstraint::Serialize(Serializer &serializer) {
	Constraint::Serialize(serializer);
	serializer.Write<idx_t>(index);
}

unique_ptr<Constraint> NotNullConstraint::Deserialize(Deserializer &source) {
	auto index = source.Read<idx_t>();
	return make_unique_base<Constraint, NotNullConstraint>(index);
}




using namespace std;
using namespace duckdb;

string UniqueConstraint::ToString() const {
	return is_primary_key ? "PRIMARY KEY constraint" : "UNIQUE Constraint";
}

unique_ptr<Constraint> UniqueConstraint::Copy() {
	if (index == INVALID_INDEX) {
		return make_unique<UniqueConstraint>(columns, is_primary_key);
	} else {
		assert(columns.size() == 0);
		return make_unique<UniqueConstraint>(index, is_primary_key);
	}
}

void UniqueConstraint::Serialize(Serializer &serializer) {
	Constraint::Serialize(serializer);
	serializer.Write<bool>(is_primary_key);
	serializer.Write<uint64_t>(index);
	assert(columns.size() <= numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)columns.size());
	for (auto &column : columns) {
		serializer.WriteString(column);
	}
}

unique_ptr<Constraint> UniqueConstraint::Deserialize(Deserializer &source) {
	auto is_primary_key = source.Read<bool>();
	auto index = source.Read<uint64_t>();
	auto column_count = source.Read<uint32_t>();

	if (index != INVALID_INDEX) {
		// single column parsed constraint
		return make_unique<UniqueConstraint>(index, is_primary_key);
	} else {
		// column list parsed constraint
		vector<string> columns;
		for (uint32_t i = 0; i < column_count; i++) {
			auto column_name = source.Read<string>();
			columns.push_back(column_name);
		}
		return make_unique<UniqueConstraint>(columns, is_primary_key);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/case_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The CaseExpression represents a CASE expression in the query
class CaseExpression : public ParsedExpression {
public:
	// this expression has 3 children, (1) the check, (2) the result if the test is true, and (3) the result if the test
	// is false
	CaseExpression();

	unique_ptr<ParsedExpression> check;
	unique_ptr<ParsedExpression> result_if_true;
	unique_ptr<ParsedExpression> result_if_false;

public:
	string ToString() const override;

	static bool Equals(const CaseExpression *a, const CaseExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

CaseExpression::CaseExpression() : ParsedExpression(ExpressionType::CASE_EXPR, ExpressionClass::CASE) {
}

string CaseExpression::ToString() const {
	return "CASE WHEN (" + check->ToString() + ") THEN (" + result_if_true->ToString() + ") ELSE (" +
	       result_if_false->ToString() + ")";
}

bool CaseExpression::Equals(const CaseExpression *a, const CaseExpression *b) {
	if (!a->check->Equals(b->check.get())) {
		return false;
	}
	if (!a->result_if_true->Equals(b->result_if_true.get())) {
		return false;
	}
	if (!a->result_if_false->Equals(b->result_if_false.get())) {
		return false;
	}
	return true;
}

unique_ptr<ParsedExpression> CaseExpression::Copy() const {
	auto copy = make_unique<CaseExpression>();
	copy->CopyProperties(*this);
	copy->check = check->Copy();
	copy->result_if_true = result_if_true->Copy();
	copy->result_if_false = result_if_false->Copy();
	return move(copy);
}

void CaseExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	check->Serialize(serializer);
	result_if_true->Serialize(serializer);
	result_if_false->Serialize(serializer);
}

unique_ptr<ParsedExpression> CaseExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto expression = make_unique<CaseExpression>();
	expression->check = ParsedExpression::Deserialize(source);
	expression->result_if_true = ParsedExpression::Deserialize(source);
	expression->result_if_false = ParsedExpression::Deserialize(source);
	return move(expression);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/cast_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! CastExpression represents a type cast from one SQL type to another SQL type
class CastExpression : public ParsedExpression {
public:
	CastExpression(SQLType target, unique_ptr<ParsedExpression> child);

	//! The child of the cast expression
	unique_ptr<ParsedExpression> child;
	//! The type to cast to
	SQLType cast_type;

public:
	string ToString() const override;

	static bool Equals(const CastExpression *a, const CastExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

CastExpression::CastExpression(SQLType target, unique_ptr<ParsedExpression> child)
    : ParsedExpression(ExpressionType::OPERATOR_CAST, ExpressionClass::CAST), cast_type(target) {
	assert(child);
	this->child = move(child);
}

string CastExpression::ToString() const {
	return "CAST[" + SQLTypeToString(cast_type) + "](" + child->ToString() + ")";
}

bool CastExpression::Equals(const CastExpression *a, const CastExpression *b) {
	if (!a->child->Equals(b->child.get())) {
		return false;
	}
	if (a->cast_type != b->cast_type) {
		return false;
	}
	return true;
}

unique_ptr<ParsedExpression> CastExpression::Copy() const {
	auto copy = make_unique<CastExpression>(cast_type, child->Copy());
	copy->CopyProperties(*this);
	return move(copy);
}

void CastExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	child->Serialize(serializer);
	cast_type.Serialize(serializer);
}

unique_ptr<ParsedExpression> CastExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto child = ParsedExpression::Deserialize(source);
	auto cast_type = SQLType::Deserialize(source);
	return make_unique_base<ParsedExpression, CastExpression>(cast_type, move(child));
}






using namespace duckdb;
using namespace std;

//! Specify both the column and table name
ColumnRefExpression::ColumnRefExpression(string column_name, string table_name)
    : ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_name(column_name),
      table_name(table_name) {
}

ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(column_name, string()) {
}

string ColumnRefExpression::GetName() const {
	return !alias.empty() ? alias : column_name;
}

string ColumnRefExpression::ToString() const {
	if (table_name.empty()) {
		return column_name;
	} else {
		return table_name + "." + column_name;
	}
}

bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) {
	return a->column_name == b->column_name && a->table_name == b->table_name;
}

hash_t ColumnRefExpression::Hash() const {
	hash_t result = ParsedExpression::Hash();
	result = CombineHash(result, duckdb::Hash<const char *>(column_name.c_str()));
	return result;
}

unique_ptr<ParsedExpression> ColumnRefExpression::Copy() const {
	auto copy = make_unique<ColumnRefExpression>(column_name, table_name);
	copy->CopyProperties(*this);
	return move(copy);
}

void ColumnRefExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.WriteString(table_name);
	serializer.WriteString(column_name);
}

unique_ptr<ParsedExpression> ColumnRefExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto table_name = source.Read<string>();
	auto column_name = source.Read<string>();
	auto expression = make_unique<ColumnRefExpression>(column_name, table_name);
	return move(expression);
}






using namespace duckdb;
using namespace std;

ComparisonExpression::ComparisonExpression(ExpressionType type, unique_ptr<ParsedExpression> left,
                                           unique_ptr<ParsedExpression> right)
    : ParsedExpression(type, ExpressionClass::COMPARISON) {
	this->left = move(left);
	this->right = move(right);
}

string ComparisonExpression::ToString() const {
	return left->ToString() + ExpressionTypeToOperator(type) + right->ToString();
}

bool ComparisonExpression::Equals(const ComparisonExpression *a, const ComparisonExpression *b) {
	if (!a->left->Equals(b->left.get())) {
		return false;
	}
	if (!a->right->Equals(b->right.get())) {
		return false;
	}
	return true;
}

unique_ptr<ParsedExpression> ComparisonExpression::Copy() const {
	auto copy = make_unique<ComparisonExpression>(type, left->Copy(), right->Copy());
	copy->CopyProperties(*this);
	return move(copy);
}

void ComparisonExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	left->Serialize(serializer);
	right->Serialize(serializer);
}

unique_ptr<ParsedExpression> ComparisonExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto left_child = ParsedExpression::Deserialize(source);
	auto right_child = ParsedExpression::Deserialize(source);
	return make_unique<ComparisonExpression>(type, move(left_child), move(right_child));
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/conjunction_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a conjunction (AND/OR)
class ConjunctionExpression : public ParsedExpression {
public:
	ConjunctionExpression(ExpressionType type);
	ConjunctionExpression(ExpressionType type, vector<unique_ptr<ParsedExpression>> children);
	ConjunctionExpression(ExpressionType type, unique_ptr<ParsedExpression> left, unique_ptr<ParsedExpression> right);

	vector<unique_ptr<ParsedExpression>> children;

public:
	void AddExpression(unique_ptr<ParsedExpression> expr);

	string ToString() const override;

	static bool Equals(const ConjunctionExpression *a, const ConjunctionExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression_util.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class ParsedExpression;
class Expression;

class ExpressionUtil {
public:
	//! ListEquals: check if a list of two expressions is equal (order is important)
	static bool ListEquals(const vector<unique_ptr<ParsedExpression>> &a,
	                       const vector<unique_ptr<ParsedExpression>> &b);
	static bool ListEquals(const vector<unique_ptr<Expression>> &a, const vector<unique_ptr<Expression>> &b);
	//! SetEquals: check if two sets of expressions are equal (order is not important)
	static bool SetEquals(const vector<unique_ptr<ParsedExpression>> &a, const vector<unique_ptr<ParsedExpression>> &b);
	static bool SetEquals(const vector<unique_ptr<Expression>> &a, const vector<unique_ptr<Expression>> &b);

private:
	template <class T> static bool ExpressionListEquals(const vector<unique_ptr<T>> &a, const vector<unique_ptr<T>> &b);
	template <class T> static bool ExpressionSetEquals(const vector<unique_ptr<T>> &a, const vector<unique_ptr<T>> &b);
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

ConjunctionExpression::ConjunctionExpression(ExpressionType type)
    : ParsedExpression(type, ExpressionClass::CONJUNCTION) {
}

ConjunctionExpression::ConjunctionExpression(ExpressionType type, vector<unique_ptr<ParsedExpression>> children)
    : ParsedExpression(type, ExpressionClass::CONJUNCTION) {
	for (auto &child : children) {
		AddExpression(move(child));
	}
}

ConjunctionExpression::ConjunctionExpression(ExpressionType type, unique_ptr<ParsedExpression> left,
                                             unique_ptr<ParsedExpression> right)
    : ParsedExpression(type, ExpressionClass::CONJUNCTION) {
	AddExpression(move(left));
	AddExpression(move(right));
}

void ConjunctionExpression::AddExpression(unique_ptr<ParsedExpression> expr) {
	if (expr->type == type) {
		// expr is a conjunction of the same type: merge the expression lists together
		auto &other = (ConjunctionExpression &)*expr;
		for (auto &child : other.children) {
			children.push_back(move(child));
		}
	} else {
		children.push_back(move(expr));
	}
}

string ConjunctionExpression::ToString() const {
	string result = children[0]->ToString();
	for (idx_t i = 1; i < children.size(); i++) {
		result += " " + ExpressionTypeToOperator(type) + " " + children[i]->ToString();
	}
	return result;
}

bool ConjunctionExpression::Equals(const ConjunctionExpression *a, const ConjunctionExpression *b) {
	return ExpressionUtil::SetEquals(a->children, b->children);
}

unique_ptr<ParsedExpression> ConjunctionExpression::Copy() const {
	auto copy = make_unique<ConjunctionExpression>(type);
	for (auto &expr : children) {
		copy->children.push_back(expr->Copy());
	}
	copy->CopyProperties(*this);
	return move(copy);
}

void ConjunctionExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.WriteList<ParsedExpression>(children);
}

unique_ptr<ParsedExpression> ConjunctionExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto result = make_unique<ConjunctionExpression>(type);
	source.ReadList<ParsedExpression>(result->children);
	return move(result);
}






using namespace duckdb;
using namespace std;

ConstantExpression::ConstantExpression(SQLType sql_type, Value val)
    : ParsedExpression(ExpressionType::VALUE_CONSTANT, ExpressionClass::CONSTANT), value(val), sql_type(sql_type) {
}

string ConstantExpression::ToString() const {
	return value.ToString();
}

bool ConstantExpression::Equals(const ConstantExpression *a, const ConstantExpression *b) {
	return a->value == b->value;
}

hash_t ConstantExpression::Hash() const {
	hash_t result = ParsedExpression::Hash();
	return CombineHash(ValueOperations::Hash(value), result);
}

unique_ptr<ParsedExpression> ConstantExpression::Copy() const {
	auto copy = make_unique<ConstantExpression>(sql_type, value);
	copy->CopyProperties(*this);
	return move(copy);
}

void ConstantExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	value.Serialize(serializer);
	sql_type.Serialize(serializer);
}

unique_ptr<ParsedExpression> ConstantExpression::Deserialize(ExpressionType type, Deserializer &source) {
	Value value = Value::Deserialize(source);
	auto sql_type = SQLType::Deserialize(source);
	return make_unique<ConstantExpression>(sql_type, value);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/default_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents the default value of a column
class DefaultExpression : public ParsedExpression {
public:
	DefaultExpression();

public:
	bool IsScalar() const override {
		return false;
	}

	string ToString() const override;

	unique_ptr<ParsedExpression> Copy() const override;

	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

DefaultExpression::DefaultExpression() : ParsedExpression(ExpressionType::VALUE_DEFAULT, ExpressionClass::DEFAULT) {
}

string DefaultExpression::ToString() const {
	return "DEFAULT";
}

unique_ptr<ParsedExpression> DefaultExpression::Copy() const {
	auto copy = make_unique<DefaultExpression>();
	copy->CopyProperties(*this);
	return move(copy);
}

unique_ptr<ParsedExpression> DefaultExpression::Deserialize(ExpressionType type, Deserializer &source) {
	return make_unique<DefaultExpression>();
}






using namespace duckdb;
using namespace std;

FunctionExpression::FunctionExpression(string schema, string function_name,
                                       vector<unique_ptr<ParsedExpression>> &children, bool distinct, bool is_operator)
    : ParsedExpression(ExpressionType::FUNCTION, ExpressionClass::FUNCTION), schema(schema),
      function_name(StringUtil::Lower(function_name)), is_operator(is_operator), distinct(distinct) {
	for (auto &child : children) {
		this->children.push_back(move(child));
	}
}

FunctionExpression::FunctionExpression(string function_name, vector<unique_ptr<ParsedExpression>> &children,
                                       bool distinct, bool is_operator)
    : FunctionExpression(DEFAULT_SCHEMA, function_name, children, distinct, is_operator) {
}

string FunctionExpression::ToString() const {
	if (is_operator) {
		// built-in operator
		if (children.size() == 1) {
			return function_name + children[0]->ToString();
		} else if (children.size() == 2) {
			return children[0]->ToString() + " " + function_name + " " + children[1]->ToString();
		}
	}
	// standard function call
	string result = function_name + "(";
	result += StringUtil::Join(children, children.size(), ", ",
	                           [](const unique_ptr<ParsedExpression> &child) { return child->ToString(); });
	return result + ")";
}

bool FunctionExpression::Equals(const FunctionExpression *a, const FunctionExpression *b) {
	if (a->schema != b->schema || a->function_name != b->function_name || b->distinct != a->distinct) {
		return false;
	}
	if (b->children.size() != a->children.size()) {
		return false;
	}
	for (idx_t i = 0; i < a->children.size(); i++) {
		if (!a->children[i]->Equals(b->children[i].get())) {
			return false;
		}
	}
	return true;
}

hash_t FunctionExpression::Hash() const {
	hash_t result = ParsedExpression::Hash();
	result = CombineHash(result, duckdb::Hash<const char *>(schema.c_str()));
	result = CombineHash(result, duckdb::Hash<const char *>(function_name.c_str()));
	result = CombineHash(result, duckdb::Hash<bool>(distinct));
	return result;
}

unique_ptr<ParsedExpression> FunctionExpression::Copy() const {
	vector<unique_ptr<ParsedExpression>> copy_children;
	for (auto &child : children) {
		copy_children.push_back(child->Copy());
	}
	auto copy = make_unique<FunctionExpression>(function_name, copy_children, distinct, is_operator);
	copy->schema = schema;
	copy->CopyProperties(*this);
	return move(copy);
}

void FunctionExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.WriteString(function_name);
	serializer.WriteString(schema);
	serializer.WriteList(children);
	serializer.Write<bool>(distinct);
	serializer.Write<bool>(is_operator);
}

unique_ptr<ParsedExpression> FunctionExpression::Deserialize(ExpressionType type, Deserializer &source) {
	vector<unique_ptr<ParsedExpression>> children;
	auto function_name = source.Read<string>();
	auto schema = source.Read<string>();
	source.ReadList<ParsedExpression>(children);
	auto distinct = source.Read<bool>();
	auto is_operator = source.Read<bool>();

	auto function = make_unique<FunctionExpression>(function_name, children, distinct, is_operator);
	function->schema = schema;
	return move(function);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/operator_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents a built-in operator expression
class OperatorExpression : public ParsedExpression {
public:
	OperatorExpression(ExpressionType type, unique_ptr<ParsedExpression> left = nullptr,
	                   unique_ptr<ParsedExpression> right = nullptr);

	vector<unique_ptr<ParsedExpression>> children;

public:
	string ToString() const override;

	static bool Equals(const OperatorExpression *a, const OperatorExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb






using namespace duckdb;
using namespace std;

OperatorExpression::OperatorExpression(ExpressionType type, unique_ptr<ParsedExpression> left,
                                       unique_ptr<ParsedExpression> right)
    : ParsedExpression(type, ExpressionClass::OPERATOR) {
	if (left) {
		children.push_back(move(left));
	}
	if (right) {
		children.push_back(move(right));
	}
}

string OperatorExpression::ToString() const {
	auto op = ExpressionTypeToOperator(type);
	if (!op.empty()) {
		// use the operator string to represent the operator
		if (children.size() == 1) {
			return op + children[0]->ToString();
		} else if (children.size() == 2) {
			return children[0]->ToString() + " " + op + " " + children[1]->ToString();
		}
	}
	// if there is no operator we render it as a function
	auto result = ExpressionTypeToString(type) + "(";
	result += StringUtil::Join(children, children.size(), ", ",
	                           [](const unique_ptr<ParsedExpression> &child) { return child->ToString(); });
	result += ")";
	return result;
}

bool OperatorExpression::Equals(const OperatorExpression *a, const OperatorExpression *b) {
	if (a->children.size() != b->children.size()) {
		return false;
	}
	for (idx_t i = 0; i < a->children.size(); i++) {
		if (!a->children[i]->Equals(b->children[i].get())) {
			return false;
		}
	}
	return true;
}

unique_ptr<ParsedExpression> OperatorExpression::Copy() const {
	auto copy = make_unique<OperatorExpression>(type);
	copy->CopyProperties(*this);
	for (auto &it : children) {
		copy->children.push_back(it->Copy());
	}
	return move(copy);
}

void OperatorExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.WriteList(children);
}

unique_ptr<ParsedExpression> OperatorExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto expression = make_unique<OperatorExpression>(type);
	source.ReadList<ParsedExpression>(expression->children);
	return move(expression);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/parameter_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class ParameterExpression : public ParsedExpression {
public:
	ParameterExpression();

	idx_t parameter_nr;

public:
	bool IsScalar() const override {
		return true;
	}
	bool HasParameter() const override {
		return true;
	}

	string ToString() const override;

	unique_ptr<ParsedExpression> Copy() const override;
	hash_t Hash() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb






using namespace duckdb;
using namespace std;

ParameterExpression::ParameterExpression()
    : ParsedExpression(ExpressionType::VALUE_PARAMETER, ExpressionClass::PARAMETER), parameter_nr(0) {
}

string ParameterExpression::ToString() const {
	return "$" + std::to_string(parameter_nr);
}

unique_ptr<ParsedExpression> ParameterExpression::Copy() const {
	auto copy = make_unique<ParameterExpression>();
	copy->CopyProperties(*this);
	return move(copy);
}

hash_t ParameterExpression::Hash() const {
	hash_t result = ParsedExpression::Hash();
	return CombineHash(duckdb::Hash(parameter_nr), result);
}

void ParameterExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.Write<idx_t>(parameter_nr);
}

unique_ptr<ParsedExpression> ParameterExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto expression = make_unique<ParameterExpression>();
	expression->parameter_nr = source.Read<idx_t>();
	return move(expression);
}


using namespace duckdb;
using namespace std;

StarExpression::StarExpression() : ParsedExpression(ExpressionType::STAR, ExpressionClass::STAR) {
}

string StarExpression::ToString() const {
	return "*";
}

unique_ptr<ParsedExpression> StarExpression::Copy() const {
	auto copy = make_unique<StarExpression>();
	copy->CopyProperties(*this);
	return move(copy);
}

unique_ptr<ParsedExpression> StarExpression::Deserialize(ExpressionType type, Deserializer &source) {
	return make_unique<StarExpression>();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/subquery_expression.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a subquery
class SubqueryExpression : public ParsedExpression {
public:
	SubqueryExpression();

	//! The actual subquery
	unique_ptr<QueryNode> subquery;
	//! The subquery type
	SubqueryType subquery_type;
	//! the child expression to compare with (in case of IN, ANY, ALL operators, empty for EXISTS queries and scalar
	//! subquery)
	unique_ptr<ParsedExpression> child;
	//! The comparison type of the child expression with the subquery (in case of ANY, ALL operators), empty otherwise
	ExpressionType comparison_type;

public:
	bool HasSubquery() const override {
		return true;
	}
	bool IsScalar() const override {
		return false;
	}

	string ToString() const override;

	static bool Equals(const SubqueryExpression *a, const SubqueryExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);
};
} // namespace duckdb





using namespace duckdb;
using namespace std;

SubqueryExpression::SubqueryExpression()
    : ParsedExpression(ExpressionType::SUBQUERY, ExpressionClass::SUBQUERY), subquery_type(SubqueryType::INVALID),
      comparison_type(ExpressionType::INVALID) {
}

string SubqueryExpression::ToString() const {
	return "SUBQUERY";
}

bool SubqueryExpression::Equals(const SubqueryExpression *a, const SubqueryExpression *b) {
	if (!a->subquery || !b->subquery) {
		return false;
	}
	return a->subquery_type == b->subquery_type && a->subquery->Equals(b->subquery.get());
}

unique_ptr<ParsedExpression> SubqueryExpression::Copy() const {
	auto copy = make_unique<SubqueryExpression>();
	copy->CopyProperties(*this);
	copy->subquery = subquery->Copy();
	copy->subquery_type = subquery_type;
	copy->child = child ? child->Copy() : nullptr;
	copy->comparison_type = comparison_type;
	return move(copy);
}

void SubqueryExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.Write<SubqueryType>(subquery_type);
	subquery->Serialize(serializer);
	serializer.WriteOptional(child);
	serializer.Write<ExpressionType>(comparison_type);
}

unique_ptr<ParsedExpression> SubqueryExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto subquery_type = source.Read<SubqueryType>();
	auto subquery = QueryNode::Deserialize(source);

	auto expression = make_unique<SubqueryExpression>();
	expression->subquery_type = subquery_type;
	expression->subquery = move(subquery);
	expression->child = source.ReadOptional<ParsedExpression>();
	expression->comparison_type = source.Read<ExpressionType>();
	return move(expression);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/expression/star_expression.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a table.* expression in the SELECT clause
class TableStarExpression : public ParsedExpression {
public:
	TableStarExpression(string relation_name);

public:
	string ToString() const override;

	static bool Equals(const TableStarExpression *a, const TableStarExpression *b);

	unique_ptr<ParsedExpression> Copy() const override;

	void Serialize(Serializer &serializer) override;
	static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, Deserializer &source);

	string relation_name;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

TableStarExpression::TableStarExpression(string relation_name)
    : ParsedExpression(ExpressionType::TABLE_STAR, ExpressionClass::TABLE_STAR), relation_name(relation_name) {
}

string TableStarExpression::ToString() const {
	return relation_name + ".*";
}

bool TableStarExpression::Equals(const TableStarExpression *a, const TableStarExpression *b) {
	return a->relation_name == b->relation_name;
}

unique_ptr<ParsedExpression> TableStarExpression::Copy() const {
	auto copy = make_unique<TableStarExpression>(relation_name);
	copy->CopyProperties(*this);
	return move(copy);
}

void TableStarExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.WriteString(relation_name);
}

unique_ptr<ParsedExpression> TableStarExpression::Deserialize(ExpressionType type, Deserializer &source) {
	return make_unique<TableStarExpression>(source.Read<string>());
}





using namespace duckdb;
using namespace std;

WindowExpression::WindowExpression(ExpressionType type, string schema, string function_name)
    : ParsedExpression(type, ExpressionClass::WINDOW), schema(schema), function_name(StringUtil::Lower(function_name)) {
	switch (type) {
	case ExpressionType::WINDOW_AGGREGATE:
	case ExpressionType::WINDOW_ROW_NUMBER:
	case ExpressionType::WINDOW_FIRST_VALUE:
	case ExpressionType::WINDOW_LAST_VALUE:
	case ExpressionType::WINDOW_RANK:
	case ExpressionType::WINDOW_RANK_DENSE:
	case ExpressionType::WINDOW_PERCENT_RANK:
	case ExpressionType::WINDOW_CUME_DIST:
	case ExpressionType::WINDOW_LEAD:
	case ExpressionType::WINDOW_LAG:
	case ExpressionType::WINDOW_NTILE:
		break;
	default:
		throw NotImplementedException("Window aggregate type %s not supported", ExpressionTypeToString(type).c_str());
	}
}

string WindowExpression::ToString() const {
	return "WINDOW";
}

bool WindowExpression::Equals(const WindowExpression *a, const WindowExpression *b) {
	// check if the child expressions are equivalent
	if (b->children.size() != a->children.size()) {
		return false;
	}
	for (idx_t i = 0; i < a->children.size(); i++) {
		if (!a->children[i]->Equals(b->children[i].get())) {
			return false;
		}
	}
	if (a->start != b->start || a->end != b->end) {
		return false;
	}
	// check if the framing expressions are equivalent
	if (!BaseExpression::Equals(a->start_expr.get(), b->start_expr.get()) ||
	    !BaseExpression::Equals(a->end_expr.get(), b->end_expr.get()) ||
	    !BaseExpression::Equals(a->offset_expr.get(), b->offset_expr.get()) ||
	    !BaseExpression::Equals(a->default_expr.get(), b->default_expr.get())) {
		return false;
	}

	// check if the partitions are equivalent
	if (a->partitions.size() != b->partitions.size()) {
		return false;
	}
	for (idx_t i = 0; i < a->partitions.size(); i++) {
		if (!a->partitions[i]->Equals(b->partitions[i].get())) {
			return false;
		}
	}
	// check if the orderings are equivalent
	if (a->orders.size() != b->orders.size()) {
		return false;
	}
	for (idx_t i = 0; i < a->orders.size(); i++) {
		if (a->orders[i].type != b->orders[i].type) {
			return false;
		}
		if (!a->orders[i].expression->Equals(b->orders[i].expression.get())) {
			return false;
		}
	}
	return true;
}

unique_ptr<ParsedExpression> WindowExpression::Copy() const {
	auto new_window = make_unique<WindowExpression>(type, schema, function_name);
	new_window->CopyProperties(*this);

	for (auto &child : children) {
		new_window->children.push_back(child->Copy());
	}

	for (auto &e : partitions) {
		new_window->partitions.push_back(e->Copy());
	}

	for (auto &o : orders) {
		OrderByNode node;
		node.type = o.type;
		node.expression = o.expression->Copy();
		new_window->orders.push_back(move(node));
	}

	new_window->start = start;
	new_window->end = end;
	new_window->start_expr = start_expr ? start_expr->Copy() : nullptr;
	new_window->end_expr = end_expr ? end_expr->Copy() : nullptr;
	new_window->offset_expr = offset_expr ? offset_expr->Copy() : nullptr;
	new_window->default_expr = default_expr ? default_expr->Copy() : nullptr;

	return move(new_window);
}

void WindowExpression::Serialize(Serializer &serializer) {
	ParsedExpression::Serialize(serializer);
	serializer.WriteString(function_name);
	serializer.WriteString(schema);
	serializer.WriteList(children);
	serializer.WriteList(partitions);
	assert(orders.size() <= numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)orders.size());
	for (auto &order : orders) {
		serializer.Write<OrderType>(order.type);
		order.expression->Serialize(serializer);
	}
	serializer.Write<WindowBoundary>(start);
	serializer.Write<WindowBoundary>(end);

	serializer.WriteOptional(start_expr);
	serializer.WriteOptional(end_expr);
	serializer.WriteOptional(offset_expr);
	serializer.WriteOptional(default_expr);
}

unique_ptr<ParsedExpression> WindowExpression::Deserialize(ExpressionType type, Deserializer &source) {
	auto function_name = source.Read<string>();
	auto schema = source.Read<string>();
	auto expr = make_unique<WindowExpression>(type, schema, function_name);
	source.ReadList<ParsedExpression>(expr->children);
	source.ReadList<ParsedExpression>(expr->partitions);

	auto order_count = source.Read<uint32_t>();
	for (idx_t i = 0; i < order_count; i++) {
		auto order_type = source.Read<OrderType>();
		auto expression = ParsedExpression::Deserialize(source);
		expr->orders.push_back(OrderByNode(order_type, move(expression)));
	}
	expr->start = source.Read<WindowBoundary>();
	expr->end = source.Read<WindowBoundary>();

	expr->start_expr = source.ReadOptional<ParsedExpression>();
	expr->end_expr = source.ReadOptional<ParsedExpression>();
	expr->offset_expr = source.ReadOptional<ParsedExpression>();
	expr->default_expr = source.ReadOptional<ParsedExpression>();
	return move(expr);
}





using namespace duckdb;
using namespace std;

template <class T>
bool ExpressionUtil::ExpressionListEquals(const vector<unique_ptr<T>> &a, const vector<unique_ptr<T>> &b) {
	if (a.size() != b.size()) {
		return false;
	}
	for (idx_t i = 0; i < a.size(); i++) {
		if (!(*a[i] == *b[i])) {
			return false;
		}
	}
	return true;
}

template <class T>
bool ExpressionUtil::ExpressionSetEquals(const vector<unique_ptr<T>> &a, const vector<unique_ptr<T>> &b) {
	if (a.size() != b.size()) {
		return false;
	}
	// we create a map of expression -> count for the left side
	// we keep the count because the same expression can occur multiple times (e.g. "1 AND 1" is legal)
	// in this case we track the following value: map["Constant(1)"] = 2
	expression_map_t<idx_t> map;
	for (idx_t i = 0; i < a.size(); i++) {
		map[a[i].get()]++;
	}
	// now on the right side we reduce the counts again
	// if the conjunctions are identical, all the counts will be 0 after the
	for (auto &expr : b) {
		auto entry = map.find(expr.get());
		// first we check if we can find the expression in the map at all
		if (entry == map.end()) {
			return false;
		}
		// if we found it we check the count; if the count is already 0 we return false
		// this happens if e.g. the left side contains "1 AND X", and the right side contains "1 AND 1"
		// "1" is contained in the map, however, the right side contains the expression twice
		// hence we know the children are not identical in this case because the LHS and RHS have a different count for
		// the Constant(1) expression
		if (entry->second == 0) {
			return false;
		}
		entry->second--;
	}
	return true;
}

bool ExpressionUtil::ListEquals(const vector<unique_ptr<ParsedExpression>> &a,
                                const vector<unique_ptr<ParsedExpression>> &b) {
	return ExpressionListEquals<ParsedExpression>(a, b);
}

bool ExpressionUtil::ListEquals(const vector<unique_ptr<Expression>> &a, const vector<unique_ptr<Expression>> &b) {
	return ExpressionListEquals<Expression>(a, b);
}

bool ExpressionUtil::SetEquals(const vector<unique_ptr<ParsedExpression>> &a,
                               const vector<unique_ptr<ParsedExpression>> &b) {
	return ExpressionSetEquals<ParsedExpression>(a, b);
}

bool ExpressionUtil::SetEquals(const vector<unique_ptr<Expression>> &a, const vector<unique_ptr<Expression>> &b) {
	return ExpressionSetEquals<Expression>(a, b);
}



using namespace duckdb;
using namespace std;

void AlterInfo::Serialize(Serializer &serializer) {
	serializer.Write<AlterType>(type);
}

unique_ptr<AlterInfo> AlterInfo::Deserialize(Deserializer &source) {
	auto type = source.Read<AlterType>();
	switch (type) {
	case AlterType::ALTER_TABLE:
		return AlterTableInfo::Deserialize(source);
	default:
		throw SerializationException("Unknown alter type for deserialization!");
	}
}

void AlterTableInfo::Serialize(Serializer &serializer) {
	AlterInfo::Serialize(serializer);
	serializer.Write<AlterTableType>(alter_table_type);
	serializer.WriteString(schema);
	serializer.WriteString(table);
}

unique_ptr<AlterInfo> AlterTableInfo::Deserialize(Deserializer &source) {
	auto type = source.Read<AlterTableType>();
	auto schema = source.Read<string>();
	auto table = source.Read<string>();
	unique_ptr<AlterTableInfo> info;
	switch (type) {
	case AlterTableType::RENAME_COLUMN:
		return RenameColumnInfo::Deserialize(source, schema, table);
    case AlterTableType::RENAME_TABLE:
        return RenameTableInfo::Deserialize(source, schema, table);
	default:
		throw SerializationException("Unknown alter table type for deserialization!");
	}
}

void RenameColumnInfo::Serialize(Serializer &serializer) {
	AlterTableInfo::Serialize(serializer);
	serializer.WriteString(name);
	serializer.WriteString(new_name);
}

unique_ptr<AlterInfo> RenameColumnInfo::Deserialize(Deserializer &source, string schema, string table) {
	auto name = source.Read<string>();
	auto new_name = source.Read<string>();
	return make_unique<RenameColumnInfo>(schema, table, name, new_name);
}

void RenameTableInfo::Serialize(Serializer &serializer) {
	AlterTableInfo::Serialize(serializer);
    serializer.WriteString(new_table_name);
}

unique_ptr<AlterInfo> RenameTableInfo::Deserialize(Deserializer &source, string schema, string table) {
    auto new_name = source.Read<string>();
	return make_unique<RenameTableInfo>(schema, table, new_name);
}




















//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/parsed_expression_iterator.hpp
//
//
//===----------------------------------------------------------------------===//





#include <functional>

namespace duckdb {

class ParsedExpressionIterator {
public:
	static void EnumerateChildren(const ParsedExpression &expression,
	                              std::function<void(const ParsedExpression &child)> callback);
};

} // namespace duckdb


using namespace duckdb;
using namespace std;

bool ParsedExpression::IsAggregate() const {
	bool is_aggregate = false;
	ParsedExpressionIterator::EnumerateChildren(
	    *this, [&](const ParsedExpression &child) { is_aggregate |= child.IsAggregate(); });
	return is_aggregate;
}

bool ParsedExpression::IsWindow() const {
	bool is_window = false;
	ParsedExpressionIterator::EnumerateChildren(*this,
	                                            [&](const ParsedExpression &child) { is_window |= child.IsWindow(); });
	return is_window;
}

bool ParsedExpression::IsScalar() const {
	bool is_scalar = true;
	ParsedExpressionIterator::EnumerateChildren(*this, [&](const ParsedExpression &child) {
		if (!child.IsScalar()) {
			is_scalar = false;
		}
	});
	return is_scalar;
}

bool ParsedExpression::HasParameter() const {
	bool has_parameter = false;
	ParsedExpressionIterator::EnumerateChildren(
	    *this, [&](const ParsedExpression &child) { has_parameter |= child.HasParameter(); });
	return has_parameter;
}

bool ParsedExpression::HasSubquery() const {
	bool has_subquery = false;
	ParsedExpressionIterator::EnumerateChildren(
	    *this, [&](const ParsedExpression &child) { has_subquery |= child.HasSubquery(); });
	return has_subquery;
}

bool ParsedExpression::Equals(const BaseExpression *other) const {
	if (other->expression_class == ExpressionClass::BOUND_EXPRESSION) {
		auto bound_expr = (BoundExpression *)other;
		other = bound_expr->parsed_expr.get();
	}
	if (!BaseExpression::Equals(other)) {
		return false;
	}
	switch (expression_class) {
	case ExpressionClass::CASE:
		return CaseExpression::Equals((CaseExpression *)this, (CaseExpression *)other);
	case ExpressionClass::CAST:
		return CastExpression::Equals((CastExpression *)this, (CastExpression *)other);
	case ExpressionClass::COLUMN_REF:
		return ColumnRefExpression::Equals((ColumnRefExpression *)this, (ColumnRefExpression *)other);
	case ExpressionClass::COMPARISON:
		return ComparisonExpression::Equals((ComparisonExpression *)this, (ComparisonExpression *)other);
	case ExpressionClass::CONJUNCTION:
		return ConjunctionExpression::Equals((ConjunctionExpression *)this, (ConjunctionExpression *)other);
	case ExpressionClass::CONSTANT:
		return ConstantExpression::Equals((ConstantExpression *)this, (ConstantExpression *)other);
	case ExpressionClass::DEFAULT:
		return true;
	case ExpressionClass::FUNCTION:
		return FunctionExpression::Equals((FunctionExpression *)this, (FunctionExpression *)other);
	case ExpressionClass::OPERATOR:
		return OperatorExpression::Equals((OperatorExpression *)this, (OperatorExpression *)other);
	case ExpressionClass::PARAMETER:
		return true;
	case ExpressionClass::STAR:
		return true;
	case ExpressionClass::TABLE_STAR:
		return TableStarExpression::Equals((TableStarExpression *)this, (TableStarExpression *)other);
	case ExpressionClass::SUBQUERY:
		return SubqueryExpression::Equals((SubqueryExpression *)this, (SubqueryExpression *)other);
	case ExpressionClass::WINDOW:
		return WindowExpression::Equals((WindowExpression *)this, (WindowExpression *)other);
	default:
		throw SerializationException("Unsupported type for expression deserialization!");
	}
}

hash_t ParsedExpression::Hash() const {
	hash_t hash = duckdb::Hash<uint32_t>((uint32_t)type);
	ParsedExpressionIterator::EnumerateChildren(
	    *this, [&](const ParsedExpression &child) { hash = CombineHash(child.Hash(), hash); });
	return hash;
}

void ParsedExpression::Serialize(Serializer &serializer) {
	serializer.Write<ExpressionClass>(GetExpressionClass());
	serializer.Write<ExpressionType>(type);
	serializer.WriteString(alias);
}

unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source) {
	auto expression_class = source.Read<ExpressionClass>();
	auto type = source.Read<ExpressionType>();
	auto alias = source.Read<string>();
	unique_ptr<ParsedExpression> result;
	switch (expression_class) {
	case ExpressionClass::CASE:
		result = CaseExpression::Deserialize(type, source);
		break;
	case ExpressionClass::CAST:
		result = CastExpression::Deserialize(type, source);
		break;
	case ExpressionClass::COLUMN_REF:
		result = ColumnRefExpression::Deserialize(type, source);
		break;
	case ExpressionClass::COMPARISON:
		result = ComparisonExpression::Deserialize(type, source);
		break;
	case ExpressionClass::CONJUNCTION:
		result = ConjunctionExpression::Deserialize(type, source);
		break;
	case ExpressionClass::CONSTANT:
		result = ConstantExpression::Deserialize(type, source);
		break;
	case ExpressionClass::DEFAULT:
		result = DefaultExpression::Deserialize(type, source);
		break;
	case ExpressionClass::FUNCTION:
		result = FunctionExpression::Deserialize(type, source);
		break;
	case ExpressionClass::OPERATOR:
		result = OperatorExpression::Deserialize(type, source);
		break;
	case ExpressionClass::PARAMETER:
		result = ParameterExpression::Deserialize(type, source);
		break;
	case ExpressionClass::STAR:
		result = StarExpression::Deserialize(type, source);
		break;
	case ExpressionClass::TABLE_STAR:
		result = TableStarExpression::Deserialize(type, source);
		break;
	case ExpressionClass::SUBQUERY:
		result = SubqueryExpression::Deserialize(type, source);
		break;
	case ExpressionClass::WINDOW:
		result = WindowExpression::Deserialize(type, source);
		break;
	default:
		throw SerializationException("Unsupported type for expression deserialization!");
	}
	result->alias = alias;
	return result;
}




using namespace duckdb;
using namespace std;

void ParsedExpressionIterator::EnumerateChildren(const ParsedExpression &expr,
                                                 function<void(const ParsedExpression &child)> callback) {
	switch (expr.expression_class) {
	case ExpressionClass::CASE: {
		auto &case_expr = (const CaseExpression &)expr;
		callback(*case_expr.check);
		callback(*case_expr.result_if_true);
		callback(*case_expr.result_if_false);
		break;
	}
	case ExpressionClass::CAST: {
		auto &cast_expr = (const CastExpression &)expr;
		callback(*cast_expr.child);
		break;
	}
	case ExpressionClass::COMPARISON: {
		auto &comp_expr = (const ComparisonExpression &)expr;
		callback(*comp_expr.left);
		callback(*comp_expr.right);
		break;
	}
	case ExpressionClass::CONJUNCTION: {
		auto &conj_expr = (const ConjunctionExpression &)expr;
		for (auto &child : conj_expr.children) {
			callback(*child);
		}
		break;
	}
	case ExpressionClass::FUNCTION: {
		auto &func_expr = (const FunctionExpression &)expr;
		for (auto &child : func_expr.children) {
			callback(*child);
		}
		break;
	}
	case ExpressionClass::OPERATOR: {
		auto &op_expr = (const OperatorExpression &)expr;
		for (auto &child : op_expr.children) {
			callback(*child);
		}
		break;
	}
	case ExpressionClass::SUBQUERY: {
		auto &subquery_expr = (const SubqueryExpression &)expr;
		if (subquery_expr.child) {
			callback(*subquery_expr.child);
		}
		break;
	}
	case ExpressionClass::WINDOW: {
		auto &window_expr = (const WindowExpression &)expr;
		for (auto &partition : window_expr.partitions) {
			callback(*partition);
		}
		for (auto &order : window_expr.orders) {
			callback(*order.expression);
		}
		for (auto &child : window_expr.children) {
			callback(*child);
		}
		if (window_expr.offset_expr) {
			callback(*window_expr.offset_expr);
		}
		if (window_expr.default_expr) {
			callback(*window_expr.default_expr);
		}
		break;
	}
	case ExpressionClass::BOUND_EXPRESSION:
	case ExpressionClass::COLUMN_REF:
	case ExpressionClass::CONSTANT:
	case ExpressionClass::DEFAULT:
	case ExpressionClass::STAR:
	case ExpressionClass::TABLE_STAR:
	case ExpressionClass::PARAMETER:
		// these node types have no children
		break;
	default:
		// called on non ParsedExpression type!
		throw NotImplementedException("Unimplemented expression class");
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/transformer.hpp
//
//
//===----------------------------------------------------------------------===//









// this is a bit of a mess from c.h, port.h and some others. Upside is it makes the parser compile with minimal
// dependencies.



#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

typedef uintptr_t PGDatum;
typedef uint64_t PGSize;

typedef uint32_t PGIndex;
typedef uint32_t PGOid;

#define InvalidOid ((PGOid)0)

#ifndef _MSC_VER
#include <assert.h>
#define Assert(a) assert(a);
#define AssertMacro(p) ((void)assert(p))
#else
#define Assert(a) (a);
#define AssertMacro(p) ((void)(p))
#endif
#define _(a) (a)

#define lengthof(array) (sizeof(array) / sizeof((array)[0]))
#define CppConcat(x, y) x##y

#define HIGHBIT (0x80)
#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch)&HIGHBIT)

#define NAMEDATALEN 64
#define FUNC_MAX_ARGS 100
#define FLEXIBLE_ARRAY_MEMBER

#define DEFAULT_INDEX_TYPE "art"
#define INTERVAL_MASK(b) (1 << (b))

#ifdef _MSC_VER
#define __thread __declspec(thread)
#endif

typedef struct {
	int32_t vl_len_;    /* these fields must match ArrayType! */
	int ndim;         /* always 1 for PGint2vector */
	int32_t dataoffset; /* always 0 for PGint2vector */
	PGOid elemtype;
	int dim1;
	int lbound1;
	int16_t values[];
} PGint2vector;

typedef struct PGNameData {
	char data[NAMEDATALEN];
} PGNameData;
typedef PGNameData *Name;

struct pg_varlena {
	char vl_len_[4];                    /* Do not touch this field directly! */
	char vl_dat[1]; /* Data content is here */
};

typedef struct pg_varlena bytea;

typedef int PGMemoryContext;

typedef enum PGPostgresParserErrors {
	PG_ERRCODE_SYNTAX_ERROR,
	PG_ERRCODE_FEATURE_NOT_SUPPORTED,
	PG_ERRCODE_INVALID_PARAMETER_VALUE,
	PG_ERRCODE_WINDOWING_ERROR,
	PG_ERRCODE_RESERVED_NAME,
	PG_ERRCODE_INVALID_ESCAPE_SEQUENCE,
	PG_ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER,
	ERRCODE_NAME_TOO_LONG
} PGPostgresParserErrors;

typedef enum PGPostgresRelPersistence {
	PG_RELPERSISTENCE_TEMP,
	PG_RELPERSISTENCE_UNLOGGED,
	RELPERSISTENCE_PERMANENT
} PGPostgresRelPersistence;

typedef enum PGPostgresErrorLevel {
	PGUNDEFINED,
	PGNOTICE,
	PGWARNING,
	ERROR
} PGPostgresErrorLevel;

typedef enum PGPostgresAttributIdentityTypes {
	PG_ATTRIBUTE_IDENTITY_ALWAYS,
	ATTRIBUTE_IDENTITY_BY_DEFAULT
} PGPostgresAttributIdentityTypes;

/*-------------------------------------------------------------------------
 *
 * parsenodes.h
 *	  definitions for parse tree nodes
 *
 * Many of the node types used in parsetrees include a "location" field.
 * This is a byte (not character) offset in the original source text, to be
 * used for positioning an error cursor when there is an error related to
 * the node.  Access to the original source text is needed to make use of
 * the location.  At the topmost (statement) level, we also provide a
 * statement length, likewise measured in bytes, for convenience in
 * identifying statement boundaries in multi-statement source strings.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/parsenodes.h
 *
 *-------------------------------------------------------------------------
 */


/*-------------------------------------------------------------------------
 *
 * bitmapset.h
 *	  PostgreSQL generic bitmap set package
 *
 * A bitmap set can represent any set of nonnegative integers, although
 * it is mainly intended for sets where the maximum value is not large,
 * say at most a few hundred.  By convention, a NULL pointer is always
 * accepted by all operations to represent the empty set.  (But beware
 * that this is not the only representation of the empty set.  Use
 * bms_is_empty() in preference to testing for NULL.)
 *
 *
 * Copyright (c) 2003-2017, PostgreSQL Global Development PGGroup
 *
 * src/include/nodes/bitmapset.h
 *
 *-------------------------------------------------------------------------
 */


#include <cstdint>

/*
 * Forward decl to save including pg_list.h
 */
struct PGList;

/*
 * Data representation
 */

/* The unit size can be adjusted by changing these three declarations: */
#define BITS_PER_BITMAPWORD 32
typedef uint32_t bitmapword;		/* must be an unsigned type */
typedef int32_t signedbitmapword; /* must be the matching signed type */

typedef struct PGBitmapset
{
	int			nwords;			/* number of words in array */
	bitmapword	words[1];	/* really [nwords] */
} PGBitmapset;


/* result of bms_subset_compare */
typedef enum PG_BMS_Comparison {
	PG_BMS_EQUAL,					/* sets are equal */
	PG_BMS_SUBSET1,				/* first set is a subset of the second */
	PG_BMS_SUBSET2,				/* second set is a subset of the first */
	BMS_DIFFERENT				/* neither set is a subset of the other */
} PG_BMS_Comparison;

/* result of bms_membership */
typedef enum PG_BMS_Membership {
	PG_BMS_EMPTY_SET,				/* 0 members */
	PG_BMS_SINGLETON,				/* 1 member */
	BMS_MULTIPLE				/* >1 member */
} PG_BMS_Membership;


/*
 * function prototypes in nodes/bitmapset.c
 */

extern PGBitmapset *bms_copy(const PGBitmapset *a);
extern bool bms_equal(const PGBitmapset *a, const PGBitmapset *b);
extern PGBitmapset *bms_make_singleton(int x);
extern void bms_free(PGBitmapset *a);

extern PGBitmapset *bms_union(const PGBitmapset *a, const PGBitmapset *b);
extern PGBitmapset *bms_intersect(const PGBitmapset *a, const PGBitmapset *b);
extern PGBitmapset *bms_difference(const PGBitmapset *a, const PGBitmapset *b);
extern bool bms_is_subset(const PGBitmapset *a, const PGBitmapset *b);
extern PG_BMS_Comparison bms_subset_compare(const PGBitmapset *a, const PGBitmapset *b);
extern bool bms_is_member(int x, const PGBitmapset *a);
extern bool bms_overlap(const PGBitmapset *a, const PGBitmapset *b);
extern bool bms_overlap_list(const PGBitmapset *a, const struct PGList *b);
extern bool bms_nonempty_difference(const PGBitmapset *a, const PGBitmapset *b);
extern int	bms_singleton_member(const PGBitmapset *a);
extern bool bms_get_singleton_member(const PGBitmapset *a, int *member);
extern int	bms_num_members(const PGBitmapset *a);

/* optimized tests when we don't need to know exact membership count: */
extern PG_BMS_Membership bms_membership(const PGBitmapset *a);
extern bool bms_is_empty(const PGBitmapset *a);

/* these routines recycle (modify or free) their non-const inputs: */

extern PGBitmapset *bms_add_member(PGBitmapset *a, int x);
extern PGBitmapset *bms_del_member(PGBitmapset *a, int x);
extern PGBitmapset *bms_add_members(PGBitmapset *a, const PGBitmapset *b);
extern PGBitmapset *bms_int_members(PGBitmapset *a, const PGBitmapset *b);
extern PGBitmapset *bms_del_members(PGBitmapset *a, const PGBitmapset *b);
extern PGBitmapset *bms_join(PGBitmapset *a, PGBitmapset *b);

/* support for iterating through the integer elements of a set: */
extern int	bms_first_member(PGBitmapset *a);
extern int	bms_next_member(const PGBitmapset *a, int prevbit);

/* support for hashtables using Bitmapsets as keys: */
extern uint32_t bms_hash_value(const PGBitmapset *a);


/*-------------------------------------------------------------------------
 *
 * lockoptions.h
 *	  Common header for some locking-related declarations.
 *
 *
 * Copyright (c) 2014-2017, PostgreSQL Global Development PGGroup
 *
 * src/include/nodes/lockoptions.h
 *
 *-------------------------------------------------------------------------
 */


/*
 * This enum represents the different strengths of FOR UPDATE/SHARE clauses.
 * The ordering here is important, because the highest numerical value takes
 * precedence when a RTE is specified multiple ways.  See applyLockingClause.
 */
typedef enum PGLockClauseStrength
{
	PG_LCS_NONE,					/* no such clause - only used in PGPlanRowMark */
	PG_LCS_FORKEYSHARE,			/* FOR KEY SHARE */
	PG_LCS_FORSHARE,				/* FOR SHARE */
	PG_LCS_FORNOKEYUPDATE,			/* FOR NO KEY UPDATE */
	LCS_FORUPDATE				/* FOR UPDATE */
} PGLockClauseStrength;

/*
 * This enum controls how to deal with rows being locked by FOR UPDATE/SHARE
 * clauses (i.e., it represents the NOWAIT and SKIP LOCKED options).
 * The ordering here is important, because the highest numerical value takes
 * precedence when a RTE is specified multiple ways.  See applyLockingClause.
 */
typedef enum PGLockWaitPolicy
{
	/* Wait for the lock to become available (default behavior) */
	PGLockWaitBlock,
	/* Skip rows that can't be locked (SKIP LOCKED) */
	PGLockWaitSkip,
	/* Raise an error if a row cannot be locked (NOWAIT) */
	LockWaitError
} PGLockWaitPolicy;


/*-------------------------------------------------------------------------
 *
 * primnodes.h
 *	  Definitions for "primitive" node types, those that are used in more
 *	  than one of the parse/plan/execute stages of the query pipeline.
 *	  Currently, these are mostly nodes for executable expressions
 *	  and join trees.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/primnodes.h
 *
 *-------------------------------------------------------------------------
 */


/*-------------------------------------------------------------------------
 *
 * attnum.h
 *	  POSTGRES attribute number definitions.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/access/attnum.h
 *
 *-------------------------------------------------------------------------
 */


#include <cstdint>

/*
 * user defined attribute numbers start at 1.   -ay 2/95
 */
typedef int16_t PGAttrNumber;

#define InvalidAttrNumber		0
#define MaxAttrNumber			32767

/* ----------------
 *		support macros
 * ----------------
 */
/*
 * AttributeNumberIsValid
 *		True iff the attribute number is valid.
 */
#define AttributeNumberIsValid(attributeNumber) \
	((bool) ((attributeNumber) != InvalidAttrNumber))

/*
 * AttrNumberIsForUserDefinedAttr
 *		True iff the attribute number corresponds to an user defined attribute.
 */
#define AttrNumberIsForUserDefinedAttr(attributeNumber) \
	((bool) ((attributeNumber) > 0))

/*
 * AttrNumberGetAttrOffset
 *		Returns the attribute offset for an attribute number.
 *
 * Note:
 *		Assumes the attribute number is for a user defined attribute.
 */
#define AttrNumberGetAttrOffset(attNum) \
( \
	AssertMacro(AttrNumberIsForUserDefinedAttr(attNum)), \
	((attNum) - 1) \
)

/*
 * AttributeOffsetGetAttributeNumber
 *		Returns the attribute number for an attribute offset.
 */
#define AttrOffsetGetAttrNumber(attributeOffset) \
	 ((PGAttrNumber) (1 + (attributeOffset)))


/*-------------------------------------------------------------------------
 *
 * pg_list.h
 *	  interface for PostgreSQL generic linked list package
 *
 * This package implements singly-linked homogeneous lists.
 *
 * It is important to have constant-time length, append, and prepend
 * operations. To achieve this, we deal with two distinct data
 * structures:
 *
 *		1. A set of "list cells": each cell contains a data field and
 *		   a link to the next cell in the list or NULL.
 *		2. A single structure containing metadata about the list: the
 *		   type of the list, pointers to the head and tail cells, and
 *		   the length of the list.
 *
 * We support three types of lists:
 *
 *	T_PGList: lists of pointers
 *		(in practice usually pointers to Nodes, but not always;
 *		declared as "void *" to minimize casting annoyances)
 *	T_PGIntList: lists of integers
 *	T_PGOidList: lists of Oids
 *
 * (At the moment, ints and Oids are the same size, but they may not
 * always be so; try to be careful to maintain the distinction.)
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/pg_list.h
 *
 *-------------------------------------------------------------------------
 */


/*-------------------------------------------------------------------------
 *
 * nodes.h
 *	  Definitions for tagged nodes.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/nodes.h
 *
 *-------------------------------------------------------------------------
 */




/*
 * The first field of every node is NodeTag. Each node created (with makeNode)
 * will have one of the following tags as the value of its first field.
 *
 * Note that inserting or deleting node types changes the numbers of other
 * node types later in the list.  This is no problem during development, since
 * the node numbers are never stored on disk.  But don't do it in a released
 * branch, because that would represent an ABI break for extensions.
 */
typedef enum PGNodeTag
{
	T_PGInvalid = 0,

	/*
	 * TAGS FOR EXECUTOR NODES (execnodes.h)
	 */
	T_PGIndexInfo,
	T_PGExprContext,
	T_PGProjectionInfo,
	T_PGJunkFilter,
	T_PGResultRelInfo,
	T_PGEState,
	T_PGTupleTableSlot,

	/*
	 * TAGS FOR PLAN NODES (plannodes.h)
	 */
	T_PGPlan,
	T_PGResult,
	T_PGProjectSet,
	T_PGModifyTable,
	T_PGAppend,
	T_PGMergeAppend,
	T_PGRecursiveUnion,
	T_PGBitmapAnd,
	T_PGBitmapOr,
	T_PGScan,
	T_PGSeqScan,
	T_PGSampleScan,
	T_PGIndexScan,
	T_PGIndexOnlyScan,
	T_PGBitmapIndexScan,
	T_PGBitmapHeapScan,
	T_PGTidScan,
	T_PGSubqueryScan,
	T_PGFunctionScan,
	T_PGValuesScan,
	T_PGTableFuncScan,
	T_PGCteScan,
	T_PGNamedTuplestoreScan,
	T_PGWorkTableScan,
	T_PGForeignScan,
	T_PGCustomScan,
	T_PGJoin,
	T_PGNestLoop,
	T_PGMergeJoin,
	T_PGHashJoin,
	T_PGMaterial,
	T_PGSort,
	T_PGGroup,
	T_PGAgg,
	T_PGWindowAgg,
	T_PGUnique,
	T_PGGather,
	T_PGGatherMerge,
	T_PGHash,
	T_PGSetOp,
	T_PGLockRows,
	T_PGLimit,
	/* these aren't subclasses of PGPlan: */
	T_PGNestLoopParam,
	T_PGPlanRowMark,
	T_PGPlanInvalItem,

	/*
	 * TAGS FOR PLAN STATE NODES (execnodes.h)
	 *
	 * These should correspond one-to-one with PGPlan node types.
	 */
	T_PGPlanState,
	T_PGResultState,
	T_PGProjectSetState,
	T_PGModifyTableState,
	T_PGAppendState,
	T_PGMergeAppendState,
	T_PGRecursiveUnionState,
	T_PGBitmapAndState,
	T_PGBitmapOrState,
	T_PGScanState,
	T_PGSeqScanState,
	T_PGSampleScanState,
	T_PGIndexScanState,
	T_PGIndexOnlyScanState,
	T_PGBitmapIndexScanState,
	T_PGBitmapHeapScanState,
	T_PGTidScanState,
	T_PGSubqueryScanState,
	T_PGFunctionScanState,
	T_PGTableFuncScanState,
	T_PGValuesScanState,
	T_PGCteScanState,
	T_PGNamedTuplestoreScanState,
	T_PGWorkTableScanState,
	T_PGForeignScanState,
	T_PGCustomScanState,
	T_PGJoinState,
	T_PGNestLoopState,
	T_PGMergeJoinState,
	T_PGHashJoinState,
	T_PGMaterialState,
	T_PGSortState,
	T_PGGroupState,
	T_PGAggState,
	T_PGWindowAggState,
	T_PGUniqueState,
	T_PGGatherState,
	T_PGGatherMergeState,
	T_PGHashState,
	T_PGSetOpState,
	T_PGLockRowsState,
	T_PGLimitState,

	/*
	 * TAGS FOR PRIMITIVE NODES (primnodes.h)
	 */
	T_PGAlias,
	T_PGRangeVar,
	T_PGTableFunc,
	T_PGExpr,
	T_PGVar,
	T_PGConst,
	T_PGParam,
	T_PGAggref,
	T_PGGroupingFunc,
	T_PGWindowFunc,
	T_PGArrayRef,
	T_PGFuncExpr,
	T_PGNamedArgExpr,
	T_PGOpExpr,
	T_PGDistinctExpr,
	T_PGNullIfExpr,
	T_PGScalarArrayOpExpr,
	T_PGBoolExpr,
	T_PGSubLink,
	T_PGSubPlan,
	T_PGAlternativeSubPlan,
	T_PGFieldSelect,
	T_PGFieldStore,
	T_PGRelabelType,
	T_PGCoerceViaIO,
	T_PGArrayCoerceExpr,
	T_PGConvertRowtypeExpr,
	T_PGCollateExpr,
	T_PGCaseExpr,
	T_PGCaseWhen,
	T_PGCaseTestExpr,
	T_PGArrayExpr,
	T_PGRowExpr,
	T_PGRowCompareExpr,
	T_PGCoalesceExpr,
	T_PGMinMaxExpr,
	T_PGSQLValueFunction,
	T_PGXmlExpr,
	T_PGNullTest,
	T_PGBooleanTest,
	T_PGCoerceToDomain,
	T_PGCoerceToDomainValue,
	T_PGSetToDefault,
	T_PGCurrentOfExpr,
	T_PGNextValueExpr,
	T_PGInferenceElem,
	T_PGTargetEntry,
	T_PGRangeTblRef,
	T_PGJoinExpr,
	T_PGFromExpr,
	T_PGOnConflictExpr,
	T_PGIntoClause,

	/*
	 * TAGS FOR EXPRESSION STATE NODES (execnodes.h)
	 *
	 * ExprState represents the evaluation state for a whole expression tree.
	 * Most Expr-based plan nodes do not have a corresponding expression state
	 * node, they're fully handled within execExpr* - but sometimes the state
	 * needs to be shared with other parts of the executor, as for example
	 * with AggrefExprState, which nodeAgg.c has to modify.
	 */
	T_PGExprState,
	T_PGAggrefExprState,
	T_PGWindowFuncExprState,
	T_PGSetExprState,
	T_PGSubPlanState,
	T_PGAlternativeSubPlanState,
	T_PGDomainConstraintState,

	/*
	 * TAGS FOR PLANNER NODES (relation.h)
	 */
	T_PGPlannerInfo,
	T_PGPlannerGlobal,
	T_PGRelOptInfo,
	T_PGIndexOptInfo,
	T_PGForeignKeyOptInfo,
	T_PGParamPathInfo,
	T_PGPath,
	T_PGIndexPath,
	T_PGBitmapHeapPath,
	T_PGBitmapAndPath,
	T_PGBitmapOrPath,
	T_PGTidPath,
	T_PGSubqueryScanPath,
	T_PGForeignPath,
	T_PGCustomPath,
	T_PGNestPath,
	T_PGMergePath,
	T_PGHashPath,
	T_PGAppendPath,
	T_PGMergeAppendPath,
	T_PGResultPath,
	T_PGMaterialPath,
	T_PGUniquePath,
	T_PGGatherPath,
	T_PGGatherMergePath,
	T_PGProjectionPath,
	T_PGProjectSetPath,
	T_PGSortPath,
	T_PGGroupPath,
	T_PGUpperUniquePath,
	T_PGAggPath,
	T_PGGroupingSetsPath,
	T_PGMinMaxAggPath,
	T_PGWindowAggPath,
	T_PGSetOpPath,
	T_PGRecursiveUnionPath,
	T_PGLockRowsPath,
	T_PGModifyTablePath,
	T_PGLimitPath,
	/* these aren't subclasses of Path: */
	T_PGEquivalenceClass,
	T_PGEquivalenceMember,
	T_PGPathKey,
	T_PGPathTarget,
	T_PGRestrictInfo,
	T_PGPlaceHolderVar,
	T_PGSpecialJoinInfo,
	T_PGAppendRelInfo,
	T_PGPartitionedChildRelInfo,
	T_PGPlaceHolderInfo,
	T_PGMinMaxAggInfo,
	T_PGPlannerParamItem,
	T_PGRollupData,
	T_PGGroupingSetData,
	T_PGStatisticExtInfo,

	/*
	 * TAGS FOR MEMORY NODES (memnodes.h)
	 */
	T_PGMemoryContext,
	T_PGAllocSetContext,
	T_PGSlabContext,

	/*
	 * TAGS FOR VALUE NODES (value.h)
	 */
	T_PGValue,
	T_PGInteger,
	T_PGFloat,
	T_PGString,
	T_PGBitString,
	T_PGNull,

	/*
	 * TAGS FOR LIST NODES (pg_list.h)
	 */
	T_PGList,
	T_PGIntList,
	T_PGOidList,

	/*
	 * TAGS FOR EXTENSIBLE NODES (extensible.h)
	 */
	T_PGExtensibleNode,

	/*
	 * TAGS FOR STATEMENT NODES (mostly in parsenodes.h)
	 */
	T_PGRawStmt,
	T_PGQuery,
	T_PGPlannedStmt,
	T_PGInsertStmt,
	T_PGDeleteStmt,
	T_PGUpdateStmt,
	T_PGSelectStmt,
	T_PGAlterTableStmt,
	T_PGAlterTableCmd,
	T_PGAlterDomainStmt,
	T_PGSetOperationStmt,
	T_PGGrantStmt,
	T_PGGrantRoleStmt,
	T_PGAlterDefaultPrivilegesStmt,
	T_PGClosePortalStmt,
	T_PGClusterStmt,
	T_PGCopyStmt,
	T_PGCreateStmt,
	T_PGDefineStmt,
	T_PGDropStmt,
	T_PGTruncateStmt,
	T_PGCommentStmt,
	T_PGFetchStmt,
	T_PGIndexStmt,
	T_PGCreateFunctionStmt,
	T_PGAlterFunctionStmt,
	T_PGDoStmt,
	T_PGRenameStmt,
	T_PGRuleStmt,
	T_PGNotifyStmt,
	T_PGListenStmt,
	T_PGUnlistenStmt,
	T_PGTransactionStmt,
	T_PGViewStmt,
	T_PGLoadStmt,
	T_PGCreateDomainStmt,
	T_PGCreatedbStmt,
	T_PGDropdbStmt,
	T_PGVacuumStmt,
	T_PGExplainStmt,
	T_PGCreateTableAsStmt,
	T_PGCreateSeqStmt,
	T_PGAlterSeqStmt,
	T_PGVariableSetStmt,
	T_PGVariableShowStmt,
	T_PGDiscardStmt,
	T_PGCreateTrigStmt,
	T_PGCreatePLangStmt,
	T_PGCreateRoleStmt,
	T_PGAlterRoleStmt,
	T_PGDropRoleStmt,
	T_PGLockStmt,
	T_PGConstraintsSetStmt,
	T_PGReindexStmt,
	T_PGCheckPointStmt,
	T_PGCreateSchemaStmt,
	T_PGAlterDatabaseStmt,
	T_PGAlterDatabaseSetStmt,
	T_PGAlterRoleSetStmt,
	T_PGCreateConversionStmt,
	T_PGCreateCastStmt,
	T_PGCreateOpClassStmt,
	T_PGCreateOpFamilyStmt,
	T_PGAlterOpFamilyStmt,
	T_PGPrepareStmt,
	T_PGExecuteStmt,
	T_PGDeallocateStmt,
	T_PGDeclareCursorStmt,
	T_PGCreateTableSpaceStmt,
	T_PGDropTableSpaceStmt,
	T_PGAlterObjectDependsStmt,
	T_PGAlterObjectSchemaStmt,
	T_PGAlterOwnerStmt,
	T_PGAlterOperatorStmt,
	T_PGDropOwnedStmt,
	T_PGReassignOwnedStmt,
	T_PGCompositeTypeStmt,
	T_PGCreateEnumStmt,
	T_PGCreateRangeStmt,
	T_PGAlterEnumStmt,
	T_PGAlterTSDictionaryStmt,
	T_PGAlterTSConfigurationStmt,
	T_PGCreateFdwStmt,
	T_PGAlterFdwStmt,
	T_PGCreateForeignServerStmt,
	T_PGAlterForeignServerStmt,
	T_PGCreateUserMappingStmt,
	T_PGAlterUserMappingStmt,
	T_PGDropUserMappingStmt,
	T_PGAlterTableSpaceOptionsStmt,
	T_PGAlterTableMoveAllStmt,
	T_PGSecLabelStmt,
	T_PGCreateForeignTableStmt,
	T_PGImportForeignSchemaStmt,
	T_PGCreateExtensionStmt,
	T_PGAlterExtensionStmt,
	T_PGAlterExtensionContentsStmt,
	T_PGCreateEventTrigStmt,
	T_PGAlterEventTrigStmt,
	T_PGRefreshMatViewStmt,
	T_PGReplicaIdentityStmt,
	T_PGAlterSystemStmt,
	T_PGCreatePolicyStmt,
	T_PGAlterPolicyStmt,
	T_PGCreateTransformStmt,
	T_PGCreateAmStmt,
	T_PGCreatePublicationStmt,
	T_PGAlterPublicationStmt,
	T_PGCreateSubscriptionStmt,
	T_PGAlterSubscriptionStmt,
	T_PGDropSubscriptionStmt,
	T_PGCreateStatsStmt,
	T_PGAlterCollationStmt,
	T_PGPragmaStmt,

	/*
	 * TAGS FOR PARSE TREE NODES (parsenodes.h)
	 */
	T_PGAExpr,
	T_PGColumnRef,
	T_PGParamRef,
	T_PGAConst,
	T_PGFuncCall,
	T_PGAStar,
	T_PGAIndices,
	T_PGAIndirection,
	T_PGAArrayExpr,
	T_PGResTarget,
	T_PGMultiAssignRef,
	T_PGTypeCast,
	T_PGCollateClause,
	T_PGSortBy,
	T_PGWindowDef,
	T_PGRangeSubselect,
	T_PGRangeFunction,
	T_PGRangeTableSample,
	T_PGRangeTableFunc,
	T_PGRangeTableFuncCol,
	T_PGTypeName,
	T_PGColumnDef,
	T_PGIndexElem,
	T_PGConstraint,
	T_PGDefElem,
	T_PGRangeTblEntry,
	T_PGRangeTblFunction,
	T_PGTableSampleClause,
	T_PGWithCheckOption,
	T_PGSortGroupClause,
	T_PGGroupingSet,
	T_PGWindowClause,
	T_PGObjectWithArgs,
	T_PGAccessPriv,
	T_PGCreateOpClassItem,
	T_PGTableLikeClause,
	T_PGFunctionParameter,
	T_PGLockingClause,
	T_PGRowMarkClause,
	T_PGXmlSerialize,
	T_PGWithClause,
	T_PGInferClause,
	T_PGOnConflictClause,
	T_PGCommonTableExpr,
	T_PGRoleSpec,
	T_PGTriggerTransition,
	T_PGPartitionElem,
	T_PGPartitionSpec,
	T_PGPartitionBoundSpec,
	T_PGPartitionRangeDatum,
	T_PGPartitionCmd,

	/*
	 * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)
	 */
	T_PGIdentifySystemCmd,
	T_PGBaseBackupCmd,
	T_PGCreateReplicationSlotCmd,
	T_PGDropReplicationSlotCmd,
	T_PGStartReplicationCmd,
	T_PGTimeLineHistoryCmd,
	T_PGSQLCmd,

	/*
	 * TAGS FOR RANDOM OTHER STUFF
	 *
	 * These are objects that aren't part of parse/plan/execute node tree
	 * structures, but we give them NodeTags anyway for identification
	 * purposes (usually because they are involved in APIs where we want to
	 * pass multiple object types through the same pointer).
	 */
	T_PGTriggerData,				/* in commands/trigger.h */
	T_PGEventTriggerData,			/* in commands/event_trigger.h */
	T_PGReturnSetInfo,			/* in nodes/execnodes.h */
	T_PGWindowObjectData,			/* private in nodeWindowAgg.c */
	T_PGTIDBitmap,				/* in nodes/tidbitmap.h */
	T_PGInlineCodeBlock,			/* in nodes/parsenodes.h */
	T_PGFdwRoutine,				/* in foreign/fdwapi.h */
	T_PGIndexAmRoutine,			/* in access/amapi.h */
	T_PGTsmRoutine,				/* in access/tsmapi.h */
	T_PGForeignKeyCacheInfo		/* in utils/rel.h */
} PGNodeTag;

/*
 * The first field of a node of any type is guaranteed to be the NodeTag.
 * Hence the type of any node can be gotten by casting it to Node. Declaring
 * a variable to be of PGNode * (instead of void *) can also facilitate
 * debugging.
 */
typedef struct PGNode
{
	PGNodeTag		type;
} PGNode;

#define nodeTag(nodeptr)		(((const PGNode*)(nodeptr))->type)

/*
 * newNode -
 *	  create a new node of the specified size and tag the node with the
 *	  specified tag.
 *
 * !WARNING!: Avoid using newNode directly. You should be using the
 *	  macro makeNode.  eg. to create a PGQuery node, use makeNode(PGQuery)
 *
 * Note: the size argument should always be a compile-time constant, so the
 * apparent risk of multiple evaluation doesn't matter in practice.
 */
#ifdef __GNUC__

/* With GCC, we can use a compound statement within an expression */
#define newNode(size, tag) \
({	PGNode   *_result; \
	AssertMacro((size) >= sizeof(PGNode));		/* need the tag, at least */ \
	_result = (PGNode *) palloc0fast(size); \
	_result->type = (tag); \
	_result; \
})
#else

/*
 *	There is no way to dereference the palloc'ed pointer to assign the
 *	tag, and also return the pointer itself, so we need a holder variable.
 *	Fortunately, this macro isn't recursive so we just define
 *	a global variable for this purpose.
 */
extern __thread PGNode *newNodeMacroHolder;

#define newNode(size, tag) \
( \
	AssertMacro((size) >= sizeof(PGNode)),		/* need the tag, at least */ \
	newNodeMacroHolder = (PGNode *) palloc0fast(size), \
	newNodeMacroHolder->type = (tag), \
	newNodeMacroHolder \
)
#endif							/* __GNUC__ */


#define makeNode(_type_)		((_type_ *) newNode(sizeof(_type_),T_##_type_))
#define NodeSetTag(nodeptr,t)	(((PGNode*)(nodeptr))->type = (t))

#define IsA(nodeptr,_type_)		(nodeTag(nodeptr) == T_##_type_)

/*
 * castNode(type, ptr) casts ptr to "type *", and if assertions are enabled,
 * verifies that the node has the appropriate type (using its nodeTag()).
 *
 * Use an inline function when assertions are enabled, to avoid multiple
 * evaluations of the ptr argument (which could e.g. be a function call).
 */
#ifdef USE_ASSERT_CHECKING
static inline PGNode *
castNodeImpl(PGNodeTag type, void *ptr)
{
	Assert(ptr == NULL || nodeTag(ptr) == type);
	return (PGNode *) ptr;
}
#define castNode(_type_, nodeptr) ((_type_ *) castNodeImpl(T_##_type_, nodeptr))
#else
#define castNode(_type_, nodeptr) ((_type_ *) (nodeptr))
#endif							/* USE_ASSERT_CHECKING */


/* ----------------------------------------------------------------
 *					  extern declarations follow
 * ----------------------------------------------------------------
 */

/*
 * nodes/{outfuncs.c,print.c}
 */
struct PGBitmapset;				/* not to include bitmapset.h here */
struct PGStringInfoData;			/* not to include stringinfo.h here */

extern void outNode(struct PGStringInfoData *str, const void *obj);
extern void outToken(struct PGStringInfoData *str, const char *s);
extern void outBitmapset(struct PGStringInfoData *str,
			 const struct PGBitmapset *bms);
extern void outDatum(struct PGStringInfoData *str, uintptr_t value,
		 int typlen, bool typbyval);
extern char *nodeToString(const void *obj);
extern char *bmsToString(const struct PGBitmapset *bms);

/*
 * nodes/{readfuncs.c,read.c}
 */
extern void *stringToNode(char *str);
extern struct PGBitmapset *readBitmapset(void);
extern uintptr_t readDatum(bool typbyval);
extern bool *readBoolCols(int numCols);
extern int *readIntCols(int numCols);
extern PGOid *readOidCols(int numCols);
extern int16_t *readAttrNumberCols(int numCols);

/*
 * nodes/copyfuncs.c
 */
extern void *copyObjectImpl(const void *obj);

/* cast result back to argument type, if supported by compiler */
//#ifdef HAVE_TYPEOF
//#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj))
//#else
//#define copyObject(obj) copyObjectImpl(obj)
//#endif

/*
 * nodes/equalfuncs.c
 */
//extern bool equal(const void *a, const void *b);


/*
 * Typedefs for identifying qualifier selectivities and plan costs as such.
 * These are just plain "double"s, but declaring a variable as Selectivity
 * or Cost makes the intent more obvious.
 *
 * These could have gone into plannodes.h or some such, but many files
 * depend on them...
 */
typedef double Selectivity;		/* fraction of tuples a qualifier will pass */
typedef double Cost;			/* execution cost (in page-access units) */


/*
 * PGCmdType -
 *	  enums for type of operation represented by a PGQuery or PGPlannedStmt
 *
 * This is needed in both parsenodes.h and plannodes.h, so put it here...
 */
typedef enum PGCmdType
{
	PG_CMD_UNKNOWN,
	PG_CMD_SELECT,					/* select stmt */
	PG_CMD_UPDATE,					/* update stmt */
	PG_CMD_INSERT,					/* insert stmt */
	PG_CMD_DELETE,
	PG_CMD_UTILITY,				/* cmds like create, destroy, copy, vacuum,
								 * etc. */
	PG_CMD_NOTHING					/* dummy command for instead nothing rules
								 * with qual */
} PGCmdType;


/*
 * PGJoinType -
 *	  enums for types of relation joins
 *
 * PGJoinType determines the exact semantics of joining two relations using
 * a matching qualification.  For example, it tells what to do with a tuple
 * that has no match in the other relation.
 *
 * This is needed in both parsenodes.h and plannodes.h, so put it here...
 */
typedef enum PGJoinType
{
	/*
	 * The canonical kinds of joins according to the SQL JOIN syntax. Only
	 * these codes can appear in parser output (e.g., PGJoinExpr nodes).
	 */
	PG_JOIN_INNER,					/* matching tuple pairs only */
	PG_JOIN_LEFT,					/* pairs + unmatched LHS tuples */
	PG_JOIN_FULL,					/* pairs + unmatched LHS + unmatched RHS */
	PG_JOIN_RIGHT,					/* pairs + unmatched RHS tuples */

	/*
	 * Semijoins and anti-semijoins (as defined in relational theory) do not
	 * appear in the SQL JOIN syntax, but there are standard idioms for
	 * representing them (e.g., using EXISTS).  The planner recognizes these
	 * cases and converts them to joins.  So the planner and executor must
	 * support these codes.  NOTE: in PG_JOIN_SEMI output, it is unspecified
	 * which matching RHS row is joined to.  In PG_JOIN_ANTI output, the row is
	 * guaranteed to be null-extended.
	 */
	PG_JOIN_SEMI,					/* 1 copy of each LHS row that has match(es) */
	PG_JOIN_ANTI,					/* 1 copy of each LHS row that has no match */

	/*
	 * These codes are used internally in the planner, but are not supported
	 * by the executor (nor, indeed, by most of the planner).
	 */
	PG_JOIN_UNIQUE_OUTER,			/* LHS path must be made unique */
	PG_JOIN_UNIQUE_INNER			/* RHS path must be made unique */

	/*
	 * We might need additional join types someday.
	 */
} PGJoinType;

/*
 * OUTER joins are those for which pushed-down quals must behave differently
 * from the join's own quals.  This is in fact everything except INNER and
 * SEMI joins.  However, this macro must also exclude the JOIN_UNIQUE symbols
 * since those are temporary proxies for what will eventually be an INNER
 * join.
 *
 * Note: semijoins are a hybrid case, but we choose to treat them as not
 * being outer joins.  This is okay principally because the SQL syntax makes
 * it impossible to have a pushed-down qual that refers to the inner relation
 * of a semijoin; so there is no strong need to distinguish join quals from
 * pushed-down quals.  This is convenient because for almost all purposes,
 * quals attached to a semijoin can be treated the same as innerjoin quals.
 */
#define IS_OUTER_JOIN(jointype) \
	(((1 << (jointype)) & \
	  ((1 << PG_JOIN_LEFT) | \
	   (1 << PG_JOIN_FULL) | \
	   (1 << PG_JOIN_RIGHT) | \
	   (1 << PG_JOIN_ANTI))) != 0)

/*
 * PGAggStrategy -
 *	  overall execution strategies for PGAgg plan nodes
 *
 * This is needed in both plannodes.h and relation.h, so put it here...
 */
typedef enum PGAggStrategy
{
	PG_AGG_PLAIN,					/* simple agg across all input rows */
	PG_AGG_SORTED,					/* grouped agg, input must be sorted */
	PG_AGG_HASHED,					/* grouped agg, use internal hashtable */
	AGG_MIXED					/* grouped agg, hash and sort both used */
} PGAggStrategy;

/*
 * PGAggSplit -
 *	  splitting (partial aggregation) modes for PGAgg plan nodes
 *
 * This is needed in both plannodes.h and relation.h, so put it here...
 */

/* Primitive options supported by nodeAgg.c: */
#define AGGSPLITOP_COMBINE		0x01	/* substitute combinefn for transfn */
#define AGGSPLITOP_SKIPFINAL	0x02	/* skip finalfn, return state as-is */
#define AGGSPLITOP_SERIALIZE	0x04	/* apply serializefn to output */
#define AGGSPLITOP_DESERIALIZE	0x08	/* apply deserializefn to input */

/* Supported operating modes (i.e., useful combinations of these options): */
typedef enum PGAggSplit
{
	/* Basic, non-split aggregation: */
	PG_AGGSPLIT_SIMPLE = 0,
	/* Initial phase of partial aggregation, with serialization: */
	PG_AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE,
	/* Final phase of partial aggregation, with deserialization: */
	PG_AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE
} PGAggSplit;

/* Test whether an PGAggSplit value selects each primitive option: */
#define DO_AGGSPLIT_COMBINE(as)		(((as) & AGGSPLITOP_COMBINE) != 0)
#define DO_AGGSPLIT_SKIPFINAL(as)	(((as) & AGGSPLITOP_SKIPFINAL) != 0)
#define DO_AGGSPLIT_SERIALIZE(as)	(((as) & AGGSPLITOP_SERIALIZE) != 0)
#define DO_AGGSPLIT_DESERIALIZE(as) (((as) & AGGSPLITOP_DESERIALIZE) != 0)

/*
 * PGSetOpCmd and PGSetOpStrategy -
 *	  overall semantics and execution strategies for PGSetOp plan nodes
 *
 * This is needed in both plannodes.h and relation.h, so put it here...
 */
typedef enum PGSetOpCmd
{
	PG_SETOPCMD_INTERSECT,
	PG_SETOPCMD_INTERSECT_ALL,
	PG_SETOPCMD_EXCEPT,
	PG_SETOPCMD_EXCEPT_ALL
} PGSetOpCmd;

typedef enum PGSetOpStrategy
{
	PG_SETOP_SORTED,				/* input must be sorted */
	PG_SETOP_HASHED				/* use internal hashtable */
} PGSetOpStrategy;

/*
 * PGOnConflictAction -
 *	  "ON CONFLICT" clause type of query
 *
 * This is needed in both parsenodes.h and plannodes.h, so put it here...
 */
typedef enum PGOnConflictAction
{
	PG_ONCONFLICT_NONE,			/* No "ON CONFLICT" clause */
	PG_ONCONFLICT_NOTHING,			/* ON CONFLICT ... DO NOTHING */
	PG_ONCONFLICT_UPDATE			/* ON CONFLICT ... DO UPDATE */
} PGOnConflictAction;




typedef struct PGListCell ListCell;

typedef struct PGList {
	PGNodeTag		type;			/* T_PGList, T_PGIntList, or T_PGOidList */
	int			length;
	PGListCell   *head;
	PGListCell   *tail;
} PGList;

struct PGListCell {
	union
	{
		void	   *ptr_value;
		int			int_value;
		PGOid			oid_value;
	}			data;
	PGListCell   *next;
};

/*
 * The *only* valid representation of an empty list is NIL; in other
 * words, a non-NIL list is guaranteed to have length >= 1 and
 * head/tail != NULL
 */
#define NIL						((PGList *) NULL)

/*
 * These routines are used frequently. However, we can't implement
 * them as macros, since we want to avoid double-evaluation of macro
 * arguments.
 */
static inline PGListCell *
list_head(const PGList *l)
{
	return l ? l->head : NULL;
}

static inline PGListCell *
list_tail(PGList *l)
{
	return l ? l->tail : NULL;
}

static inline int
list_length(const PGList *l)
{
	return l ? l->length : 0;
}

/*
 * NB: There is an unfortunate legacy from a previous incarnation of
 * the PGList API: the macro lfirst() was used to mean "the data in this
 * cons cell". To avoid changing every usage of lfirst(), that meaning
 * has been kept. As a result, lfirst() takes a PGListCell and returns
 * the data it contains; to get the data in the first cell of a
 * PGList, use linitial(). Worse, lsecond() is more closely related to
 * linitial() than lfirst(): given a PGList, lsecond() returns the data
 * in the second cons cell.
 */

#define lnext(lc)				((lc)->next)
#define lfirst(lc)				((lc)->data.ptr_value)
#define lfirst_int(lc)			((lc)->data.int_value)
#define lfirst_oid(lc)			((lc)->data.oid_value)
#define lfirst_node(type,lc)	castNode(type, lfirst(lc))

#define linitial(l)				lfirst(list_head(l))
#define linitial_int(l)			lfirst_int(list_head(l))
#define linitial_oid(l)			lfirst_oid(list_head(l))
#define linitial_node(type,l)	castNode(type, linitial(l))

#define lsecond(l)				lfirst(lnext(list_head(l)))
#define lsecond_int(l)			lfirst_int(lnext(list_head(l)))
#define lsecond_oid(l)			lfirst_oid(lnext(list_head(l)))
#define lsecond_node(type,l)	castNode(type, lsecond(l))

#define lthird(l)				lfirst(lnext(lnext(list_head(l))))
#define lthird_int(l)			lfirst_int(lnext(lnext(list_head(l))))
#define lthird_oid(l)			lfirst_oid(lnext(lnext(list_head(l))))
#define lthird_node(type,l)		castNode(type, lthird(l))

#define lfourth(l)				lfirst(lnext(lnext(lnext(list_head(l)))))
#define lfourth_int(l)			lfirst_int(lnext(lnext(lnext(list_head(l)))))
#define lfourth_oid(l)			lfirst_oid(lnext(lnext(lnext(list_head(l)))))
#define lfourth_node(type,l)	castNode(type, lfourth(l))

#define llast(l)				lfirst(list_tail(l))
#define llast_int(l)			lfirst_int(list_tail(l))
#define llast_oid(l)			lfirst_oid(list_tail(l))
#define llast_node(type,l)		castNode(type, llast(l))

/*
 * Convenience macros for building fixed-length lists
 */
#define list_make1(x1)				lcons(x1, NIL)
#define list_make2(x1,x2)			lcons(x1, list_make1(x2))
#define list_make3(x1,x2,x3)		lcons(x1, list_make2(x2, x3))
#define list_make4(x1,x2,x3,x4)		lcons(x1, list_make3(x2, x3, x4))
#define list_make5(x1,x2,x3,x4,x5)	lcons(x1, list_make4(x2, x3, x4, x5))

#define list_make1_int(x1)			lcons_int(x1, NIL)
#define list_make2_int(x1,x2)		lcons_int(x1, list_make1_int(x2))
#define list_make3_int(x1,x2,x3)	lcons_int(x1, list_make2_int(x2, x3))
#define list_make4_int(x1,x2,x3,x4) lcons_int(x1, list_make3_int(x2, x3, x4))
#define list_make5_int(x1,x2,x3,x4,x5)	lcons_int(x1, list_make4_int(x2, x3, x4, x5))

#define list_make1_oid(x1)			lcons_oid(x1, NIL)
#define list_make2_oid(x1,x2)		lcons_oid(x1, list_make1_oid(x2))
#define list_make3_oid(x1,x2,x3)	lcons_oid(x1, list_make2_oid(x2, x3))
#define list_make4_oid(x1,x2,x3,x4) lcons_oid(x1, list_make3_oid(x2, x3, x4))
#define list_make5_oid(x1,x2,x3,x4,x5)	lcons_oid(x1, list_make4_oid(x2, x3, x4, x5))

/*
 * foreach -
 *	  a convenience macro which loops through the list
 */
#define foreach(cell, l)	\
	for ((cell) = list_head(l); (cell) != NULL; (cell) = lnext(cell))

/*
 * for_each_cell -
 *	  a convenience macro which loops through a list starting from a
 *	  specified cell
 */
#define for_each_cell(cell, initcell)	\
	for ((cell) = (initcell); (cell) != NULL; (cell) = lnext(cell))

/*
 * forboth -
 *	  a convenience macro for advancing through two linked lists
 *	  simultaneously. This macro loops through both lists at the same
 *	  time, stopping when either list runs out of elements. Depending
 *	  on the requirements of the call site, it may also be wise to
 *	  assert that the lengths of the two lists are equal.
 */
#define forboth(cell1, list1, cell2, list2)							\
	for ((cell1) = list_head(list1), (cell2) = list_head(list2);	\
		 (cell1) != NULL && (cell2) != NULL;						\
		 (cell1) = lnext(cell1), (cell2) = lnext(cell2))

/*
 * for_both_cell -
 *	  a convenience macro which loops through two lists starting from the
 *	  specified cells of each. This macro loops through both lists at the same
 *	  time, stopping when either list runs out of elements.  Depending on the
 *	  requirements of the call site, it may also be wise to assert that the
 *	  lengths of the two lists are equal, and initcell1 and initcell2 are at
 *	  the same position in the respective lists.
 */
#define for_both_cell(cell1, initcell1, cell2, initcell2)	\
	for ((cell1) = (initcell1), (cell2) = (initcell2);		\
		 (cell1) != NULL && (cell2) != NULL;				\
		 (cell1) = lnext(cell1), (cell2) = lnext(cell2))

/*
 * forthree -
 *	  the same for three lists
 */
#define forthree(cell1, list1, cell2, list2, cell3, list3)			\
	for ((cell1) = list_head(list1), (cell2) = list_head(list2), (cell3) = list_head(list3); \
		 (cell1) != NULL && (cell2) != NULL && (cell3) != NULL;		\
		 (cell1) = lnext(cell1), (cell2) = lnext(cell2), (cell3) = lnext(cell3))

extern PGList *lappend(PGList *list, void *datum);
extern PGList *lappend_int(PGList *list, int datum);
extern PGList *lappend_oid(PGList *list, PGOid datum);

extern PGListCell *lappend_cell(PGList *list, PGListCell *prev, void *datum);
extern PGListCell *lappend_cell_int(PGList *list, PGListCell *prev, int datum);
extern PGListCell *lappend_cell_oid(PGList *list, PGListCell *prev, PGOid datum);

extern PGList *lcons(void *datum, PGList *list);
extern PGList *lcons_int(int datum, PGList *list);
extern PGList *lcons_oid(PGOid datum, PGList *list);

extern PGList *list_concat(PGList *list1, PGList *list2);
extern PGList *list_truncate(PGList *list, int new_size);

extern PGListCell *list_nth_cell(const PGList *list, int n);
extern void *list_nth(const PGList *list, int n);
extern int	list_nth_int(const PGList *list, int n);
extern PGOid	list_nth_oid(const PGList *list, int n);
#define list_nth_node(type,list,n)	castNode(type, list_nth(list, n))

extern bool list_member(const PGList *list, const void *datum);
extern bool list_member_ptr(const PGList *list, const void *datum);
extern bool list_member_int(const PGList *list, int datum);
extern bool list_member_oid(const PGList *list, PGOid datum);

extern PGList *list_delete(PGList *list, void *datum);
extern PGList *list_delete_ptr(PGList *list, void *datum);
extern PGList *list_delete_int(PGList *list, int datum);
extern PGList *list_delete_oid(PGList *list, PGOid datum);
extern PGList *list_delete_first(PGList *list);
extern PGList *list_delete_cell(PGList *list, PGListCell *cell, PGListCell *prev);

extern PGList *list_union(const PGList *list1, const PGList *list2);
extern PGList *list_union_ptr(const PGList *list1, const PGList *list2);
extern PGList *list_union_int(const PGList *list1, const PGList *list2);
extern PGList *list_union_oid(const PGList *list1, const PGList *list2);

extern PGList *list_intersection(const PGList *list1, const PGList *list2);
extern PGList *list_intersection_int(const PGList *list1, const PGList *list2);

/* currently, there's no need for list_intersection_ptr etc */

extern PGList *list_difference(const PGList *list1, const PGList *list2);
extern PGList *list_difference_ptr(const PGList *list1, const PGList *list2);
extern PGList *list_difference_int(const PGList *list1, const PGList *list2);
extern PGList *list_difference_oid(const PGList *list1, const PGList *list2);

extern PGList *list_append_unique(PGList *list, void *datum);
extern PGList *list_append_unique_ptr(PGList *list, void *datum);
extern PGList *list_append_unique_int(PGList *list, int datum);
extern PGList *list_append_unique_oid(PGList *list, PGOid datum);

extern PGList *list_concat_unique(PGList *list1, PGList *list2);
extern PGList *list_concat_unique_ptr(PGList *list1, PGList *list2);
extern PGList *list_concat_unique_int(PGList *list1, PGList *list2);
extern PGList *list_concat_unique_oid(PGList *list1, PGList *list2);

extern void list_free(PGList *list);
extern void list_free_deep(PGList *list);

extern PGList *list_copy(const PGList *list);
extern PGList *list_copy_tail(const PGList *list, int nskip);

/*
 * To ease migration to the new list API, a set of compatibility
 * macros are provided that reduce the impact of the list API changes
 * as far as possible. Until client code has been rewritten to use the
 * new list API, the ENABLE_LIST_COMPAT symbol can be defined before
 * including pg_list.h
 */
#ifdef ENABLE_LIST_COMPAT

#define lfirsti(lc)					lfirst_int(lc)
#define lfirsto(lc)					lfirst_oid(lc)

#define makeList1(x1)				list_make1(x1)
#define makeList2(x1, x2)			list_make2(x1, x2)
#define makeList3(x1, x2, x3)		list_make3(x1, x2, x3)
#define makeList4(x1, x2, x3, x4)	list_make4(x1, x2, x3, x4)

#define makeListi1(x1)				list_make1_int(x1)
#define makeListi2(x1, x2)			list_make2_int(x1, x2)

#define makeListo1(x1)				list_make1_oid(x1)
#define makeListo2(x1, x2)			list_make2_oid(x1, x2)

#define lconsi(datum, list)			lcons_int(datum, list)
#define lconso(datum, list)			lcons_oid(datum, list)

#define lappendi(list, datum)		lappend_int(list, datum)
#define lappendo(list, datum)		lappend_oid(list, datum)

#define nconc(l1, l2)				list_concat(l1, l2)

#define nth(n, list)				list_nth(list, n)

#define member(datum, list)			list_member(list, datum)
#define ptrMember(datum, list)		list_member_ptr(list, datum)
#define intMember(datum, list)		list_member_int(list, datum)
#define oidMember(datum, list)		list_member_oid(list, datum)

/*
 * Note that the old lremove() determined equality via pointer
 * comparison, whereas the new list_delete() uses equal(); in order to
 * keep the same behavior, we therefore need to map lremove() calls to
 * list_delete_ptr() rather than list_delete()
 */
#define lremove(elem, list)			list_delete_ptr(list, elem)
#define LispRemove(elem, list)		list_delete(list, elem)
#define lremovei(elem, list)		list_delete_int(list, elem)
#define lremoveo(elem, list)		list_delete_oid(list, elem)

#define ltruncate(n, list)			list_truncate(list, n)

#define set_union(l1, l2)			list_union(l1, l2)
#define set_uniono(l1, l2)			list_union_oid(l1, l2)
#define set_ptrUnion(l1, l2)		list_union_ptr(l1, l2)

#define set_difference(l1, l2)		list_difference(l1, l2)
#define set_differenceo(l1, l2)		list_difference_oid(l1, l2)
#define set_ptrDifference(l1, l2)	list_difference_ptr(l1, l2)

#define equali(l1, l2)				equal(l1, l2)
#define equalo(l1, l2)				equal(l1, l2)

#define freeList(list)				list_free(list)

#define listCopy(list)				list_copy(list)

extern int	length(PGList *list);
#endif							/* ENABLE_LIST_COMPAT */




/* ----------------------------------------------------------------
 *						node definitions
 * ----------------------------------------------------------------
 */

/*
 * PGAlias -
 *	  specifies an alias for a range variable; the alias might also
 *	  specify renaming of columns within the table.
 *
 * Note: colnames is a list of PGValue nodes (always strings).  In PGAlias structs
 * associated with RTEs, there may be entries corresponding to dropped
 * columns; these are normally empty strings ("").  See parsenodes.h for info.
 */
typedef struct PGAlias
{
	PGNodeTag		type;
	char	   *aliasname;		/* aliased rel name (never qualified) */
	PGList	   *colnames;		/* optional list of column aliases */
} PGAlias;

/* What to do at commit time for temporary relations */
typedef enum PGOnCommitAction
{
	PG_ONCOMMIT_NOOP,				/* No ON COMMIT clause (do nothing) */
	PG_ONCOMMIT_PRESERVE_ROWS,		/* ON COMMIT PRESERVE ROWS (do nothing) */
	PG_ONCOMMIT_DELETE_ROWS,		/* ON COMMIT DELETE ROWS */
	ONCOMMIT_DROP				/* ON COMMIT DROP */
} PGOnCommitAction;

/*
 * PGRangeVar - range variable, used in FROM clauses
 *
 * Also used to represent table names in utility statements; there, the alias
 * field is not used, and inh tells whether to apply the operation
 * recursively to child tables.  In some contexts it is also useful to carry
 * a TEMP table indication here.
 */
typedef struct PGRangeVar
{
	PGNodeTag		type;
	char	   *catalogname;	/* the catalog (database) name, or NULL */
	char	   *schemaname;		/* the schema name, or NULL */
	char	   *relname;		/* the relation/sequence name */
	bool		inh;			/* expand rel by inheritance? recursively act
								 * on children? */
	char		relpersistence; /* see RELPERSISTENCE_* in pg_class.h */
	PGAlias	   *alias;			/* table alias & optional column aliases */
	int			location;		/* token location, or -1 if unknown */
} PGRangeVar;

/*
 * PGTableFunc - node for a table function, such as XMLTABLE.
 */
typedef struct PGTableFunc
{
	PGNodeTag		type;
	PGList	   *ns_uris;		/* list of namespace uri */
	PGList	   *ns_names;		/* list of namespace names */
	PGNode	   *docexpr;		/* input document expression */
	PGNode	   *rowexpr;		/* row filter expression */
	PGList	   *colnames;		/* column names (list of String) */
	PGList	   *coltypes;		/* OID list of column type OIDs */
	PGList	   *coltypmods;		/* integer list of column typmods */
	PGList	   *colcollations;	/* OID list of column collation OIDs */
	PGList	   *colexprs;		/* list of column filter expressions */
	PGList	   *coldefexprs;	/* list of column default expressions */
	PGBitmapset  *notnulls;		/* nullability flag for each output column */
	int			ordinalitycol;	/* counts from 0; -1 if none specified */
	int			location;		/* token location, or -1 if unknown */
} PGTableFunc;

/*
 * PGIntoClause - target information for SELECT INTO, CREATE TABLE AS, and
 * CREATE MATERIALIZED VIEW
 *
 * For CREATE MATERIALIZED VIEW, viewQuery is the parsed-but-not-rewritten
 * SELECT PGQuery for the view; otherwise it's NULL.  (Although it's actually
 * PGQuery*, we declare it as PGNode* to avoid a forward reference.)
 */
typedef struct PGIntoClause
{
	PGNodeTag		type;

	PGRangeVar   *rel;			/* target relation name */
	PGList	   *colNames;		/* column names to assign, or NIL */
	PGList	   *options;		/* options from WITH clause */
	PGOnCommitAction onCommit;	/* what do we do at COMMIT? */
	char	   *tableSpaceName; /* table space to use, or NULL */
	PGNode	   *viewQuery;		/* materialized view's SELECT query */
	bool		skipData;		/* true for WITH NO DATA */
} PGIntoClause;


/* ----------------------------------------------------------------
 *					node types for executable expressions
 * ----------------------------------------------------------------
 */

/*
 * PGExpr - generic superclass for executable-expression nodes
 *
 * All node types that are used in executable expression trees should derive
 * from PGExpr (that is, have PGExpr as their first field).  Since PGExpr only
 * contains PGNodeTag, this is a formality, but it is an easy form of
 * documentation.  See also the ExprState node types in execnodes.h.
 */
typedef struct PGExpr
{
	PGNodeTag		type;
} PGExpr;

/*
 * PGVar - expression node representing a variable (ie, a table column)
 *
 * Note: during parsing/planning, varnoold/varoattno are always just copies
 * of varno/varattno.  At the tail end of planning, PGVar nodes appearing in
 * upper-level plan nodes are reassigned to point to the outputs of their
 * subplans; for example, in a join node varno becomes INNER_VAR or OUTER_VAR
 * and varattno becomes the index of the proper element of that subplan's
 * target list.  Similarly, INDEX_VAR is used to identify Vars that reference
 * an index column rather than a heap column.  (In PGForeignScan and PGCustomScan
 * plan nodes, INDEX_VAR is abused to signify references to columns of a
 * custom scan tuple type.)  In all these cases, varnoold/varoattno hold the
 * original values.  The code doesn't really need varnoold/varoattno, but they
 * are very useful for debugging and interpreting completed plans, so we keep
 * them around.
 */
#define    INNER_VAR		65000	/* reference to inner subplan */
#define    OUTER_VAR		65001	/* reference to outer subplan */
#define    INDEX_VAR		65002	/* reference to index column */

#define IS_SPECIAL_VARNO(varno)		((varno) >= INNER_VAR)

/* Symbols for the indexes of the special RTE entries in rules */
#define    PRS2_OLD_VARNO			1
#define    PRS2_NEW_VARNO			2

typedef struct PGVar
{
	PGExpr		xpr;
	PGIndex		varno;			/* index of this var's relation in the range
								 * table, or INNER_VAR/OUTER_VAR/INDEX_VAR */
	PGAttrNumber	varattno;		/* attribute number of this var, or zero for
								 * all */
	PGOid			vartype;		/* pg_type OID for the type of this var */
	int32_t		vartypmod;		/* pg_attribute typmod value */
	PGOid			varcollid;		/* OID of collation, or InvalidOid if none */
	PGIndex		varlevelsup;	/* for subquery variables referencing outer
								 * relations; 0 in a normal var, >0 means N
								 * levels up */
	PGIndex		varnoold;		/* original value of varno, for debugging */
	PGAttrNumber	varoattno;		/* original value of varattno */
	int			location;		/* token location, or -1 if unknown */
} PGVar;

/*
 * PGConst
 *
 * Note: for pg_varlena data types, we make a rule that a PGConst node's value
 * must be in non-extended form (4-byte header, no compression or external
 * references).  This ensures that the PGConst node is self-contained and makes
 * it more likely that equal() will see logically identical values as equal.
 */
typedef struct PGConst
{
	PGExpr		xpr;
	PGOid			consttype;		/* pg_type OID of the constant's datatype */
	int32_t		consttypmod;	/* typmod value, if any */
	PGOid			constcollid;	/* OID of collation, or InvalidOid if none */
	int			constlen;		/* typlen of the constant's datatype */
	PGDatum		constvalue;		/* the constant's value */
	bool		constisnull;	/* whether the constant is null (if true,
								 * constvalue is undefined) */
	bool		constbyval;		/* whether this datatype is passed by value.
								 * If true, then all the information is stored
								 * in the Datum. If false, then the PGDatum
								 * contains a pointer to the information. */
	int			location;		/* token location, or -1 if unknown */
} PGConst;

/*
 * PGParam
 *
 *		paramkind specifies the kind of parameter. The possible values
 *		for this field are:
 *
 *		PG_PARAM_EXTERN:  The parameter value is supplied from outside the plan.
 *				Such parameters are numbered from 1 to n.
 *
 *		PG_PARAM_EXEC:  The parameter is an internal executor parameter, used
 *				for passing values into and out of sub-queries or from
 *				nestloop joins to their inner scans.
 *				For historical reasons, such parameters are numbered from 0.
 *				These numbers are independent of PG_PARAM_EXTERN numbers.
 *
 *		PG_PARAM_SUBLINK:	The parameter represents an output column of a PGSubLink
 *				node's sub-select.  The column number is contained in the
 *				`paramid' field.  (This type of PGParam is converted to
 *				PG_PARAM_EXEC during planning.)
 *
 *		PG_PARAM_MULTIEXPR:  Like PG_PARAM_SUBLINK, the parameter represents an
 *				output column of a PGSubLink node's sub-select, but here, the
 *				PGSubLink is always a MULTIEXPR SubLink.  The high-order 16 bits
 *				of the `paramid' field contain the SubLink's subLinkId, and
 *				the low-order 16 bits contain the column number.  (This type
 *				of PGParam is also converted to PG_PARAM_EXEC during planning.)
 */
typedef enum PGParamKind
{
	PG_PARAM_EXTERN,
	PG_PARAM_EXEC,
	PG_PARAM_SUBLINK,
	PG_PARAM_MULTIEXPR
} PGParamKind;

typedef struct PGParam
{
	PGExpr		xpr;
	PGParamKind	paramkind;		/* kind of parameter. See above */
	int			paramid;		/* numeric ID for parameter */
	PGOid			paramtype;		/* pg_type OID of parameter's datatype */
	int32_t		paramtypmod;	/* typmod value, if known */
	PGOid			paramcollid;	/* OID of collation, or InvalidOid if none */
	int			location;		/* token location, or -1 if unknown */
} PGParam;

/*
 * PGAggref
 *
 * The aggregate's args list is a targetlist, ie, a list of PGTargetEntry nodes.
 *
 * For a normal (non-ordered-set) aggregate, the non-resjunk TargetEntries
 * represent the aggregate's regular arguments (if any) and resjunk TLEs can
 * be added at the end to represent ORDER BY expressions that are not also
 * arguments.  As in a top-level PGQuery, the TLEs can be marked with
 * ressortgroupref indexes to let them be referenced by PGSortGroupClause
 * entries in the aggorder and/or aggdistinct lists.  This represents ORDER BY
 * and DISTINCT operations to be applied to the aggregate input rows before
 * they are passed to the transition function.  The grammar only allows a
 * simple "DISTINCT" specifier for the arguments, but we use the full
 * query-level representation to allow more code sharing.
 *
 * For an ordered-set aggregate, the args list represents the WITHIN GROUP
 * (aggregated) arguments, all of which will be listed in the aggorder list.
 * DISTINCT is not supported in this case, so aggdistinct will be NIL.
 * The direct arguments appear in aggdirectargs (as a list of plain
 * expressions, not PGTargetEntry nodes).
 *
 * aggtranstype is the data type of the state transition values for this
 * aggregate (resolved to an actual type, if agg's transtype is polymorphic).
 * This is determined during planning and is InvalidOid before that.
 *
 * aggargtypes is an OID list of the data types of the direct and regular
 * arguments.  Normally it's redundant with the aggdirectargs and args lists,
 * but in a combining aggregate, it's not because the args list has been
 * replaced with a single argument representing the partial-aggregate
 * transition values.
 *
 * aggsplit indicates the expected partial-aggregation mode for the Aggref's
 * parent plan node.  It's always set to PG_AGGSPLIT_SIMPLE in the parser, but
 * the planner might change it to something else.  We use this mainly as
 * a crosscheck that the Aggrefs match the plan; but note that when aggsplit
 * indicates a non-final mode, aggtype reflects the transition data type
 * not the SQL-level output type of the aggregate.
 */
typedef struct PGAggref
{
	PGExpr		xpr;
	PGOid			aggfnoid;		/* pg_proc PGOid of the aggregate */
	PGOid			aggtype;		/* type PGOid of result of the aggregate */
	PGOid			aggcollid;		/* OID of collation of result */
	PGOid			inputcollid;	/* OID of collation that function should use */
	PGOid			aggtranstype;	/* type PGOid of aggregate's transition value */
	PGList	   *aggargtypes;	/* type Oids of direct and aggregated args */
	PGList	   *aggdirectargs;	/* direct arguments, if an ordered-set agg */
	PGList	   *args;			/* aggregated arguments and sort expressions */
	PGList	   *aggorder;		/* ORDER BY (list of PGSortGroupClause) */
	PGList	   *aggdistinct;	/* DISTINCT (list of PGSortGroupClause) */
	PGExpr	   *aggfilter;		/* FILTER expression, if any */
	bool		aggstar;		/* true if argument list was really '*' */
	bool		aggvariadic;	/* true if variadic arguments have been
								 * combined into an array last argument */
	char		aggkind;		/* aggregate kind (see pg_aggregate.h) */
	PGIndex		agglevelsup;	/* > 0 if agg belongs to outer query */
	PGAggSplit	aggsplit;		/* expected agg-splitting mode of parent PGAgg */
	int			location;		/* token location, or -1 if unknown */
} PGAggref;

/*
 * PGGroupingFunc
 *
 * A PGGroupingFunc is a GROUPING(...) expression, which behaves in many ways
 * like an aggregate function (e.g. it "belongs" to a specific query level,
 * which might not be the one immediately containing it), but also differs in
 * an important respect: it never evaluates its arguments, they merely
 * designate expressions from the GROUP BY clause of the query level to which
 * it belongs.
 *
 * The spec defines the evaluation of GROUPING() purely by syntactic
 * replacement, but we make it a real expression for optimization purposes so
 * that one PGAgg node can handle multiple grouping sets at once.  Evaluating the
 * result only needs the column positions to check against the grouping set
 * being projected.  However, for EXPLAIN to produce meaningful output, we have
 * to keep the original expressions around, since expression deparse does not
 * give us any feasible way to get at the GROUP BY clause.
 *
 * Also, we treat two PGGroupingFunc nodes as equal if they have equal arguments
 * lists and agglevelsup, without comparing the refs and cols annotations.
 *
 * In raw parse output we have only the args list; parse analysis fills in the
 * refs list, and the planner fills in the cols list.
 */
typedef struct PGGroupingFunc
{
	PGExpr		xpr;
	PGList	   *args;			/* arguments, not evaluated but kept for
								 * benefit of EXPLAIN etc. */
	PGList	   *refs;			/* ressortgrouprefs of arguments */
	PGList	   *cols;			/* actual column positions set by planner */
	PGIndex		agglevelsup;	/* same as Aggref.agglevelsup */
	int			location;		/* token location */
} PGGroupingFunc;

/*
 * PGWindowFunc
 */
typedef struct PGWindowFunc
{
	PGExpr		xpr;
	PGOid			winfnoid;		/* pg_proc PGOid of the function */
	PGOid			wintype;		/* type PGOid of result of the window function */
	PGOid			wincollid;		/* OID of collation of result */
	PGOid			inputcollid;	/* OID of collation that function should use */
	PGList	   *args;			/* arguments to the window function */
	PGExpr	   *aggfilter;		/* FILTER expression, if any */
	PGIndex		winref;			/* index of associated PGWindowClause */
	bool		winstar;		/* true if argument list was really '*' */
	bool		winagg;			/* is function a simple aggregate? */
	int			location;		/* token location, or -1 if unknown */
} PGWindowFunc;

/* ----------------
 *	PGArrayRef: describes an array subscripting operation
 *
 * An PGArrayRef can describe fetching a single element from an array,
 * fetching a subarray (array slice), storing a single element into
 * an array, or storing a slice.  The "store" cases work with an
 * initial array value and a source value that is inserted into the
 * appropriate part of the array; the result of the operation is an
 * entire new modified array value.
 *
 * If reflowerindexpr = NIL, then we are fetching or storing a single array
 * element at the subscripts given by refupperindexpr.  Otherwise we are
 * fetching or storing an array slice, that is a rectangular subarray
 * with lower and upper bounds given by the index expressions.
 * reflowerindexpr must be the same length as refupperindexpr when it
 * is not NIL.
 *
 * In the slice case, individual expressions in the subscript lists can be
 * NULL, meaning "substitute the array's current lower or upper bound".
 *
 * Note: the result datatype is the element type when fetching a single
 * element; but it is the array type when doing subarray fetch or either
 * type of store.
 *
 * Note: for the cases where an array is returned, if refexpr yields a R/W
 * expanded array, then the implementation is allowed to modify that object
 * in-place and return the same object.)
 * ----------------
 */
typedef struct PGArrayRef
{
	PGExpr		xpr;
	PGOid			refarraytype;	/* type of the array proper */
	PGOid			refelemtype;	/* type of the array elements */
	int32_t		reftypmod;		/* typmod of the array (and elements too) */
	PGOid			refcollid;		/* OID of collation, or InvalidOid if none */
	PGList	   *refupperindexpr;	/* expressions that evaluate to upper
									 * array indexes */
	PGList	   *reflowerindexpr;	/* expressions that evaluate to lower
									 * array indexes, or NIL for single array
									 * element */
	PGExpr	   *refexpr;		/* the expression that evaluates to an array
								 * value */
	PGExpr	   *refassgnexpr;	/* expression for the source value, or NULL if
								 * fetch */
} PGArrayRef;

/*
 * PGCoercionContext - distinguishes the allowed set of type casts
 *
 * NB: ordering of the alternatives is significant; later (larger) values
 * allow more casts than earlier ones.
 */
typedef enum PGCoercionContext
{
	PG_COERCION_IMPLICIT,			/* coercion in context of expression */
	PG_COERCION_ASSIGNMENT,		/* coercion in context of assignment */
	PG_COERCION_EXPLICIT			/* explicit cast operation */
} PGCoercionContext;

/*
 * PGCoercionForm - how to display a node that could have come from a cast
 *
 * NB: equal() ignores PGCoercionForm fields, therefore this *must* not carry
 * any semantically significant information.  We need that behavior so that
 * the planner will consider equivalent implicit and explicit casts to be
 * equivalent.  In cases where those actually behave differently, the coercion
 * function's arguments will be different.
 */
typedef enum PGCoercionForm
{
	PG_COERCE_EXPLICIT_CALL,		/* display as a function call */
	PG_COERCE_EXPLICIT_CAST,		/* display as an explicit cast */
	PG_COERCE_IMPLICIT_CAST		/* implicit cast, so hide it */
} PGCoercionForm;

/*
 * PGFuncExpr - expression node for a function call
 */
typedef struct PGFuncExpr
{
	PGExpr		xpr;
	PGOid			funcid;			/* PG_PROC OID of the function */
	PGOid			funcresulttype; /* PG_TYPE OID of result value */
	bool		funcretset;		/* true if function returns set */
	bool		funcvariadic;	/* true if variadic arguments have been
								 * combined into an array last argument */
	PGCoercionForm funcformat;	/* how to display this function call */
	PGOid			funccollid;		/* OID of collation of result */
	PGOid			inputcollid;	/* OID of collation that function should use */
	PGList	   *args;			/* arguments to the function */
	int			location;		/* token location, or -1 if unknown */
} PGFuncExpr;

/*
 * PGNamedArgExpr - a named argument of a function
 *
 * This node type can only appear in the args list of a PGFuncCall or PGFuncExpr
 * node.  We support pure positional call notation (no named arguments),
 * named notation (all arguments are named), and mixed notation (unnamed
 * arguments followed by named ones).
 *
 * Parse analysis sets argnumber to the positional index of the argument,
 * but doesn't rearrange the argument list.
 *
 * The planner will convert argument lists to pure positional notation
 * during expression preprocessing, so execution never sees a NamedArgExpr.
 */
typedef struct PGNamedArgExpr
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* the argument expression */
	char	   *name;			/* the name */
	int			argnumber;		/* argument's number in positional notation */
	int			location;		/* argument name location, or -1 if unknown */
} PGNamedArgExpr;

/*
 * PGOpExpr - expression node for an operator invocation
 *
 * Semantically, this is essentially the same as a function call.
 *
 * Note that opfuncid is not necessarily filled in immediately on creation
 * of the node.  The planner makes sure it is valid before passing the node
 * tree to the executor, but during parsing/planning opfuncid can be 0.
 */
typedef struct PGOpExpr
{
	PGExpr		xpr;
	PGOid			opno;			/* PG_OPERATOR OID of the operator */
	PGOid			opfuncid;		/* PG_PROC OID of underlying function */
	PGOid			opresulttype;	/* PG_TYPE OID of result value */
	bool		opretset;		/* true if operator returns set */
	PGOid			opcollid;		/* OID of collation of result */
	PGOid			inputcollid;	/* OID of collation that operator should use */
	PGList	   *args;			/* arguments to the operator (1 or 2) */
	int			location;		/* token location, or -1 if unknown */
} PGOpExpr;

/*
 * DistinctExpr - expression node for "x IS DISTINCT FROM y"
 *
 * Except for the nodetag, this is represented identically to an PGOpExpr
 * referencing the "=" operator for x and y.
 * We use "=", not the more obvious "<>", because more datatypes have "="
 * than "<>".  This means the executor must invert the operator result.
 * Note that the operator function won't be called at all if either input
 * is NULL, since then the result can be determined directly.
 */
typedef PGOpExpr DistinctExpr;

/*
 * NullIfExpr - a NULLIF expression
 *
 * Like DistinctExpr, this is represented the same as an PGOpExpr referencing
 * the "=" operator for x and y.
 */
typedef PGOpExpr NullIfExpr;

/*
 * PGScalarArrayOpExpr - expression node for "scalar op ANY/ALL (array)"
 *
 * The operator must yield boolean.  It is applied to the left operand
 * and each element of the righthand array, and the results are combined
 * with OR or AND (for ANY or ALL respectively).  The node representation
 * is almost the same as for the underlying operator, but we need a useOr
 * flag to remember whether it's ANY or ALL, and we don't have to store
 * the result type (or the collation) because it must be boolean.
 */
typedef struct PGScalarArrayOpExpr
{
	PGExpr		xpr;
	PGOid			opno;			/* PG_OPERATOR OID of the operator */
	PGOid			opfuncid;		/* PG_PROC OID of underlying function */
	bool		useOr;			/* true for ANY, false for ALL */
	PGOid			inputcollid;	/* OID of collation that operator should use */
	PGList	   *args;			/* the scalar and array operands */
	int			location;		/* token location, or -1 if unknown */
} PGScalarArrayOpExpr;

/*
 * PGBoolExpr - expression node for the basic Boolean operators AND, OR, NOT
 *
 * Notice the arguments are given as a List.  For NOT, of course the list
 * must always have exactly one element.  For AND and OR, there can be two
 * or more arguments.
 */
typedef enum PGBoolExprType
{
	PG_AND_EXPR,
	PG_OR_EXPR,
	PG_NOT_EXPR
} PGBoolExprType;

typedef struct PGBoolExpr
{
	PGExpr		xpr;
	PGBoolExprType boolop;
	PGList	   *args;			/* arguments to this expression */
	int			location;		/* token location, or -1 if unknown */
} PGBoolExpr;

/*
 * PGSubLink
 *
 * A PGSubLink represents a subselect appearing in an expression, and in some
 * cases also the combining operator(s) just above it.  The subLinkType
 * indicates the form of the expression represented:
 *	PG_EXISTS_SUBLINK		EXISTS(SELECT ...)
 *	PG_ALL_SUBLINK			(lefthand) op ALL (SELECT ...)
 *	PG_ANY_SUBLINK			(lefthand) op ANY (SELECT ...)
 *	PG_ROWCOMPARE_SUBLINK	(lefthand) op (SELECT ...)
 *	PG_EXPR_SUBLINK		(SELECT with single targetlist item ...)
 *	PG_MULTIEXPR_SUBLINK	(SELECT with multiple targetlist items ...)
 *	PG_ARRAY_SUBLINK		ARRAY(SELECT with single targetlist item ...)
 *	PG_CTE_SUBLINK			WITH query (never actually part of an expression)
 * For ALL, ANY, and ROWCOMPARE, the lefthand is a list of expressions of the
 * same length as the subselect's targetlist.  ROWCOMPARE will *always* have
 * a list with more than one entry; if the subselect has just one target
 * then the parser will create an PG_EXPR_SUBLINK instead (and any operator
 * above the subselect will be represented separately).
 * ROWCOMPARE, EXPR, and MULTIEXPR require the subselect to deliver at most
 * one row (if it returns no rows, the result is NULL).
 * ALL, ANY, and ROWCOMPARE require the combining operators to deliver boolean
 * results.  ALL and ANY combine the per-row results using AND and OR
 * semantics respectively.
 * ARRAY requires just one target column, and creates an array of the target
 * column's type using any number of rows resulting from the subselect.
 *
 * PGSubLink is classed as an PGExpr node, but it is not actually executable;
 * it must be replaced in the expression tree by a PGSubPlan node during
 * planning.
 *
 * NOTE: in the raw output of gram.y, testexpr contains just the raw form
 * of the lefthand expression (if any), and operName is the String name of
 * the combining operator.  Also, subselect is a raw parsetree.  During parse
 * analysis, the parser transforms testexpr into a complete boolean expression
 * that compares the lefthand value(s) to PG_PARAM_SUBLINK nodes representing the
 * output columns of the subselect.  And subselect is transformed to a Query.
 * This is the representation seen in saved rules and in the rewriter.
 *
 * In EXISTS, EXPR, MULTIEXPR, and ARRAY SubLinks, testexpr and operName
 * are unused and are always null.
 *
 * subLinkId is currently used only for MULTIEXPR SubLinks, and is zero in
 * other SubLinks.  This number identifies different multiple-assignment
 * subqueries within an UPDATE statement's SET list.  It is unique only
 * within a particular targetlist.  The output column(s) of the MULTIEXPR
 * are referenced by PG_PARAM_MULTIEXPR Params appearing elsewhere in the tlist.
 *
 * The PG_CTE_SUBLINK case never occurs in actual PGSubLink nodes, but it is used
 * in SubPlans generated for WITH subqueries.
 */
typedef enum PGSubLinkType
{
	PG_EXISTS_SUBLINK,
	PG_ALL_SUBLINK,
	PG_ANY_SUBLINK,
	PG_ROWCOMPARE_SUBLINK,
	PG_EXPR_SUBLINK,
	PG_MULTIEXPR_SUBLINK,
	PG_ARRAY_SUBLINK,
	PG_CTE_SUBLINK					/* for SubPlans only */
} PGSubLinkType;


typedef struct PGSubLink
{
	PGExpr		xpr;
	PGSubLinkType subLinkType;	/* see above */
	int			subLinkId;		/* ID (1..n); 0 if not MULTIEXPR */
	PGNode	   *testexpr;		/* outer-query test for ALL/ANY/ROWCOMPARE */
	PGList	   *operName;		/* originally specified operator name */
	PGNode	   *subselect;		/* subselect as PGQuery* or raw parsetree */
	int			location;		/* token location, or -1 if unknown */
} PGSubLink;

/*
 * PGSubPlan - executable expression node for a subplan (sub-SELECT)
 *
 * The planner replaces PGSubLink nodes in expression trees with PGSubPlan
 * nodes after it has finished planning the subquery.  PGSubPlan references
 * a sub-plantree stored in the subplans list of the toplevel PlannedStmt.
 * (We avoid a direct link to make it easier to copy expression trees
 * without causing multiple processing of the subplan.)
 *
 * In an ordinary subplan, testexpr points to an executable expression
 * (PGOpExpr, an AND/OR tree of OpExprs, or PGRowCompareExpr) for the combining
 * operator(s); the left-hand arguments are the original lefthand expressions,
 * and the right-hand arguments are PG_PARAM_EXEC PGParam nodes representing the
 * outputs of the sub-select.  (NOTE: runtime coercion functions may be
 * inserted as well.)  This is just the same expression tree as testexpr in
 * the original PGSubLink node, but the PG_PARAM_SUBLINK nodes are replaced by
 * suitably numbered PG_PARAM_EXEC nodes.
 *
 * If the sub-select becomes an initplan rather than a subplan, the executable
 * expression is part of the outer plan's expression tree (and the PGSubPlan
 * node itself is not, but rather is found in the outer plan's initPlan
 * list).  In this case testexpr is NULL to avoid duplication.
 *
 * The planner also derives lists of the values that need to be passed into
 * and out of the subplan.  Input values are represented as a list "args" of
 * expressions to be evaluated in the outer-query context (currently these
 * args are always just Vars, but in principle they could be any expression).
 * The values are assigned to the global PG_PARAM_EXEC params indexed by parParam
 * (the parParam and args lists must have the same ordering).  setParam is a
 * list of the PG_PARAM_EXEC params that are computed by the sub-select, if it
 * is an initplan; they are listed in order by sub-select output column
 * position.  (parParam and setParam are integer Lists, not Bitmapsets,
 * because their ordering is significant.)
 *
 * Also, the planner computes startup and per-call costs for use of the
 * SubPlan.  Note that these include the cost of the subquery proper,
 * evaluation of the testexpr if any, and any hashtable management overhead.
 */
typedef struct PGSubPlan
{
	PGExpr		xpr;
	/* Fields copied from original PGSubLink: */
	PGSubLinkType subLinkType;	/* see above */
	/* The combining operators, transformed to an executable expression: */
	PGNode	   *testexpr;		/* PGOpExpr or PGRowCompareExpr expression tree */
	PGList	   *paramIds;		/* IDs of Params embedded in the above */
	/* Identification of the PGPlan tree to use: */
	int			plan_id;		/* PGIndex (from 1) in PlannedStmt.subplans */
	/* Identification of the PGSubPlan for EXPLAIN and debugging purposes: */
	char	   *plan_name;		/* A name assigned during planning */
	/* Extra data useful for determining subplan's output type: */
	PGOid			firstColType;	/* Type of first column of subplan result */
	int32_t		firstColTypmod; /* Typmod of first column of subplan result */
	PGOid			firstColCollation;	/* Collation of first column of subplan
									 * result */
	/* Information about execution strategy: */
	bool		useHashTable;	/* true to store subselect output in a hash
								 * table (implies we are doing "IN") */
	bool		unknownEqFalse; /* true if it's okay to return false when the
								 * spec result is UNKNOWN; this allows much
								 * simpler handling of null values */
	bool		parallel_safe;	/* is the subplan parallel-safe? */
	/* Note: parallel_safe does not consider contents of testexpr or args */
	/* Information for passing params into and out of the subselect: */
	/* setParam and parParam are lists of integers (param IDs) */
	PGList	   *setParam;		/* initplan subqueries have to set these
								 * Params for parent plan */
	PGList	   *parParam;		/* indices of input Params from parent plan */
	PGList	   *args;			/* exprs to pass as parParam values */
	/* Estimated execution costs: */
	Cost		startup_cost;	/* one-time setup cost */
	Cost		per_call_cost;	/* cost for each subplan evaluation */
} PGSubPlan;

/*
 * PGAlternativeSubPlan - expression node for a choice among SubPlans
 *
 * The subplans are given as a PGList so that the node definition need not
 * change if there's ever more than two alternatives.  For the moment,
 * though, there are always exactly two; and the first one is the fast-start
 * plan.
 */
typedef struct PGAlternativeSubPlan
{
	PGExpr		xpr;
	PGList	   *subplans;		/* SubPlan(s) with equivalent results */
} PGAlternativeSubPlan;

/* ----------------
 * PGFieldSelect
 *
 * PGFieldSelect represents the operation of extracting one field from a tuple
 * value.  At runtime, the input expression is expected to yield a rowtype
 * Datum.  The specified field number is extracted and returned as a Datum.
 * ----------------
 */

typedef struct PGFieldSelect
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGAttrNumber	fieldnum;		/* attribute number of field to extract */
	PGOid			resulttype;		/* type of the field (result type of this
								 * node) */
	int32_t		resulttypmod;	/* output typmod (usually -1) */
	PGOid			resultcollid;	/* OID of collation of the field */
} PGFieldSelect;

/* ----------------
 * PGFieldStore
 *
 * PGFieldStore represents the operation of modifying one field in a tuple
 * value, yielding a new tuple value (the input is not touched!).  Like
 * the assign case of PGArrayRef, this is used to implement UPDATE of a
 * portion of a column.
 *
 * A single PGFieldStore can actually represent updates of several different
 * fields.  The parser only generates FieldStores with single-element lists,
 * but the planner will collapse multiple updates of the same base column
 * into one FieldStore.
 * ----------------
 */

typedef struct PGFieldStore
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input tuple value */
	PGList	   *newvals;		/* new value(s) for field(s) */
	PGList	   *fieldnums;		/* integer list of field attnums */
	PGOid			resulttype;		/* type of result (same as type of arg) */
	/* Like PGRowExpr, we deliberately omit a typmod and collation here */
} PGFieldStore;

/* ----------------
 * PGRelabelType
 *
 * PGRelabelType represents a "dummy" type coercion between two binary-
 * compatible datatypes, such as reinterpreting the result of an OID
 * expression as an int4.  It is a no-op at runtime; we only need it
 * to provide a place to store the correct type to be attributed to
 * the expression result during type resolution.  (We can't get away
 * with just overwriting the type field of the input expression node,
 * so we need a separate node to show the coercion's result type.)
 * ----------------
 */

typedef struct PGRelabelType
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGOid			resulttype;		/* output type of coercion expression */
	int32_t		resulttypmod;	/* output typmod (usually -1) */
	PGOid			resultcollid;	/* OID of collation, or InvalidOid if none */
	PGCoercionForm relabelformat; /* how to display this node */
	int			location;		/* token location, or -1 if unknown */
} PGRelabelType;

/* ----------------
 * PGCoerceViaIO
 *
 * PGCoerceViaIO represents a type coercion between two types whose textual
 * representations are compatible, implemented by invoking the source type's
 * typoutput function then the destination type's typinput function.
 * ----------------
 */

typedef struct PGCoerceViaIO
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGOid			resulttype;		/* output type of coercion */
	/* output typmod is not stored, but is presumed -1 */
	PGOid			resultcollid;	/* OID of collation, or InvalidOid if none */
	PGCoercionForm coerceformat;	/* how to display this node */
	int			location;		/* token location, or -1 if unknown */
} PGCoerceViaIO;

/* ----------------
 * PGArrayCoerceExpr
 *
 * PGArrayCoerceExpr represents a type coercion from one array type to another,
 * which is implemented by applying the indicated element-type coercion
 * function to each element of the source array.  If elemfuncid is InvalidOid
 * then the element types are binary-compatible, but the coercion still
 * requires some effort (we have to fix the element type ID stored in the
 * array header).
 * ----------------
 */

typedef struct PGArrayCoerceExpr
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression (yields an array) */
	PGOid			elemfuncid;		/* OID of element coercion function, or 0 */
	PGOid			resulttype;		/* output type of coercion (an array type) */
	int32_t		resulttypmod;	/* output typmod (also element typmod) */
	PGOid			resultcollid;	/* OID of collation, or InvalidOid if none */
	bool		isExplicit;		/* conversion semantics flag to pass to func */
	PGCoercionForm coerceformat;	/* how to display this node */
	int			location;		/* token location, or -1 if unknown */
} PGArrayCoerceExpr;

/* ----------------
 * PGConvertRowtypeExpr
 *
 * PGConvertRowtypeExpr represents a type coercion from one composite type
 * to another, where the source type is guaranteed to contain all the columns
 * needed for the destination type plus possibly others; the columns need not
 * be in the same positions, but are matched up by name.  This is primarily
 * used to convert a whole-row value of an inheritance child table into a
 * valid whole-row value of its parent table's rowtype.
 * ----------------
 */

typedef struct PGConvertRowtypeExpr
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGOid			resulttype;		/* output type (always a composite type) */
	/* Like PGRowExpr, we deliberately omit a typmod and collation here */
	PGCoercionForm convertformat; /* how to display this node */
	int			location;		/* token location, or -1 if unknown */
} PGConvertRowtypeExpr;

/*----------
 * PGCollateExpr - COLLATE
 *
 * The planner replaces PGCollateExpr with PGRelabelType during expression
 * preprocessing, so execution never sees a CollateExpr.
 *----------
 */
typedef struct PGCollateExpr
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGOid			collOid;		/* collation's OID */
	int			location;		/* token location, or -1 if unknown */
} PGCollateExpr;

/*----------
 * PGCaseExpr - a CASE expression
 *
 * We support two distinct forms of CASE expression:
 *		CASE WHEN boolexpr THEN expr [ WHEN boolexpr THEN expr ... ]
 *		CASE testexpr WHEN compexpr THEN expr [ WHEN compexpr THEN expr ... ]
 * These are distinguishable by the "arg" field being NULL in the first case
 * and the testexpr in the second case.
 *
 * In the raw grammar output for the second form, the condition expressions
 * of the WHEN clauses are just the comparison values.  Parse analysis
 * converts these to valid boolean expressions of the form
 *		PGCaseTestExpr '=' compexpr
 * where the PGCaseTestExpr node is a placeholder that emits the correct
 * value at runtime.  This structure is used so that the testexpr need be
 * evaluated only once.  Note that after parse analysis, the condition
 * expressions always yield boolean.
 *
 * Note: we can test whether a PGCaseExpr has been through parse analysis
 * yet by checking whether casetype is InvalidOid or not.
 *----------
 */
typedef struct PGCaseExpr
{
	PGExpr		xpr;
	PGOid			casetype;		/* type of expression result */
	PGOid			casecollid;		/* OID of collation, or InvalidOid if none */
	PGExpr	   *arg;			/* implicit equality comparison argument */
	PGList	   *args;			/* the arguments (list of WHEN clauses) */
	PGExpr	   *defresult;		/* the default result (ELSE clause) */
	int			location;		/* token location, or -1 if unknown */
} PGCaseExpr;

/*
 * PGCaseWhen - one arm of a CASE expression
 */
typedef struct PGCaseWhen
{
	PGExpr		xpr;
	PGExpr	   *expr;			/* condition expression */
	PGExpr	   *result;			/* substitution result */
	int			location;		/* token location, or -1 if unknown */
} PGCaseWhen;

/*
 * Placeholder node for the test value to be processed by a CASE expression.
 * This is effectively like a PGParam, but can be implemented more simply
 * since we need only one replacement value at a time.
 *
 * We also use this in nested UPDATE expressions.
 * See transformAssignmentIndirection().
 */
typedef struct PGCaseTestExpr
{
	PGExpr		xpr;
	PGOid			typeId;			/* type for substituted value */
	int32_t		typeMod;		/* typemod for substituted value */
	PGOid			collation;		/* collation for the substituted value */
} PGCaseTestExpr;

/*
 * PGArrayExpr - an ARRAY[] expression
 *
 * Note: if multidims is false, the constituent expressions all yield the
 * scalar type identified by element_typeid.  If multidims is true, the
 * constituent expressions all yield arrays of element_typeid (ie, the same
 * type as array_typeid); at runtime we must check for compatible subscripts.
 */
typedef struct PGArrayExpr
{
	PGExpr		xpr;
	PGOid			array_typeid;	/* type of expression result */
	PGOid			array_collid;	/* OID of collation, or InvalidOid if none */
	PGOid			element_typeid; /* common type of array elements */
	PGList	   *elements;		/* the array elements or sub-arrays */
	bool		multidims;		/* true if elements are sub-arrays */
	int			location;		/* token location, or -1 if unknown */
} PGArrayExpr;

/*
 * PGRowExpr - a ROW() expression
 *
 * Note: the list of fields must have a one-for-one correspondence with
 * physical fields of the associated rowtype, although it is okay for it
 * to be shorter than the rowtype.  That is, the N'th list element must
 * match up with the N'th physical field.  When the N'th physical field
 * is a dropped column (attisdropped) then the N'th list element can just
 * be a NULL constant.  (This case can only occur for named composite types,
 * not RECORD types, since those are built from the PGRowExpr itself rather
 * than vice versa.)  It is important not to assume that length(args) is
 * the same as the number of columns logically present in the rowtype.
 *
 * colnames provides field names in cases where the names can't easily be
 * obtained otherwise.  Names *must* be provided if row_typeid is RECORDOID.
 * If row_typeid identifies a known composite type, colnames can be NIL to
 * indicate the type's cataloged field names apply.  Note that colnames can
 * be non-NIL even for a composite type, and typically is when the PGRowExpr
 * was created by expanding a whole-row Var.  This is so that we can retain
 * the column alias names of the RTE that the PGVar referenced (which would
 * otherwise be very difficult to extract from the parsetree).  Like the
 * args list, colnames is one-for-one with physical fields of the rowtype.
 */
typedef struct PGRowExpr
{
	PGExpr		xpr;
	PGList	   *args;			/* the fields */
	PGOid			row_typeid;		/* RECORDOID or a composite type's ID */

	/*
	 * Note: we deliberately do NOT store a typmod.  Although a typmod will be
	 * associated with specific RECORD types at runtime, it will differ for
	 * different backends, and so cannot safely be stored in stored
	 * parsetrees.  We must assume typmod -1 for a PGRowExpr node.
	 *
	 * We don't need to store a collation either.  The result type is
	 * necessarily composite, and composite types never have a collation.
	 */
	PGCoercionForm row_format;	/* how to display this node */
	PGList	   *colnames;		/* list of String, or NIL */
	int			location;		/* token location, or -1 if unknown */
} PGRowExpr;

/*
 * PGRowCompareExpr - row-wise comparison, such as (a, b) <= (1, 2)
 *
 * We support row comparison for any operator that can be determined to
 * act like =, <>, <, <=, >, or >= (we determine this by looking for the
 * operator in btree opfamilies).  Note that the same operator name might
 * map to a different operator for each pair of row elements, since the
 * element datatypes can vary.
 *
 * A PGRowCompareExpr node is only generated for the < <= > >= cases;
 * the = and <> cases are translated to simple AND or OR combinations
 * of the pairwise comparisons.  However, we include = and <> in the
 * PGRowCompareType enum for the convenience of parser logic.
 */
typedef enum PGRowCompareType
{
	/* Values of this enum are chosen to match btree strategy numbers */
	PG_ROWCOMPARE_LT = 1,			/* BTLessStrategyNumber */
	PG_ROWCOMPARE_LE = 2,			/* BTLessEqualStrategyNumber */
	PG_ROWCOMPARE_EQ = 3,			/* BTEqualStrategyNumber */
	PG_ROWCOMPARE_GE = 4,			/* BTGreaterEqualStrategyNumber */
	PG_ROWCOMPARE_GT = 5,			/* BTGreaterStrategyNumber */
	PG_ROWCOMPARE_NE = 6			/* no such btree strategy */
} PGRowCompareType;

typedef struct PGRowCompareExpr
{
	PGExpr		xpr;
	PGRowCompareType rctype;		/* LT LE GE or GT, never EQ or NE */
	PGList	   *opnos;			/* OID list of pairwise comparison ops */
	PGList	   *opfamilies;		/* OID list of containing operator families */
	PGList	   *inputcollids;	/* OID list of collations for comparisons */
	PGList	   *largs;			/* the left-hand input arguments */
	PGList	   *rargs;			/* the right-hand input arguments */
} PGRowCompareExpr;

/*
 * PGCoalesceExpr - a COALESCE expression
 */
typedef struct PGCoalesceExpr
{
	PGExpr		xpr;
	PGOid			coalescetype;	/* type of expression result */
	PGOid			coalescecollid; /* OID of collation, or InvalidOid if none */
	PGList	   *args;			/* the arguments */
	int			location;		/* token location, or -1 if unknown */
} PGCoalesceExpr;

/*
 * PGMinMaxExpr - a GREATEST or LEAST function
 */
typedef enum PGMinMaxOp
{
	PG_IS_GREATEST,
	IS_LEAST
} PGMinMaxOp;

typedef struct PGMinMaxExpr
{
	PGExpr		xpr;
	PGOid			minmaxtype;		/* common type of arguments and result */
	PGOid			minmaxcollid;	/* OID of collation of result */
	PGOid			inputcollid;	/* OID of collation that function should use */
	PGMinMaxOp	op;				/* function to execute */
	PGList	   *args;			/* the arguments */
	int			location;		/* token location, or -1 if unknown */
} PGMinMaxExpr;

/*
 * PGSQLValueFunction - parameterless functions with special grammar productions
 *
 * The SQL standard categorizes some of these as <datetime value function>
 * and others as <general value specification>.  We call 'em SQLValueFunctions
 * for lack of a better term.  We store type and typmod of the result so that
 * some code doesn't need to know each function individually, and because
 * we would need to store typmod anyway for some of the datetime functions.
 * Note that currently, all variants return non-collating datatypes, so we do
 * not need a collation field; also, all these functions are stable.
 */
typedef enum PGSQLValueFunctionOp
{
	PG_SVFOP_CURRENT_DATE,
	PG_SVFOP_CURRENT_TIME,
	PG_SVFOP_CURRENT_TIME_N,
	PG_SVFOP_CURRENT_TIMESTAMP,
	PG_SVFOP_CURRENT_TIMESTAMP_N,
	PG_SVFOP_LOCALTIME,
	PG_SVFOP_LOCALTIME_N,
	PG_SVFOP_LOCALTIMESTAMP,
	PG_SVFOP_LOCALTIMESTAMP_N,
	PG_SVFOP_CURRENT_ROLE,
	PG_SVFOP_CURRENT_USER,
	PG_SVFOP_USER,
	PG_SVFOP_SESSION_USER,
	PG_SVFOP_CURRENT_CATALOG,
	PG_SVFOP_CURRENT_SCHEMA
} PGSQLValueFunctionOp;

typedef struct PGSQLValueFunction
{
	PGExpr		xpr;
	PGSQLValueFunctionOp op;		/* which function this is */
	PGOid			type;			/* result type/typmod */
	int32_t		typmod;
	int			location;		/* token location, or -1 if unknown */
} PGSQLValueFunction;

/* ----------------
 * PGNullTest
 *
 * PGNullTest represents the operation of testing a value for NULLness.
 * The appropriate test is performed and returned as a boolean Datum.
 *
 * When argisrow is false, this simply represents a test for the null value.
 *
 * When argisrow is true, the input expression must yield a rowtype, and
 * the node implements "row IS [NOT] NULL" per the SQL standard.  This
 * includes checking individual fields for NULLness when the row datum
 * itself isn't NULL.
 *
 * NOTE: the combination of a rowtype input and argisrow==false does NOT
 * correspond to the SQL notation "row IS [NOT] NULL"; instead, this case
 * represents the SQL notation "row IS [NOT] DISTINCT FROM NULL".
 * ----------------
 */

typedef enum PGNullTestType
{
	PG_IS_NULL, IS_NOT_NULL
} PGNullTestType;

typedef struct PGNullTest
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGNullTestType nulltesttype;	/* IS NULL, IS NOT NULL */
	bool		argisrow;		/* T to perform field-by-field null checks */
	int			location;		/* token location, or -1 if unknown */
} PGNullTest;

/*
 * PGBooleanTest
 *
 * PGBooleanTest represents the operation of determining whether a boolean
 * is true, false, or UNKNOWN (ie, NULL).  All six meaningful combinations
 * are supported.  Note that a NULL input does *not* cause a NULL result.
 * The appropriate test is performed and returned as a boolean Datum.
 */

typedef enum PGBoolTestType
{
	PG_IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN
} PGBoolTestType;

typedef struct PGBooleanTest
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGBoolTestType booltesttype;	/* test type */
	int			location;		/* token location, or -1 if unknown */
} PGBooleanTest;

/*
 * PGCoerceToDomain
 *
 * PGCoerceToDomain represents the operation of coercing a value to a domain
 * type.  At runtime (and not before) the precise set of constraints to be
 * checked will be determined.  If the value passes, it is returned as the
 * result; if not, an error is raised.  Note that this is equivalent to
 * PGRelabelType in the scenario where no constraints are applied.
 */
typedef struct PGCoerceToDomain
{
	PGExpr		xpr;
	PGExpr	   *arg;			/* input expression */
	PGOid			resulttype;		/* domain type ID (result type) */
	int32_t		resulttypmod;	/* output typmod (currently always -1) */
	PGOid			resultcollid;	/* OID of collation, or InvalidOid if none */
	PGCoercionForm coercionformat;	/* how to display this node */
	int			location;		/* token location, or -1 if unknown */
} PGCoerceToDomain;

/*
 * Placeholder node for the value to be processed by a domain's check
 * constraint.  This is effectively like a PGParam, but can be implemented more
 * simply since we need only one replacement value at a time.
 *
 * Note: the typeId/typeMod/collation will be set from the domain's base type,
 * not the domain itself.  This is because we shouldn't consider the value
 * to be a member of the domain if we haven't yet checked its constraints.
 */
typedef struct PGCoerceToDomainValue
{
	PGExpr		xpr;
	PGOid			typeId;			/* type for substituted value */
	int32_t		typeMod;		/* typemod for substituted value */
	PGOid			collation;		/* collation for the substituted value */
	int			location;		/* token location, or -1 if unknown */
} PGCoerceToDomainValue;

/*
 * Placeholder node for a DEFAULT marker in an INSERT or UPDATE command.
 *
 * This is not an executable expression: it must be replaced by the actual
 * column default expression during rewriting.  But it is convenient to
 * treat it as an expression node during parsing and rewriting.
 */
typedef struct PGSetToDefault
{
	PGExpr		xpr;
	PGOid			typeId;			/* type for substituted value */
	int32_t		typeMod;		/* typemod for substituted value */
	PGOid			collation;		/* collation for the substituted value */
	int			location;		/* token location, or -1 if unknown */
} PGSetToDefault;

/*
 * PGNode representing [WHERE] CURRENT OF cursor_name
 *
 * CURRENT OF is a bit like a PGVar, in that it carries the rangetable index
 * of the target relation being constrained; this aids placing the expression
 * correctly during planning.  We can assume however that its "levelsup" is
 * always zero, due to the syntactic constraints on where it can appear.
 *
 * The referenced cursor can be represented either as a hardwired string
 * or as a reference to a run-time parameter of type REFCURSOR.  The latter
 * case is for the convenience of plpgsql.
 */
typedef struct PGCurrentOfExpr
{
	PGExpr		xpr;
	PGIndex		cvarno;			/* RT index of target relation */
	char	   *cursor_name;	/* name of referenced cursor, or NULL */
	int			cursor_param;	/* refcursor parameter number, or 0 */
} PGCurrentOfExpr;

/*
 * PGNextValueExpr - get next value from sequence
 *
 * This has the same effect as calling the nextval() function, but it does not
 * check permissions on the sequence.  This is used for identity columns,
 * where the sequence is an implicit dependency without its own permissions.
 */
typedef struct PGNextValueExpr
{
	PGExpr		xpr;
	PGOid			seqid;
	PGOid			typeId;
} PGNextValueExpr;

/*
 * PGInferenceElem - an element of a unique index inference specification
 *
 * This mostly matches the structure of IndexElems, but having a dedicated
 * primnode allows for a clean separation between the use of index parameters
 * by utility commands, and this node.
 */
typedef struct PGInferenceElem
{
	PGExpr		xpr;
	PGNode	   *expr;			/* expression to infer from, or NULL */
	PGOid			infercollid;	/* OID of collation, or InvalidOid */
	PGOid			inferopclass;	/* OID of att opclass, or InvalidOid */
} PGInferenceElem;

/*--------------------
 * PGTargetEntry -
 *	   a target entry (used in query target lists)
 *
 * Strictly speaking, a PGTargetEntry isn't an expression node (since it can't
 * be evaluated by ExecEvalExpr).  But we treat it as one anyway, since in
 * very many places it's convenient to process a whole query targetlist as a
 * single expression tree.
 *
 * In a SELECT's targetlist, resno should always be equal to the item's
 * ordinal position (counting from 1).  However, in an INSERT or UPDATE
 * targetlist, resno represents the attribute number of the destination
 * column for the item; so there may be missing or out-of-order resnos.
 * It is even legal to have duplicated resnos; consider
 *		UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ...
 * The two meanings come together in the executor, because the planner
 * transforms INSERT/UPDATE tlists into a normalized form with exactly
 * one entry for each column of the destination table.  Before that's
 * happened, however, it is risky to assume that resno == position.
 * Generally get_tle_by_resno() should be used rather than list_nth()
 * to fetch tlist entries by resno, and only in SELECT should you assume
 * that resno is a unique identifier.
 *
 * resname is required to represent the correct column name in non-resjunk
 * entries of top-level SELECT targetlists, since it will be used as the
 * column title sent to the frontend.  In most other contexts it is only
 * a debugging aid, and may be wrong or even NULL.  (In particular, it may
 * be wrong in a tlist from a stored rule, if the referenced column has been
 * renamed by ALTER TABLE since the rule was made.  Also, the planner tends
 * to store NULL rather than look up a valid name for tlist entries in
 * non-toplevel plan nodes.)  In resjunk entries, resname should be either
 * a specific system-generated name (such as "ctid") or NULL; anything else
 * risks confusing ExecGetJunkAttribute!
 *
 * ressortgroupref is used in the representation of ORDER BY, GROUP BY, and
 * DISTINCT items.  Targetlist entries with ressortgroupref=0 are not
 * sort/group items.  If ressortgroupref>0, then this item is an ORDER BY,
 * GROUP BY, and/or DISTINCT target value.  No two entries in a targetlist
 * may have the same nonzero ressortgroupref --- but there is no particular
 * meaning to the nonzero values, except as tags.  (For example, one must
 * not assume that lower ressortgroupref means a more significant sort key.)
 * The order of the associated PGSortGroupClause lists determine the semantics.
 *
 * resorigtbl/resorigcol identify the source of the column, if it is a
 * simple reference to a column of a base table (or view).  If it is not
 * a simple reference, these fields are zeroes.
 *
 * If resjunk is true then the column is a working column (such as a sort key)
 * that should be removed from the final output of the query.  Resjunk columns
 * must have resnos that cannot duplicate any regular column's resno.  Also
 * note that there are places that assume resjunk columns come after non-junk
 * columns.
 *--------------------
 */
typedef struct PGTargetEntry
{
	PGExpr		xpr;
	PGExpr	   *expr;			/* expression to evaluate */
	PGAttrNumber	resno;			/* attribute number (see notes above) */
	char	   *resname;		/* name of the column (could be NULL) */
	PGIndex		ressortgroupref;	/* nonzero if referenced by a sort/group
									 * clause */
	PGOid			resorigtbl;		/* OID of column's source table */
	PGAttrNumber	resorigcol;		/* column's number in source table */
	bool		resjunk;		/* set to true to eliminate the attribute from
								 * final target list */
} PGTargetEntry;


/* ----------------------------------------------------------------
 *					node types for join trees
 *
 * The leaves of a join tree structure are PGRangeTblRef nodes.  Above
 * these, PGJoinExpr nodes can appear to denote a specific kind of join
 * or qualified join.  Also, PGFromExpr nodes can appear to denote an
 * ordinary cross-product join ("FROM foo, bar, baz WHERE ...").
 * PGFromExpr is like a PGJoinExpr of jointype PG_JOIN_INNER, except that it
 * may have any number of child nodes, not just two.
 *
 * NOTE: the top level of a Query's jointree is always a FromExpr.
 * Even if the jointree contains no rels, there will be a FromExpr.
 *
 * NOTE: the qualification expressions present in PGJoinExpr nodes are
 * *in addition to* the query's main WHERE clause, which appears as the
 * qual of the top-level FromExpr.  The reason for associating quals with
 * specific nodes in the jointree is that the position of a qual is critical
 * when outer joins are present.  (If we enforce a qual too soon or too late,
 * that may cause the outer join to produce the wrong set of NULL-extended
 * rows.)  If all joins are inner joins then all the qual positions are
 * semantically interchangeable.
 *
 * NOTE: in the raw output of gram.y, a join tree contains PGRangeVar,
 * PGRangeSubselect, and PGRangeFunction nodes, which are all replaced by
 * PGRangeTblRef nodes during the parse analysis phase.  Also, the top-level
 * PGFromExpr is added during parse analysis; the grammar regards FROM and
 * WHERE as separate.
 * ----------------------------------------------------------------
 */

/*
 * PGRangeTblRef - reference to an entry in the query's rangetable
 *
 * We could use direct pointers to the RT entries and skip having these
 * nodes, but multiple pointers to the same node in a querytree cause
 * lots of headaches, so it seems better to store an index into the RT.
 */
typedef struct PGRangeTblRef
{
	PGNodeTag		type;
	int			rtindex;
} PGRangeTblRef;

/*----------
 * PGJoinExpr - for SQL JOIN expressions
 *
 * isNatural, usingClause, and quals are interdependent.  The user can write
 * only one of NATURAL, USING(), or ON() (this is enforced by the grammar).
 * If he writes NATURAL then parse analysis generates the equivalent USING()
 * list, and from that fills in "quals" with the right equality comparisons.
 * If he writes USING() then "quals" is filled with equality comparisons.
 * If he writes ON() then only "quals" is set.  Note that NATURAL/USING
 * are not equivalent to ON() since they also affect the output column list.
 *
 * alias is an PGAlias node representing the AS alias-clause attached to the
 * join expression, or NULL if no clause.  NB: presence or absence of the
 * alias has a critical impact on semantics, because a join with an alias
 * restricts visibility of the tables/columns inside it.
 *
 * During parse analysis, an RTE is created for the PGJoin, and its index
 * is filled into rtindex.  This RTE is present mainly so that Vars can
 * be created that refer to the outputs of the join.  The planner sometimes
 * generates JoinExprs internally; these can have rtindex = 0 if there are
 * no join alias variables referencing such joins.
 *----------
 */
typedef struct PGJoinExpr
{
	PGNodeTag		type;
	PGJoinType	jointype;		/* type of join */
	bool		isNatural;		/* Natural join? Will need to shape table */
	PGNode	   *larg;			/* left subtree */
	PGNode	   *rarg;			/* right subtree */
	PGList	   *usingClause;	/* USING clause, if any (list of String) */
	PGNode	   *quals;			/* qualifiers on join, if any */
	PGAlias	   *alias;			/* user-written alias clause, if any */
	int			rtindex;		/* RT index assigned for join, or 0 */
} PGJoinExpr;

/*----------
 * PGFromExpr - represents a FROM ... WHERE ... construct
 *
 * This is both more flexible than a PGJoinExpr (it can have any number of
 * children, including zero) and less so --- we don't need to deal with
 * aliases and so on.  The output column set is implicitly just the union
 * of the outputs of the children.
 *----------
 */
typedef struct PGFromExpr
{
	PGNodeTag		type;
	PGList	   *fromlist;		/* PGList of join subtrees */
	PGNode	   *quals;			/* qualifiers on join, if any */
} PGFromExpr;

/*----------
 * PGOnConflictExpr - represents an ON CONFLICT DO ... expression
 *
 * The optimizer requires a list of inference elements, and optionally a WHERE
 * clause to infer a unique index.  The unique index (or, occasionally,
 * indexes) inferred are used to arbitrate whether or not the alternative ON
 * CONFLICT path is taken.
 *----------
 */
typedef struct PGOnConflictExpr
{
	PGNodeTag		type;
	PGOnConflictAction action;	/* DO NOTHING or UPDATE? */

	/* Arbiter */
	PGList	   *arbiterElems;	/* unique index arbiter list (of
								 * InferenceElem's) */
	PGNode	   *arbiterWhere;	/* unique index arbiter WHERE clause */
	PGOid			constraint;		/* pg_constraint OID for arbiter */

	/* ON CONFLICT UPDATE */
	PGList	   *onConflictSet;	/* PGList of ON CONFLICT SET TargetEntrys */
	PGNode	   *onConflictWhere;	/* qualifiers to restrict UPDATE to */
	int			exclRelIndex;	/* RT index of 'excluded' relation */
	PGList	   *exclRelTlist;	/* tlist of the EXCLUDED pseudo relation */
} PGOnConflictExpr;


/*-------------------------------------------------------------------------
 *
 * value.h
 *	  interface for PGValue nodes
 *
 *
 * Copyright (c) 2003-2017, PostgreSQL Global Development PGGroup
 *
 * src/include/nodes/value.h
 *
 *-------------------------------------------------------------------------
 */





/*----------------------
 *		PGValue node
 *
 * The same PGValue struct is used for five node types: T_PGInteger,
 * T_PGFloat, T_PGString, T_PGBitString, T_Null.
 *
 * Integral values are actually represented by a machine integer,
 * but both floats and strings are represented as strings.
 * Using T_PGFloat as the node type simply indicates that
 * the contents of the string look like a valid numeric literal.
 *
 * (Before Postgres 7.0, we used a double to represent T_PGFloat,
 * but that creates loss-of-precision problems when the value is
 * ultimately destined to be converted to NUMERIC.  Since PGValue nodes
 * are only used in the parsing process, not for runtime data, it's
 * better to use the more general representation.)
 *
 * Note that an integer-looking string will get lexed as T_PGFloat if
 * the value is too large to fit in a 'long'.
 *
 * Nulls, of course, don't need the value part at all.
 *----------------------
 */
typedef struct PGValue
{
	PGNodeTag		type;			/* tag appropriately (eg. T_PGString) */
	union ValUnion
	{
		long		ival;		/* machine integer */
		char	   *str;		/* string */
	}			val;
} PGValue;

#define intVal(v)		(((PGValue *)(v))->val.ival)
#define floatVal(v)		atof(((PGValue *)(v))->val.str)
#define strVal(v)		(((PGValue *)(v))->val.str)

extern PGValue *makeInteger(long i);
extern PGValue *makeFloat(char *numericStr);
extern PGValue *makeString(const char *str);
extern PGValue *makeBitString(char *str);


typedef enum PGOverridingKind
{
	PG_OVERRIDING_NOT_SET = 0,
	PG_OVERRIDING_USER_VALUE,
	OVERRIDING_SYSTEM_VALUE
} PGOverridingKind;

/* Possible sources of a PGQuery */
typedef enum PGQuerySource
{
	PG_QSRC_ORIGINAL,				/* original parsetree (explicit query) */
	PG_QSRC_PARSER,				/* added by parse analysis (now unused) */
	PG_QSRC_INSTEAD_RULE,			/* added by unconditional INSTEAD rule */
	PG_QSRC_QUAL_INSTEAD_RULE,		/* added by conditional INSTEAD rule */
	QSRC_NON_INSTEAD_RULE		/* added by non-INSTEAD rule */
} PGQuerySource;

/* PGSort ordering options for ORDER BY and CREATE INDEX */
typedef enum PGSortByDir
{
	PG_SORTBY_DEFAULT,
	PG_SORTBY_ASC,
	PG_SORTBY_DESC,
	SORTBY_USING				/* not allowed in CREATE INDEX ... */
} PGSortByDir;

typedef enum PGSortByNulls
{
	PG_SORTBY_NULLS_DEFAULT,
	PG_SORTBY_NULLS_FIRST,
	SORTBY_NULLS_LAST
} PGSortByNulls;

/*****************************************************************************
 *	PGQuery Tree
 *****************************************************************************/

/*
 * PGQuery -
 *	  Parse analysis turns all statements into a PGQuery tree
 *	  for further processing by the rewriter and planner.
 *
 *	  Utility statements (i.e. non-optimizable statements) have the
 *	  utilityStmt field set, and the rest of the PGQuery is mostly dummy.
 *
 *	  Planning converts a PGQuery tree into a PGPlan tree headed by a PGPlannedStmt
 *	  node --- the PGQuery structure is not used by the executor.
 */
typedef struct PGQuery
{
	PGNodeTag		type;

	PGCmdType		commandType;	/* select|insert|update|delete|utility */

	PGQuerySource querySource;	/* where did I come from? */

	uint32_t		queryId;		/* query identifier (can be set by plugins) */

	bool		canSetTag;		/* do I set the command result tag? */

	PGNode	   *utilityStmt;	/* non-null if commandType == PG_CMD_UTILITY */

	int			resultRelation; /* rtable index of target relation for
								 * INSERT/UPDATE/DELETE; 0 for SELECT */

	bool		hasAggs;		/* has aggregates in tlist or havingQual */
	bool		hasWindowFuncs; /* has window functions in tlist */
	bool		hasTargetSRFs;	/* has set-returning functions in tlist */
	bool		hasSubLinks;	/* has subquery PGSubLink */
	bool		hasDistinctOn;	/* distinctClause is from DISTINCT ON */
	bool		hasRecursive;	/* WITH RECURSIVE was specified */
	bool		hasModifyingCTE;	/* has INSERT/UPDATE/DELETE in WITH */
	bool		hasForUpdate;	/* FOR [KEY] UPDATE/SHARE was specified */
	bool		hasRowSecurity; /* rewriter has applied some RLS policy */

	PGList	   *cteList;		/* WITH list (of CommonTableExpr's) */

	PGList	   *rtable;			/* list of range table entries */
	PGFromExpr   *jointree;		/* table join tree (FROM and WHERE clauses) */

	PGList	   *targetList;		/* target list (of PGTargetEntry) */

	PGOverridingKind override;	/* OVERRIDING clause */

	PGOnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */

	PGList	   *returningList;	/* return-values list (of PGTargetEntry) */

	PGList	   *groupClause;	/* a list of SortGroupClause's */

	PGList	   *groupingSets;	/* a list of GroupingSet's if present */

	PGNode	   *havingQual;		/* qualifications applied to groups */

	PGList	   *windowClause;	/* a list of WindowClause's */

	PGList	   *distinctClause; /* a list of SortGroupClause's */

	PGList	   *sortClause;		/* a list of SortGroupClause's */

	PGNode	   *limitOffset;	/* # of result tuples to skip (int8_t expr) */
	PGNode	   *limitCount;		/* # of result tuples to return (int8_t expr) */

	PGList	   *rowMarks;		/* a list of RowMarkClause's */

	PGNode	   *setOperations;	/* set-operation tree if this is top level of
								 * a UNION/INTERSECT/EXCEPT query */

	PGList	   *constraintDeps; /* a list of pg_constraint OIDs that the query
								 * depends on to be semantically valid */

	PGList	   *withCheckOptions;	/* a list of WithCheckOption's, which are
									 * only added during rewrite and therefore
									 * are not written out as part of Query. */

	/*
	 * The following two fields identify the portion of the source text string
	 * containing this query.  They are typically only populated in top-level
	 * Queries, not in sub-queries.  When not set, they might both be zero, or
	 * both be -1 meaning "unknown".
	 */
	int			stmt_location;	/* start location, or -1 if unknown */
	int			stmt_len;		/* length in bytes; 0 means "rest of string" */
} PGQuery;


/****************************************************************************
 *	Supporting data structures for Parse Trees
 *
 *	Most of these node types appear in raw parsetrees output by the grammar,
 *	and get transformed to something else by the analyzer.  A few of them
 *	are used as-is in transformed querytrees.
 ****************************************************************************/

/*
 * PGTypeName - specifies a type in definitions
 *
 * For PGTypeName structures generated internally, it is often easier to
 * specify the type by OID than by name.  If "names" is NIL then the
 * actual type OID is given by typeOid, otherwise typeOid is unused.
 * Similarly, if "typmods" is NIL then the actual typmod is expected to
 * be prespecified in typemod, otherwise typemod is unused.
 *
 * If pct_type is true, then names is actually a field name and we look up
 * the type of that field.  Otherwise (the normal case), names is a type
 * name possibly qualified with schema and database name.
 */
typedef struct PGTypeName
{
	PGNodeTag		type;
	PGList	   *names;			/* qualified name (list of PGValue strings) */
	PGOid			typeOid;		/* type identified by OID */
	bool		setof;			/* is a set? */
	bool		pct_type;		/* %TYPE specified? */
	PGList	   *typmods;		/* type modifier expression(s) */
	int32_t		typemod;		/* prespecified type modifier */
	PGList	   *arrayBounds;	/* array bounds */
	int			location;		/* token location, or -1 if unknown */
} PGTypeName;

/*
 * PGColumnRef - specifies a reference to a column, or possibly a whole tuple
 *
 * The "fields" list must be nonempty.  It can contain string PGValue nodes
 * (representing names) and PGAStar nodes (representing occurrence of a '*').
 * Currently, PGAStar must appear only as the last list element --- the grammar
 * is responsible for enforcing this!
 *
 * Note: any array subscripting or selection of fields from composite columns
 * is represented by an PGAIndirection node above the ColumnRef.  However,
 * for simplicity in the normal case, initial field selection from a table
 * name is represented within PGColumnRef and not by adding AIndirection.
 */
typedef struct PGColumnRef
{
	PGNodeTag		type;
	PGList	   *fields;			/* field names (PGValue strings) or PGAStar */
	int			location;		/* token location, or -1 if unknown */
} PGColumnRef;

/*
 * PGParamRef - specifies a $n parameter reference
 */
typedef struct PGParamRef
{
	PGNodeTag		type;
	int			number;			/* the number of the parameter */
	int			location;		/* token location, or -1 if unknown */
} PGParamRef;

/*
 * PGAExpr - infix, prefix, and postfix expressions
 */
typedef enum PGAExpr_Kind
{
	PG_AEXPR_OP,					/* normal operator */
	PG_AEXPR_OP_ANY,				/* scalar op ANY (array) */
	PG_AEXPR_OP_ALL,				/* scalar op ALL (array) */
	PG_AEXPR_DISTINCT,				/* IS DISTINCT FROM - name must be "=" */
	PG_AEXPR_NOT_DISTINCT,			/* IS NOT DISTINCT FROM - name must be "=" */
	PG_AEXPR_NULLIF,				/* NULLIF - name must be "=" */
	PG_AEXPR_OF,					/* IS [NOT] OF - name must be "=" or "<>" */
	PG_AEXPR_IN,					/* [NOT] IN - name must be "=" or "<>" */
	PG_AEXPR_LIKE,					/* [NOT] LIKE - name must be "~~" or "!~~" */
	PG_AEXPR_ILIKE,				/* [NOT] ILIKE - name must be "~~*" or "!~~*" */
	PG_AEXPR_SIMILAR,				/* [NOT] SIMILAR - name must be "~" or "!~" */
	PG_AEXPR_BETWEEN,				/* name must be "BETWEEN" */
	PG_AEXPR_NOT_BETWEEN,			/* name must be "NOT BETWEEN" */
	PG_AEXPR_BETWEEN_SYM,			/* name must be "BETWEEN SYMMETRIC" */
	PG_AEXPR_NOT_BETWEEN_SYM,		/* name must be "NOT BETWEEN SYMMETRIC" */
	AEXPR_PAREN					/* nameless dummy node for parentheses */
} PGAExpr_Kind;

typedef struct PGAExpr
{
	PGNodeTag		type;
	PGAExpr_Kind kind;			/* see above */
	PGList	   *name;			/* possibly-qualified name of operator */
	PGNode	   *lexpr;			/* left argument, or NULL if none */
	PGNode	   *rexpr;			/* right argument, or NULL if none */
	int			location;		/* token location, or -1 if unknown */
} PGAExpr;

/*
 * PGAConst - a literal constant
 */
typedef struct PGAConst
{
	PGNodeTag		type;
	PGValue		val;			/* value (includes type info, see value.h) */
	int			location;		/* token location, or -1 if unknown */
} PGAConst;

/*
 * PGTypeCast - a CAST expression
 */
typedef struct PGTypeCast
{
	PGNodeTag		type;
	PGNode	   *arg;			/* the expression being casted */
	PGTypeName   *typeName;		/* the target type */
	int			location;		/* token location, or -1 if unknown */
} PGTypeCast;

/*
 * PGCollateClause - a COLLATE expression
 */
typedef struct PGCollateClause
{
	PGNodeTag		type;
	PGNode	   *arg;			/* input expression */
	PGList	   *collname;		/* possibly-qualified collation name */
	int			location;		/* token location, or -1 if unknown */
} PGCollateClause;

/*
 * PGFuncCall - a function or aggregate invocation
 *
 * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)', or if
 * agg_within_group is true, it was 'foo(...) WITHIN GROUP (ORDER BY ...)'.
 * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct
 * indicates we saw 'foo(DISTINCT ...)'.  In any of these cases, the
 * construct *must* be an aggregate call.  Otherwise, it might be either an
 * aggregate or some other kind of function.  However, if FILTER or OVER is
 * present it had better be an aggregate or window function.
 *
 * Normally, you'd initialize this via makeFuncCall() and then only change the
 * parts of the struct its defaults don't match afterwards, as needed.
 */
typedef struct PGFuncCall
{
	PGNodeTag		type;
	PGList	   *funcname;		/* qualified name of function */
	PGList	   *args;			/* the arguments (list of exprs) */
	PGList	   *agg_order;		/* ORDER BY (list of PGSortBy) */
	PGNode	   *agg_filter;		/* FILTER clause, if any */
	bool		agg_within_group;	/* ORDER BY appeared in WITHIN GROUP */
	bool		agg_star;		/* argument was really '*' */
	bool		agg_distinct;	/* arguments were labeled DISTINCT */
	bool		func_variadic;	/* last argument was labeled VARIADIC */
	struct PGWindowDef *over;		/* OVER clause, if any */
	int			location;		/* token location, or -1 if unknown */
} PGFuncCall;

/*
 * PGAStar - '*' representing all columns of a table or compound field
 *
 * This can appear within ColumnRef.fields, AIndirection.indirection, and
 * ResTarget.indirection lists.
 */
typedef struct PGAStar
{
	PGNodeTag		type;
} PGAStar;

/*
 * PGAIndices - array subscript or slice bounds ([idx] or [lidx:uidx])
 *
 * In slice case, either or both of lidx and uidx can be NULL (omitted).
 * In non-slice case, uidx holds the single subscript and lidx is always NULL.
 */
typedef struct PGAIndices
{
	PGNodeTag		type;
	bool		is_slice;		/* true if slice (i.e., colon present) */
	PGNode	   *lidx;			/* slice lower bound, if any */
	PGNode	   *uidx;			/* subscript, or slice upper bound if any */
} PGAIndices;

/*
 * PGAIndirection - select a field and/or array element from an expression
 *
 * The indirection list can contain PGAIndices nodes (representing
 * subscripting), string PGValue nodes (representing field selection --- the
 * string value is the name of the field to select), and PGAStar nodes
 * (representing selection of all fields of a composite type).
 * For example, a complex selection operation like
 *				(foo).field1[42][7].field2
 * would be represented with a single PGAIndirection node having a 4-element
 * indirection list.
 *
 * Currently, PGAStar must appear only as the last list element --- the grammar
 * is responsible for enforcing this!
 */
typedef struct PGAIndirection
{
	PGNodeTag		type;
	PGNode	   *arg;			/* the thing being selected from */
	PGList	   *indirection;	/* subscripts and/or field names and/or * */
} PGAIndirection;

/*
 * PGAArrayExpr - an ARRAY[] construct
 */
typedef struct PGAArrayExpr
{
	PGNodeTag		type;
	PGList	   *elements;		/* array element expressions */
	int			location;		/* token location, or -1 if unknown */
} PGAArrayExpr;

/*
 * PGResTarget -
 *	  result target (used in target list of pre-transformed parse trees)
 *
 * In a SELECT target list, 'name' is the column label from an
 * 'AS ColumnLabel' clause, or NULL if there was none, and 'val' is the
 * value expression itself.  The 'indirection' field is not used.
 *
 * INSERT uses PGResTarget in its target-column-names list.  Here, 'name' is
 * the name of the destination column, 'indirection' stores any subscripts
 * attached to the destination, and 'val' is not used.
 *
 * In an UPDATE target list, 'name' is the name of the destination column,
 * 'indirection' stores any subscripts attached to the destination, and
 * 'val' is the expression to assign.
 *
 * See PGAIndirection for more info about what can appear in 'indirection'.
 */
typedef struct PGResTarget
{
	PGNodeTag		type;
	char	   *name;			/* column name or NULL */
	PGList	   *indirection;	/* subscripts, field names, and '*', or NIL */
	PGNode	   *val;			/* the value expression to compute or assign */
	int			location;		/* token location, or -1 if unknown */
} PGResTarget;

/*
 * PGMultiAssignRef - element of a row source expression for UPDATE
 *
 * In an UPDATE target list, when we have SET (a,b,c) = row-valued-expression,
 * we generate separate PGResTarget items for each of a,b,c.  Their "val" trees
 * are PGMultiAssignRef nodes numbered 1..n, linking to a common copy of the
 * row-valued-expression (which parse analysis will process only once, when
 * handling the PGMultiAssignRef with colno=1).
 */
typedef struct PGMultiAssignRef
{
	PGNodeTag		type;
	PGNode	   *source;			/* the row-valued expression */
	int			colno;			/* column number for this target (1..n) */
	int			ncolumns;		/* number of targets in the construct */
} PGMultiAssignRef;

/*
 * PGSortBy - for ORDER BY clause
 */
typedef struct PGSortBy
{
	PGNodeTag		type;
	PGNode	   *node;			/* expression to sort on */
	PGSortByDir	sortby_dir;		/* ASC/DESC/USING/default */
	PGSortByNulls sortby_nulls;	/* NULLS FIRST/LAST */
	PGList	   *useOp;			/* name of op to use, if SORTBY_USING */
	int			location;		/* operator location, or -1 if none/unknown */
} PGSortBy;

/*
 * PGWindowDef - raw representation of WINDOW and OVER clauses
 *
 * For entries in a WINDOW list, "name" is the window name being defined.
 * For OVER clauses, we use "name" for the "OVER window" syntax, or "refname"
 * for the "OVER (window)" syntax, which is subtly different --- the latter
 * implies overriding the window frame clause.
 */
typedef struct PGWindowDef
{
	PGNodeTag		type;
	char	   *name;			/* window's own name */
	char	   *refname;		/* referenced window name, if any */
	PGList	   *partitionClause;	/* PARTITION BY expression list */
	PGList	   *orderClause;	/* ORDER BY (list of PGSortBy) */
	int			frameOptions;	/* frame_clause options, see below */
	PGNode	   *startOffset;	/* expression for starting bound, if any */
	PGNode	   *endOffset;		/* expression for ending bound, if any */
	int			location;		/* parse location, or -1 if none/unknown */
} PGWindowDef;

/*
 * frameOptions is an OR of these bits.  The NONDEFAULT and BETWEEN bits are
 * used so that ruleutils.c can tell which properties were specified and
 * which were defaulted; the correct behavioral bits must be set either way.
 * The START_foo and END_foo options must come in pairs of adjacent bits for
 * the convenience of gram.y, even though some of them are useless/invalid.
 * We will need more bits (and fields) to cover the full SQL:2008 option set.
 */
#define FRAMEOPTION_NONDEFAULT					0x00001 /* any specified? */
#define FRAMEOPTION_RANGE						0x00002 /* RANGE behavior */
#define FRAMEOPTION_ROWS						0x00004 /* ROWS behavior */
#define FRAMEOPTION_BETWEEN						0x00008 /* BETWEEN given? */
#define FRAMEOPTION_START_UNBOUNDED_PRECEDING	0x00010 /* start is U. P. */
#define FRAMEOPTION_END_UNBOUNDED_PRECEDING		0x00020 /* (disallowed) */
#define FRAMEOPTION_START_UNBOUNDED_FOLLOWING	0x00040 /* (disallowed) */
#define FRAMEOPTION_END_UNBOUNDED_FOLLOWING		0x00080 /* end is U. F. */
#define FRAMEOPTION_START_CURRENT_ROW			0x00100 /* start is C. R. */
#define FRAMEOPTION_END_CURRENT_ROW				0x00200 /* end is C. R. */
#define FRAMEOPTION_START_VALUE_PRECEDING		0x00400 /* start is V. P. */
#define FRAMEOPTION_END_VALUE_PRECEDING			0x00800 /* end is V. P. */
#define FRAMEOPTION_START_VALUE_FOLLOWING		0x01000 /* start is V. F. */
#define FRAMEOPTION_END_VALUE_FOLLOWING			0x02000 /* end is V. F. */

#define FRAMEOPTION_START_VALUE \
	(FRAMEOPTION_START_VALUE_PRECEDING | FRAMEOPTION_START_VALUE_FOLLOWING)
#define FRAMEOPTION_END_VALUE \
	(FRAMEOPTION_END_VALUE_PRECEDING | FRAMEOPTION_END_VALUE_FOLLOWING)

#define FRAMEOPTION_DEFAULTS \
	(FRAMEOPTION_RANGE | FRAMEOPTION_START_UNBOUNDED_PRECEDING | \
	 FRAMEOPTION_END_CURRENT_ROW)

/*
 * PGRangeSubselect - subquery appearing in a FROM clause
 */
typedef struct PGRangeSubselect
{
	PGNodeTag		type;
	bool		lateral;		/* does it have LATERAL prefix? */
	PGNode	   *subquery;		/* the untransformed sub-select clause */
	PGAlias	   *alias;			/* table alias & optional column aliases */
} PGRangeSubselect;

/*
 * PGRangeFunction - function call appearing in a FROM clause
 *
 * functions is a PGList because we use this to represent the construct
 * ROWS FROM(func1(...), func2(...), ...).  Each element of this list is a
 * two-element sublist, the first element being the untransformed function
 * call tree, and the second element being a possibly-empty list of PGColumnDef
 * nodes representing any columndef list attached to that function within the
 * ROWS FROM() syntax.
 *
 * alias and coldeflist represent any alias and/or columndef list attached
 * at the top level.  (We disallow coldeflist appearing both here and
 * per-function, but that's checked in parse analysis, not by the grammar.)
 */
typedef struct PGRangeFunction
{
	PGNodeTag		type;
	bool		lateral;		/* does it have LATERAL prefix? */
	bool		ordinality;		/* does it have WITH ORDINALITY suffix? */
	bool		is_rowsfrom;	/* is result of ROWS FROM() syntax? */
	PGList	   *functions;		/* per-function information, see above */
	PGAlias	   *alias;			/* table alias & optional column aliases */
	PGList	   *coldeflist;		/* list of PGColumnDef nodes to describe result
								 * of function returning RECORD */
} PGRangeFunction;

/*
 * PGRangeTableSample - TABLESAMPLE appearing in a raw FROM clause
 *
 * This node, appearing only in raw parse trees, represents
 *		<relation> TABLESAMPLE <method> (<params>) REPEATABLE (<num>)
 * Currently, the <relation> can only be a PGRangeVar, but we might in future
 * allow PGRangeSubselect and other options.  Note that the PGRangeTableSample
 * is wrapped around the node representing the <relation>, rather than being
 * a subfield of it.
 */
typedef struct PGRangeTableSample
{
	PGNodeTag		type;
	PGNode	   *relation;		/* relation to be sampled */
	PGList	   *method;			/* sampling method name (possibly qualified) */
	PGList	   *args;			/* argument(s) for sampling method */
	PGNode	   *repeatable;		/* REPEATABLE expression, or NULL if none */
	int			location;		/* method name location, or -1 if unknown */
} PGRangeTableSample;

/*
 * PGColumnDef - column definition (used in various creates)
 *
 * If the column has a default value, we may have the value expression
 * in either "raw" form (an untransformed parse tree) or "cooked" form
 * (a post-parse-analysis, executable expression tree), depending on
 * how this PGColumnDef node was created (by parsing, or by inheritance
 * from an existing relation).  We should never have both in the same node!
 *
 * Similarly, we may have a COLLATE specification in either raw form
 * (represented as a PGCollateClause with arg==NULL) or cooked form
 * (the collation's OID).
 *
 * The constraints list may contain a PG_CONSTR_DEFAULT item in a raw
 * parsetree produced by gram.y, but transformCreateStmt will remove
 * the item and set raw_default instead.  PG_CONSTR_DEFAULT items
 * should not appear in any subsequent processing.
 */
typedef struct PGColumnDef
{
	PGNodeTag		type;
	char	   *colname;		/* name of column */
	PGTypeName   *typeName;		/* type of column */
	int			inhcount;		/* number of times column is inherited */
	bool		is_local;		/* column has local (non-inherited) def'n */
	bool		is_not_null;	/* NOT NULL constraint specified? */
	bool		is_from_type;	/* column definition came from table type */
	bool		is_from_parent; /* column def came from partition parent */
	char		storage;		/* attstorage setting, or 0 for default */
	PGNode	   *raw_default;	/* default value (untransformed parse tree) */
	PGNode	   *cooked_default; /* default value (transformed expr tree) */
	char		identity;		/* attidentity setting */
	PGRangeVar   *identitySequence; /* to store identity sequence name for ALTER
								   * TABLE ... ADD COLUMN */
	PGCollateClause *collClause;	/* untransformed COLLATE spec, if any */
	PGOid			collOid;		/* collation OID (InvalidOid if not set) */
	PGList	   *constraints;	/* other constraints on column */
	PGList	   *fdwoptions;		/* per-column FDW options */
	int			location;		/* parse location, or -1 if none/unknown */
} PGColumnDef;

/*
 * PGTableLikeClause - CREATE TABLE ( ... LIKE ... ) clause
 */
typedef struct PGTableLikeClause
{
	PGNodeTag		type;
	PGRangeVar   *relation;
	uint32_t		options;		/* OR of PGTableLikeOption flags */
} PGTableLikeClause;

typedef enum PGTableLikeOption
{
	PG_CREATE_TABLE_LIKE_DEFAULTS = 1 << 0,
	PG_CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 1,
	PG_CREATE_TABLE_LIKE_IDENTITY = 1 << 2,
	PG_CREATE_TABLE_LIKE_INDEXES = 1 << 3,
	PG_CREATE_TABLE_LIKE_STORAGE = 1 << 4,
	PG_CREATE_TABLE_LIKE_COMMENTS = 1 << 5,
	PG_CREATE_TABLE_LIKE_STATISTICS = 1 << 6,
	PG_CREATE_TABLE_LIKE_ALL = INT_MAX
} PGTableLikeOption;

/*
 * PGIndexElem - index parameters (used in CREATE INDEX, and in ON CONFLICT)
 *
 * For a plain index attribute, 'name' is the name of the table column to
 * index, and 'expr' is NULL.  For an index expression, 'name' is NULL and
 * 'expr' is the expression tree.
 */
typedef struct PGIndexElem
{
	PGNodeTag		type;
	char	   *name;			/* name of attribute to index, or NULL */
	PGNode	   *expr;			/* expression to index, or NULL */
	char	   *indexcolname;	/* name for index column; NULL = default */
	PGList	   *collation;		/* name of collation; NIL = default */
	PGList	   *opclass;		/* name of desired opclass; NIL = default */
	PGSortByDir	ordering;		/* ASC/DESC/default */
	PGSortByNulls nulls_ordering; /* FIRST/LAST/default */
} PGIndexElem;

/*
 * PGDefElem - a generic "name = value" option definition
 *
 * In some contexts the name can be qualified.  Also, certain SQL commands
 * allow a SET/ADD/DROP action to be attached to option settings, so it's
 * convenient to carry a field for that too.  (Note: currently, it is our
 * practice that the grammar allows namespace and action only in statements
 * where they are relevant; C code can just ignore those fields in other
 * statements.)
 */
typedef enum PGDefElemAction
{
	PG_DEFELEM_UNSPEC,				/* no action given */
	PG_DEFELEM_SET,
	PG_DEFELEM_ADD,
	DEFELEM_DROP
} PGDefElemAction;

typedef struct PGDefElem
{
	PGNodeTag		type;
	char	   *defnamespace;	/* NULL if unqualified name */
	char	   *defname;
	PGNode	   *arg;			/* a (PGValue *) or a (PGTypeName *) */
	PGDefElemAction defaction;	/* unspecified action, or SET/ADD/DROP */
	int			location;		/* token location, or -1 if unknown */
} PGDefElem;

/*
 * PGLockingClause - raw representation of FOR [NO KEY] UPDATE/[KEY] SHARE
 *		options
 *
 * Note: lockedRels == NIL means "all relations in query".  Otherwise it
 * is a list of PGRangeVar nodes.  (We use PGRangeVar mainly because it carries
 * a location field --- currently, parse analysis insists on unqualified
 * names in LockingClause.)
 */
typedef struct PGLockingClause
{
	PGNodeTag		type;
	PGList	   *lockedRels;		/* FOR [KEY] UPDATE/SHARE relations */
	PGLockClauseStrength strength;
	PGLockWaitPolicy waitPolicy;	/* NOWAIT and SKIP LOCKED */
} PGLockingClause;

/****************************************************************************
 *	Nodes for a PGQuery tree
 ****************************************************************************/

/*--------------------
 * PGRangeTblEntry -
 *	  A range table is a PGList of PGRangeTblEntry nodes.
 *
 *	  A range table entry may represent a plain relation, a sub-select in
 *	  FROM, or the result of a JOIN clause.  (Only explicit JOIN syntax
 *	  produces an RTE, not the implicit join resulting from multiple FROM
 *	  items.  This is because we only need the RTE to deal with SQL features
 *	  like outer joins and join-output-column aliasing.)  Other special
 *	  RTE types also exist, as indicated by RTEKind.
 *
 *	  Note that we consider PG_RTE_RELATION to cover anything that has a pg_class
 *	  entry.  relkind distinguishes the sub-cases.
 *
 *	  alias is an PGAlias node representing the AS alias-clause attached to the
 *	  FROM expression, or NULL if no clause.
 *
 *	  eref is the table reference name and column reference names (either
 *	  real or aliases).  Note that system columns (OID etc) are not included
 *	  in the column list.
 *	  eref->aliasname is required to be present, and should generally be used
 *	  to identify the RTE for error messages etc.
 *
 *	  In RELATION RTEs, the colnames in both alias and eref are indexed by
 *	  physical attribute number; this means there must be colname entries for
 *	  dropped columns.  When building an RTE we insert empty strings ("") for
 *	  dropped columns.  Note however that a stored rule may have nonempty
 *	  colnames for columns dropped since the rule was created (and for that
 *	  matter the colnames might be out of date due to column renamings).
 *	  The same comments apply to FUNCTION RTEs when a function's return type
 *	  is a named composite type.
 *
 *	  In JOIN RTEs, the colnames in both alias and eref are one-to-one with
 *	  joinaliasvars entries.  A JOIN RTE will omit columns of its inputs when
 *	  those columns are known to be dropped at parse time.  Again, however,
 *	  a stored rule might contain entries for columns dropped since the rule
 *	  was created.  (This is only possible for columns not actually referenced
 *	  in the rule.)  When loading a stored rule, we replace the joinaliasvars
 *	  items for any such columns with null pointers.  (We can't simply delete
 *	  them from the joinaliasvars list, because that would affect the attnums
 *	  of Vars referencing the rest of the list.)
 *
 *	  inh is true for relation references that should be expanded to include
 *	  inheritance children, if the rel has any.  This *must* be false for
 *	  RTEs other than PG_RTE_RELATION entries.
 *
 *	  inFromCl marks those range variables that are listed in the FROM clause.
 *	  It's false for RTEs that are added to a query behind the scenes, such
 *	  as the NEW and OLD variables for a rule, or the subqueries of a UNION.
 *	  This flag is not used anymore during parsing, since the parser now uses
 *	  a separate "namespace" data structure to control visibility, but it is
 *	  needed by ruleutils.c to determine whether RTEs should be shown in
 *	  decompiled queries.
 *--------------------
 */
typedef enum PGRTEKind
{
	PG_RTE_RELATION,				/* ordinary relation reference */
	PG_RTE_SUBQUERY,				/* subquery in FROM */
	PG_RTE_JOIN,					/* join */
	PG_RTE_FUNCTION,				/* function in FROM */
	PG_RTE_TABLEFUNC,				/* TableFunc(.., column list) */
	PG_RTE_VALUES,					/* VALUES (<exprlist>), (<exprlist>), ... */
	PG_RTE_CTE,					/* common table expr (WITH list element) */
	RTE_NAMEDTUPLESTORE			/* tuplestore, e.g. for AFTER triggers */
} PGRTEKind;

typedef struct PGRangeTblEntry
{
	PGNodeTag		type;

	PGRTEKind		rtekind;		/* see above */

	/*
	 * XXX the fields applicable to only some rte kinds should be merged into
	 * a union.  I didn't do this yet because the diffs would impact a lot of
	 * code that is being actively worked on.  FIXME someday.
	 */

	/*
	 * Fields valid for a plain relation RTE (else zero):
	 *
	 * As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate
	 * that the tuple format of the tuplestore is the same as the referenced
	 * relation.  This allows plans referencing AFTER trigger transition
	 * tables to be invalidated if the underlying table is altered.
	 */
	PGOid			relid;			/* OID of the relation */
	char		relkind;		/* relation kind (see pg_class.relkind) */
	struct PGTableSampleClause *tablesample;	/* sampling info, or NULL */

	/*
	 * Fields valid for a subquery RTE (else NULL):
	 */
	PGQuery	   *subquery;		/* the sub-query */

	/*
	 * Fields valid for a join RTE (else NULL/zero):
	 *
	 * joinaliasvars is a list of (usually) Vars corresponding to the columns
	 * of the join result.  An alias PGVar referencing column K of the join
	 * result can be replaced by the K'th element of joinaliasvars --- but to
	 * simplify the task of reverse-listing aliases correctly, we do not do
	 * that until planning time.  In detail: an element of joinaliasvars can
	 * be a PGVar of one of the join's input relations, or such a PGVar with an
	 * implicit coercion to the join's output column type, or a COALESCE
	 * expression containing the two input column Vars (possibly coerced).
	 * Within a PGQuery loaded from a stored rule, it is also possible for
	 * joinaliasvars items to be null pointers, which are placeholders for
	 * (necessarily unreferenced) columns dropped since the rule was made.
	 * Also, once planning begins, joinaliasvars items can be almost anything,
	 * as a result of subquery-flattening substitutions.
	 */
	PGJoinType	jointype;		/* type of join */
	PGList	   *joinaliasvars;	/* list of alias-var expansions */

	/*
	 * Fields valid for a function RTE (else NIL/zero):
	 *
	 * When funcordinality is true, the eref->colnames list includes an alias
	 * for the ordinality column.  The ordinality column is otherwise
	 * implicit, and must be accounted for "by hand" in places such as
	 * expandRTE().
	 */
	PGList	   *functions;		/* list of PGRangeTblFunction nodes */
	bool		funcordinality; /* is this called WITH ORDINALITY? */

	/*
	 * Fields valid for a PGTableFunc RTE (else NULL):
	 */
	PGTableFunc  *tablefunc;

	/*
	 * Fields valid for a values RTE (else NIL):
	 */
	PGList	   *values_lists;	/* list of expression lists */

	/*
	 * Fields valid for a CTE RTE (else NULL/zero):
	 */
	char	   *ctename;		/* name of the WITH list item */
	PGIndex		ctelevelsup;	/* number of query levels up */
	bool		self_reference; /* is this a recursive self-reference? */

	/*
	 * Fields valid for table functions, values, CTE and ENR RTEs (else NIL):
	 *
	 * We need these for CTE RTEs so that the types of self-referential
	 * columns are well-defined.  For VALUES RTEs, storing these explicitly
	 * saves having to re-determine the info by scanning the values_lists. For
	 * ENRs, we store the types explicitly here (we could get the information
	 * from the catalogs if 'relid' was supplied, but we'd still need these
	 * for TupleDesc-based ENRs, so we might as well always store the type
	 * info here).
	 *
	 * For ENRs only, we have to consider the possibility of dropped columns.
	 * A dropped column is included in these lists, but it will have zeroes in
	 * all three lists (as well as an empty-string entry in eref).  Testing
	 * for zero coltype is the standard way to detect a dropped column.
	 */
	PGList	   *coltypes;		/* OID list of column type OIDs */
	PGList	   *coltypmods;		/* integer list of column typmods */
	PGList	   *colcollations;	/* OID list of column collation OIDs */

	/*
	 * Fields valid for ENR RTEs (else NULL/zero):
	 */
	char	   *enrname;		/* name of ephemeral named relation */
	double		enrtuples;		/* estimated or actual from caller */

	/*
	 * Fields valid in all RTEs:
	 */
	PGAlias	   *alias;			/* user-written alias clause, if any */
	PGAlias	   *eref;			/* expanded reference names */
	bool		lateral;		/* subquery, function, or values is LATERAL? */
	bool		inh;			/* inheritance requested? */
	bool		inFromCl;		/* present in FROM clause? */
} PGRangeTblEntry;

/*
 * PGRangeTblFunction -
 *	  PGRangeTblEntry subsidiary data for one function in a FUNCTION RTE.
 *
 * If the function had a column definition list (required for an
 * otherwise-unspecified RECORD result), funccolnames lists the names given
 * in the definition list, funccoltypes lists their declared column types,
 * funccoltypmods lists their typmods, funccolcollations their collations.
 * Otherwise, those fields are NIL.
 *
 * Notice we don't attempt to store info about the results of functions
 * returning named composite types, because those can change from time to
 * time.  We do however remember how many columns we thought the type had
 * (including dropped columns!), so that we can successfully ignore any
 * columns added after the query was parsed.
 */
typedef struct PGRangeTblFunction
{
	PGNodeTag		type;

	PGNode	   *funcexpr;		/* expression tree for func call */
	int			funccolcount;	/* number of columns it contributes to RTE */
	/* These fields record the contents of a column definition list, if any: */
	PGList	   *funccolnames;	/* column names (list of String) */
	PGList	   *funccoltypes;	/* OID list of column type OIDs */
	PGList	   *funccoltypmods; /* integer list of column typmods */
	PGList	   *funccolcollations;	/* OID list of column collation OIDs */
	/* This is set during planning for use by the executor: */
	PGBitmapset  *funcparams;		/* PG_PARAM_EXEC PGParam IDs affecting this func */
} PGRangeTblFunction;

/*
 * PGTableSampleClause - TABLESAMPLE appearing in a transformed FROM clause
 *
 * Unlike PGRangeTableSample, this is a subnode of the relevant RangeTblEntry.
 */
typedef struct PGTableSampleClause
{
	PGNodeTag		type;
	PGOid			tsmhandler;		/* OID of the tablesample handler function */
	PGList	   *args;			/* tablesample argument expression(s) */
	PGExpr	   *repeatable;		/* REPEATABLE expression, or NULL if none */
} PGTableSampleClause;

/*
 * PGSortGroupClause -
 *		representation of ORDER BY, GROUP BY, PARTITION BY,
 *		DISTINCT, DISTINCT ON items
 *
 * You might think that ORDER BY is only interested in defining ordering,
 * and GROUP/DISTINCT are only interested in defining equality.  However,
 * one way to implement grouping is to sort and then apply a "uniq"-like
 * filter.  So it's also interesting to keep track of possible sort operators
 * for GROUP/DISTINCT, and in particular to try to sort for the grouping
 * in a way that will also yield a requested ORDER BY ordering.  So we need
 * to be able to compare ORDER BY and GROUP/DISTINCT lists, which motivates
 * the decision to give them the same representation.
 *
 * tleSortGroupRef must match ressortgroupref of exactly one entry of the
 *		query's targetlist; that is the expression to be sorted or grouped by.
 * eqop is the OID of the equality operator.
 * sortop is the OID of the ordering operator (a "<" or ">" operator),
 *		or InvalidOid if not available.
 * nulls_first means about what you'd expect.  If sortop is InvalidOid
 *		then nulls_first is meaningless and should be set to false.
 * hashable is true if eqop is hashable (note this condition also depends
 *		on the datatype of the input expression).
 *
 * In an ORDER BY item, all fields must be valid.  (The eqop isn't essential
 * here, but it's cheap to get it along with the sortop, and requiring it
 * to be valid eases comparisons to grouping items.)  Note that this isn't
 * actually enough information to determine an ordering: if the sortop is
 * collation-sensitive, a collation OID is needed too.  We don't store the
 * collation in PGSortGroupClause because it's not available at the time the
 * parser builds the PGSortGroupClause; instead, consult the exposed collation
 * of the referenced targetlist expression to find out what it is.
 *
 * In a grouping item, eqop must be valid.  If the eqop is a btree equality
 * operator, then sortop should be set to a compatible ordering operator.
 * We prefer to set eqop/sortop/nulls_first to match any ORDER BY item that
 * the query presents for the same tlist item.  If there is none, we just
 * use the default ordering op for the datatype.
 *
 * If the tlist item's type has a hash opclass but no btree opclass, then
 * we will set eqop to the hash equality operator, sortop to InvalidOid,
 * and nulls_first to false.  A grouping item of this kind can only be
 * implemented by hashing, and of course it'll never match an ORDER BY item.
 *
 * The hashable flag is provided since we generally have the requisite
 * information readily available when the PGSortGroupClause is constructed,
 * and it's relatively expensive to get it again later.  Note there is no
 * need for a "sortable" flag since OidIsValid(sortop) serves the purpose.
 *
 * A query might have both ORDER BY and DISTINCT (or DISTINCT ON) clauses.
 * In SELECT DISTINCT, the distinctClause list is as long or longer than the
 * sortClause list, while in SELECT DISTINCT ON it's typically shorter.
 * The two lists must match up to the end of the shorter one --- the parser
 * rearranges the distinctClause if necessary to make this true.  (This
 * restriction ensures that only one sort step is needed to both satisfy the
 * ORDER BY and set up for the PGUnique step.  This is semantically necessary
 * for DISTINCT ON, and presents no real drawback for DISTINCT.)
 */
typedef struct PGSortGroupClause
{
	PGNodeTag		type;
	PGIndex		tleSortGroupRef;	/* reference into targetlist */
	PGOid			eqop;			/* the equality operator ('=' op) */
	PGOid			sortop;			/* the ordering operator ('<' op), or 0 */
	bool		nulls_first;	/* do NULLs come before normal values? */
	bool		hashable;		/* can eqop be implemented by hashing? */
} PGSortGroupClause;

/*
 * PGGroupingSet -
 *		representation of CUBE, ROLLUP and GROUPING SETS clauses
 *
 * In a PGQuery with grouping sets, the groupClause contains a flat list of
 * PGSortGroupClause nodes for each distinct expression used.  The actual
 * structure of the GROUP BY clause is given by the groupingSets tree.
 *
 * In the raw parser output, PGGroupingSet nodes (of all types except SIMPLE
 * which is not used) are potentially mixed in with the expressions in the
 * groupClause of the SelectStmt.  (An expression can't contain a PGGroupingSet,
 * but a list may mix PGGroupingSet and expression nodes.)  At this stage, the
 * content of each node is a list of expressions, some of which may be RowExprs
 * which represent sublists rather than actual row constructors, and nested
 * PGGroupingSet nodes where legal in the grammar.  The structure directly
 * reflects the query syntax.
 *
 * In parse analysis, the transformed expressions are used to build the tlist
 * and groupClause list (of PGSortGroupClause nodes), and the groupingSets tree
 * is eventually reduced to a fixed format:
 *
 * EMPTY nodes represent (), and obviously have no content
 *
 * SIMPLE nodes represent a list of one or more expressions to be treated as an
 * atom by the enclosing structure; the content is an integer list of
 * ressortgroupref values (see PGSortGroupClause)
 *
 * CUBE and ROLLUP nodes contain a list of one or more SIMPLE nodes.
 *
 * SETS nodes contain a list of EMPTY, SIMPLE, CUBE or ROLLUP nodes, but after
 * parse analysis they cannot contain more SETS nodes; enough of the syntactic
 * transforms of the spec have been applied that we no longer have arbitrarily
 * deep nesting (though we still preserve the use of cube/rollup).
 *
 * Note that if the groupingSets tree contains no SIMPLE nodes (only EMPTY
 * nodes at the leaves), then the groupClause will be empty, but this is still
 * an aggregation query (similar to using aggs or HAVING without GROUP BY).
 *
 * As an example, the following clause:
 *
 * GROUP BY GROUPING SETS ((a,b), CUBE(c,(d,e)))
 *
 * looks like this after raw parsing:
 *
 * SETS( RowExpr(a,b) , CUBE( c, RowExpr(d,e) ) )
 *
 * and parse analysis converts it to:
 *
 * SETS( SIMPLE(1,2), CUBE( SIMPLE(3), SIMPLE(4,5) ) )
 */
typedef enum
{
	GROUPING_SET_EMPTY,
	GROUPING_SET_SIMPLE,
	GROUPING_SET_ROLLUP,
	GROUPING_SET_CUBE,
	GROUPING_SET_SETS
} GroupingSetKind;

typedef struct PGGroupingSet
{
	PGNodeTag		type;
	GroupingSetKind kind;
	PGList	   *content;
	int			location;
} PGGroupingSet;

/*
 * PGWindowClause -
 *		transformed representation of WINDOW and OVER clauses
 *
 * A parsed Query's windowClause list contains these structs.  "name" is set
 * if the clause originally came from WINDOW, and is NULL if it originally
 * was an OVER clause (but note that we collapse out duplicate OVERs).
 * partitionClause and orderClause are lists of PGSortGroupClause structs.
 * winref is an ID number referenced by PGWindowFunc nodes; it must be unique
 * among the members of a Query's windowClause list.
 * When refname isn't null, the partitionClause is always copied from there;
 * the orderClause might or might not be copied (see copiedOrder); the framing
 * options are never copied, per spec.
 */
typedef struct PGWindowClause
{
	PGNodeTag		type;
	char	   *name;			/* window name (NULL in an OVER clause) */
	char	   *refname;		/* referenced window name, if any */
	PGList	   *partitionClause;	/* PARTITION BY list */
	PGList	   *orderClause;	/* ORDER BY list */
	int			frameOptions;	/* frame_clause options, see PGWindowDef */
	PGNode	   *startOffset;	/* expression for starting bound, if any */
	PGNode	   *endOffset;		/* expression for ending bound, if any */
	PGIndex		winref;			/* ID referenced by window functions */
	bool		copiedOrder;	/* did we copy orderClause from refname? */
} PGWindowClause;

/*
 * RowMarkClause -
 *	   parser output representation of FOR [KEY] UPDATE/SHARE clauses
 *
 * Query.rowMarks contains a separate RowMarkClause node for each relation
 * identified as a FOR [KEY] UPDATE/SHARE target.  If one of these clauses
 * is applied to a subquery, we generate RowMarkClauses for all normal and
 * subquery rels in the subquery, but they are marked pushedDown = true to
 * distinguish them from clauses that were explicitly written at this query
 * level.  Also, Query.hasForUpdate tells whether there were explicit FOR
 * UPDATE/SHARE/KEY SHARE clauses in the current query level.
 */


/*
 * PGWithClause -
 *	   representation of WITH clause
 *
 * Note: PGWithClause does not propagate into the PGQuery representation;
 * but PGCommonTableExpr does.
 */
typedef struct PGWithClause
{
	PGNodeTag		type;
	PGList	   *ctes;			/* list of CommonTableExprs */
	bool		recursive;		/* true = WITH RECURSIVE */
	int			location;		/* token location, or -1 if unknown */
} PGWithClause;

/*
 * PGInferClause -
 *		ON CONFLICT unique index inference clause
 *
 * Note: PGInferClause does not propagate into the PGQuery representation.
 */
typedef struct PGInferClause
{
	PGNodeTag		type;
	PGList	   *indexElems;		/* IndexElems to infer unique index */
	PGNode	   *whereClause;	/* qualification (partial-index predicate) */
	char	   *conname;		/* PGConstraint name, or NULL if unnamed */
	int			location;		/* token location, or -1 if unknown */
} PGInferClause;

/*
 * PGOnConflictClause -
 *		representation of ON CONFLICT clause
 *
 * Note: PGOnConflictClause does not propagate into the PGQuery representation.
 */
typedef struct PGOnConflictClause
{
	PGNodeTag		type;
	PGOnConflictAction action;	/* DO NOTHING or UPDATE? */
	PGInferClause *infer;			/* Optional index inference clause */
	PGList	   *targetList;		/* the target list (of PGResTarget) */
	PGNode	   *whereClause;	/* qualifications */
	int			location;		/* token location, or -1 if unknown */
} PGOnConflictClause;

/*
 * PGCommonTableExpr -
 *	   representation of WITH list element
 *
 * We don't currently support the SEARCH or CYCLE clause.
 */
typedef struct PGCommonTableExpr
{
	PGNodeTag		type;
	char	   *ctename;		/* query name (never qualified) */
	PGList	   *aliascolnames;	/* optional list of column names */
	/* SelectStmt/InsertStmt/etc before parse analysis, PGQuery afterwards: */
	PGNode	   *ctequery;		/* the CTE's subquery */
	int			location;		/* token location, or -1 if unknown */
	/* These fields are set during parse analysis: */
	bool		cterecursive;	/* is this CTE actually recursive? */
	int			cterefcount;	/* number of RTEs referencing this CTE
								 * (excluding internal self-references) */
	PGList	   *ctecolnames;	/* list of output column names */
	PGList	   *ctecoltypes;	/* OID list of output column type OIDs */
	PGList	   *ctecoltypmods;	/* integer list of output column typmods */
	PGList	   *ctecolcollations;	/* OID list of column collation OIDs */
} PGCommonTableExpr;

/* Convenience macro to get the output tlist of a CTE's query */
#define GetCTETargetList(cte) \
	(AssertMacro(IsA((cte)->ctequery, PGQuery)), \
	 ((PGQuery *) (cte)->ctequery)->commandType == PG_CMD_SELECT ? \
	 ((PGQuery *) (cte)->ctequery)->targetList : \
	 ((PGQuery *) (cte)->ctequery)->returningList)

/*
 * TriggerTransition -
 *	   representation of transition row or table naming clause
 *
 * Only transition tables are initially supported in the syntax, and only for
 * AFTER triggers, but other permutations are accepted by the parser so we can
 * give a meaningful message from C code.
 */


/*****************************************************************************
 *		Raw Grammar Output Statements
 *****************************************************************************/

/*
 *		PGRawStmt --- container for any one statement's raw parse tree
 *
 * Parse analysis converts a raw parse tree headed by a PGRawStmt node into
 * an analyzed statement headed by a PGQuery node.  For optimizable statements,
 * the conversion is complex.  For utility statements, the parser usually just
 * transfers the raw parse tree (sans PGRawStmt) into the utilityStmt field of
 * the PGQuery node, and all the useful work happens at execution time.
 *
 * stmt_location/stmt_len identify the portion of the source text string
 * containing this raw statement (useful for multi-statement strings).
 */
typedef struct PGRawStmt
{
	PGNodeTag		type;
	PGNode	   *stmt;			/* raw parse tree */
	int			stmt_location;	/* start location, or -1 if unknown */
	int			stmt_len;		/* length in bytes; 0 means "rest of string" */
} PGRawStmt;

/*****************************************************************************
 *		Optimizable Statements
 *****************************************************************************/

/* ----------------------
 *		Insert Statement
 *
 * The source expression is represented by PGSelectStmt for both the
 * SELECT and VALUES cases.  If selectStmt is NULL, then the query
 * is INSERT ... DEFAULT VALUES.
 * ----------------------
 */
typedef struct PGInsertStmt
{
	PGNodeTag		type;
	PGRangeVar   *relation;		/* relation to insert into */
	PGList	   *cols;			/* optional: names of the target columns */
	PGNode	   *selectStmt;		/* the source SELECT/VALUES, or NULL */
	PGOnConflictClause *onConflictClause; /* ON CONFLICT clause */
	PGList	   *returningList;	/* list of expressions to return */
	PGWithClause *withClause;		/* WITH clause */
	PGOverridingKind override;	/* OVERRIDING clause */
} PGInsertStmt;

/* ----------------------
 *		Delete Statement
 * ----------------------
 */
typedef struct PGDeleteStmt
{
	PGNodeTag		type;
	PGRangeVar   *relation;		/* relation to delete from */
	PGList	   *usingClause;	/* optional using clause for more tables */
	PGNode	   *whereClause;	/* qualifications */
	PGList	   *returningList;	/* list of expressions to return */
	PGWithClause *withClause;		/* WITH clause */
} PGDeleteStmt;

/* ----------------------
 *		Update Statement
 * ----------------------
 */
typedef struct PGUpdateStmt
{
	PGNodeTag		type;
	PGRangeVar   *relation;		/* relation to update */
	PGList	   *targetList;		/* the target list (of PGResTarget) */
	PGNode	   *whereClause;	/* qualifications */
	PGList	   *fromClause;		/* optional from clause for more tables */
	PGList	   *returningList;	/* list of expressions to return */
	PGWithClause *withClause;		/* WITH clause */
} PGUpdateStmt;

/* ----------------------
 *		Select Statement
 *
 * A "simple" SELECT is represented in the output of gram.y by a single
 * PGSelectStmt node; so is a VALUES construct.  A query containing set
 * operators (UNION, INTERSECT, EXCEPT) is represented by a tree of PGSelectStmt
 * nodes, in which the leaf nodes are component SELECTs and the internal nodes
 * represent UNION, INTERSECT, or EXCEPT operators.  Using the same node
 * type for both leaf and internal nodes allows gram.y to stick ORDER BY,
 * LIMIT, etc, clause values into a SELECT statement without worrying
 * whether it is a simple or compound SELECT.
 * ----------------------
 */
typedef enum PGSetOperation
{
	PG_SETOP_NONE = 0,
	PG_SETOP_UNION,
	PG_SETOP_INTERSECT,
	PG_SETOP_EXCEPT
} PGSetOperation;

typedef struct PGSelectStmt
{
	PGNodeTag		type;

	/*
	 * These fields are used only in "leaf" SelectStmts.
	 */
	PGList	   *distinctClause; /* NULL, list of DISTINCT ON exprs, or
								 * lcons(NIL,NIL) for all (SELECT DISTINCT) */
	PGIntoClause *intoClause;		/* target for SELECT INTO */
	PGList	   *targetList;		/* the target list (of PGResTarget) */
	PGList	   *fromClause;		/* the FROM clause */
	PGNode	   *whereClause;	/* WHERE qualification */
	PGList	   *groupClause;	/* GROUP BY clauses */
	PGNode	   *havingClause;	/* HAVING conditional-expression */
	PGList	   *windowClause;	/* WINDOW window_name AS (...), ... */

	/*
	 * In a "leaf" node representing a VALUES list, the above fields are all
	 * null, and instead this field is set.  Note that the elements of the
	 * sublists are just expressions, without PGResTarget decoration. Also note
	 * that a list element can be DEFAULT (represented as a PGSetToDefault
	 * node), regardless of the context of the VALUES list. It's up to parse
	 * analysis to reject that where not valid.
	 */
	PGList	   *valuesLists;	/* untransformed list of expression lists */

	/*
	 * These fields are used in both "leaf" SelectStmts and upper-level
	 * SelectStmts.
	 */
	PGList	   *sortClause;		/* sort clause (a list of SortBy's) */
	PGNode	   *limitOffset;	/* # of result tuples to skip */
	PGNode	   *limitCount;		/* # of result tuples to return */
	PGList	   *lockingClause;	/* FOR UPDATE (list of LockingClause's) */
	PGWithClause *withClause;		/* WITH clause */

	/*
	 * These fields are used only in upper-level SelectStmts.
	 */
	PGSetOperation op;			/* type of set op */
	bool		all;			/* ALL specified? */
	struct PGSelectStmt *larg;	/* left child */
	struct PGSelectStmt *rarg;	/* right child */
	/* Eventually add fields for CORRESPONDING spec here */
} PGSelectStmt;


/* ----------------------
 *		Set Operation node for post-analysis query trees
 *
 * After parse analysis, a SELECT with set operations is represented by a
 * top-level PGQuery node containing the leaf SELECTs as subqueries in its
 * range table.  Its setOperations field shows the tree of set operations,
 * with leaf PGSelectStmt nodes replaced by PGRangeTblRef nodes, and internal
 * nodes replaced by SetOperationStmt nodes.  Information about the output
 * column types is added, too.  (Note that the child nodes do not necessarily
 * produce these types directly, but we've checked that their output types
 * can be coerced to the output column type.)  Also, if it's not UNION ALL,
 * information about the types' sort/group semantics is provided in the form
 * of a PGSortGroupClause list (same representation as, eg, DISTINCT).
 * The resolved common column collations are provided too; but note that if
 * it's not UNION ALL, it's okay for a column to not have a common collation,
 * so a member of the colCollations list could be InvalidOid even though the
 * column has a collatable type.
 * ----------------------
 */



/*****************************************************************************
 *		Other Statements (no optimizations required)
 *
 *		These are not touched by parser/analyze.c except to put them into
 *		the utilityStmt field of a Query.  This is eventually passed to
 *		ProcessUtility (by-passing rewriting and planning).  Some of the
 *		statements do need attention from parse analysis, and this is
 *		done by routines in parser/parse_utilcmd.c after ProcessUtility
 *		receives the command for execution.
 *		DECLARE CURSOR, EXPLAIN, and CREATE TABLE AS are special cases:
 *		they contain optimizable statements, which get processed normally
 *		by parser/analyze.c.
 *****************************************************************************/

/*
 * When a command can act on several kinds of objects with only one
 * parse structure required, use these constants to designate the
 * object type.  Note that commands typically don't support all the types.
 */

typedef enum PGObjectType
{
	PG_OBJECT_ACCESS_METHOD,
	PG_OBJECT_AGGREGATE,
	PG_OBJECT_AMOP,
	PG_OBJECT_AMPROC,
	PG_OBJECT_ATTRIBUTE,			/* type's attribute, when distinct from column */
	PG_OBJECT_CAST,
	PG_OBJECT_COLUMN,
	PG_OBJECT_COLLATION,
	PG_OBJECT_CONVERSION,
	PG_OBJECT_DATABASE,
	PG_OBJECT_DEFAULT,
	PG_OBJECT_DEFACL,
	PG_OBJECT_DOMAIN,
	PG_OBJECT_DOMCONSTRAINT,
	PG_OBJECT_EVENT_TRIGGER,
	PG_OBJECT_EXTENSION,
	PG_OBJECT_FDW,
	PG_OBJECT_FOREIGN_SERVER,
	PG_OBJECT_FOREIGN_TABLE,
	PG_OBJECT_FUNCTION,
	PG_OBJECT_INDEX,
	PG_OBJECT_LANGUAGE,
	PG_OBJECT_LARGEOBJECT,
	PG_OBJECT_MATVIEW,
	PG_OBJECT_OPCLASS,
	PG_OBJECT_OPERATOR,
	PG_OBJECT_OPFAMILY,
	PG_OBJECT_POLICY,
	PG_OBJECT_PUBLICATION,
	PG_OBJECT_PUBLICATION_REL,
	PG_OBJECT_ROLE,
	PG_OBJECT_RULE,
	PG_OBJECT_SCHEMA,
	PG_OBJECT_SEQUENCE,
	PG_OBJECT_SUBSCRIPTION,
	PG_OBJECT_STATISTIC_EXT,
	PG_OBJECT_TABCONSTRAINT,
	PG_OBJECT_TABLE,
	PG_OBJECT_TABLESPACE,
	PG_OBJECT_TRANSFORM,
	PG_OBJECT_TRIGGER,
	PG_OBJECT_TSCONFIGURATION,
	PG_OBJECT_TSDICTIONARY,
	PG_OBJECT_TSPARSER,
	PG_OBJECT_TSTEMPLATE,
	PG_OBJECT_TYPE,
	PG_OBJECT_USER_MAPPING,
	PG_OBJECT_VIEW
} PGObjectType;

/* ----------------------
 *		Create Schema Statement
 *
 * NOTE: the schemaElts list contains raw parsetrees for component statements
 * of the schema, such as CREATE TABLE, GRANT, etc.  These are analyzed and
 * executed after the schema itself is created.
 * ----------------------
 */
typedef struct PGCreateSchemaStmt
{
	PGNodeTag		type;
	char	   *schemaname;		/* the name of the schema to create */
	PGList	   *schemaElts;		/* schema components (list of parsenodes) */
	bool		if_not_exists;	/* just do nothing if schema already exists? */
} PGCreateSchemaStmt;

typedef enum PGDropBehavior
{
	PG_DROP_RESTRICT,				/* drop fails if any dependent objects */
	PG_DROP_CASCADE				/* remove dependent objects too */
} PGDropBehavior;

/* ----------------------
 *	Alter Table
 * ----------------------
 */
typedef struct PGAlterTableStmt
{
	PGNodeTag		type;
	PGRangeVar   *relation;		/* table to work on */
	PGList	   *cmds;			/* list of subcommands */
	PGObjectType	relkind;		/* type of object */
	bool		missing_ok;		/* skip error if table missing */
} PGAlterTableStmt;

typedef enum PGAlterTableType
{
	PG_AT_AddColumn,				/* add column */
	PG_AT_AddColumnRecurse,		/* internal to commands/tablecmds.c */
	PG_AT_AddColumnToView,			/* implicitly via CREATE OR REPLACE VIEW */
	PG_AT_ColumnDefault,			/* alter column default */
	PG_AT_DropNotNull,				/* alter column drop not null */
	PG_AT_SetNotNull,				/* alter column set not null */
	PG_AT_SetStatistics,			/* alter column set statistics */
	PG_AT_SetOptions,				/* alter column set ( options ) */
	PG_AT_ResetOptions,			/* alter column reset ( options ) */
	PG_AT_SetStorage,				/* alter column set storage */
	PG_AT_DropColumn,				/* drop column */
	PG_AT_DropColumnRecurse,		/* internal to commands/tablecmds.c */
	PG_AT_AddIndex,				/* add index */
	PG_AT_ReAddIndex,				/* internal to commands/tablecmds.c */
	PG_AT_AddConstraint,			/* add constraint */
	PG_AT_AddConstraintRecurse,	/* internal to commands/tablecmds.c */
	PG_AT_ReAddConstraint,			/* internal to commands/tablecmds.c */
	PG_AT_AlterConstraint,			/* alter constraint */
	PG_AT_ValidateConstraint,		/* validate constraint */
	PG_AT_ValidateConstraintRecurse,	/* internal to commands/tablecmds.c */
	PG_AT_ProcessedConstraint,		/* pre-processed add constraint (local in
								 * parser/parse_utilcmd.c) */
	PG_AT_AddIndexConstraint,		/* add constraint using existing index */
	PG_AT_DropConstraint,			/* drop constraint */
	PG_AT_DropConstraintRecurse,	/* internal to commands/tablecmds.c */
	PG_AT_ReAddComment,			/* internal to commands/tablecmds.c */
	PG_AT_AlterColumnType,			/* alter column type */
	PG_AT_AlterColumnGenericOptions,	/* alter column OPTIONS (...) */
	PG_AT_ChangeOwner,				/* change owner */
	PG_AT_ClusterOn,				/* CLUSTER ON */
	PG_AT_DropCluster,				/* SET WITHOUT CLUSTER */
	PG_AT_SetLogged,				/* SET LOGGED */
	PG_AT_SetUnLogged,				/* SET UNLOGGED */
	PG_AT_AddOids,					/* SET WITH OIDS */
	PG_AT_AddOidsRecurse,			/* internal to commands/tablecmds.c */
	PG_AT_DropOids,				/* SET WITHOUT OIDS */
	PG_AT_SetTableSpace,			/* SET TABLESPACE */
	PG_AT_SetRelOptions,			/* SET (...) -- AM specific parameters */
	PG_AT_ResetRelOptions,			/* RESET (...) -- AM specific parameters */
	PG_AT_ReplaceRelOptions,		/* replace reloption list in its entirety */
	PG_AT_EnableTrig,				/* ENABLE TRIGGER name */
	PG_AT_EnableAlwaysTrig,		/* ENABLE ALWAYS TRIGGER name */
	PG_AT_EnableReplicaTrig,		/* ENABLE REPLICA TRIGGER name */
	PG_AT_DisableTrig,				/* DISABLE TRIGGER name */
	PG_AT_EnableTrigAll,			/* ENABLE TRIGGER ALL */
	PG_AT_DisableTrigAll,			/* DISABLE TRIGGER ALL */
	PG_AT_EnableTrigUser,			/* ENABLE TRIGGER USER */
	PG_AT_DisableTrigUser,			/* DISABLE TRIGGER USER */
	PG_AT_EnableRule,				/* ENABLE RULE name */
	PG_AT_EnableAlwaysRule,		/* ENABLE ALWAYS RULE name */
	PG_AT_EnableReplicaRule,		/* ENABLE REPLICA RULE name */
	PG_AT_DisableRule,				/* DISABLE RULE name */
	PG_AT_AddInherit,				/* INHERIT parent */
	PG_AT_DropInherit,				/* NO INHERIT parent */
	PG_AT_AddOf,					/* OF <type_name> */
	PG_AT_DropOf,					/* NOT OF */
	PG_AT_ReplicaIdentity,			/* REPLICA IDENTITY */
	PG_AT_EnableRowSecurity,		/* ENABLE ROW SECURITY */
	PG_AT_DisableRowSecurity,		/* DISABLE ROW SECURITY */
	PG_AT_ForceRowSecurity,		/* FORCE ROW SECURITY */
	PG_AT_NoForceRowSecurity,		/* NO FORCE ROW SECURITY */
	PG_AT_GenericOptions,			/* OPTIONS (...) */
	PG_AT_AttachPartition,			/* ATTACH PARTITION */
	PG_AT_DetachPartition,			/* DETACH PARTITION */
	PG_AT_AddIdentity,				/* ADD IDENTITY */
	PG_AT_SetIdentity,				/* SET identity column options */
	AT_DropIdentity				/* DROP IDENTITY */
} PGAlterTableType;



typedef struct PGAlterTableCmd	/* one subcommand of an ALTER TABLE */
{
	PGNodeTag		type;
	PGAlterTableType subtype;		/* Type of table alteration to apply */
	char	   *name;			/* column, constraint, or trigger to act on,
								 * or tablespace */
	PGNode	   *def;			/* definition of new column, index,
								 * constraint, or parent table */
	PGDropBehavior behavior;		/* RESTRICT or CASCADE for DROP cases */
	bool		missing_ok;		/* skip error if missing? */
} PGAlterTableCmd;

/*
 * Note: PGObjectWithArgs carries only the types of the input parameters of the
 * function.  So it is sufficient to identify an existing function, but it
 * is not enough info to define a function nor to call it.
 */
typedef struct PGObjectWithArgs
{
	PGNodeTag		type;
	PGList	   *objname;		/* qualified name of function/operator */
	PGList	   *objargs;		/* list of Typename nodes */
	bool		args_unspecified;	/* argument list was omitted, so name must
									 * be unique (note that objargs == NIL
									 * means zero args) */
} PGObjectWithArgs;

/* ----------------------
 *		Copy Statement
 *
 * We support "COPY relation FROM file", "COPY relation TO file", and
 * "COPY (query) TO file".  In any given PGCopyStmt, exactly one of "relation"
 * and "query" must be non-NULL.
 * ----------------------
 */
typedef struct PGCopyStmt
{
	PGNodeTag		type;
	PGRangeVar   *relation;		/* the relation to copy */
	PGNode	   *query;			/* the query (SELECT or DML statement with
								 * RETURNING) to copy, as a raw parse tree */
	PGList	   *attlist;		/* PGList of column names (as Strings), or NIL
								 * for all columns */
	bool		is_from;		/* TO or FROM */
	bool		is_program;		/* is 'filename' a program to popen? */
	char	   *filename;		/* filename, or NULL for STDIN/STDOUT */
	PGList	   *options;		/* PGList of PGDefElem nodes */
} PGCopyStmt;

/* ----------------------
 * SET Statement (includes RESET)
 *
 * "SET var TO DEFAULT" and "RESET var" are semantically equivalent, but we
 * preserve the distinction in VariableSetKind for CreateCommandTag().
 * ----------------------
 */
typedef enum
{
	VAR_SET_VALUE,				/* SET var = value */
	VAR_SET_DEFAULT,			/* SET var TO DEFAULT */
	VAR_SET_CURRENT,			/* SET var FROM CURRENT */
	VAR_SET_MULTI,				/* special case for SET TRANSACTION ... */
	VAR_RESET,					/* RESET var */
	VAR_RESET_ALL				/* RESET ALL */
} VariableSetKind;

typedef struct PGVariableSetStmt
{
	PGNodeTag		type;
	VariableSetKind kind;
	char	   *name;			/* variable to be set */
	PGList	   *args;			/* PGList of PGAConst nodes */
	bool		is_local;		/* SET LOCAL? */
} PGVariableSetStmt;

/* ----------------------
 * Show Statement
 * ----------------------
 */
typedef struct PGVariableShowStmt
{
	PGNodeTag		type;
	char	   *name;
} PGVariableShowStmt;

/* ----------------------
 *		Create Table Statement
 *
 * NOTE: in the raw gram.y output, PGColumnDef and PGConstraint nodes are
 * intermixed in tableElts, and constraints is NIL.  After parse analysis,
 * tableElts contains just ColumnDefs, and constraints contains just
 * PGConstraint nodes (in fact, only PG_CONSTR_CHECK nodes, in the present
 * implementation).
 * ----------------------
 */

typedef struct PGCreateStmt
{
	PGNodeTag		type;
	PGRangeVar   *relation;		/* relation to create */
	PGList	   *tableElts;		/* column definitions (list of PGColumnDef) */
	PGList	   *inhRelations;	/* relations to inherit from (list of
								 * inhRelation) */
	PGTypeName   *ofTypename;		/* OF typename */
	PGList	   *constraints;	/* constraints (list of PGConstraint nodes) */
	PGList	   *options;		/* options from WITH clause */
	PGOnCommitAction oncommit;	/* what do we do at COMMIT? */
	char	   *tablespacename; /* table space to use, or NULL */
	bool		if_not_exists;	/* just do nothing if it already exists? */
} PGCreateStmt;

/* ----------
 * Definitions for constraints in PGCreateStmt
 *
 * Note that column defaults are treated as a type of constraint,
 * even though that's a bit odd semantically.
 *
 * For constraints that use expressions (CONSTR_CHECK, PG_CONSTR_DEFAULT)
 * we may have the expression in either "raw" form (an untransformed
 * parse tree) or "cooked" form (the nodeToString representation of
 * an executable expression tree), depending on how this PGConstraint
 * node was created (by parsing, or by inheritance from an existing
 * relation).  We should never have both in the same node!
 *
 * PG_FKCONSTR_ACTION_xxx values are stored into pg_constraint.confupdtype
 * and pg_constraint.confdeltype columns; PG_FKCONSTR_MATCH_xxx values are
 * stored into pg_constraint.confmatchtype.  Changing the code values may
 * require an initdb!
 *
 * If skip_validation is true then we skip checking that the existing rows
 * in the table satisfy the constraint, and just install the catalog entries
 * for the constraint.  A new FK constraint is marked as valid iff
 * initially_valid is true.  (Usually skip_validation and initially_valid
 * are inverses, but we can set both true if the table is known empty.)
 *
 * PGConstraint attributes (DEFERRABLE etc) are initially represented as
 * separate PGConstraint nodes for simplicity of parsing.  parse_utilcmd.c makes
 * a pass through the constraints list to insert the info into the appropriate
 * PGConstraint node.
 * ----------
 */

typedef enum PGConstrType			/* types of constraints */
{
	PG_CONSTR_NULL,				/* not standard SQL, but a lot of people
								 * expect it */
	PG_CONSTR_NOTNULL,
	PG_CONSTR_DEFAULT,
	PG_CONSTR_IDENTITY,
	PG_CONSTR_CHECK,
	PG_CONSTR_PRIMARY,
	PG_CONSTR_UNIQUE,
	PG_CONSTR_EXCLUSION,
	PG_CONSTR_FOREIGN,
	PG_CONSTR_ATTR_DEFERRABLE,		/* attributes for previous constraint node */
	PG_CONSTR_ATTR_NOT_DEFERRABLE,
	PG_CONSTR_ATTR_DEFERRED,
	PG_CONSTR_ATTR_IMMEDIATE
} PGConstrType;

/* Foreign key action codes */
#define PG_FKCONSTR_ACTION_NOACTION	'a'
#define PG_FKCONSTR_ACTION_RESTRICT	'r'
#define PG_FKCONSTR_ACTION_CASCADE		'c'
#define PG_FKCONSTR_ACTION_SETNULL		'n'
#define PG_FKCONSTR_ACTION_SETDEFAULT	'd'

/* Foreign key matchtype codes */
#define PG_FKCONSTR_MATCH_FULL			'f'
#define PG_FKCONSTR_MATCH_PARTIAL		'p'
#define PG_FKCONSTR_MATCH_SIMPLE		's'

typedef struct PGConstraint
{
	PGNodeTag		type;
	PGConstrType	contype;		/* see above */

	/* Fields used for most/all constraint types: */
	char	   *conname;		/* PGConstraint name, or NULL if unnamed */
	bool		deferrable;		/* DEFERRABLE? */
	bool		initdeferred;	/* INITIALLY DEFERRED? */
	int			location;		/* token location, or -1 if unknown */

	/* Fields used for constraints with expressions (CHECK and DEFAULT): */
	bool		is_no_inherit;	/* is constraint non-inheritable? */
	PGNode	   *raw_expr;		/* expr, as untransformed parse tree */
	char	   *cooked_expr;	/* expr, as nodeToString representation */
	char		generated_when;

	/* Fields used for unique constraints (UNIQUE and PRIMARY KEY): */
	PGList	   *keys;			/* String nodes naming referenced column(s) */

	/* Fields used for EXCLUSION constraints: */
	PGList	   *exclusions;		/* list of (PGIndexElem, operator name) pairs */

	/* Fields used for index constraints (UNIQUE, PRIMARY KEY, EXCLUSION): */
	PGList	   *options;		/* options from WITH clause */
	char	   *indexname;		/* existing index to use; otherwise NULL */
	char	   *indexspace;		/* index tablespace; NULL for default */
	/* These could be, but currently are not, used for UNIQUE/PKEY: */
	char	   *access_method;	/* index access method; NULL for default */
	PGNode	   *where_clause;	/* partial index predicate */

	/* Fields used for FOREIGN KEY constraints: */
	PGRangeVar   *pktable;		/* Primary key table */
	PGList	   *fk_attrs;		/* Attributes of foreign key */
	PGList	   *pk_attrs;		/* Corresponding attrs in PK table */
	char		fk_matchtype;	/* FULL, PARTIAL, SIMPLE */
	char		fk_upd_action;	/* ON UPDATE action */
	char		fk_del_action;	/* ON DELETE action */
	PGList	   *old_conpfeqop;	/* pg_constraint.conpfeqop of my former self */
	PGOid			old_pktable_oid;	/* pg_constraint.confrelid of my former
									 * self */

	/* Fields used for constraints that allow a NOT VALID specification */
	bool		skip_validation;	/* skip validation of existing rows? */
	bool		initially_valid;	/* mark the new constraint as valid? */
} PGConstraint;

/* ----------------------
 *		{Create|Alter} SEQUENCE Statement
 * ----------------------
 */

typedef struct PGCreateSeqStmt
{
	PGNodeTag		type;
	PGRangeVar   *sequence;		/* the sequence to create */
	PGList	   *options;
	PGOid			ownerId;		/* ID of owner, or InvalidOid for default */
	bool		for_identity;
	bool		if_not_exists;	/* just do nothing if it already exists? */
} PGCreateSeqStmt;

typedef struct PGAlterSeqStmt
{
	PGNodeTag		type;
	PGRangeVar   *sequence;		/* the sequence to alter */
	PGList	   *options;
	bool		for_identity;
	bool		missing_ok;		/* skip error if a role is missing? */
} PGAlterSeqStmt;

/* ----------------------
 *		Drop Table|Sequence|View|Index|Type|Domain|Conversion|Schema Statement
 * ----------------------
 */

typedef struct PGDropStmt
{
	PGNodeTag		type;
	PGList	   *objects;		/* list of names */
	PGObjectType	removeType;		/* object type */
	PGDropBehavior behavior;		/* RESTRICT or CASCADE behavior */
	bool		missing_ok;		/* skip error if object is missing? */
	bool		concurrent;		/* drop index concurrently? */
} PGDropStmt;

/* ----------------------
 *		Create PGIndex Statement
 *
 * This represents creation of an index and/or an associated constraint.
 * If isconstraint is true, we should create a pg_constraint entry along
 * with the index.  But if indexOid isn't InvalidOid, we are not creating an
 * index, just a UNIQUE/PKEY constraint using an existing index.  isconstraint
 * must always be true in this case, and the fields describing the index
 * properties are empty.
 * ----------------------
 */
typedef struct PGIndexStmt
{
	PGNodeTag		type;
	char	   *idxname;		/* name of new index, or NULL for default */
	PGRangeVar   *relation;		/* relation to build index on */
	char	   *accessMethod;	/* name of access method (eg. btree) */
	char	   *tableSpace;		/* tablespace, or NULL for default */
	PGList	   *indexParams;	/* columns to index: a list of PGIndexElem */
	PGList	   *options;		/* WITH clause options: a list of PGDefElem */
	PGNode	   *whereClause;	/* qualification (partial-index predicate) */
	PGList	   *excludeOpNames; /* exclusion operator names, or NIL if none */
	char	   *idxcomment;		/* comment to apply to index, or NULL */
	PGOid			indexOid;		/* OID of an existing index, if any */
	PGOid			oldNode;		/* relfilenode of existing storage, if any */
	bool		unique;			/* is index unique? */
	bool		primary;		/* is index a primary key? */
	bool		isconstraint;	/* is it for a pkey/unique constraint? */
	bool		deferrable;		/* is the constraint DEFERRABLE? */
	bool		initdeferred;	/* is the constraint INITIALLY DEFERRED? */
	bool		transformed;	/* true when transformIndexStmt is finished */
	bool		concurrent;		/* should this be a concurrent index build? */
	bool		if_not_exists;	/* just do nothing if index already exists? */
} PGIndexStmt;


/* ----------------------
 *		Alter Object Rename Statement
 * ----------------------
 */
typedef struct PGRenameStmt
{
	PGNodeTag		type;
	PGObjectType	renameType;		/* PG_OBJECT_TABLE, PG_OBJECT_COLUMN, etc */
	PGObjectType	relationType;	/* if column name, associated relation type */
	PGRangeVar   *relation;		/* in case it's a table */
	PGNode	   *object;			/* in case it's some other object */
	char	   *subname;		/* name of contained object (column, rule,
								 * trigger, etc) */
	char	   *newname;		/* the new name */
	PGDropBehavior behavior;		/* RESTRICT or CASCADE behavior */
	bool		missing_ok;		/* skip error if missing? */
} PGRenameStmt;


/* ----------------------
 *		ALTER object SET SCHEMA Statement
 * ----------------------
 */
typedef struct PGAlterObjectSchemaStmt
{
	PGNodeTag		type;
	PGObjectType	objectType;		/* PG_OBJECT_TABLE, PG_OBJECT_TYPE, etc */
	PGRangeVar   *relation;		/* in case it's a table */
	PGNode	   *object;			/* in case it's some other object */
	char	   *newschema;		/* the new schema */
	bool		missing_ok;		/* skip error if missing? */
} PGAlterObjectSchemaStmt;

/* ----------------------
 *		{Begin|Commit|Rollback} Transaction Statement
 * ----------------------
 */
typedef enum PGTransactionStmtKind
{
	PG_TRANS_STMT_BEGIN,
	PG_TRANS_STMT_START,			/* semantically identical to BEGIN */
	PG_TRANS_STMT_COMMIT,
	PG_TRANS_STMT_ROLLBACK,
	PG_TRANS_STMT_SAVEPOINT,
	PG_TRANS_STMT_RELEASE,
	PG_TRANS_STMT_ROLLBACK_TO,
	PG_TRANS_STMT_PREPARE,
	PG_TRANS_STMT_COMMIT_PREPARED,
	TRANS_STMT_ROLLBACK_PREPARED
} PGTransactionStmtKind;

typedef struct PGTransactionStmt
{
	PGNodeTag		type;
	PGTransactionStmtKind kind;	/* see above */
	PGList	   *options;		/* for BEGIN/START and savepoint commands */
	char	   *gid;			/* for two-phase-commit related commands */
} PGTransactionStmt;

/* ----------------------
 *		Create View Statement
 * ----------------------
 */
typedef enum PGViewCheckOption
{
	PG_NO_CHECK_OPTION,
	PG_LOCAL_CHECK_OPTION,
	CASCADED_CHECK_OPTION
} PGViewCheckOption;

typedef struct PGViewStmt
{
	PGNodeTag		type;
	PGRangeVar   *view;			/* the view to be created */
	PGList	   *aliases;		/* target column names */
	PGNode	   *query;			/* the SELECT query (as a raw parse tree) */
	bool		replace;		/* replace an existing view? */
	PGList	   *options;		/* options from WITH clause */
	PGViewCheckOption withCheckOption;	/* WITH CHECK OPTION */
} PGViewStmt;

/* ----------------------
 *		Load Statement
 * ----------------------
 */
typedef struct PGLoadStmt
{
	PGNodeTag		type;
	char	   *filename;		/* file to load */
} PGLoadStmt;

/* ----------------------
 *		Vacuum and Analyze Statements
 *
 * Even though these are nominally two statements, it's convenient to use
 * just one node type for both.  Note that at least one of PG_VACOPT_VACUUM
 * and PG_VACOPT_ANALYZE must be set in options.
 * ----------------------
 */
typedef enum PGVacuumOption
{
	PG_VACOPT_VACUUM = 1 << 0,		/* do VACUUM */
	PG_VACOPT_ANALYZE = 1 << 1,	/* do ANALYZE */
	PG_VACOPT_VERBOSE = 1 << 2,	/* print progress info */
	PG_VACOPT_FREEZE = 1 << 3,		/* FREEZE option */
	PG_VACOPT_FULL = 1 << 4,		/* FULL (non-concurrent) vacuum */
	PG_VACOPT_NOWAIT = 1 << 5,		/* don't wait to get lock (autovacuum only) */
	PG_VACOPT_SKIPTOAST = 1 << 6,	/* don't process the TOAST table, if any */
	PG_VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7	/* don't skip any pages */
} PGVacuumOption;

typedef struct PGVacuumStmt
{
	PGNodeTag		type;
	int			options;		/* OR of PGVacuumOption flags */
	PGRangeVar   *relation;		/* single table to process, or NULL */
	PGList	   *va_cols;		/* list of column names, or NIL for all */
} PGVacuumStmt;

/* ----------------------
 *		Explain Statement
 *
 * The "query" field is initially a raw parse tree, and is converted to a
 * PGQuery node during parse analysis.  Note that rewriting and planning
 * of the query are always postponed until execution.
 * ----------------------
 */
typedef struct PGExplainStmt
{
	PGNodeTag		type;
	PGNode	   *query;			/* the query (see comments above) */
	PGList	   *options;		/* list of PGDefElem nodes */
} PGExplainStmt;

/* ----------------------
 *		CREATE TABLE AS Statement (a/k/a SELECT INTO)
 *
 * A query written as CREATE TABLE AS will produce this node type natively.
 * A query written as SELECT ... INTO will be transformed to this form during
 * parse analysis.
 * A query written as CREATE MATERIALIZED view will produce this node type,
 * during parse analysis, since it needs all the same data.
 *
 * The "query" field is handled similarly to EXPLAIN, though note that it
 * can be a SELECT or an EXECUTE, but not other DML statements.
 * ----------------------
 */
typedef struct PGCreateTableAsStmt
{
	PGNodeTag		type;
	PGNode	   *query;			/* the query (see comments above) */
	PGIntoClause *into;			/* destination table */
	PGObjectType	relkind;		/* PG_OBJECT_TABLE or PG_OBJECT_MATVIEW */
	bool		is_select_into; /* it was written as SELECT INTO */
	bool		if_not_exists;	/* just do nothing if it already exists? */
} PGCreateTableAsStmt;

/* ----------------------
 * Checkpoint Statement
 * ----------------------
 */
typedef struct PGCheckPointStmt
{
	PGNodeTag		type;
} PGCheckPointStmt;

/* ----------------------
 *		PREPARE Statement
 * ----------------------
 */
typedef struct PGPrepareStmt
{
	PGNodeTag		type;
	char	   *name;			/* Name of plan, arbitrary */
	PGList	   *argtypes;		/* Types of parameters (PGList of PGTypeName) */
	PGNode	   *query;			/* The query itself (as a raw parsetree) */
} PGPrepareStmt;


/* ----------------------
 *		EXECUTE Statement
 * ----------------------
 */

typedef struct PGExecuteStmt
{
	PGNodeTag		type;
	char	   *name;			/* The name of the plan to execute */
	PGList	   *params;			/* Values to assign to parameters */
} PGExecuteStmt;


/* ----------------------
 *		DEALLOCATE Statement
 * ----------------------
 */
typedef struct PGDeallocateStmt
{
	PGNodeTag		type;
	char	   *name;			/* The name of the plan to remove */
	/* NULL means DEALLOCATE ALL */
} PGDeallocateStmt;


/* ----------------------
 * PRAGMA statements
 * Three types of pragma statements:
 * PRAGMA pragma_name;          (NOTHING)
 * PRAGMA pragma_name='param';  (ASSIGNMENT)
 * PRAGMA pragma_name('param'); (CALL)
 * ----------------------
 */
typedef enum
	{
	PG_PRAGMA_TYPE_NOTHING,
	PG_PRAGMA_TYPE_ASSIGNMENT,
	PG_PRAGMA_TYPE_CALL
} PGPragmaKind;

typedef struct PGPragmaStmt
{
	PGNodeTag		type;
	PGPragmaKind kind;
	char	   *name;			/* variable to be set */
	PGList	   *args;			/* PGList of PGAConst nodes */
} PGPragmaStmt;


namespace duckdb {

class ColumnDefinition;
struct OrderByNode;

//! The transformer class is responsible for transforming the internal Postgres
//! parser representation into the DuckDB representation
class Transformer {
public:
	//! Transforms a Postgres parse tree into a set of SQL Statements
	bool TransformParseTree(PGList *tree, vector<unique_ptr<SQLStatement>> &statements);
	string NodetypeToString(PGNodeTag type);

	idx_t prepared_statement_parameter_index = 0;

private:
	//! Transforms a Postgres statement into a single SQL statement
	unique_ptr<SQLStatement> TransformStatement(PGNode *stmt);
	//===--------------------------------------------------------------------===//
	// Statement transformation
	//===--------------------------------------------------------------------===//
	//! Transform a Postgres T_PGSelectStmt node into a SelectStatement
	unique_ptr<SelectStatement> TransformSelect(PGNode *node);
	//! Transform a Postgres T_AlterStmt node into a AlterTableStatement
	unique_ptr<AlterTableStatement> TransformAlter(PGNode *node);
	//! Transform a Postgres T_PGRenameStmt node into a RenameStatement
	unique_ptr<AlterTableStatement> TransformRename(PGNode *node);
	//! Transform a Postgres T_PGCreateStmt node into a CreateStatement
	unique_ptr<CreateStatement> TransformCreateTable(PGNode *node);
	//! Transform a Postgres T_PGCreateStmt node into a CreateStatement
	unique_ptr<CreateStatement> TransformCreateTableAs(PGNode *node);
	//! Transform a Postgres node into a CreateStatement
	unique_ptr<CreateStatement> TransformCreateSchema(PGNode *node);
	//! Transform a Postgres T_PGCreateSeqStmt node into a CreateStatement
	unique_ptr<CreateStatement> TransformCreateSequence(PGNode *node);
	//! Transform a Postgres T_PGViewStmt node into a CreateStatement
	unique_ptr<CreateStatement> TransformCreateView(PGNode *node);
	//! Transform a Postgres T_PGIndexStmt node into CreateStatement
	unique_ptr<CreateStatement> TransformCreateIndex(PGNode *node);
	//! Transform a Postgres T_PGDropStmt node into a Drop[Table,Schema]Statement
	unique_ptr<SQLStatement> TransformDrop(PGNode *node);
	//! Transform a Postgres T_PGInsertStmt node into a InsertStatement
	unique_ptr<InsertStatement> TransformInsert(PGNode *node);
	//! Transform a Postgres T_PGCopyStmt node into a CopyStatement
	unique_ptr<CopyStatement> TransformCopy(PGNode *node);
	//! Transform a Postgres T_PGTransactionStmt node into a TransactionStatement
	unique_ptr<TransactionStatement> TransformTransaction(PGNode *node);
	//! Transform a Postgres T_DeleteStatement node into a DeleteStatement
	unique_ptr<DeleteStatement> TransformDelete(PGNode *node);
	//! Transform a Postgres T_PGUpdateStmt node into a UpdateStatement
	unique_ptr<UpdateStatement> TransformUpdate(PGNode *node);
	//! Transform a Postgres T_PGPragmaStmt node into a PragmaStatement
	unique_ptr<PragmaStatement> TransformPragma(PGNode *node);
	unique_ptr<ExplainStatement> TransformExplain(PGNode *node);
	unique_ptr<VacuumStatement> TransformVacuum(PGNode *node);

	unique_ptr<PrepareStatement> TransformPrepare(PGNode *node);
	unique_ptr<ExecuteStatement> TransformExecute(PGNode *node);
	unique_ptr<DropStatement> TransformDeallocate(PGNode *node);

	//===--------------------------------------------------------------------===//
	// Query Node Transform
	//===--------------------------------------------------------------------===//
	//! Transform a Postgres T_PGSelectStmt node into a QueryNode
	unique_ptr<QueryNode> TransformSelectNode(PGSelectStmt *node);

	//===--------------------------------------------------------------------===//
	// Expression Transform
	//===--------------------------------------------------------------------===//
	//! Transform a Postgres boolean expression into an Expression
	unique_ptr<ParsedExpression> TransformBoolExpr(PGBoolExpr *root);
	//! Transform a Postgres case expression into an Expression
	unique_ptr<ParsedExpression> TransformCase(PGCaseExpr *root);
	//! Transform a Postgres type cast into an Expression
	unique_ptr<ParsedExpression> TransformTypeCast(PGTypeCast *root);
	//! Transform a Postgres coalesce into an Expression
	unique_ptr<ParsedExpression> TransformCoalesce(PGAExpr *root);
	//! Transform a Postgres column reference into an Expression
	unique_ptr<ParsedExpression> TransformColumnRef(PGColumnRef *root);
	//! Transform a Postgres constant value into an Expression
	unique_ptr<ParsedExpression> TransformValue(PGValue val);
	//! Transform a Postgres operator into an Expression
	unique_ptr<ParsedExpression> TransformAExpr(PGAExpr *root);
	//! Transform a Postgres abstract expression into an Expression
	unique_ptr<ParsedExpression> TransformExpression(PGNode *node);
	//! Transform a Postgres function call into an Expression
	unique_ptr<ParsedExpression> TransformFuncCall(PGFuncCall *root);

	//! Transform a Postgres constant value into an Expression
	unique_ptr<ParsedExpression> TransformConstant(PGAConst *c);

	unique_ptr<ParsedExpression> TransformResTarget(PGResTarget *root);
	unique_ptr<ParsedExpression> TransformNullTest(PGNullTest *root);
	unique_ptr<ParsedExpression> TransformParamRef(PGParamRef *node);
	unique_ptr<ParsedExpression> TransformNamedArg(PGNamedArgExpr *root);

	unique_ptr<ParsedExpression> TransformSQLValueFunction(PGSQLValueFunction *node);

	unique_ptr<ParsedExpression> TransformSubquery(PGSubLink *root);
	//===--------------------------------------------------------------------===//
	// Constraints transform
	//===--------------------------------------------------------------------===//
	unique_ptr<Constraint> TransformConstraint(PGListCell *cell);

	unique_ptr<Constraint> TransformConstraint(PGListCell *cell, ColumnDefinition &column, idx_t index);

	//===--------------------------------------------------------------------===//
	// Helpers
	//===--------------------------------------------------------------------===//
	string TransformAlias(PGAlias *root);
	void TransformCTE(PGWithClause *de_with_clause, SelectStatement &select);
	unique_ptr<QueryNode> TransformRecursiveCTE(PGCommonTableExpr *node);
	// Operator String to ExpressionType (e.g. + => OPERATOR_ADD)
	ExpressionType OperatorToExpressionType(string &op);

	unique_ptr<ParsedExpression> TransformUnaryOperator(string op, unique_ptr<ParsedExpression> child);
	unique_ptr<ParsedExpression> TransformBinaryOperator(string op, unique_ptr<ParsedExpression> left,
	                                                     unique_ptr<ParsedExpression> right);
	//===--------------------------------------------------------------------===//
	// TableRef transform
	//===--------------------------------------------------------------------===//
	//! Transform a Postgres node into a TableRef
	unique_ptr<TableRef> TransformTableRefNode(PGNode *node);
	//! Transform a Postgres FROM clause into a TableRef
	unique_ptr<TableRef> TransformFrom(PGList *root);
	//! Transform a Postgres table reference into a TableRef
	unique_ptr<TableRef> TransformRangeVar(PGRangeVar *root);
	//! Transform a Postgres table-producing function into a TableRef
	unique_ptr<TableRef> TransformRangeFunction(PGRangeFunction *root);
	//! Transform a Postgres join node into a TableRef
	unique_ptr<TableRef> TransformJoin(PGJoinExpr *root);
	//! Transform a table producing subquery into a TableRef
	unique_ptr<TableRef> TransformRangeSubselect(PGRangeSubselect *root);
	//! Transform a VALUES list into a set of expressions
	unique_ptr<TableRef> TransformValuesList(PGList *list);

	//! Transform a Postgres TypeName string into a SQLType
	SQLType TransformTypeName(PGTypeName *name);

	//! Transform a Postgres GROUP BY expression into a list of Expression
	bool TransformGroupBy(PGList *group, vector<unique_ptr<ParsedExpression>> &result);
	//! Transform a Postgres ORDER BY expression into an OrderByDescription
	bool TransformOrderBy(PGList *order, vector<OrderByNode> &result);

	//! Transform a Postgres SELECT clause into a list of Expressions
	bool TransformExpressionList(PGList *list, vector<unique_ptr<ParsedExpression>> &result);

	void TransformWindowDef(PGWindowDef *window_spec, WindowExpression *expr);

	//! Holds window expressions defined by name. We need those when transforming the expressions referring to them.
	unordered_map<string, PGWindowDef *> window_clauses;
};

} // namespace duckdb



#include <string>


namespace duckdb {
class PostgresParser {
public:
	PostgresParser();
	void Parse(std::string query);
	~PostgresParser();

	bool success;
	PGList *parse_tree;
	std::string error_message;
	int error_location;
};
}


/*-------------------------------------------------------------------------
 *
 * parser.h
 *		Definitions for the "raw" parser (flex and bison phases only)
 *
 * This is the external API for the raw lexing/parsing functions.
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/parser.h
 *
 *-------------------------------------------------------------------------
 */





typedef enum PGBackslashQuoteType
{
	PG_BACKSLASH_QUOTE_OFF,
	PG_BACKSLASH_QUOTE_ON,
	PG_BACKSLASH_QUOTE_SAFE_ENCODING
} PGBackslashQuoteType;

/* GUC variables in scan.l (every one of these is a bad idea :-() */
extern __thread  int backslash_quote;
extern __thread  bool escape_string_warning;
extern __thread  bool standard_conforming_strings;

/* Primary entry point for the raw parsing functions */
extern PGList *raw_parser(const char *str);

/* Utility functions exported by gram.y (perhaps these should be elsewhere) */
extern PGList *SystemFuncName(const char *name);
extern PGTypeName *SystemTypeName(const char *name);



using namespace duckdb;
using namespace std;

Parser::Parser() {
}

void Parser::ParseQuery(string query) {
	PostgresParser parser;
	parser.Parse(query);

	if (!parser.success) {
		throw ParserException("%s [%d]", parser.error_message.c_str(), parser.error_location);
	}

	if (!parser.parse_tree) {
		// empty statement
		return;
	}

	// if it succeeded, we transform the Postgres parse tree into a list of
	// SQLStatements
	Transformer transformer;
	transformer.TransformParseTree(parser.parse_tree, statements);
	n_prepared_parameters = transformer.prepared_statement_parameter_index;

	if (statements.size() > 0) {
		auto &last_statement = statements.back();
		last_statement->stmt_length = query.size() - last_statement->stmt_location;
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/query_node/recursive_cte_node.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

    class RecursiveCTENode : public QueryNode {
    public:
        RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
        }

        string ctename;
        bool union_all;
        //! The left side of the set operation
        unique_ptr<QueryNode> left;
        //! The right side of the set operation
        unique_ptr<QueryNode> right;

        const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
            return left->GetSelectList();
        }

    public:
        bool Equals(const QueryNode *other) const override;
        //! Create a copy of this SelectNode
        unique_ptr<QueryNode> Copy() override;

        //! Serializes a SelectNode to a stand-alone binary blob
        void Serialize(Serializer &serializer) override;
        //! Deserializes a blob back into a SelectNode
        static unique_ptr<QueryNode> Deserialize(Deserializer &source);
    };

}; // namespace duckdb


using namespace duckdb;
using namespace std;

bool RecursiveCTENode::Equals(const QueryNode *other_) const {
    if (!QueryNode::Equals(other_)) {
        return false;
    }
    if (this == other_) {
        return true;
    }
    auto other = (RecursiveCTENode *)other_;

    if(other->union_all != union_all) {
        return false;
    }
    if (!left->Equals(other->left.get())) {
        return false;
    }
    if (!right->Equals(other->right.get())) {
        return false;
    }
    return true;
}

unique_ptr<QueryNode> RecursiveCTENode::Copy() {
    auto result = make_unique<RecursiveCTENode>();
    result->ctename = ctename;
    result->union_all = union_all;
    result->left = left->Copy();
    result->right = right->Copy();
    this->CopyProperties(*result);
    return move(result);
}

void RecursiveCTENode::Serialize(Serializer &serializer) {
    QueryNode::Serialize(serializer);
    serializer.WriteString(ctename);
    serializer.WriteString(union_all ? "T" : "F");
    left->Serialize(serializer);
    right->Serialize(serializer);
}

unique_ptr<QueryNode> RecursiveCTENode::Deserialize(Deserializer &source) {
    auto result = make_unique<RecursiveCTENode>();
    result->ctename = source.Read<string>();
    result->union_all = source.Read<string>() == "T" ? true : false;
    result->left = QueryNode::Deserialize(source);
    result->right = QueryNode::Deserialize(source);
    return move(result);
}



using namespace duckdb;
using namespace std;

bool SelectNode::Equals(const QueryNode *other_) const {
	if (!QueryNode::Equals(other_)) {
		return false;
	}
	if (this == other_) {
		return true;
	}
	auto other = (SelectNode *)other_;

	// first check counts of all lists and such
	if (select_distinct != other->select_distinct || orders.size() != other->orders.size()) {
		return false;
	}
	// SELECT
	if (!ExpressionUtil::ListEquals(select_list, other->select_list)) {
		return false;
	}
	// DISTINCT ON
	if (!ExpressionUtil::ListEquals(distinct_on_targets, other->distinct_on_targets)) {
		return false;
	}
	// FROM
	if (from_table) {
		// we have a FROM clause, compare to the other one
		if (!from_table->Equals(other->from_table.get())) {
			return false;
		}
	} else if (other->from_table) {
		// we don't have a FROM clause, if the other statement has one they are
		// not equal
		return false;
	}
	// WHERE
	if (!BaseExpression::Equals(where_clause.get(), other->where_clause.get())) {
		return false;
	}
	// GROUP BY
	if (!ExpressionUtil::ListEquals(groups, other->groups)) {
		return false;
	}

	// HAVING
	if (!BaseExpression::Equals(having.get(), other->having.get())) {
		return false;
	}
	return true;
}

unique_ptr<QueryNode> SelectNode::Copy() {
	auto result = make_unique<SelectNode>();
	for (auto &child : select_list) {
		result->select_list.push_back(child->Copy());
	}
	// distinct on
	for (auto &target : distinct_on_targets) {
		result->distinct_on_targets.push_back(target->Copy());
	}
	result->from_table = from_table ? from_table->Copy() : nullptr;
	result->where_clause = where_clause ? where_clause->Copy() : nullptr;
	// groups
	for (auto &group : groups) {
		result->groups.push_back(group->Copy());
	}
	result->having = having ? having->Copy() : nullptr;
	this->CopyProperties(*result);
	return move(result);
}

void SelectNode::Serialize(Serializer &serializer) {
	QueryNode::Serialize(serializer);
	// select_list
	serializer.WriteList(select_list);
	// distinct on
	serializer.WriteList(distinct_on_targets);
	// from clause
	serializer.WriteOptional(from_table);
	// where_clause
	serializer.WriteOptional(where_clause);
	// group by / having
	serializer.WriteList(groups);
	serializer.WriteOptional(having);
}

unique_ptr<QueryNode> SelectNode::Deserialize(Deserializer &source) {
	auto result = make_unique<SelectNode>();
	// select_list
	source.ReadList<ParsedExpression>(result->select_list);
	// distinct on
	source.ReadList<ParsedExpression>(result->distinct_on_targets);
	// from clause
	result->from_table = source.ReadOptional<TableRef>();
	// where_clause
	result->where_clause = source.ReadOptional<ParsedExpression>();
	// group by / having
	source.ReadList<ParsedExpression>(result->groups);
	result->having = source.ReadOptional<ParsedExpression>();
	return move(result);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/query_node/set_operation_node.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/common/enums/set_operation_type.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

enum class SetOperationType : uint8_t { NONE = 0, UNION = 1, EXCEPT = 2, INTERSECT = 3 };
}





namespace duckdb {

class SetOperationNode : public QueryNode {
public:
	SetOperationNode() : QueryNode(QueryNodeType::SET_OPERATION_NODE) {
	}

	//! The type of set operation
	SetOperationType setop_type = SetOperationType::NONE;
	//! The left side of the set operation
	unique_ptr<QueryNode> left;
	//! The right side of the set operation
	unique_ptr<QueryNode> right;

	const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
		return left->GetSelectList();
	}

public:
	bool Equals(const QueryNode *other) const override;
	//! Create a copy of this SelectNode
	unique_ptr<QueryNode> Copy() override;

	//! Serializes a SelectNode to a stand-alone binary blob
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a SelectNode
	static unique_ptr<QueryNode> Deserialize(Deserializer &source);
};

}; // namespace duckdb


using namespace duckdb;
using namespace std;

bool SetOperationNode::Equals(const QueryNode *other_) const {
	if (!QueryNode::Equals(other_)) {
		return false;
	}
	if (this == other_) {
		return true;
	}
	auto other = (SetOperationNode *)other_;
	if (setop_type != other->setop_type) {
		return false;
	}
	if (!left->Equals(other->left.get())) {
		return false;
	}
	if (!right->Equals(other->right.get())) {
		return false;
	}
	return true;
}

unique_ptr<QueryNode> SetOperationNode::Copy() {
	auto result = make_unique<SetOperationNode>();
	result->setop_type = setop_type;
	result->left = left->Copy();
	result->right = right->Copy();
	this->CopyProperties(*result);
	return move(result);
}

void SetOperationNode::Serialize(Serializer &serializer) {
	QueryNode::Serialize(serializer);
	serializer.Write<SetOperationType>(setop_type);
	left->Serialize(serializer);
	right->Serialize(serializer);
}

unique_ptr<QueryNode> SetOperationNode::Deserialize(Deserializer &source) {
	auto result = make_unique<SetOperationNode>();
	result->setop_type = source.Read<SetOperationType>();
	result->left = QueryNode::Deserialize(source);
	result->right = QueryNode::Deserialize(source);
	return move(result);
}






using namespace duckdb;
using namespace std;

bool QueryNode::Equals(const QueryNode *other) const {
	if (!other) {
		return false;
	}
	if (this == other) {
		return true;
	}
	if (other->type != this->type) {
		return false;
	}
	if (select_distinct != other->select_distinct) {
		return false;
	}
	if (!BaseExpression::Equals(limit.get(), other->limit.get())) {
		return false;
	}
	if (!BaseExpression::Equals(offset.get(), other->offset.get())) {
		return false;
	}
	if (orders.size() != other->orders.size()) {
		return false;
	}
	for (idx_t i = 0; i < orders.size(); i++) {
		if (orders[i].type != other->orders[i].type ||
		    !orders[i].expression->Equals(other->orders[i].expression.get())) {
			return false;
		}
	}
	return other->type == type;
}

void QueryNode::CopyProperties(QueryNode &other) {
	other.select_distinct = select_distinct;
	// order
	for (auto &order : orders) {
		other.orders.push_back(OrderByNode(order.type, order.expression->Copy()));
	}
	// limit
	other.limit = limit ? limit->Copy() : nullptr;
	other.offset = offset ? offset->Copy() : nullptr;
}

void QueryNode::Serialize(Serializer &serializer) {
	serializer.Write<QueryNodeType>(type);
	serializer.Write<bool>(select_distinct);
	serializer.WriteOptional(limit);
	serializer.WriteOptional(offset);
	serializer.Write<idx_t>(orders.size());
	for (idx_t i = 0; i < orders.size(); i++) {
		serializer.Write<OrderType>(orders[i].type);
		orders[i].expression->Serialize(serializer);
	}
}

unique_ptr<QueryNode> QueryNode::Deserialize(Deserializer &source) {
	unique_ptr<QueryNode> result;
	auto type = source.Read<QueryNodeType>();
	auto select_distinct = source.Read<bool>();
	auto limit = source.ReadOptional<ParsedExpression>();
	auto offset = source.ReadOptional<ParsedExpression>();
	idx_t order_count = source.Read<idx_t>();
	vector<OrderByNode> orders;
	for (idx_t i = 0; i < order_count; i++) {
		OrderByNode node;
		node.type = source.Read<OrderType>();
		node.expression = ParsedExpression::Deserialize(source);
		orders.push_back(move(node));
	}
	switch (type) {
	case QueryNodeType::SELECT_NODE:
		result = SelectNode::Deserialize(source);
		break;
	case QueryNodeType::SET_OPERATION_NODE:
		result = SetOperationNode::Deserialize(source);
		break;
	case QueryNodeType::RECURSIVE_CTE_NODE:
		result = RecursiveCTENode::Deserialize(source);
		break;
	default:
		throw SerializationException("Could not deserialize Query Node: unknown type!");
	}
	result->select_distinct = select_distinct;
	result->limit = move(limit);
	result->offset = move(offset);
	result->orders = move(orders);
	return result;
}





using namespace duckdb;
using namespace std;

unique_ptr<SelectStatement> SelectStatement::Copy() {
	auto result = make_unique<SelectStatement>();
	for (auto &cte : cte_map) {
		result->cte_map[cte.first] = cte.second->Copy();
	}
	result->node = node->Copy();
	return result;
}

void SelectStatement::Serialize(Serializer &serializer) {
	// with clauses
	assert(cte_map.size() <= numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)cte_map.size());
	for (auto &cte : cte_map) {
		serializer.WriteString(cte.first);
		cte.second->Serialize(serializer);
	}
	node->Serialize(serializer);
}

unique_ptr<SelectStatement> SelectStatement::Deserialize(Deserializer &source) {
	auto result = make_unique<SelectStatement>();
	auto cte_count = source.Read<uint32_t>();
	for (idx_t i = 0; i < cte_count; i++) {
		auto name = source.Read<string>();
		auto statement = QueryNode::Deserialize(source);
		result->cte_map[name] = move(statement);
	}
	result->node = QueryNode::Deserialize(source);
	return result;
}

bool SelectStatement::Equals(const SQLStatement *other_) const {
	if (type != other_->type) {
		return false;
	}
	auto other = (SelectStatement *)other_;
	// WITH clauses (CTEs)
	if (cte_map.size() != other->cte_map.size()) {
		return false;
	}
	for (auto &entry : cte_map) {
		auto other_entry = other->cte_map.find(entry.first);
		if (other_entry == other->cte_map.end()) {
			return false;
		}
		if (!entry.second->Equals(other_entry->second.get())) {
			return false;
		}
	}
	return node->Equals(other->node.get());
}




using namespace duckdb;
using namespace std;

bool BaseTableRef::Equals(const TableRef *other_) const {
	if (!TableRef::Equals(other_)) {
		return false;
	}
	auto other = (BaseTableRef *)other_;
	return other->schema_name == schema_name && other->table_name == table_name;
}

void BaseTableRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);

	serializer.WriteString(schema_name);
	serializer.WriteString(table_name);
}

unique_ptr<TableRef> BaseTableRef::Deserialize(Deserializer &source) {
	auto result = make_unique<BaseTableRef>();

	result->schema_name = source.Read<string>();
	result->table_name = source.Read<string>();

	return move(result);
}

unique_ptr<TableRef> BaseTableRef::Copy() {
	auto copy = make_unique<BaseTableRef>();

	copy->schema_name = schema_name;
	copy->table_name = table_name;
	copy->alias = alias;

	return move(copy);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/crossproductref.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents a cross product
class CrossProductRef : public TableRef {
public:
	CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) {
	}

	//! The left hand side of the cross product
	unique_ptr<TableRef> left;
	//! The right hand side of the cross product
	unique_ptr<TableRef> right;

public:
	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a CrossProductRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a CrossProductRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

bool CrossProductRef::Equals(const TableRef *other_) const {
	if (!TableRef::Equals(other_)) {
		return false;
	}
	auto other = (CrossProductRef *)other_;
	return left->Equals(other->left.get()) && right->Equals(other->right.get());
}

unique_ptr<TableRef> CrossProductRef::Copy() {
	auto copy = make_unique<CrossProductRef>();
	copy->left = left->Copy();
	copy->right = right->Copy();
	copy->alias = alias;
	return move(copy);
}

void CrossProductRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);

	left->Serialize(serializer);
	right->Serialize(serializer);
}

unique_ptr<TableRef> CrossProductRef::Deserialize(Deserializer &source) {
	auto result = make_unique<CrossProductRef>();

	result->left = TableRef::Deserialize(source);
	result->right = TableRef::Deserialize(source);

	if (!result->left || !result->right) {
		return nullptr;
	}

	return move(result);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/emptytableref.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Represents a cross product
class EmptyTableRef : public TableRef {
public:
	EmptyTableRef() : TableRef(TableReferenceType::EMPTY) {
	}

public:
	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a DummyTableRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a DummyTableRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

bool EmptyTableRef::Equals(const TableRef *other) const {
	return TableRef::Equals(other);
}

unique_ptr<TableRef> EmptyTableRef::Copy() {
	return make_unique<EmptyTableRef>();
}

void EmptyTableRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);
}

unique_ptr<TableRef> EmptyTableRef::Deserialize(Deserializer &source) {
	return make_unique<EmptyTableRef>();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/expressionlistref.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Represents an expression list as generated by a VALUES statement
class ExpressionListRef : public TableRef {
public:
	ExpressionListRef() : TableRef(TableReferenceType::EXPRESSION_LIST) {
	}

	//! Value list, only used for VALUES statement
	vector<vector<unique_ptr<ParsedExpression>>> values;
	//! Expected SQL types
	vector<SQLType> expected_types;
	//! The set of expected names
	vector<string> expected_names;

public:
	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a ExpressionListRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a ExpressionListRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

bool ExpressionListRef::Equals(const TableRef *other_) const {
	if (!TableRef::Equals(other_)) {
		return false;
	}
	auto other = (ExpressionListRef *)other_;
	if (values.size() != other->values.size()) {
		return false;
	}
	for (idx_t i = 0; i < values.size(); i++) {
		if (values[i].size() != other->values[i].size()) {
			return false;
		}
		for (idx_t j = 0; j < values[i].size(); j++) {
			if (!values[i][j]->Equals(other->values[i][j].get())) {
				return false;
			}
		}
	}
	return true;
}

unique_ptr<TableRef> ExpressionListRef::Copy() {
	// value list
	auto result = make_unique<ExpressionListRef>();
	for (auto &val_list : values) {
		vector<unique_ptr<ParsedExpression>> new_val_list;
		for (auto &val : val_list) {
			new_val_list.push_back(val->Copy());
		}
		result->values.push_back(move(new_val_list));
	}
	result->alias = alias;
	return move(result);
}

void ExpressionListRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);
	serializer.Write<idx_t>(values.size());
	for (idx_t i = 0; i < values.size(); i++) {
		serializer.WriteList(values[i]);
	}
}

unique_ptr<TableRef> ExpressionListRef::Deserialize(Deserializer &source) {
	auto result = make_unique<ExpressionListRef>();
	// value list
	idx_t value_list_size = source.Read<idx_t>();
	for (idx_t i = 0; i < value_list_size; i++) {
		vector<unique_ptr<ParsedExpression>> value_list;
		source.ReadList<ParsedExpression>(value_list);
		result->values.push_back(move(value_list));
	}
	return move(result);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/joinref.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
//! Represents a JOIN between two expressions
class JoinRef : public TableRef {
public:
	JoinRef() : TableRef(TableReferenceType::JOIN) {
	}

	//! The left hand side of the join
	unique_ptr<TableRef> left;
	//! The right hand side of the join
	unique_ptr<TableRef> right;
	//! The join condition
	unique_ptr<ParsedExpression> condition;
	//! The join type
	JoinType type;
	//! Columns hidden from SELECT * expansion (because of USING clause)
	unordered_set<string> hidden_columns;

public:
	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a JoinRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a JoinRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

bool JoinRef::Equals(const TableRef *other_) const {
	if (!TableRef::Equals(other_)) {
		return false;
	}
	auto other = (JoinRef *)other_;
	return left->Equals(other->left.get()) && right->Equals(other->right.get()) &&
	       condition->Equals(other->condition.get()) && type == other->type;
}

unique_ptr<TableRef> JoinRef::Copy() {
	auto copy = make_unique<JoinRef>();
	copy->left = left->Copy();
	copy->right = right->Copy();
	copy->condition = condition->Copy();
	copy->type = type;
	copy->alias = alias;
	copy->hidden_columns = hidden_columns;
	return move(copy);
}

void JoinRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);

	left->Serialize(serializer);
	right->Serialize(serializer);
	condition->Serialize(serializer);
	serializer.Write<JoinType>(type);
	assert(hidden_columns.size() <= numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)hidden_columns.size());
	for (auto &hidden_column : hidden_columns) {
		serializer.WriteString(hidden_column);
	}
}

unique_ptr<TableRef> JoinRef::Deserialize(Deserializer &source) {
	auto result = make_unique<JoinRef>();

	result->left = TableRef::Deserialize(source);
	result->right = TableRef::Deserialize(source);
	result->condition = ParsedExpression::Deserialize(source);
	result->type = source.Read<JoinType>();
	auto count = source.Read<uint32_t>();
	for (idx_t i = 0; i < count; i++) {
		result->hidden_columns.insert(source.Read<string>());
	}
	return move(result);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/tableref/subqueryref.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Represents a subquery
class SubqueryRef : public TableRef {
public:
	SubqueryRef(unique_ptr<QueryNode> subquery);

	//! The subquery
	unique_ptr<QueryNode> subquery;
	//! Alises for the column names
	vector<string> column_name_alias;

public:
	bool Equals(const TableRef *other_) const override;

	unique_ptr<TableRef> Copy() override;

	//! Serializes a blob into a SubqueryRef
	void Serialize(Serializer &serializer) override;
	//! Deserializes a blob back into a SubqueryRef
	static unique_ptr<TableRef> Deserialize(Deserializer &source);
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

SubqueryRef::SubqueryRef(unique_ptr<QueryNode> subquery_)
    : TableRef(TableReferenceType::SUBQUERY), subquery(move(subquery_)) {
}

bool SubqueryRef::Equals(const TableRef *other_) const {
	if (!TableRef::Equals(other_)) {
		return false;
	}
	auto other = (SubqueryRef *)other_;
	return subquery->Equals(other->subquery.get());
}

unique_ptr<TableRef> SubqueryRef::Copy() {
	auto copy = make_unique<SubqueryRef>(subquery->Copy());
	copy->alias = alias;
	copy->column_name_alias = column_name_alias;
	return move(copy);
}

void SubqueryRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);
	subquery->Serialize(serializer);
	assert(column_name_alias.size() <= numeric_limits<uint32_t>::max());
	serializer.Write<uint32_t>((uint32_t)column_name_alias.size());
	for (auto &alias : column_name_alias) {
		serializer.WriteString(alias);
	}
}

unique_ptr<TableRef> SubqueryRef::Deserialize(Deserializer &source) {
	auto subquery = QueryNode::Deserialize(source);
	if (!subquery) {
		return nullptr;
	}
	auto result = make_unique<SubqueryRef>(move(subquery));
	idx_t column_count = (idx_t)source.Read<uint32_t>();
	for (idx_t i = 0; i < column_count; i++) {
		result->column_name_alias.push_back(source.Read<string>());
	}
	return move(result);
}




using namespace duckdb;
using namespace std;

bool TableFunctionRef::Equals(const TableRef *other_) const {
	if (!TableRef::Equals(other_)) {
		return false;
	}
	auto other = (TableFunctionRef *)other_;
	return function->Equals(other->function.get());
}

void TableFunctionRef::Serialize(Serializer &serializer) {
	TableRef::Serialize(serializer);
	function->Serialize(serializer);
}

unique_ptr<TableRef> TableFunctionRef::Deserialize(Deserializer &source) {
	auto result = make_unique<TableFunctionRef>();

	result->function = ParsedExpression::Deserialize(source);

	return move(result);
}

unique_ptr<TableRef> TableFunctionRef::Copy() {
	auto copy = make_unique<TableFunctionRef>();

	copy->function = function->Copy();
	copy->alias = alias;

	return move(copy);
}













using namespace duckdb;
using namespace std;

void TableRef::Serialize(Serializer &serializer) {
	serializer.Write<TableReferenceType>(type);
	serializer.WriteString(alias);
}

//! Deserializes a blob back into an TableRef
unique_ptr<TableRef> TableRef::Deserialize(Deserializer &source) {
	auto type = source.Read<TableReferenceType>();
	auto alias = source.Read<string>();
	unique_ptr<TableRef> result;
	switch (type) {
	case TableReferenceType::BASE_TABLE:
		result = BaseTableRef::Deserialize(source);
		break;
	case TableReferenceType::CROSS_PRODUCT:
		result = CrossProductRef::Deserialize(source);
		break;
	case TableReferenceType::JOIN:
		result = JoinRef::Deserialize(source);
		break;
	case TableReferenceType::SUBQUERY:
		result = SubqueryRef::Deserialize(source);
		break;
	case TableReferenceType::TABLE_FUNCTION:
		result = TableFunctionRef::Deserialize(source);
		break;
	case TableReferenceType::EMPTY:
		result = EmptyTableRef::Deserialize(source);
		break;
	case TableReferenceType::EXPRESSION_LIST:
		result = ExpressionListRef::Deserialize(source);
		break;
    case TableReferenceType::CTE:
	case TableReferenceType::INVALID:
		return nullptr;
	}
	result->alias = alias;
	return result;
}

void TableRef::Print() {
	Printer::Print(ToString());
}





using namespace duckdb;
using namespace std;

unique_ptr<Constraint> Transformer::TransformConstraint(PGListCell *cell) {
	auto constraint = reinterpret_cast<PGConstraint *>(cell->data.ptr_value);
	switch (constraint->contype) {
	case PG_CONSTR_UNIQUE:
	case PG_CONSTR_PRIMARY: {
		bool is_primary_key = constraint->contype == PG_CONSTR_PRIMARY;
		vector<string> columns;
		for (auto kc = constraint->keys->head; kc; kc = kc->next) {
			columns.push_back(string(reinterpret_cast<PGValue *>(kc->data.ptr_value)->val.str));
		}
		return make_unique<UniqueConstraint>(columns, is_primary_key);
	}
	default:
		throw NotImplementedException("Constraint type not handled yet!");
	}
}

unique_ptr<Constraint> Transformer::TransformConstraint(PGListCell *cell, ColumnDefinition &column, idx_t index) {
	auto constraint = reinterpret_cast<PGConstraint *>(cell->data.ptr_value);
	assert(constraint);
	switch (constraint->contype) {
	case PG_CONSTR_NOTNULL:
		return make_unique<NotNullConstraint>(index);
	case PG_CONSTR_CHECK: {
		auto expression = TransformExpression(constraint->raw_expr);
		if (expression->HasSubquery()) {
			throw ParserException("subqueries prohibited in CHECK constraints");
		}
		if (expression->IsAggregate()) {
			throw ParserException("aggregates prohibited in CHECK constraints");
		}
		return make_unique<CheckConstraint>(TransformExpression(constraint->raw_expr));
	}
	case PG_CONSTR_PRIMARY:
		return make_unique<UniqueConstraint>(index, true);
	case PG_CONSTR_UNIQUE:
		return make_unique<UniqueConstraint>(index, false);
	case PG_CONSTR_NULL:
		return nullptr;
	case PG_CONSTR_DEFAULT:
		column.default_value = TransformExpression(constraint->raw_expr);
		return nullptr;
	case PG_CONSTR_FOREIGN:
	default:
		throw NotImplementedException("Constraint not implemented!");
	}
}




using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformBoolExpr(PGBoolExpr *root) {
	unique_ptr<ParsedExpression> result;
	for (auto node = root->args->head; node != nullptr; node = node->next) {
		auto next = TransformExpression(reinterpret_cast<PGNode *>(node->data.ptr_value));

		switch (root->boolop) {
		case PG_AND_EXPR: {
			if (!result) {
				result = move(next);
			} else {
				result = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_AND, move(result), move(next));
			}
			break;
		}
		case PG_OR_EXPR: {
			if (!result) {
				result = move(next);
			} else {
				result = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_OR, move(result), move(next));
			}
			break;
		}
		case PG_NOT_EXPR: {
			if (next->type == ExpressionType::COMPARE_IN) {
				// convert COMPARE_IN to COMPARE_NOT_IN
				next->type = ExpressionType::COMPARE_NOT_IN;
				result = move(next);
			} else {
				result = make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(next));
			}
			break;
		}
		}
	}
	return result;
}





using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformCase(PGCaseExpr *root) {
	if (!root) {
		return nullptr;
	}
	// CASE expression WHEN value THEN result [WHEN ...] ELSE result uses this,
	// but we rewrite to CASE WHEN expression = value THEN result ... to only
	// have to handle one case downstream.

	unique_ptr<ParsedExpression> def_res;
	if (root->defresult) {
		def_res = TransformExpression(reinterpret_cast<PGNode *>(root->defresult));
	} else {
		def_res = make_unique<ConstantExpression>(SQLType::SQLNULL, Value());
	}
	// def_res will be the else part of the innermost case expression

	// CASE WHEN e1 THEN r1 WHEN w2 THEN r2 ELSE r3 is rewritten to
	// CASE WHEN e1 THEN r1 ELSE CASE WHEN e2 THEN r2 ELSE r3

	auto exp_root = make_unique<CaseExpression>();
	auto cur_root = exp_root.get();
	for (auto cell = root->args->head; cell != nullptr; cell = cell->next) {
		auto w = reinterpret_cast<PGCaseWhen *>(cell->data.ptr_value);
		auto test_raw = TransformExpression(reinterpret_cast<PGNode *>(w->expr));
		unique_ptr<ParsedExpression> test;
		auto arg = TransformExpression(reinterpret_cast<PGNode *>(root->arg));
		if (arg) {
			test = make_unique<ComparisonExpression>(ExpressionType::COMPARE_EQUAL, move(arg), move(test_raw));
		} else {
			test = move(test_raw);
		}

		cur_root->check = move(test);
		cur_root->result_if_true = TransformExpression(reinterpret_cast<PGNode *>(w->result));
		if (cell->next == nullptr) {
			// finished all cases
			// res_false is the default result
			cur_root->result_if_false = move(def_res);
		} else {
			// more cases remain, create a case statement within the FALSE branch
			auto next_case = make_unique<CaseExpression>();
			auto case_ptr = next_case.get();
			cur_root->result_if_false = move(next_case);
			cur_root = case_ptr;
		}
	}

	return move(exp_root);
}





using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformTypeCast(PGTypeCast *root) {
	if (!root) {
		return nullptr;
	}
	// get the type to cast to
	auto type_name = root->typeName;
	SQLType target_type = TransformTypeName(type_name);

	// transform the expression node
	auto expression = TransformExpression(root->arg);
	// now create a cast operation
	return make_unique<CastExpression>(target_type, move(expression));
}




using namespace duckdb;
using namespace std;

// COALESCE(a,b,c) returns the first argument that is NOT NULL, so
// rewrite into CASE(a IS NOT NULL, a, CASE(b IS NOT NULL, b, c))
unique_ptr<ParsedExpression> Transformer::TransformCoalesce(PGAExpr *root) {
	if (!root) {
		return nullptr;
	}
	auto coalesce_args = reinterpret_cast<PGList *>(root->lexpr);

	auto exp_root = make_unique<CaseExpression>();
	auto cur_root = exp_root.get();
	for (auto cell = coalesce_args->head; cell && cell->next; cell = cell->next) {
		// get the value of the COALESCE
		auto value_expr = TransformExpression(reinterpret_cast<PGNode *>(cell->data.ptr_value));
		// perform an IS NOT NULL comparison with the value here
		cur_root->check = make_unique<OperatorExpression>(ExpressionType::OPERATOR_IS_NOT_NULL, value_expr->Copy());
		// if IS NOT NULL, we output the value
		cur_root->result_if_true = move(value_expr);
		if (cell->next->next == nullptr) {
			// if there is no next in the chain, the COALESCE ends there
			cur_root->result_if_false = TransformExpression(reinterpret_cast<PGNode *>(cell->next->data.ptr_value));
		} else {
			// more COALESCE parameters remain, create a nested CASE statement
			auto next_case = make_unique<CaseExpression>();
			auto case_ptr = next_case.get();
			cur_root->result_if_false = move(next_case);
			cur_root = case_ptr;
		}
	}
	return move(exp_root);
}






using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformColumnRef(PGColumnRef *root) {
	auto fields = root->fields;
	switch ((reinterpret_cast<PGNode *>(fields->head->data.ptr_value))->type) {
	case T_PGString: {
		if (fields->length < 1 || fields->length > 2) {
			throw ParserException("Unexpected field length");
		}
		string column_name, table_name;
		if (fields->length == 1) {
			column_name = string(reinterpret_cast<PGValue *>(fields->head->data.ptr_value)->val.str);
			return make_unique<ColumnRefExpression>(column_name, table_name);
		} else {
			table_name = string(reinterpret_cast<PGValue *>(fields->head->data.ptr_value)->val.str);
			auto col_node = reinterpret_cast<PGNode *>(fields->head->next->data.ptr_value);
			switch (col_node->type) {
			case T_PGString: {
				column_name = string(reinterpret_cast<PGValue *>(col_node)->val.str);
				return make_unique<ColumnRefExpression>(column_name, table_name);
			}
			case T_PGAStar: {
				return make_unique<TableStarExpression>(table_name);
			}
			default:
				throw NotImplementedException("ColumnRef not implemented!");
			}
		}
	}
	case T_PGAStar: {
		return make_unique<StarExpression>();
	}
	default:
		break;
	}
	throw NotImplementedException("ColumnRef not implemented!");
}




using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformValue(PGValue val) {
	switch (val.type) {
	case T_PGInteger:
		assert(val.val.ival <= numeric_limits<int32_t>::max());
		return make_unique<ConstantExpression>(SQLType::INTEGER, Value::INTEGER((int32_t)val.val.ival));
	case T_PGBitString: // FIXME: this should actually convert to BLOB
	case T_PGString:
		return make_unique<ConstantExpression>(SQLType::VARCHAR, Value(string(val.val.str)));
	case T_PGFloat: {
		bool cast_as_double = false;
		for (auto ptr = val.val.str; *ptr; ptr++) {
			if (*ptr == '.') {
				// found decimal point, cast as double
				cast_as_double = true;
				break;
			}
		}
		int64_t value;
		if (!cast_as_double && TryCast::Operation<string_t, int64_t>(string_t(val.val.str), value)) {
			// successfully cast to bigint: bigint value
			return make_unique<ConstantExpression>(SQLType::BIGINT, Value::BIGINT(value));
		} else {
			// could not cast to bigint: cast to double
			double dbl_value = Cast::Operation<string_t, double>(string_t(val.val.str));
			return make_unique<ConstantExpression>(SQLType::DOUBLE, Value::DOUBLE(dbl_value));
		}
	}
	case T_PGNull:
		return make_unique<ConstantExpression>(SQLType::SQLNULL, Value());
	default:
		throw NotImplementedException("Value not implemented!");
	}
}

unique_ptr<ParsedExpression> Transformer::TransformConstant(PGAConst *c) {
	return TransformValue(c->val);
}




using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformResTarget(PGResTarget *root) {
	if (!root) {
		return nullptr;
	}
	auto expr = TransformExpression(root->val);
	if (!expr) {
		return nullptr;
	}
	if (root->name) {
		expr->alias = string(root->name);
	}
	return expr;
}

unique_ptr<ParsedExpression> Transformer::TransformNamedArg(PGNamedArgExpr *root) {
	if (!root) {
		return nullptr;
	}
	auto expr = TransformExpression((PGNode *)root->arg);
	if (root->name) {
		expr->alias = string(root->name);
	}
	return expr;
}

unique_ptr<ParsedExpression> Transformer::TransformExpression(PGNode *node) {
	if (!node) {
		return nullptr;
	}

	switch (node->type) {
	case T_PGColumnRef:
		return TransformColumnRef(reinterpret_cast<PGColumnRef *>(node));
	case T_PGAConst:
		return TransformConstant(reinterpret_cast<PGAConst *>(node));
	case T_PGAExpr:
		return TransformAExpr(reinterpret_cast<PGAExpr *>(node));
	case T_PGFuncCall:
		return TransformFuncCall(reinterpret_cast<PGFuncCall *>(node));
	case T_PGBoolExpr:
		return TransformBoolExpr(reinterpret_cast<PGBoolExpr *>(node));
	case T_PGTypeCast:
		return TransformTypeCast(reinterpret_cast<PGTypeCast *>(node));
	case T_PGCaseExpr:
		return TransformCase(reinterpret_cast<PGCaseExpr *>(node));
	case T_PGSubLink:
		return TransformSubquery(reinterpret_cast<PGSubLink *>(node));
	case T_PGCoalesceExpr:
		return TransformCoalesce(reinterpret_cast<PGAExpr *>(node));
	case T_PGNullTest:
		return TransformNullTest(reinterpret_cast<PGNullTest *>(node));
	case T_PGResTarget:
		return TransformResTarget(reinterpret_cast<PGResTarget *>(node));
	case T_PGParamRef:
		return TransformParamRef(reinterpret_cast<PGParamRef *>(node));
	case T_PGNamedArgExpr:
		return TransformNamedArg(reinterpret_cast<PGNamedArgExpr *>(node));
	case T_PGSQLValueFunction:
		return TransformSQLValueFunction(reinterpret_cast<PGSQLValueFunction *>(node));
	case T_PGSetToDefault:
		return make_unique<DefaultExpression>();

	default:
		throw NotImplementedException("Expr of type %d not implemented\n", (int)node->type);
	}
}

bool Transformer::TransformExpressionList(PGList *list, vector<unique_ptr<ParsedExpression>> &result) {
	if (!list) {
		return false;
	}
	for (auto node = list->head; node != nullptr; node = node->next) {
		auto target = reinterpret_cast<PGNode *>(node->data.ptr_value);
		if (!target) {
			return false;
		}
		auto expr = TransformExpression(target);
		if (!expr) {
			return false;
		}
		result.push_back(move(expr));
	}
	return true;
}








using namespace duckdb;
using namespace std;

static ExpressionType WindowToExpressionType(string &fun_name) {
	if (fun_name == "rank") {
		return ExpressionType::WINDOW_RANK;
	} else if (fun_name == "rank_dense" || fun_name == "dense_rank") {
		return ExpressionType::WINDOW_RANK_DENSE;
	} else if (fun_name == "percent_rank") {
		return ExpressionType::WINDOW_PERCENT_RANK;
	} else if (fun_name == "row_number") {
		return ExpressionType::WINDOW_ROW_NUMBER;
	} else if (fun_name == "first_value" || fun_name == "first") {
		return ExpressionType::WINDOW_FIRST_VALUE;
	} else if (fun_name == "last_value" || fun_name == "last") {
		return ExpressionType::WINDOW_LAST_VALUE;
	} else if (fun_name == "cume_dist") {
		return ExpressionType::WINDOW_CUME_DIST;
	} else if (fun_name == "lead") {
		return ExpressionType::WINDOW_LEAD;
	} else if (fun_name == "lag") {
		return ExpressionType::WINDOW_LAG;
	} else if (fun_name == "ntile") {
		return ExpressionType::WINDOW_NTILE;
	}

	return ExpressionType::WINDOW_AGGREGATE;
}

void Transformer::TransformWindowDef(PGWindowDef *window_spec, WindowExpression *expr) {
	assert(window_spec);
	assert(expr);

	// next: partitioning/ordering expressions
	TransformExpressionList(window_spec->partitionClause, expr->partitions);
	TransformOrderBy(window_spec->orderClause, expr->orders);

	// finally: specifics of bounds
	expr->start_expr = TransformExpression(window_spec->startOffset);
	expr->end_expr = TransformExpression(window_spec->endOffset);

	if ((window_spec->frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) ||
	    (window_spec->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)) {
		throw Exception(
		    "Window frames starting with unbounded following or ending in unbounded preceding make no sense");
	}

	if (window_spec->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
		expr->start = WindowBoundary::UNBOUNDED_PRECEDING;
	} else if (window_spec->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
		expr->start = WindowBoundary::UNBOUNDED_FOLLOWING;
	} else if (window_spec->frameOptions & FRAMEOPTION_START_VALUE_PRECEDING) {
		expr->start = WindowBoundary::EXPR_PRECEDING;
	} else if (window_spec->frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING) {
		expr->start = WindowBoundary::EXPR_FOLLOWING;
	} else if (window_spec->frameOptions & (FRAMEOPTION_START_CURRENT_ROW | FRAMEOPTION_RANGE)) {
		expr->start = WindowBoundary::CURRENT_ROW_RANGE;
	} else if (window_spec->frameOptions & (FRAMEOPTION_START_CURRENT_ROW | FRAMEOPTION_ROWS)) {
		expr->start = WindowBoundary::CURRENT_ROW_ROWS;
	}

	if (window_spec->frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
		expr->end = WindowBoundary::UNBOUNDED_PRECEDING;
	} else if (window_spec->frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
		expr->end = WindowBoundary::UNBOUNDED_FOLLOWING;
	} else if (window_spec->frameOptions & FRAMEOPTION_END_VALUE_PRECEDING) {
		expr->end = WindowBoundary::EXPR_PRECEDING;
	} else if (window_spec->frameOptions & FRAMEOPTION_END_VALUE_FOLLOWING) {
		expr->end = WindowBoundary::EXPR_FOLLOWING;
	} else if (window_spec->frameOptions & (FRAMEOPTION_END_CURRENT_ROW | FRAMEOPTION_RANGE)) {
		expr->end = WindowBoundary::CURRENT_ROW_RANGE;
	} else if (window_spec->frameOptions & (FRAMEOPTION_END_CURRENT_ROW | FRAMEOPTION_ROWS)) {
		expr->end = WindowBoundary::CURRENT_ROW_ROWS;
	}

	assert(expr->start != WindowBoundary::INVALID && expr->end != WindowBoundary::INVALID);
	if (((expr->start == WindowBoundary::EXPR_PRECEDING || expr->start == WindowBoundary::EXPR_PRECEDING) &&
	     !expr->start_expr) ||
	    ((expr->end == WindowBoundary::EXPR_PRECEDING || expr->end == WindowBoundary::EXPR_PRECEDING) &&
	     !expr->end_expr)) {
		throw Exception("Failed to transform window boundary expression");
	}
}

unique_ptr<ParsedExpression> Transformer::TransformFuncCall(PGFuncCall *root) {
	auto name = root->funcname;
	string schema, function_name;
	if (name->length == 2) {
		// schema + name
		schema = reinterpret_cast<PGValue *>(name->head->data.ptr_value)->val.str;
		function_name = reinterpret_cast<PGValue *>(name->head->next->data.ptr_value)->val.str;
	} else {
		// unqualified name
		schema = DEFAULT_SCHEMA;
		function_name = reinterpret_cast<PGValue *>(name->head->data.ptr_value)->val.str;
	}

	auto lowercase_name = StringUtil::Lower(function_name);

	if (root->agg_filter) {
		throw ParserException("FILTER is not implemented for aggregates");
	}
	if (root->agg_order) {
		throw ParserException("ORDER BY is not implemented for aggregates");
	}

	if (root->over) {
		if (root->agg_distinct) {
			throw ParserException("DISTINCT is not implemented for window functions!");
		}

		auto win_fun_type = WindowToExpressionType(lowercase_name);
		if (win_fun_type == ExpressionType::INVALID) {
			throw Exception("Unknown/unsupported window function");
		}

		auto expr = make_unique<WindowExpression>(win_fun_type, schema, lowercase_name);

		if (root->args) {
			vector<unique_ptr<ParsedExpression>> function_list;
			auto res = TransformExpressionList(root->args, function_list);
			if (!res) {
				throw Exception("Failed to transform window function children");
			}
			if (win_fun_type == ExpressionType::WINDOW_AGGREGATE) {
				for (auto &child : function_list) {
					expr->children.push_back(move(child));
				}
			} else {
				if (function_list.size() > 0) {
					expr->children.push_back(move(function_list[0]));
				}
				if (function_list.size() > 1) {
					assert(win_fun_type == ExpressionType::WINDOW_LEAD || win_fun_type == ExpressionType::WINDOW_LAG);
					expr->offset_expr = move(function_list[1]);
				}
				if (function_list.size() > 2) {
					assert(win_fun_type == ExpressionType::WINDOW_LEAD || win_fun_type == ExpressionType::WINDOW_LAG);
					expr->default_expr = move(function_list[2]);
				}
				assert(function_list.size() <= 3);
			}
		}
		auto window_spec = reinterpret_cast<PGWindowDef *>(root->over);
		if (window_spec->name) {
			auto it = window_clauses.find(StringUtil::Lower(string(window_spec->name)));
			if (it == window_clauses.end()) {
				throw Exception("Could not find named window specification");
			}
			window_spec = it->second;
			assert(window_spec);
		}
		TransformWindowDef(window_spec, expr.get());

		return move(expr);
	}

	vector<unique_ptr<ParsedExpression>> children;
	if (root->args != nullptr) {
		for (auto node = root->args->head; node != nullptr; node = node->next) {
			auto child_expr = TransformExpression((PGNode *)node->data.ptr_value);
			children.push_back(move(child_expr));
		}
	}

	return make_unique<FunctionExpression>(schema, lowercase_name.c_str(), children, root->agg_distinct);
}

static string SQLValueOpToString(PGSQLValueFunctionOp op) {
	switch (op) {
	case PG_SVFOP_CURRENT_DATE:
		return "current_date";
	case PG_SVFOP_CURRENT_TIME:
		return "current_time";
	case PG_SVFOP_CURRENT_TIME_N:
		return "current_time_n";
	case PG_SVFOP_CURRENT_TIMESTAMP:
		return "current_timestamp";
	case PG_SVFOP_CURRENT_TIMESTAMP_N:
		return "current_timestamp_n";
	case PG_SVFOP_LOCALTIME:
		return "current_localtime";
	case PG_SVFOP_LOCALTIME_N:
		return "current_localtime_n";
	case PG_SVFOP_LOCALTIMESTAMP:
		return "current_localtimestamp";
	case PG_SVFOP_LOCALTIMESTAMP_N:
		return "current_localtimestamp_n";
	case PG_SVFOP_CURRENT_ROLE:
		return "current_role";
	case PG_SVFOP_CURRENT_USER:
		return "current_user";
	case PG_SVFOP_USER:
		return "user";
	case PG_SVFOP_SESSION_USER:
		return "session_user";
	case PG_SVFOP_CURRENT_CATALOG:
		return "current_catalog";
	case PG_SVFOP_CURRENT_SCHEMA:
		return "current_schema";
	default:
		throw Exception("Could not find named SQL value function specification " + to_string((int)op));
	}
}

unique_ptr<ParsedExpression> Transformer::TransformSQLValueFunction(PGSQLValueFunction *node) {
	if (!node) {
		return nullptr;
	}
	vector<unique_ptr<ParsedExpression>> children;
	auto fname = SQLValueOpToString(node->op);
	return make_unique<FunctionExpression>(DEFAULT_SCHEMA, fname, children);
}




using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformNullTest(PGNullTest *root) {
	assert(root);
	auto arg = TransformExpression(reinterpret_cast<PGNode *>(root->arg));
	if (root->argisrow) {
		throw NotImplementedException("IS NULL argisrow");
	}
	ExpressionType expr_type =
	    (root->nulltesttype == PG_IS_NULL) ? ExpressionType::OPERATOR_IS_NULL : ExpressionType::OPERATOR_IS_NOT_NULL;

	return unique_ptr<ParsedExpression>(new OperatorExpression(expr_type, move(arg)));
}








using namespace duckdb;
using namespace std;

ExpressionType Transformer::OperatorToExpressionType(string &op) {
	if (op == "=" || op == "==") {
		return ExpressionType::COMPARE_EQUAL;
	} else if (op == "!=" || op == "<>") {
		return ExpressionType::COMPARE_NOTEQUAL;
	} else if (op == "<") {
		return ExpressionType::COMPARE_LESSTHAN;
	} else if (op == ">") {
		return ExpressionType::COMPARE_GREATERTHAN;
	} else if (op == "<=") {
		return ExpressionType::COMPARE_LESSTHANOREQUALTO;
	} else if (op == ">=") {
		return ExpressionType::COMPARE_GREATERTHANOREQUALTO;
	}
	return ExpressionType::INVALID;
}

unique_ptr<ParsedExpression> Transformer::TransformUnaryOperator(string op, unique_ptr<ParsedExpression> child) {
	const auto schema = DEFAULT_SCHEMA;

	vector<unique_ptr<ParsedExpression>> children;
	children.push_back(move(child));

	// built-in operator function
	auto result = make_unique<FunctionExpression>(schema, op, children);
	result->is_operator = true;
	return move(result);
}

unique_ptr<ParsedExpression> Transformer::TransformBinaryOperator(string op, unique_ptr<ParsedExpression> left,
                                                                  unique_ptr<ParsedExpression> right) {
	const auto schema = DEFAULT_SCHEMA;

	vector<unique_ptr<ParsedExpression>> children;
	children.push_back(move(left));
	children.push_back(move(right));

	if (op == "~" || op == "!~") {
		// rewrite SIMILAR TO into regexp_matches('asdf', '.*sd.*')
		bool invert_similar = op == "!~";

		auto result = make_unique<FunctionExpression>(schema, "regexp_matches", children);
		if (invert_similar) {
			return make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(result));
		} else {
			return move(result);
		}
	} else {
		auto target_type = OperatorToExpressionType(op);
		if (target_type != ExpressionType::INVALID) {
			// built-in comparison operator
			return make_unique<ComparisonExpression>(target_type, move(children[0]), move(children[1]));
		} else {
			// built-in operator function
			auto result = make_unique<FunctionExpression>(schema, op, children);
			result->is_operator = true;
			return move(result);
		}
	}
}

unique_ptr<ParsedExpression> Transformer::TransformAExpr(PGAExpr *root) {
	if (!root) {
		return nullptr;
	}
	auto name = string((reinterpret_cast<PGValue *>(root->name->head->data.ptr_value))->val.str);

	switch (root->kind) {
	case PG_AEXPR_DISTINCT:
		break;
	case PG_AEXPR_IN: {
		auto left_expr = TransformExpression(root->lexpr);
		ExpressionType operator_type;
		// this looks very odd, but seems to be the way to find out its NOT IN
		if (name == "<>") {
			// NOT IN
			operator_type = ExpressionType::COMPARE_NOT_IN;
		} else {
			// IN
			operator_type = ExpressionType::COMPARE_IN;
		}
		auto result = make_unique<OperatorExpression>(operator_type, move(left_expr));
		TransformExpressionList((PGList *)root->rexpr, result->children);
		return move(result);
	} break;
	// rewrite NULLIF(a, b) into CASE WHEN a=b THEN NULL ELSE a END
	case PG_AEXPR_NULLIF: {
		auto case_expr = make_unique<CaseExpression>();
		auto value = TransformExpression(root->lexpr);
		// the check (A = B)
		case_expr->check = make_unique<ComparisonExpression>(ExpressionType::COMPARE_EQUAL, value->Copy(),
		                                                     TransformExpression(root->rexpr));
		// if A = B, then constant NULL
		case_expr->result_if_true = make_unique<ConstantExpression>(SQLType::SQLNULL, Value());
		// else A
		case_expr->result_if_false = move(value);
		return move(case_expr);
	} break;
	// rewrite (NOT) X BETWEEN A AND B into (NOT) AND(GREATERTHANOREQUALTO(X,
	// A), LESSTHANOREQUALTO(X, B))
	case PG_AEXPR_BETWEEN:
	case PG_AEXPR_NOT_BETWEEN: {
		auto between_args = reinterpret_cast<PGList *>(root->rexpr);

		if (between_args->length != 2 || !between_args->head->data.ptr_value || !between_args->tail->data.ptr_value) {
			throw Exception("(NOT) BETWEEN needs two args");
		}

		auto between_left = TransformExpression(reinterpret_cast<PGNode *>(between_args->head->data.ptr_value));
		auto between_right = TransformExpression(reinterpret_cast<PGNode *>(between_args->tail->data.ptr_value));

		auto compare_left = make_unique<ComparisonExpression>(ExpressionType::COMPARE_GREATERTHANOREQUALTO,
		                                                      TransformExpression(root->lexpr), move(between_left));
		auto compare_right = make_unique<ComparisonExpression>(ExpressionType::COMPARE_LESSTHANOREQUALTO,
		                                                       TransformExpression(root->lexpr), move(between_right));
		auto compare_between = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_AND, move(compare_left),
		                                                          move(compare_right));
		if (root->kind == PG_AEXPR_BETWEEN) {
			return move(compare_between);
		} else {
			return make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(compare_between));
		}
	} break;
	// rewrite SIMILAR TO into regexp_matches('asdf', '.*sd.*')
	case PG_AEXPR_SIMILAR: {
		auto left_expr = TransformExpression(root->lexpr);
		auto right_expr = TransformExpression(root->rexpr);

		vector<unique_ptr<ParsedExpression>> children;
		children.push_back(move(left_expr));

		auto &similar_func = reinterpret_cast<FunctionExpression &>(*right_expr);
		assert(similar_func.function_name == "similar_escape");
		assert(similar_func.children.size() == 2);
		if (similar_func.children[1]->type != ExpressionType::VALUE_CONSTANT) {
			throw NotImplementedException("Custom escape in SIMILAR TO");
		}
		auto &constant = (ConstantExpression &)*similar_func.children[1];
		if (!constant.value.is_null) {
			throw NotImplementedException("Custom escape in SIMILAR TO");
		}
		// take the child of the similar_func
		children.push_back(move(similar_func.children[0]));

		// this looks very odd, but seems to be the way to find out its NOT IN
		bool invert_similar = false;
		if (name == "!~") {
			// NOT SIMILAR TO
			invert_similar = true;
		}
		const auto schema = DEFAULT_SCHEMA;
		const auto regex_function = "regexp_matches";
		auto result = make_unique<FunctionExpression>(schema, regex_function, children);

		if (invert_similar) {
			return make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(result));
		} else {
			return move(result);
		}
	} break;
	default:
		break;
	}

	auto left_expr = TransformExpression(root->lexpr);
	auto right_expr = TransformExpression(root->rexpr);

	if (!left_expr) {
		// prefix operator
		return TransformUnaryOperator(name, move(right_expr));
	} else if (!right_expr) {
		throw NotImplementedException("Postfix operators not implemented!");
	} else {
		return TransformBinaryOperator(name, move(left_expr), move(right_expr));
	}
}



using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformParamRef(PGParamRef *node) {
	if (!node) {
		return nullptr;
	}
	auto expr = make_unique<ParameterExpression>();
	if (node->number == 0) {
		expr->parameter_nr = prepared_statement_parameter_index + 1;
	} else {
		expr->parameter_nr = node->number;
	}
	prepared_statement_parameter_index = max(prepared_statement_parameter_index, expr->parameter_nr);
	return move(expr);
}




using namespace duckdb;
using namespace std;

unique_ptr<ParsedExpression> Transformer::TransformSubquery(PGSubLink *root) {
	if (!root) {
		return nullptr;
	}
	auto subquery_expr = make_unique<SubqueryExpression>();
	subquery_expr->subquery = TransformSelectNode((PGSelectStmt *)root->subselect);
	if (!subquery_expr->subquery) {
		return nullptr;
	}
	assert(subquery_expr->subquery->GetSelectList().size() > 0);

	switch (root->subLinkType) {
	case PG_EXISTS_SUBLINK: {
		subquery_expr->subquery_type = SubqueryType::EXISTS;
		break;
	}
	case PG_ANY_SUBLINK:
	case PG_ALL_SUBLINK: {
		// comparison with ANY() or ALL()
		subquery_expr->subquery_type = SubqueryType::ANY;
		subquery_expr->child = TransformExpression(root->testexpr);
		// get the operator name
		if (!root->operName) {
			// simple IN
			subquery_expr->comparison_type = ExpressionType::COMPARE_EQUAL;
		} else {
			auto operator_name = string((reinterpret_cast<PGValue *>(root->operName->head->data.ptr_value))->val.str);
			subquery_expr->comparison_type = OperatorToExpressionType(operator_name);
		}
		assert(subquery_expr->comparison_type == ExpressionType::COMPARE_EQUAL ||
		       subquery_expr->comparison_type == ExpressionType::COMPARE_NOTEQUAL ||
		       subquery_expr->comparison_type == ExpressionType::COMPARE_GREATERTHAN ||
		       subquery_expr->comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO ||
		       subquery_expr->comparison_type == ExpressionType::COMPARE_LESSTHAN ||
		       subquery_expr->comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO);
		if (root->subLinkType == PG_ALL_SUBLINK) {
			// ALL sublink is equivalent to NOT(ANY) with inverted comparison
			// e.g. [= ALL()] is equivalent to [NOT(<> ANY())]
			// first invert the comparison type
			subquery_expr->comparison_type = NegateComparisionExpression(subquery_expr->comparison_type);
			return make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(subquery_expr));
		}
		break;
	}
	case PG_EXPR_SUBLINK: {
		// return a single scalar value from the subquery
		// no child expression to compare to
		subquery_expr->subquery_type = SubqueryType::SCALAR;
		break;
	}
	default:
		throw NotImplementedException("Subquery of type %d not implemented\n", (int)root->subLinkType);
	}
	return move(subquery_expr);
}


using namespace duckdb;

std::string Transformer::NodetypeToString(PGNodeTag type) {
	switch (type) {
	case T_PGInvalid:
		return "T_Invalid";
	case T_PGIndexInfo:
		return "T_IndexInfo";
	case T_PGExprContext:
		return "T_ExprContext";
	case T_PGProjectionInfo:
		return "T_ProjectionInfo";
	case T_PGJunkFilter:
		return "T_JunkFilter";
	case T_PGResultRelInfo:
		return "T_ResultRelInfo";
	case T_PGEState:
		return "T_EState";
	case T_PGTupleTableSlot:
		return "T_TupleTableSlot";
	case T_PGPlan:
		return "T_Plan";
	case T_PGResult:
		return "T_Result";
	case T_PGProjectSet:
		return "T_ProjectSet";
	case T_PGModifyTable:
		return "T_ModifyTable";
	case T_PGAppend:
		return "T_Append";
	case T_PGMergeAppend:
		return "T_MergeAppend";
	case T_PGRecursiveUnion:
		return "T_RecursiveUnion";
	case T_PGBitmapAnd:
		return "T_BitmapAnd";
	case T_PGBitmapOr:
		return "T_BitmapOr";
	case T_PGScan:
		return "T_Scan";
	case T_PGSeqScan:
		return "T_SeqScan";
	case T_PGSampleScan:
		return "T_SampleScan";
	case T_PGIndexScan:
		return "T_IndexScan";
	case T_PGIndexOnlyScan:
		return "T_IndexOnlyScan";
	case T_PGBitmapIndexScan:
		return "T_BitmapIndexScan";
	case T_PGBitmapHeapScan:
		return "T_BitmapHeapScan";
	case T_PGTidScan:
		return "T_TidScan";
	case T_PGSubqueryScan:
		return "T_SubqueryScan";
	case T_PGFunctionScan:
		return "T_FunctionScan";
	case T_PGValuesScan:
		return "T_ValuesScan";
	case T_PGTableFuncScan:
		return "T_TableFuncScan";
	case T_PGCteScan:
		return "T_CteScan";
	case T_PGNamedTuplestoreScan:
		return "T_NamedTuplestoreScan";
	case T_PGWorkTableScan:
		return "T_WorkTableScan";
	case T_PGForeignScan:
		return "T_ForeignScan";
	case T_PGCustomScan:
		return "T_CustomScan";
	case T_PGJoin:
		return "T_Join";
	case T_PGNestLoop:
		return "T_NestLoop";
	case T_PGMergeJoin:
		return "T_MergeJoin";
	case T_PGHashJoin:
		return "T_HashJoin";
	case T_PGMaterial:
		return "T_Material";
	case T_PGSort:
		return "T_Sort";
	case T_PGGroup:
		return "T_Group";
	case T_PGAgg:
		return "T_Agg";
	case T_PGWindowAgg:
		return "T_WindowAgg";
	case T_PGUnique:
		return "T_Unique";
	case T_PGGather:
		return "T_Gather";
	case T_PGGatherMerge:
		return "T_GatherMerge";
	case T_PGHash:
		return "T_Hash";
	case T_PGSetOp:
		return "T_SetOp";
	case T_PGLockRows:
		return "T_LockRows";
	case T_PGLimit:
		return "T_Limit";
	case T_PGNestLoopParam:
		return "T_NestLoopParam";
	case T_PGPlanRowMark:
		return "T_PlanRowMark";
	case T_PGPlanInvalItem:
		return "T_PlanInvalItem";
	case T_PGPlanState:
		return "T_PlanState";
	case T_PGResultState:
		return "T_ResultState";
	case T_PGProjectSetState:
		return "T_ProjectSetState";
	case T_PGModifyTableState:
		return "T_ModifyTableState";
	case T_PGAppendState:
		return "T_AppendState";
	case T_PGMergeAppendState:
		return "T_MergeAppendState";
	case T_PGRecursiveUnionState:
		return "T_RecursiveUnionState";
	case T_PGBitmapAndState:
		return "T_BitmapAndState";
	case T_PGBitmapOrState:
		return "T_BitmapOrState";
	case T_PGScanState:
		return "T_ScanState";
	case T_PGSeqScanState:
		return "T_SeqScanState";
	case T_PGSampleScanState:
		return "T_SampleScanState";
	case T_PGIndexScanState:
		return "T_IndexScanState";
	case T_PGIndexOnlyScanState:
		return "T_IndexOnlyScanState";
	case T_PGBitmapIndexScanState:
		return "T_BitmapIndexScanState";
	case T_PGBitmapHeapScanState:
		return "T_BitmapHeapScanState";
	case T_PGTidScanState:
		return "T_TidScanState";
	case T_PGSubqueryScanState:
		return "T_SubqueryScanState";
	case T_PGFunctionScanState:
		return "T_FunctionScanState";
	case T_PGTableFuncScanState:
		return "T_TableFuncScanState";
	case T_PGValuesScanState:
		return "T_ValuesScanState";
	case T_PGCteScanState:
		return "T_CteScanState";
	case T_PGNamedTuplestoreScanState:
		return "T_NamedTuplestoreScanState";
	case T_PGWorkTableScanState:
		return "T_WorkTableScanState";
	case T_PGForeignScanState:
		return "T_ForeignScanState";
	case T_PGCustomScanState:
		return "T_CustomScanState";
	case T_PGJoinState:
		return "T_JoinState";
	case T_PGNestLoopState:
		return "T_NestLoopState";
	case T_PGMergeJoinState:
		return "T_MergeJoinState";
	case T_PGHashJoinState:
		return "T_HashJoinState";
	case T_PGMaterialState:
		return "T_MaterialState";
	case T_PGSortState:
		return "T_SortState";
	case T_PGGroupState:
		return "T_GroupState";
	case T_PGAggState:
		return "T_AggState";
	case T_PGWindowAggState:
		return "T_WindowAggState";
	case T_PGUniqueState:
		return "T_UniqueState";
	case T_PGGatherState:
		return "T_GatherState";
	case T_PGGatherMergeState:
		return "T_GatherMergeState";
	case T_PGHashState:
		return "T_HashState";
	case T_PGSetOpState:
		return "T_SetOpState";
	case T_PGLockRowsState:
		return "T_LockRowsState";
	case T_PGLimitState:
		return "T_LimitState";
	case T_PGAlias:
		return "T_Alias";
	case T_PGRangeVar:
		return "T_RangeVar";
	case T_PGTableFunc:
		return "T_TableFunc";
	case T_PGExpr:
		return "T_Expr";
	case T_PGVar:
		return "T_Var";
	case T_PGConst:
		return "T_Const";
	case T_PGParam:
		return "T_Param";
	case T_PGAggref:
		return "T_Aggref";
	case T_PGGroupingFunc:
		return "T_GroupingFunc";
	case T_PGWindowFunc:
		return "T_WindowFunc";
	case T_PGArrayRef:
		return "T_ArrayRef";
	case T_PGFuncExpr:
		return "T_FuncExpr";
	case T_PGNamedArgExpr:
		return "T_NamedArgExpr";
	case T_PGOpExpr:
		return "T_OpExpr";
	case T_PGDistinctExpr:
		return "T_DistinctExpr";
	case T_PGNullIfExpr:
		return "T_NullIfExpr";
	case T_PGScalarArrayOpExpr:
		return "T_ScalarArrayOpExpr";
	case T_PGBoolExpr:
		return "T_BoolExpr";
	case T_PGSubLink:
		return "T_SubLink";
	case T_PGSubPlan:
		return "T_SubPlan";
	case T_PGAlternativeSubPlan:
		return "T_AlternativeSubPlan";
	case T_PGFieldSelect:
		return "T_FieldSelect";
	case T_PGFieldStore:
		return "T_FieldStore";
	case T_PGRelabelType:
		return "T_RelabelType";
	case T_PGCoerceViaIO:
		return "T_CoerceViaIO";
	case T_PGArrayCoerceExpr:
		return "T_ArrayCoerceExpr";
	case T_PGConvertRowtypeExpr:
		return "T_ConvertRowtypeExpr";
	case T_PGCollateExpr:
		return "T_CollateExpr";
	case T_PGCaseExpr:
		return "T_CaseExpr";
	case T_PGCaseWhen:
		return "T_CaseWhen";
	case T_PGCaseTestExpr:
		return "T_CaseTestExpr";
	case T_PGArrayExpr:
		return "T_ArrayExpr";
	case T_PGRowExpr:
		return "T_RowExpr";
	case T_PGRowCompareExpr:
		return "T_RowCompareExpr";
	case T_PGCoalesceExpr:
		return "T_CoalesceExpr";
	case T_PGMinMaxExpr:
		return "T_MinMaxExpr";
	case T_PGSQLValueFunction:
		return "T_SQLValueFunction";
	case T_PGXmlExpr:
		return "T_XmlExpr";
	case T_PGNullTest:
		return "T_NullTest";
	case T_PGBooleanTest:
		return "T_BooleanTest";
	case T_PGCoerceToDomain:
		return "T_CoerceToDomain";
	case T_PGCoerceToDomainValue:
		return "T_CoerceToDomainValue";
	case T_PGSetToDefault:
		return "T_SetToDefault";
	case T_PGCurrentOfExpr:
		return "T_CurrentOfExpr";
	case T_PGNextValueExpr:
		return "T_NextValueExpr";
	case T_PGInferenceElem:
		return "T_InferenceElem";
	case T_PGTargetEntry:
		return "T_TargetEntry";
	case T_PGRangeTblRef:
		return "T_RangeTblRef";
	case T_PGJoinExpr:
		return "T_JoinExpr";
	case T_PGFromExpr:
		return "T_FromExpr";
	case T_PGOnConflictExpr:
		return "T_OnConflictExpr";
	case T_PGIntoClause:
		return "T_IntoClause";
	case T_PGExprState:
		return "T_ExprState";
	case T_PGAggrefExprState:
		return "T_AggrefExprState";
	case T_PGWindowFuncExprState:
		return "T_WindowFuncExprState";
	case T_PGSetExprState:
		return "T_SetExprState";
	case T_PGSubPlanState:
		return "T_SubPlanState";
	case T_PGAlternativeSubPlanState:
		return "T_AlternativeSubPlanState";
	case T_PGDomainConstraintState:
		return "T_DomainConstraintState";
	case T_PGPlannerInfo:
		return "T_PlannerInfo";
	case T_PGPlannerGlobal:
		return "T_PlannerGlobal";
	case T_PGRelOptInfo:
		return "T_RelOptInfo";
	case T_PGIndexOptInfo:
		return "T_IndexOptInfo";
	case T_PGForeignKeyOptInfo:
		return "T_ForeignKeyOptInfo";
	case T_PGParamPathInfo:
		return "T_ParamPathInfo";
	case T_PGPath:
		return "T_Path";
	case T_PGIndexPath:
		return "T_IndexPath";
	case T_PGBitmapHeapPath:
		return "T_BitmapHeapPath";
	case T_PGBitmapAndPath:
		return "T_BitmapAndPath";
	case T_PGBitmapOrPath:
		return "T_BitmapOrPath";
	case T_PGTidPath:
		return "T_TidPath";
	case T_PGSubqueryScanPath:
		return "T_SubqueryScanPath";
	case T_PGForeignPath:
		return "T_ForeignPath";
	case T_PGCustomPath:
		return "T_CustomPath";
	case T_PGNestPath:
		return "T_NestPath";
	case T_PGMergePath:
		return "T_MergePath";
	case T_PGHashPath:
		return "T_HashPath";
	case T_PGAppendPath:
		return "T_AppendPath";
	case T_PGMergeAppendPath:
		return "T_MergeAppendPath";
	case T_PGResultPath:
		return "T_ResultPath";
	case T_PGMaterialPath:
		return "T_MaterialPath";
	case T_PGUniquePath:
		return "T_UniquePath";
	case T_PGGatherPath:
		return "T_GatherPath";
	case T_PGGatherMergePath:
		return "T_GatherMergePath";
	case T_PGProjectionPath:
		return "T_ProjectionPath";
	case T_PGProjectSetPath:
		return "T_ProjectSetPath";
	case T_PGSortPath:
		return "T_SortPath";
	case T_PGGroupPath:
		return "T_GroupPath";
	case T_PGUpperUniquePath:
		return "T_UpperUniquePath";
	case T_PGAggPath:
		return "T_AggPath";
	case T_PGGroupingSetsPath:
		return "T_GroupingSetsPath";
	case T_PGMinMaxAggPath:
		return "T_MinMaxAggPath";
	case T_PGWindowAggPath:
		return "T_WindowAggPath";
	case T_PGSetOpPath:
		return "T_SetOpPath";
	case T_PGRecursiveUnionPath:
		return "T_RecursiveUnionPath";
	case T_PGLockRowsPath:
		return "T_LockRowsPath";
	case T_PGModifyTablePath:
		return "T_ModifyTablePath";
	case T_PGLimitPath:
		return "T_LimitPath";
	case T_PGEquivalenceClass:
		return "T_EquivalenceClass";
	case T_PGEquivalenceMember:
		return "T_EquivalenceMember";
	case T_PGPathKey:
		return "T_PathKey";
	case T_PGPathTarget:
		return "T_PathTarget";
	case T_PGRestrictInfo:
		return "T_RestrictInfo";
	case T_PGPlaceHolderVar:
		return "T_PlaceHolderVar";
	case T_PGSpecialJoinInfo:
		return "T_SpecialJoinInfo";
	case T_PGAppendRelInfo:
		return "T_AppendRelInfo";
	case T_PGPartitionedChildRelInfo:
		return "T_PartitionedChildRelInfo";
	case T_PGPlaceHolderInfo:
		return "T_PlaceHolderInfo";
	case T_PGMinMaxAggInfo:
		return "T_MinMaxAggInfo";
	case T_PGPlannerParamItem:
		return "T_PlannerParamItem";
	case T_PGRollupData:
		return "T_RollupData";
	case T_PGGroupingSetData:
		return "T_GroupingSetData";
	case T_PGStatisticExtInfo:
		return "T_StatisticExtInfo";
	case T_PGMemoryContext:
		return "T_MemoryContext";
	case T_PGAllocSetContext:
		return "T_AllocSetContext";
	case T_PGSlabContext:
		return "T_SlabContext";
	case T_PGValue:
		return "T_Value";
	case T_PGInteger:
		return "T_Integer";
	case T_PGFloat:
		return "T_Float";
	case T_PGString:
		return "T_String";
	case T_PGBitString:
		return "T_BitString";
	case T_PGNull:
		return "T_Null";
	case T_PGList:
		return "T_List";
	case T_PGIntList:
		return "T_IntList";
	case T_PGOidList:
		return "T_OidList";
	case T_PGExtensibleNode:
		return "T_ExtensibleNode";
	case T_PGRawStmt:
		return "T_RawStmt";
	case T_PGQuery:
		return "T_Query";
	case T_PGPlannedStmt:
		return "T_PlannedStmt";
	case T_PGInsertStmt:
		return "T_InsertStmt";
	case T_PGDeleteStmt:
		return "T_DeleteStmt";
	case T_PGUpdateStmt:
		return "T_UpdateStmt";
	case T_PGSelectStmt:
		return "T_SelectStmt";
	case T_PGAlterTableStmt:
		return "T_AlterTableStmt";
	case T_PGAlterTableCmd:
		return "T_AlterTableCmd";
	case T_PGAlterDomainStmt:
		return "T_AlterDomainStmt";
	case T_PGSetOperationStmt:
		return "T_SetOperationStmt";
	case T_PGGrantStmt:
		return "T_GrantStmt";
	case T_PGGrantRoleStmt:
		return "T_GrantRoleStmt";
	case T_PGAlterDefaultPrivilegesStmt:
		return "T_AlterDefaultPrivilegesStmt";
	case T_PGClosePortalStmt:
		return "T_ClosePortalStmt";
	case T_PGClusterStmt:
		return "T_ClusterStmt";
	case T_PGCopyStmt:
		return "T_CopyStmt";
	case T_PGCreateStmt:
		return "T_CreateStmt";
	case T_PGDefineStmt:
		return "T_DefineStmt";
	case T_PGDropStmt:
		return "T_DropStmt";
	case T_PGTruncateStmt:
		return "T_TruncateStmt";
	case T_PGCommentStmt:
		return "T_CommentStmt";
	case T_PGFetchStmt:
		return "T_FetchStmt";
	case T_PGIndexStmt:
		return "T_IndexStmt";
	case T_PGCreateFunctionStmt:
		return "T_CreateFunctionStmt";
	case T_PGAlterFunctionStmt:
		return "T_AlterFunctionStmt";
	case T_PGDoStmt:
		return "T_DoStmt";
	case T_PGRenameStmt:
		return "T_RenameStmt";
	case T_PGRuleStmt:
		return "T_RuleStmt";
	case T_PGNotifyStmt:
		return "T_NotifyStmt";
	case T_PGListenStmt:
		return "T_ListenStmt";
	case T_PGUnlistenStmt:
		return "T_UnlistenStmt";
	case T_PGTransactionStmt:
		return "T_TransactionStmt";
	case T_PGViewStmt:
		return "T_ViewStmt";
	case T_PGLoadStmt:
		return "T_LoadStmt";
	case T_PGCreateDomainStmt:
		return "T_CreateDomainStmt";
	case T_PGCreatedbStmt:
		return "T_CreatedbStmt";
	case T_PGDropdbStmt:
		return "T_DropdbStmt";
	case T_PGVacuumStmt:
		return "T_VacuumStmt";
	case T_PGExplainStmt:
		return "T_ExplainStmt";
	case T_PGCreateTableAsStmt:
		return "T_CreateTableAsStmt";
	case T_PGCreateSeqStmt:
		return "T_CreateSeqStmt";
	case T_PGAlterSeqStmt:
		return "T_AlterSeqStmt";
	case T_PGVariableSetStmt:
		return "T_VariableSetStmt";
	case T_PGVariableShowStmt:
		return "T_VariableShowStmt";
	case T_PGDiscardStmt:
		return "T_DiscardStmt";
	case T_PGCreateTrigStmt:
		return "T_CreateTrigStmt";
	case T_PGCreatePLangStmt:
		return "T_CreatePLangStmt";
	case T_PGCreateRoleStmt:
		return "T_CreateRoleStmt";
	case T_PGAlterRoleStmt:
		return "T_AlterRoleStmt";
	case T_PGDropRoleStmt:
		return "T_DropRoleStmt";
	case T_PGLockStmt:
		return "T_LockStmt";
	case T_PGConstraintsSetStmt:
		return "T_ConstraintsSetStmt";
	case T_PGReindexStmt:
		return "T_ReindexStmt";
	case T_PGCheckPointStmt:
		return "T_CheckPointStmt";
	case T_PGCreateSchemaStmt:
		return "T_CreateSchemaStmt";
	case T_PGAlterDatabaseStmt:
		return "T_AlterDatabaseStmt";
	case T_PGAlterDatabaseSetStmt:
		return "T_AlterDatabaseSetStmt";
	case T_PGAlterRoleSetStmt:
		return "T_AlterRoleSetStmt";
	case T_PGCreateConversionStmt:
		return "T_CreateConversionStmt";
	case T_PGCreateCastStmt:
		return "T_CreateCastStmt";
	case T_PGCreateOpClassStmt:
		return "T_CreateOpClassStmt";
	case T_PGCreateOpFamilyStmt:
		return "T_CreateOpFamilyStmt";
	case T_PGAlterOpFamilyStmt:
		return "T_AlterOpFamilyStmt";
	case T_PGPrepareStmt:
		return "T_PrepareStmt";
	case T_PGExecuteStmt:
		return "T_ExecuteStmt";
	case T_PGDeallocateStmt:
		return "T_DeallocateStmt";
	case T_PGDeclareCursorStmt:
		return "T_DeclareCursorStmt";
	case T_PGCreateTableSpaceStmt:
		return "T_CreateTableSpaceStmt";
	case T_PGDropTableSpaceStmt:
		return "T_DropTableSpaceStmt";
	case T_PGAlterObjectDependsStmt:
		return "T_AlterObjectDependsStmt";
	case T_PGAlterObjectSchemaStmt:
		return "T_AlterObjectSchemaStmt";
	case T_PGAlterOwnerStmt:
		return "T_AlterOwnerStmt";
	case T_PGAlterOperatorStmt:
		return "T_AlterOperatorStmt";
	case T_PGDropOwnedStmt:
		return "T_DropOwnedStmt";
	case T_PGReassignOwnedStmt:
		return "T_ReassignOwnedStmt";
	case T_PGCompositeTypeStmt:
		return "T_CompositeTypeStmt";
	case T_PGCreateEnumStmt:
		return "T_CreateEnumStmt";
	case T_PGCreateRangeStmt:
		return "T_CreateRangeStmt";
	case T_PGAlterEnumStmt:
		return "T_AlterEnumStmt";
	case T_PGAlterTSDictionaryStmt:
		return "T_AlterTSDictionaryStmt";
	case T_PGAlterTSConfigurationStmt:
		return "T_AlterTSConfigurationStmt";
	case T_PGCreateFdwStmt:
		return "T_CreateFdwStmt";
	case T_PGAlterFdwStmt:
		return "T_AlterFdwStmt";
	case T_PGCreateForeignServerStmt:
		return "T_CreateForeignServerStmt";
	case T_PGAlterForeignServerStmt:
		return "T_AlterForeignServerStmt";
	case T_PGCreateUserMappingStmt:
		return "T_CreateUserMappingStmt";
	case T_PGAlterUserMappingStmt:
		return "T_AlterUserMappingStmt";
	case T_PGDropUserMappingStmt:
		return "T_DropUserMappingStmt";
	case T_PGAlterTableSpaceOptionsStmt:
		return "T_AlterTableSpaceOptionsStmt";
	case T_PGAlterTableMoveAllStmt:
		return "T_AlterTableMoveAllStmt";
	case T_PGSecLabelStmt:
		return "T_SecLabelStmt";
	case T_PGCreateForeignTableStmt:
		return "T_CreateForeignTableStmt";
	case T_PGImportForeignSchemaStmt:
		return "T_ImportForeignSchemaStmt";
	case T_PGCreateExtensionStmt:
		return "T_CreateExtensionStmt";
	case T_PGAlterExtensionStmt:
		return "T_AlterExtensionStmt";
	case T_PGAlterExtensionContentsStmt:
		return "T_AlterExtensionContentsStmt";
	case T_PGCreateEventTrigStmt:
		return "T_CreateEventTrigStmt";
	case T_PGAlterEventTrigStmt:
		return "T_AlterEventTrigStmt";
	case T_PGRefreshMatViewStmt:
		return "T_RefreshMatViewStmt";
	case T_PGReplicaIdentityStmt:
		return "T_ReplicaIdentityStmt";
	case T_PGAlterSystemStmt:
		return "T_AlterSystemStmt";
	case T_PGCreatePolicyStmt:
		return "T_CreatePolicyStmt";
	case T_PGAlterPolicyStmt:
		return "T_AlterPolicyStmt";
	case T_PGCreateTransformStmt:
		return "T_CreateTransformStmt";
	case T_PGCreateAmStmt:
		return "T_CreateAmStmt";
	case T_PGCreatePublicationStmt:
		return "T_CreatePublicationStmt";
	case T_PGAlterPublicationStmt:
		return "T_AlterPublicationStmt";
	case T_PGCreateSubscriptionStmt:
		return "T_CreateSubscriptionStmt";
	case T_PGAlterSubscriptionStmt:
		return "T_AlterSubscriptionStmt";
	case T_PGDropSubscriptionStmt:
		return "T_DropSubscriptionStmt";
	case T_PGCreateStatsStmt:
		return "T_CreateStatsStmt";
	case T_PGAlterCollationStmt:
		return "T_AlterCollationStmt";
	case T_PGAExpr:
		return "TAExpr";
	case T_PGColumnRef:
		return "T_ColumnRef";
	case T_PGParamRef:
		return "T_ParamRef";
	case T_PGAConst:
		return "TAConst";
	case T_PGFuncCall:
		return "T_FuncCall";
	case T_PGAStar:
		return "TAStar";
	case T_PGAIndices:
		return "TAIndices";
	case T_PGAIndirection:
		return "TAIndirection";
	case T_PGAArrayExpr:
		return "TAArrayExpr";
	case T_PGResTarget:
		return "T_ResTarget";
	case T_PGMultiAssignRef:
		return "T_MultiAssignRef";
	case T_PGTypeCast:
		return "T_TypeCast";
	case T_PGCollateClause:
		return "T_CollateClause";
	case T_PGSortBy:
		return "T_SortBy";
	case T_PGWindowDef:
		return "T_WindowDef";
	case T_PGRangeSubselect:
		return "T_RangeSubselect";
	case T_PGRangeFunction:
		return "T_RangeFunction";
	case T_PGRangeTableSample:
		return "T_RangeTableSample";
	case T_PGRangeTableFunc:
		return "T_RangeTableFunc";
	case T_PGRangeTableFuncCol:
		return "T_RangeTableFuncCol";
	case T_PGTypeName:
		return "T_TypeName";
	case T_PGColumnDef:
		return "T_ColumnDef";
	case T_PGIndexElem:
		return "T_IndexElem";
	case T_PGConstraint:
		return "T_Constraint";
	case T_PGDefElem:
		return "T_DefElem";
	case T_PGRangeTblEntry:
		return "T_RangeTblEntry";
	case T_PGRangeTblFunction:
		return "T_RangeTblFunction";
	case T_PGTableSampleClause:
		return "T_TableSampleClause";
	case T_PGWithCheckOption:
		return "T_WithCheckOption";
	case T_PGSortGroupClause:
		return "T_SortGroupClause";
	case T_PGGroupingSet:
		return "T_GroupingSet";
	case T_PGWindowClause:
		return "T_WindowClause";
	case T_PGObjectWithArgs:
		return "T_ObjectWithArgs";
	case T_PGAccessPriv:
		return "T_AccessPriv";
	case T_PGCreateOpClassItem:
		return "T_CreateOpClassItem";
	case T_PGTableLikeClause:
		return "T_TableLikeClause";
	case T_PGFunctionParameter:
		return "T_FunctionParameter";
	case T_PGLockingClause:
		return "T_LockingClause";
	case T_PGRowMarkClause:
		return "T_RowMarkClause";
	case T_PGXmlSerialize:
		return "T_XmlSerialize";
	case T_PGWithClause:
		return "T_WithClause";
	case T_PGInferClause:
		return "T_InferClause";
	case T_PGOnConflictClause:
		return "T_OnConflictClause";
	case T_PGCommonTableExpr:
		return "T_CommonTableExpr";
	case T_PGRoleSpec:
		return "T_RoleSpec";
	case T_PGTriggerTransition:
		return "T_TriggerTransition";
	case T_PGPartitionElem:
		return "T_PartitionElem";
	case T_PGPartitionSpec:
		return "T_PartitionSpec";
	case T_PGPartitionBoundSpec:
		return "T_PartitionBoundSpec";
	case T_PGPartitionRangeDatum:
		return "T_PartitionRangeDatum";
	case T_PGPartitionCmd:
		return "T_PartitionCmd";
	case T_PGIdentifySystemCmd:
		return "T_IdentifySystemCmd";
	case T_PGBaseBackupCmd:
		return "T_BaseBackupCmd";
	case T_PGCreateReplicationSlotCmd:
		return "T_CreateReplicationSlotCmd";
	case T_PGDropReplicationSlotCmd:
		return "T_DropReplicationSlotCmd";
	case T_PGStartReplicationCmd:
		return "T_StartReplicationCmd";
	case T_PGTimeLineHistoryCmd:
		return "T_TimeLineHistoryCmd";
	case T_PGSQLCmd:
		return "T_SQLCmd";
	case T_PGTriggerData:
		return "T_TriggerData";
	case T_PGEventTriggerData:
		return "T_EventTriggerData";
	case T_PGReturnSetInfo:
		return "T_ReturnSetInfo";
	case T_PGWindowObjectData:
		return "T_WindowObjectData";
	case T_PGTIDBitmap:
		return "T_TIDBitmap";
	case T_PGInlineCodeBlock:
		return "T_InlineCodeBlock";
	case T_PGFdwRoutine:
		return "T_FdwRoutine";
	case T_PGIndexAmRoutine:
		return "T_IndexAmRoutine";
	case T_PGTsmRoutine:
		return "T_TsmRoutine";
	case T_PGForeignKeyCacheInfo:
		return "T_ForeignKeyCacheInfo";
	default:
		assert(0);
		return "";
	}
}


using namespace duckdb;
using namespace std;

string Transformer::TransformAlias(PGAlias *root) {
	if (!root) {
		return "";
	}
	return root->aliasname;
}







using namespace duckdb;
using namespace std;

void Transformer::TransformCTE(PGWithClause *de_with_clause, SelectStatement &select) {
	// TODO: might need to update in case of future lawsuit
	assert(de_with_clause);

	assert(de_with_clause->ctes);
	for (auto cte_ele = de_with_clause->ctes->head; cte_ele != NULL; cte_ele = cte_ele->next) {
		auto cte = reinterpret_cast<PGCommonTableExpr *>(cte_ele->data.ptr_value);
		// lets throw some errors on unsupported features early

		if (cte->aliascolnames) {
			throw NotImplementedException("Column name aliases not supported in CTEs");
		}
		if (cte->ctecolnames) {
			throw NotImplementedException("Column name setting not supported in CTEs");
		}
		if (cte->ctecoltypes) {
			throw NotImplementedException("Column type setting not supported in CTEs");
		}
		if (cte->ctecoltypmods) {
			throw NotImplementedException("Column type modification not supported in CTEs");
		}
		if (cte->ctecolcollations) {
			throw NotImplementedException("CTE collations not supported");
		}
		// we need a query
		if (!cte->ctequery || cte->ctequery->type != T_PGSelectStmt) {
			throw Exception("A CTE needs a SELECT");
		}

        unique_ptr<QueryNode> cte_select;

		// CTE transformation can either result in inlining for non recursive CTEs, or in recursive CTE bindings otherwise.
		if(cte->cterecursive || de_with_clause->recursive) {
		    cte_select = TransformRecursiveCTE(cte);
		} else {
		    cte_select = TransformSelectNode((PGSelectStmt *)cte->ctequery);
		}

		if (!cte_select) {
			throw Exception("A CTE needs a SELECT");
		}
		auto cte_name = string(cte->ctename);

		auto it = select.cte_map.find(cte_name);
		if (it != select.cte_map.end()) {
			// can't have two CTEs with same name
			throw Exception("A CTE needs an unique name");
		}
		select.cte_map[cte_name] = move(cte_select);
	}
}

unique_ptr<QueryNode> Transformer::TransformRecursiveCTE(PGCommonTableExpr *cte) {
    auto stmt = (PGSelectStmt *)cte->ctequery;

    unique_ptr<QueryNode> node;
    switch (stmt->op) {
        case PG_SETOP_UNION:
        case PG_SETOP_EXCEPT:
        case PG_SETOP_INTERSECT: {
            node = make_unique<RecursiveCTENode>();
            auto result = (RecursiveCTENode *)node.get();
            result->ctename = string(cte->ctename);
            result->union_all = stmt->all;
            result->left = TransformSelectNode(stmt->larg);
            result->right = TransformSelectNode(stmt->rarg);

            if (!result->left || !result->right) {
                throw Exception("Failed to transform recursive CTE children.");
            }

            result->select_distinct = true;
            switch (stmt->op) {
                case PG_SETOP_UNION:
                    // We don't need a DISTINCT operation on top of a recursive UNION CTE.
                    result->select_distinct = false;
                    break;
                default:
                    throw Exception("Unexpected setop type for recursive CTE");
            }
            // if we compute the distinct result here, we do not have to do this in
            // the children. This saves a bunch of unnecessary DISTINCTs.
            if (result->select_distinct) {
                result->left->select_distinct = false;
                result->right->select_distinct = false;
            }
            break;
        }
        default:
            // This CTE is not recursive. Fallback to regular query transformation.
            return TransformSelectNode((PGSelectStmt *)cte->ctequery);
    }

    if(!node->orders.empty()) {
        throw Exception("ORDER BY in a recursive query is not implemented");
    }

    if (stmt->limitCount) {
        throw Exception("LIMIT in a recursive query is not implemented");
    }

    if (stmt->limitOffset) {
        throw Exception("OFFSET in a recursive query is not implemented");
    }
    return node;
}



using namespace duckdb;
using namespace std;

// FIXME: what is the difference between GroupBy and expression list?
bool Transformer::TransformGroupBy(PGList *group, vector<unique_ptr<ParsedExpression>> &result) {
	if (!group) {
		return false;
	}

	for (auto node = group->head; node != nullptr; node = node->next) {
		auto n = reinterpret_cast<PGNode *>(node->data.ptr_value);
		result.push_back(TransformExpression(n));
	}
	return true;
}




using namespace duckdb;
using namespace std;

bool Transformer::TransformOrderBy(PGList *order, vector<OrderByNode> &result) {
	if (!order) {
		return false;
	}

	for (auto node = order->head; node != nullptr; node = node->next) {
		auto temp = reinterpret_cast<PGNode *>(node->data.ptr_value);
		if (temp->type == T_PGSortBy) {
			OrderByNode ordernode;
			auto sort = reinterpret_cast<PGSortBy *>(temp);
			auto target = sort->node;
			if (sort->sortby_dir == PG_SORTBY_ASC || sort->sortby_dir == PG_SORTBY_DEFAULT) {
				ordernode.type = OrderType::ASCENDING;
			} else if (sort->sortby_dir == PG_SORTBY_DESC) {
				ordernode.type = OrderType::DESCENDING;
			} else {
				throw NotImplementedException("Unimplemented order by type");
			}
			ordernode.expression = TransformExpression(target);
			result.push_back(OrderByNode(ordernode.type, move(ordernode.expression)));
		} else {
			throw NotImplementedException("ORDER BY list member type %d\n", temp->type);
		}
	}
	return true;
}




using namespace duckdb;
using namespace std;

SQLType Transformer::TransformTypeName(PGTypeName *type_name) {
	auto name = (reinterpret_cast<PGValue *>(type_name->names->tail->data.ptr_value)->val.str);
	// transform it to the SQL type
	return TransformStringToSQLType(name);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/alter_table_statement.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

class AlterTableStatement : public SQLStatement {
public:
	AlterTableStatement(unique_ptr<AlterTableInfo> info) : SQLStatement(StatementType::ALTER), info(std::move(info)){};

	unique_ptr<TableRef> table;
	unique_ptr<AlterTableInfo> info;
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<AlterTableStatement> Transformer::TransformAlter(PGNode *node) {
	throw NotImplementedException("Alter table not supported yet!");
	// auto stmt = reinterpret_cast<AlterTableStmt *>(node);
	// assert(stmt);
	// assert(stmt->relation);

	// auto result = make_unique<AlterTableStatement>();
	// auto &info = *result->info.get();
	// auto new_alter_cmd = make_unique<AlterTableCmd>();
	// result->table = TransformRangeVar(stmt->relation);

	// info.table = stmt->relation->relname;

	// // first we check the type of ALTER
	// for (auto c = stmt->cmds->head; c != NULL; c = c->next) {
	// 	auto command = reinterpret_cast<PGAlterTableCmd *>(lfirst(c));
	// 	//TODO: Include more options for command->subtype
	// 	switch (command->subtype) {
	// 		case PG_AT_AddColumn: {
	//                auto cdef = (ColumnDef *)command->def;
	//                char *name = (reinterpret_cast<PGValue *>(
	//                        cdef->typeName->names->tail->data.ptr_value)
	//                        ->val.str);
	//                auto centry =
	//                        ColumnDefinition(cdef->colname,
	//                        TransformStringToTypeId(name));
	//                info.new_columns.push_back(centry);
	//                break;
	//            }
	// 		case PG_AT_DropColumn:
	// 		case PG_AT_AlterColumnType:
	// 		default:
	// 			throw NotImplementedException(
	// 			    "ALTER TABLE option not supported yet!");
	// 	}
	// }

	// return result;
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/copy_statement.hpp
//
//
//===----------------------------------------------------------------------===//







#include <vector>

namespace duckdb {

class CopyStatement : public SQLStatement {
public:
	CopyStatement() : SQLStatement(StatementType::COPY), info(make_unique<CopyInfo>()){};

	unique_ptr<CopyInfo> info;
	// The SQL statement used instead of a table when copying data out to a file
	unique_ptr<QueryNode> select_statement;
};
} // namespace duckdb







#include <cstring>

using namespace duckdb;
using namespace std;

static ExternalFileFormat StringToExternalFileFormat(const string &str) {
	auto upper = StringUtil::Upper(str);
	return ExternalFileFormat::CSV;
}

void SetControlString(PGDefElem *def_elem, string option, string option_example, string &info_str) {
	auto *val = (PGValue *)(def_elem->arg);
	if (!val || val->type != T_PGString) {
		throw ParserException("Unsupported parameter type for " + option + ": expected e.g. " + option_example);
	}
	info_str = val->val.str;
}

void SubstringDetection(string &str_1, string &str_2, string name_str_1, string name_str_2) {
	if (str_1.find(str_2) != string::npos || str_2.find(str_1) != std::string::npos) {
		throw Exception("COPY " + name_str_1 + " must not appear in the " + name_str_2 +
		                " specification and vice versa");
	}
}

void HandleOptions(PGCopyStmt *stmt, CopyInfo &info) {
	// option names
	const string kDelimiterTok = "delimiter";
	const string kFormatTok = "format";
	const string kQuoteTok = "quote";
	const string kEscapeTok = "escape";
	const string kHeaderTok = "header";
	const string kNullTok = "null";
	const string kForceQuoteTok = "force_quote";
	const string kForceNotNullTok = "force_not_null";
	const string kEncodingTok = "encoding";

	PGListCell *cell = nullptr;

	// iterate over each option
	for_each_cell(cell, stmt->options->head) {
		auto *def_elem = reinterpret_cast<PGDefElem *>(cell->data.ptr_value);

		if (StringUtil::StartsWith(def_elem->defname, "delim") || StringUtil::StartsWith(def_elem->defname, "sep")) {
			// delimiter
			SetControlString(def_elem, "DELIMITER", "DELIMITER ','", info.delimiter);

		} else if (def_elem->defname == kFormatTok) {
			// format
			auto *format_val = (PGValue *)(def_elem->arg);
			if (!format_val || format_val->type != T_PGString) {
				throw ParserException("Unsupported parameter type for FORMAT: expected e.g. FORMAT 'csv'");
			}
			if (StringUtil::Upper(format_val->val.str) != "CSV") {
				throw Exception("Copy is only supported for .CSV-files, FORMAT 'csv'");
			}
			info.format = StringToExternalFileFormat(format_val->val.str);

		} else if (def_elem->defname == kQuoteTok) {
			// quote
			SetControlString(def_elem, "QUOTE", "QUOTE '\"'", info.quote);
			if (info.quote.length() == 0) {
				throw Exception("QUOTE must not be empty");
			}

		} else if (def_elem->defname == kEscapeTok) {
			// escape
			SetControlString(def_elem, "ESCAPE", "ESCAPE '\"'", info.escape);
			if (info.escape.length() == 0) {
				throw Exception("ESCAPE must not be empty");
			}

		} else if (def_elem->defname == kHeaderTok) {
			// header
			auto *header_val = (PGValue *)(def_elem->arg);
			if (!header_val) {
				info.header = true;
				continue;
			}
			switch (header_val->type) {
			case T_PGInteger:
				info.header = header_val->val.ival == 1 ? true : false;
				break;
			case T_PGString: {
				auto val = duckdb::Value(string(header_val->val.str));
				info.header = val.CastAs(TypeId::BOOL).value_.boolean;
				break;
			}
			default:
				throw ParserException("Unsupported parameter type for HEADER: expected e.g. HEADER 1");
			}

		} else if (def_elem->defname == kNullTok) {
			// null
			SetControlString(def_elem, "NULL", "NULL 'null'", info.null_str);

		} else if (def_elem->defname == kForceQuoteTok) {
			// force quote
			// only for COPY ... TO ...
			if (info.is_from) {
				throw Exception("The FORCE_QUOTE option is only for COPY ... TO ...");
			}

			auto *force_quote_val = def_elem->arg;
			if (!force_quote_val || (force_quote_val->type != T_PGAStar && force_quote_val->type != T_PGList)) {
				throw ParserException("Unsupported parameter type for FORCE_QUOTE: expected e.g. FORCE_QUOTE *");
			}

			// * option (all columns)
			if (force_quote_val->type == T_PGAStar) {
				info.quote_all = true;
			}

			// list of columns
			if (force_quote_val->type == T_PGList) {
				auto column_list = (PGList *)(force_quote_val);
				for (auto c = column_list->head; c != NULL; c = lnext(c)) {
					auto target = (PGResTarget *)(c->data.ptr_value);
					info.force_quote_list.push_back(string(target->name));
				}
			}

		} else if (def_elem->defname == kForceNotNullTok) {
			// force not null
			// only for COPY ... FROM ...
			if (!info.is_from) {
				throw Exception("The FORCE_NOT_NULL option is only for COPY ... FROM ...");
			}

			auto *force_not_null_val = def_elem->arg;
			if (!force_not_null_val || force_not_null_val->type != T_PGList) {
				throw ParserException("Unsupported parameter type for FORCE_NOT_NULL: expected e.g. FORCE_NOT_NULL *");
			}

			auto column_list = (PGList *)(force_not_null_val);
			for (auto c = column_list->head; c != NULL; c = lnext(c)) {
				auto target = (PGResTarget *)(c->data.ptr_value);
				info.force_not_null_list.push_back(string(target->name));
			}

		} else if (def_elem->defname == kEncodingTok) {
			// encoding
			auto *encoding_val = (PGValue *)(def_elem->arg);
			if (!encoding_val || encoding_val->type != T_PGString) {
				throw ParserException("Unsupported parameter type for ENCODING: expected e.g. ENCODING 'UTF-8'");
			}
			if (StringUtil::Upper(encoding_val->val.str) != "UTF8" &&
			    StringUtil::Upper(encoding_val->val.str) != "UTF-8") {
				throw Exception("Copy is only supported for UTF-8 encoded files, ENCODING 'UTF-8'");
			}

		} else {
			throw ParserException("Unsupported COPY option: %s", def_elem->defname);
		}
	}
}

unique_ptr<CopyStatement> Transformer::TransformCopy(PGNode *node) {
	auto stmt = reinterpret_cast<PGCopyStmt *>(node);
	assert(stmt);
	auto result = make_unique<CopyStatement>();
	auto &info = *result->info;

	// get file_path and is_from
	info.file_path = stmt->filename;
	info.is_from = stmt->is_from;

	// get select_list
	if (stmt->attlist) {
		for (auto n = stmt->attlist->head; n != nullptr; n = n->next) {
			auto target = reinterpret_cast<PGResTarget *>(n->data.ptr_value);
			if (target->name) {
				info.select_list.push_back(string(target->name));
			}
		}
	}

	if (stmt->relation) {
		auto ref = TransformRangeVar(stmt->relation);
		if (info.is_from) {
			// copy file into table
			auto &table = *reinterpret_cast<BaseTableRef *>(ref.get());
			info.table = table.table_name;
			info.schema = table.schema_name;
		} else {
			// copy table into file, generate SELECT * FROM table;
			auto statement = make_unique<SelectNode>();
			statement->from_table = move(ref);
			if (stmt->attlist) {
				for (idx_t i = 0; i < info.select_list.size(); i++)
					statement->select_list.push_back(make_unique<ColumnRefExpression>(info.select_list[i]));
			} else {
				statement->select_list.push_back(make_unique<StarExpression>());
			}
			result->select_statement = move(statement);
		}
	} else {
		result->select_statement = TransformSelectNode((PGSelectStmt *)stmt->query);
	}

	// handle options
	if (stmt->options) {
		HandleOptions(stmt, info);
	}

	// the default character of the ESCAPE option is the same as the QUOTE character
	if (info.escape == "") {
		info.escape = info.quote;
	}
	// escape and delimiter must not be substrings of each other
	SubstringDetection(info.delimiter, info.escape, "DELIMITER", "ESCAPE");
	// delimiter and quote must not be substrings of each other
	SubstringDetection(info.quote, info.delimiter, "DELIMITER", "QUOTE");
	// escape and quote must not be substrings of each other (but can be the same)
	if (info.quote != info.escape) {
		SubstringDetection(info.quote, info.escape, "QUOTE", "ESCAPE");
	}
	// null string and delimiter must not be substrings of each other
	if (info.null_str != "") {
		SubstringDetection(info.delimiter, info.null_str, "DELIMITER", "NULL");
	}

	return result;
}

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/create_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class CreateStatement : public SQLStatement {
public:
	CreateStatement() : SQLStatement(StatementType::CREATE){};

	unique_ptr<CreateInfo> info;
};

} // namespace duckdb






using namespace duckdb;
using namespace std;

static IndexType StringToIndexType(const string &str) {
	string upper_str = StringUtil::Upper(str);
	if (upper_str == "INVALID") {
		return IndexType::INVALID;
	} else if (upper_str == "ART") {
		return IndexType::ART;
	} else {
		throw ConversionException(StringUtil::Format("No IndexType conversion from string '%s'", upper_str.c_str()));
	}
	return IndexType::INVALID;
}

unique_ptr<CreateStatement> Transformer::TransformCreateIndex(PGNode *node) {
	auto stmt = reinterpret_cast<PGIndexStmt *>(node);
	assert(stmt);
	auto result = make_unique<CreateStatement>();
	auto info = make_unique<CreateIndexInfo>();

	info->unique = stmt->unique;
	info->on_conflict = stmt->if_not_exists ? OnCreateConflict::IGNORE : OnCreateConflict::ERROR;

	for (auto cell = stmt->indexParams->head; cell != nullptr; cell = cell->next) {
		auto index_element = (PGIndexElem *)cell->data.ptr_value;
		if (index_element->collation) {
			throw NotImplementedException("Index with collation not supported yet!");
		}
		if (index_element->opclass) {
			throw NotImplementedException("Index with opclass not supported yet!");
		}

		if (index_element->name) {
			// create a column reference expression
			info->expressions.push_back(make_unique<ColumnRefExpression>(index_element->name, stmt->relation->relname));
		} else {
			// parse the index expression
			assert(index_element->expr);
			info->expressions.push_back(TransformExpression(index_element->expr));
		}
	}

	info->index_type = StringToIndexType(string(stmt->accessMethod));
	auto tableref = make_unique<BaseTableRef>();
	tableref->table_name = stmt->relation->relname;
	if (stmt->relation->schemaname) {
		tableref->schema_name = stmt->relation->schemaname;
	}
	info->table = move(tableref);
	if (stmt->idxname) {
		info->index_name = stmt->idxname;
	} else {
		throw NotImplementedException("Index wout a name not supported yet!");
	}
	result->info = move(info);
	return result;
}




using namespace duckdb;
using namespace std;

unique_ptr<CreateStatement> Transformer::TransformCreateSchema(PGNode *node) {
	auto stmt = reinterpret_cast<PGCreateSchemaStmt *>(node);
	assert(stmt);
	auto result = make_unique<CreateStatement>();
	auto info = make_unique<CreateSchemaInfo>();

	assert(stmt->schemaname);
	info->schema = stmt->schemaname;
	info->on_conflict = stmt->if_not_exists ? OnCreateConflict::IGNORE : OnCreateConflict::ERROR;

	if (stmt->schemaElts) {
		// schema elements
		for (auto cell = stmt->schemaElts->head; cell != nullptr; cell = cell->next) {
			auto node = reinterpret_cast<PGNode *>(cell->data.ptr_value);
			switch (node->type) {
			case T_PGCreateStmt:
			case T_PGViewStmt:
			default:
				throw NotImplementedException("Schema element not supported yet!");
			}
		}
	}
	result->info = move(info);
	return result;
}





using namespace duckdb;
using namespace std;

unique_ptr<CreateStatement> Transformer::TransformCreateSequence(PGNode *node) {
	auto stmt = reinterpret_cast<PGCreateSeqStmt *>(node);

	auto result = make_unique<CreateStatement>();
	auto info = make_unique<CreateSequenceInfo>();

	auto sequence_name = TransformRangeVar(stmt->sequence);
	auto &sequence_ref = (BaseTableRef &)*sequence_name;
	info->schema = sequence_ref.schema_name;
	info->name = sequence_ref.table_name;

	if (stmt->options) {
		PGListCell *cell = nullptr;
		for_each_cell(cell, stmt->options->head) {
			auto *def_elem = reinterpret_cast<PGDefElem *>(cell->data.ptr_value);
			string opt_name = string(def_elem->defname);

			auto val = (PGValue *)def_elem->arg;
			if (def_elem->defaction == PG_DEFELEM_UNSPEC && !val) { // e.g. NO MINVALUE
				continue;
			}
			assert(val);

			if (opt_name == "increment") {
				assert(val->type == T_PGInteger);
				info->increment = val->val.ival;
				if (info->increment == 0) {
					throw ParserException("Increment must not be zero");
				}
				if (info->increment < 0) {
					info->start_value = info->max_value = -1;
					info->min_value = numeric_limits<int64_t>::min();
				} else {
					info->start_value = info->min_value = 1;
					info->max_value = numeric_limits<int64_t>::max();
				}
			} else if (opt_name == "minvalue") {
				assert(val->type == T_PGInteger);
				info->min_value = val->val.ival;
				if (info->increment > 0) {
					info->start_value = info->min_value;
				}
			} else if (opt_name == "maxvalue") {
				assert(val->type == T_PGInteger);
				info->max_value = val->val.ival;
				if (info->increment < 0) {
					info->start_value = info->max_value;
				}
			} else if (opt_name == "start") {
				assert(val->type == T_PGInteger);
				info->start_value = val->val.ival;
			} else if (opt_name == "cycle") {
				assert(val->type == T_PGInteger);
				info->cycle = val->val.ival > 0;
			} else {
				throw ParserException("Unrecognized option \"%s\" for CREATE SEQUENCE", opt_name.c_str());
			}
		}
	}
	info->temporary = !stmt->sequence->relpersistence;
	info->on_conflict = stmt->if_not_exists ? OnCreateConflict::IGNORE : OnCreateConflict::ERROR;
	if (info->max_value <= info->min_value) {
		throw ParserException("MINVALUE (%lld) must be less than MAXVALUE (%lld)", info->min_value, info->max_value);
	}
	if (info->start_value < info->min_value) {
		throw ParserException("START value (%lld) cannot be less than MINVALUE (%lld)", info->start_value,
		                      info->min_value);
	}
	if (info->start_value > info->max_value) {
		throw ParserException("START value (%lld) cannot be greater than MAXVALUE (%lld)", info->start_value,
		                      info->max_value);
	}
	result->info = move(info);
	return result;
}





using namespace duckdb;
using namespace std;

unique_ptr<CreateStatement> Transformer::TransformCreateTable(PGNode *node) {
	auto stmt = reinterpret_cast<PGCreateStmt *>(node);
	assert(stmt);
	auto result = make_unique<CreateStatement>();
	auto info = make_unique<CreateTableInfo>();

	if (stmt->inhRelations) {
		throw NotImplementedException("inherited relations not implemented");
	}
	assert(stmt->relation);

	info->schema = INVALID_SCHEMA;
	if (stmt->relation->schemaname) {
		info->schema = stmt->relation->schemaname;
	}
	info->table = stmt->relation->relname;
	info->on_conflict = stmt->if_not_exists ? OnCreateConflict::IGNORE : OnCreateConflict::ERROR;
	info->temporary = stmt->relation->relpersistence == PGPostgresRelPersistence::PG_RELPERSISTENCE_TEMP;

	if (info->temporary && stmt->oncommit != PGOnCommitAction::PG_ONCOMMIT_PRESERVE_ROWS &&
	    stmt->oncommit != PGOnCommitAction::PG_ONCOMMIT_NOOP) {
		throw NotImplementedException("Only ON COMMIT PRESERVE ROWS is supported");
	}

	assert(stmt->tableElts);

	for (auto c = stmt->tableElts->head; c != NULL; c = lnext(c)) {
		auto node = reinterpret_cast<PGNode *>(c->data.ptr_value);
		switch (node->type) {
		case T_PGColumnDef: {
			auto cdef = (PGColumnDef *)c->data.ptr_value;
			SQLType target_type = TransformTypeName(cdef->typeName);
			auto centry = ColumnDefinition(cdef->colname, target_type);

			if (cdef->constraints) {
				for (auto constr = cdef->constraints->head; constr != nullptr; constr = constr->next) {
					auto constraint = TransformConstraint(constr, centry, info->columns.size());
					if (constraint) {
						info->constraints.push_back(move(constraint));
					}
				}
			}
			info->columns.push_back(move(centry));
			break;
		}
		case T_PGConstraint: {
			info->constraints.push_back(TransformConstraint(c));
			break;
		}
		default:
			throw NotImplementedException("ColumnDef type not handled yet");
		}
	}
	result->info = move(info);
	return result;
}





using namespace duckdb;
using namespace std;

unique_ptr<CreateStatement> Transformer::TransformCreateTableAs(PGNode *node) {
	auto stmt = reinterpret_cast<PGCreateTableAsStmt *>(node);
	assert(stmt);
	if (stmt->relkind == PG_OBJECT_MATVIEW) {
		throw NotImplementedException("Materialized view not implemented");
	}
	if (stmt->is_select_into || stmt->into->colNames || stmt->into->options) {
		throw NotImplementedException("Unimplemented features for CREATE TABLE as");
	}
	auto tableref = TransformRangeVar(stmt->into->rel);
	auto query = TransformSelect(stmt->query);
	auto &basetable = (BaseTableRef &)*tableref;

	auto result = make_unique<CreateStatement>();
	auto info = make_unique<CreateTableInfo>();
	info->schema = basetable.schema_name;
	info->table = basetable.table_name;
	info->on_conflict = stmt->if_not_exists ? OnCreateConflict::IGNORE : OnCreateConflict::ERROR;
	info->query = move(query);
	result->info = move(info);
	return result;
}




using namespace duckdb;
using namespace std;

unique_ptr<CreateStatement> Transformer::TransformCreateView(PGNode *node) {
	assert(node);
	assert(node->type == T_PGViewStmt);

	auto stmt = reinterpret_cast<PGViewStmt *>(node);
	assert(stmt);
	assert(stmt->view);

	auto result = make_unique<CreateStatement>();
	auto info = make_unique<CreateViewInfo>();

	if (stmt->view->schemaname) {
		info->schema = stmt->view->schemaname;
	}
	info->view_name = stmt->view->relname;
	info->temporary = !stmt->view->relpersistence;
	if (info->temporary) {
		info->schema = TEMP_SCHEMA;
	}
	info->on_conflict = stmt->replace ? OnCreateConflict::REPLACE : OnCreateConflict::ERROR;

	info->query = TransformSelectNode((PGSelectStmt *)stmt->query);

	if (stmt->aliases && stmt->aliases->length > 0) {
		for (auto c = stmt->aliases->head; c != NULL; c = lnext(c)) {
			auto node = reinterpret_cast<PGNode *>(c->data.ptr_value);
			switch (node->type) {
			case T_PGString: {
				auto val = (PGValue *)node;
				info->aliases.push_back(string(val->val.str));
				break;
			}
			default:
				throw NotImplementedException("View projection type");
			}
		}
		if (info->aliases.size() < 1) {
			throw ParserException("Need at least one column name in CREATE VIEW projection list");
		}
	}

	if (stmt->options && stmt->options->length > 0) {
		throw NotImplementedException("VIEW options");
	}

	if (stmt->withCheckOption != PGViewCheckOption::PG_NO_CHECK_OPTION) {
		throw NotImplementedException("VIEW CHECK options");
	}
	result->info = move(info);
	return result;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/delete_statement.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class DeleteStatement : public SQLStatement {
public:
	DeleteStatement() : SQLStatement(StatementType::DELETE) {
	}

	unique_ptr<ParsedExpression> condition;
	unique_ptr<TableRef> table;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<DeleteStatement> Transformer::TransformDelete(PGNode *node) {
	auto stmt = reinterpret_cast<PGDeleteStmt *>(node);
	assert(stmt);
	auto result = make_unique<DeleteStatement>();

	result->condition = TransformExpression(stmt->whereClause);
	result->table = TransformRangeVar(stmt->relation);
	if (result->table->type != TableReferenceType::BASE_TABLE) {
		throw Exception("Can only delete from base tables!");
	}
	return result;
}



using namespace duckdb;
using namespace std;

unique_ptr<SQLStatement> Transformer::TransformDrop(PGNode *node) {
	auto stmt = (PGDropStmt *)(node);
	auto result = make_unique<DropStatement>();
	auto &info = *result->info.get();
	assert(stmt);
	if (stmt->objects->length != 1) {
		throw NotImplementedException("Can only drop one object at a time");
	}
	switch (stmt->removeType) {
	case PG_OBJECT_TABLE:
		info.type = CatalogType::TABLE;
		break;
	case PG_OBJECT_SCHEMA:
		info.type = CatalogType::SCHEMA;
		break;
	case PG_OBJECT_INDEX:
		info.type = CatalogType::INDEX;
		break;
	case PG_OBJECT_VIEW:
		info.type = CatalogType::VIEW;
		break;
	case PG_OBJECT_SEQUENCE:
		info.type = CatalogType::SEQUENCE;
		break;
	default:
		throw NotImplementedException("Cannot drop this type yet");
	}

	switch (stmt->removeType) {
	case PG_OBJECT_SCHEMA:
		assert(stmt->objects && stmt->objects->length == 1);
		info.name = ((PGValue *)stmt->objects->head->data.ptr_value)->val.str;
		break;
	default: {
		auto view_list = (PGList *)stmt->objects->head->data.ptr_value;
		if (view_list->length == 2) {
			info.schema = ((PGValue *)view_list->head->data.ptr_value)->val.str;
			info.name = ((PGValue *)view_list->head->next->data.ptr_value)->val.str;
		} else {
			info.name = ((PGValue *)view_list->head->data.ptr_value)->val.str;
		}
		break;
	}
	}
	info.cascade = stmt->behavior == PGDropBehavior::PG_DROP_CASCADE;
	info.if_exists = stmt->missing_ok;
	return move(result);
}



using namespace duckdb;
using namespace std;

unique_ptr<ExplainStatement> Transformer::TransformExplain(PGNode *node) {
	PGExplainStmt *stmt = reinterpret_cast<PGExplainStmt *>(node);
	assert(stmt);
	return make_unique<ExplainStatement>(TransformStatement(stmt->query));

}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/insert_statement.hpp
//
//
//===----------------------------------------------------------------------===//






#include <vector>

namespace duckdb {

class InsertStatement : public SQLStatement {
public:
	InsertStatement() : SQLStatement(StatementType::INSERT), schema(DEFAULT_SCHEMA){};

	//! The select statement to insert from
	unique_ptr<SelectStatement> select_statement;
	//! Column names to insert into
	vector<string> columns;

	//! Table name to insert to
	string table;
	//! Schema name to insert to
	string schema;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

unique_ptr<TableRef> Transformer::TransformValuesList(PGList *list) {
	auto result = make_unique<ExpressionListRef>();
	for (auto value_list = list->head; value_list != NULL; value_list = value_list->next) {
		auto target = (PGList *)(value_list->data.ptr_value);

		vector<unique_ptr<ParsedExpression>> insert_values;
		if (!TransformExpressionList(target, insert_values)) {
			throw ParserException("Could not parse expression list!");
		}
		if (result->values.size() > 0) {
			if (result->values[0].size() != insert_values.size()) {
				throw ParserException("VALUES lists must all be the same length");
			}
		}
		result->values.push_back(move(insert_values));
	}
	result->alias = "valueslist";
	return move(result);
}

unique_ptr<InsertStatement> Transformer::TransformInsert(PGNode *node) {
	auto stmt = reinterpret_cast<PGInsertStmt *>(node);
	assert(stmt);

	auto result = make_unique<InsertStatement>();

	// first check if there are any columns specified
	if (stmt->cols) {
		for (auto c = stmt->cols->head; c != NULL; c = lnext(c)) {
			auto target = (PGResTarget *)(c->data.ptr_value);
			result->columns.push_back(string(target->name));
		}
	}
	result->select_statement = TransformSelect(stmt->selectStmt);

	auto ref = TransformRangeVar(stmt->relation);
	auto &table = *reinterpret_cast<BaseTableRef *>(ref.get());
	result->table = table.table_name;
	result->schema = table.schema_name;
	return result;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/pragma_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class PragmaStatement : public SQLStatement {
public:
	PragmaStatement() : SQLStatement(StatementType::PRAGMA), info(make_unique<PragmaInfo>()){};

	unique_ptr<PragmaInfo> info;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

unique_ptr<PragmaStatement> Transformer::TransformPragma(PGNode *node) {
	auto stmt = reinterpret_cast<PGPragmaStmt *>(node);

	auto result = make_unique<PragmaStatement>();
	auto &info = *result->info;

	info.name = stmt->name;
	// parse the arguments, if any
	if (stmt->args) {
		for (auto cell = stmt->args->head; cell != nullptr; cell = cell->next) {
			auto node = reinterpret_cast<PGNode *>(cell->data.ptr_value);
			if (node->type != T_PGAConst) {
				throw ParserException("Unsupported PRAGMA parameter: can only accept constants!");
			}
			auto constant = TransformConstant((PGAConst *)node);
			info.parameters.push_back(((ConstantExpression &)*constant).value);
		}
	}
	// now parse the pragma type
	switch (stmt->kind) {
	case PG_PRAGMA_TYPE_NOTHING:
		if (info.parameters.size() > 0) {
			throw ParserException("PRAGMA statement that is not a call or assignment cannot contain parameters");
		}
		info.pragma_type = PragmaType::NOTHING;
		break;
	case PG_PRAGMA_TYPE_ASSIGNMENT:
		if (info.parameters.size() != 1) {
			throw ParserException("PRAGMA statement with assignment should contain exactly one parameter");
		}
		info.pragma_type = PragmaType::ASSIGNMENT;
		break;
	case PG_PRAGMA_TYPE_CALL:
		info.pragma_type = PragmaType::CALL;
		break;
	default:
		throw ParserException("Unknown pragma type");
	}

	return result;
}





using namespace duckdb;
using namespace std;

unique_ptr<PrepareStatement> Transformer::TransformPrepare(PGNode *node) {
	auto stmt = reinterpret_cast<PGPrepareStmt *>(node);
	assert(stmt);

	if (stmt->argtypes && stmt->argtypes->length > 0) {
		throw NotImplementedException("Prepared statement argument types are not supported, use CAST");
	}

	auto result = make_unique<PrepareStatement>();
	result->name = string(stmt->name);
	result->statement = TransformStatement(stmt->query);
	prepared_statement_parameter_index = 0;

	return result;
}

unique_ptr<ExecuteStatement> Transformer::TransformExecute(PGNode *node) {
	auto stmt = reinterpret_cast<PGExecuteStmt *>(node);
	assert(stmt);

	auto result = make_unique<ExecuteStatement>();
	result->name = string(stmt->name);

	TransformExpressionList(stmt->params, result->values);
	for (auto &expr : result->values) {
		if (expr->GetExpressionType() != ExpressionType::VALUE_CONSTANT &&
		    expr->GetExpressionType() != ExpressionType::VALUE_NULL) {
			throw Exception("Only scalar parameters or NULL supported for EXECUTE");
		}
	}

	return result;
}

unique_ptr<DropStatement> Transformer::TransformDeallocate(PGNode *node) {
	auto stmt = reinterpret_cast<PGDeallocateStmt *>(node);
	assert(stmt);

	auto result = make_unique<DropStatement>();
	result->info->type = CatalogType::PREPARED_STATEMENT;
	result->info->name = string(stmt->name);
	return result;
}



using namespace duckdb;
using namespace std;

unique_ptr<AlterTableStatement> Transformer::TransformRename(PGNode *node) {
	auto stmt = reinterpret_cast<PGRenameStmt *>(node);
	assert(stmt);
	assert(stmt->relation);

	unique_ptr<AlterTableInfo> info;

	// first we check the type of ALTER
	switch (stmt->renameType) {
	case PG_OBJECT_COLUMN: {
		// change column name

		// get the table and schema
		string schema = INVALID_SCHEMA;
		string table;
		assert(stmt->relation->relname);
		if (stmt->relation->relname) {
			table = stmt->relation->relname;
		}
		if (stmt->relation->schemaname) {
			schema = stmt->relation->schemaname;
		}
		// get the old name and the new name
		string old_name = stmt->subname;
		string new_name = stmt->newname;
		info = make_unique<RenameColumnInfo>(schema, table, old_name, new_name);
		break;
	}
    case PG_OBJECT_TABLE: {
        // change table name

        // get the table and schema
        string schema = DEFAULT_SCHEMA;
        string table;
        assert(stmt->relation->relname);
        if (stmt->relation->relname) {
            table = stmt->relation->relname;
        }
        if (stmt->relation->schemaname) {
            schema = stmt->relation->schemaname;
        }
        string new_name = stmt->newname;
        info = make_unique<RenameTableInfo>(schema, table, new_name);
        break;
    }

	case PG_OBJECT_DATABASE:
	default:
		throw NotImplementedException("Schema element not supported yet!");
	}
	assert(info);
	return make_unique<AlterTableStatement>(move(info));
}




using namespace duckdb;
using namespace std;

unique_ptr<SelectStatement> Transformer::TransformSelect(PGNode *node) {
	auto stmt = reinterpret_cast<PGSelectStmt *>(node);
	auto result = make_unique<SelectStatement>();

	if (stmt->windowClause) {
		for (auto window_ele = stmt->windowClause->head; window_ele != NULL; window_ele = window_ele->next) {
			auto window_def = reinterpret_cast<PGWindowDef *>(window_ele->data.ptr_value);
			assert(window_def);
			assert(window_def->name);
			auto window_name = StringUtil::Lower(string(window_def->name));

			auto it = window_clauses.find(window_name);
			if (it != window_clauses.end()) {
				throw Exception("A window specification needs an unique name");
			}
			window_clauses[window_name] = window_def;
		}
	}

	// may contain windows so second
	if (stmt->withClause) {
		TransformCTE(reinterpret_cast<PGWithClause *>(stmt->withClause), *result);
	}

	result->node = TransformSelectNode(stmt);
	return result;
}







using namespace duckdb;
using namespace std;

unique_ptr<QueryNode> Transformer::TransformSelectNode(PGSelectStmt *stmt) {
	unique_ptr<QueryNode> node;
	switch (stmt->op) {
	case PG_SETOP_NONE: {
		node = make_unique<SelectNode>();
		auto result = (SelectNode *)node.get();
		// do this early so the value lists also have a `FROM`
		if (stmt->valuesLists) {
			// VALUES list, create an ExpressionList
			assert(!stmt->fromClause);
			result->from_table = TransformValuesList(stmt->valuesLists);
			result->select_list.push_back(make_unique<StarExpression>());
		} else {
			result->from_table = TransformFrom(stmt->fromClause);
			if (!stmt->targetList) {
				throw ParserException("SELECT clause without selection list");
			}
			// select list
			if (!TransformExpressionList(stmt->targetList, result->select_list)) {
				throw Exception("Failed to transform expression list.");
			}
		}
		// checks distinct clause
		if (stmt->distinctClause != NULL) {
			result->select_distinct = true;
			// checks distinct on clause
			auto target = reinterpret_cast<PGNode *>(stmt->distinctClause->head->data.ptr_value);
			if (target) {
				//  add the columns defined in the ON clause to the select list
				if (!TransformExpressionList(stmt->distinctClause, result->distinct_on_targets)) {
					throw Exception("Failed to transform expression list from DISTINCT ON.");
				}
			}
		}
		// from table
		// group by
		TransformGroupBy(stmt->groupClause, result->groups);
		result->having = TransformExpression(stmt->havingClause);
		// where
		result->where_clause = TransformExpression(stmt->whereClause);
		break;
	}
	case PG_SETOP_UNION:
	case PG_SETOP_EXCEPT:
	case PG_SETOP_INTERSECT: {
		node = make_unique<SetOperationNode>();
		auto result = (SetOperationNode *)node.get();
		result->left = TransformSelectNode(stmt->larg);
		result->right = TransformSelectNode(stmt->rarg);
		if (!result->left || !result->right) {
			throw Exception("Failed to transform setop children.");
		}

		result->select_distinct = true;
		switch (stmt->op) {
		case PG_SETOP_UNION:
			result->select_distinct = !stmt->all;
			result->setop_type = SetOperationType::UNION;
			break;
		case PG_SETOP_EXCEPT:
			result->setop_type = SetOperationType::EXCEPT;
			break;
		case PG_SETOP_INTERSECT:
			result->setop_type = SetOperationType::INTERSECT;
			break;
		default:
			throw Exception("Unexpected setop type");
		}
		// if we compute the distinct result here, we do not have to do this in
		// the children. This saves a bunch of unnecessary DISTINCTs.
		if (result->select_distinct) {
			result->left->select_distinct = false;
			result->right->select_distinct = false;
		}
		break;
	}
	default:
		throw NotImplementedException("Statement type %d not implemented!", stmt->op);
	}
	// transform the common properties
	// both the set operations and the regular select can have an ORDER BY/LIMIT attached to them
	TransformOrderBy(stmt->sortClause, node->orders);
	if (stmt->limitCount) {
		node->limit = TransformExpression(stmt->limitCount);
	}
	if (stmt->limitOffset) {
		node->offset = TransformExpression(stmt->limitOffset);
	}
	return node;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/transaction_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class TransactionStatement : public SQLStatement {
public:
	TransactionStatement(TransactionType type)
	    : SQLStatement(StatementType::TRANSACTION), info(make_unique<TransactionInfo>(type)){};

	unique_ptr<TransactionInfo> info;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<TransactionStatement> Transformer::TransformTransaction(PGNode *node) {
	auto stmt = reinterpret_cast<PGTransactionStmt *>(node);
	assert(stmt);
	switch (stmt->kind) {
	case PG_TRANS_STMT_BEGIN:
	case PG_TRANS_STMT_START:
		return make_unique<TransactionStatement>(TransactionType::BEGIN_TRANSACTION);
	case PG_TRANS_STMT_COMMIT:
		return make_unique<TransactionStatement>(TransactionType::COMMIT);
	case PG_TRANS_STMT_ROLLBACK:
		return make_unique<TransactionStatement>(TransactionType::ROLLBACK);
	default:
		throw NotImplementedException("Transaction type %d not implemented yet", stmt->kind);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/update_statement.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class UpdateStatement : public SQLStatement {
public:
	UpdateStatement() : SQLStatement(StatementType::UPDATE) {
	}

	unique_ptr<ParsedExpression> condition;
	unique_ptr<TableRef> table;

	vector<string> columns;
	vector<unique_ptr<ParsedExpression>> expressions;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<UpdateStatement> Transformer::TransformUpdate(PGNode *node) {
	auto stmt = reinterpret_cast<PGUpdateStmt *>(node);
	assert(stmt);

	auto result = make_unique<UpdateStatement>();

	result->table = TransformRangeVar(stmt->relation);
	result->condition = TransformExpression(stmt->whereClause);

	auto root = stmt->targetList;
	for (auto cell = root->head; cell != NULL; cell = cell->next) {
		auto target = (PGResTarget *)(cell->data.ptr_value);
		result->columns.push_back(target->name);
		result->expressions.push_back(TransformExpression(target->val));
	}
	return result;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/parser/statement/explain_statement.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

class VacuumStatement : public SQLStatement {
public:
	VacuumStatement() : SQLStatement(StatementType::VACUUM){};
	unique_ptr<VacuumInfo> info;

};

} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<VacuumStatement> Transformer::TransformVacuum(PGNode *node) {
	auto stmt = reinterpret_cast<PGVacuumStmt *>(node);
	assert(stmt);
	auto result = make_unique<VacuumStatement>();
	return result;
}



using namespace duckdb;
using namespace std;

unique_ptr<TableRef> Transformer::TransformRangeVar(PGRangeVar *root) {
	auto result = make_unique<BaseTableRef>();

	result->alias = TransformAlias(root->alias);
	if (root->relname)
		result->table_name = root->relname;
	if (root->schemaname)
		result->schema_name = root->schemaname;
	return move(result);
}




using namespace duckdb;
using namespace std;

unique_ptr<TableRef> Transformer::TransformFrom(PGList *root) {
	if (!root) {
		return make_unique<EmptyTableRef>();
	}

	if (root->length > 1) {
		// Cross Product
		auto result = make_unique<CrossProductRef>();
		CrossProductRef *cur_root = result.get();
		for (auto node = root->head; node != nullptr; node = node->next) {
			auto n = reinterpret_cast<PGNode *>(node->data.ptr_value);
			unique_ptr<TableRef> next = TransformTableRefNode(n);
			if (!cur_root->left) {
				cur_root->left = move(next);
			} else if (!cur_root->right) {
				cur_root->right = move(next);
			} else {
				auto old_res = move(result);
				result = make_unique<CrossProductRef>();
				result->left = move(old_res);
				result->right = move(next);
				cur_root = result.get();
			}
		}
		return move(result);
	}

	auto n = reinterpret_cast<PGNode *>(root->head->data.ptr_value);
	return TransformTableRefNode(n);
}









using namespace duckdb;
using namespace std;

static string get_tablename_union(TableRef *ref) {
	switch (ref->type) {
	case TableReferenceType::BASE_TABLE:
		if (ref->alias.size() > 0) {
			return ref->alias;
		}
		return ((BaseTableRef *)ref)->table_name;
	case TableReferenceType::SUBQUERY:
		assert(ref->alias.length() > 0);
		return ref->alias;
	default:
		throw ParserException("Cannot get table name for USING");
	}
}

unique_ptr<TableRef> Transformer::TransformJoin(PGJoinExpr *root) {
	auto result = make_unique<JoinRef>();
	switch (root->jointype) {
	case PG_JOIN_INNER: {
		result->type = JoinType::INNER;
		break;
	}
	case PG_JOIN_LEFT: {
		result->type = JoinType::LEFT;
		break;
	}
	case PG_JOIN_FULL: {
		result->type = JoinType::OUTER;
		break;
	}
	case PG_JOIN_RIGHT: {
		result->type = JoinType::RIGHT;
		break;
	}
	case PG_JOIN_SEMI: {
		result->type = JoinType::SEMI;
		break;
	}
	default: {
		throw NotImplementedException("Join type %d not supported yet...\n", root->jointype);
	}
	}

	// Check the type of left arg and right arg before transform
	result->left = TransformTableRefNode(root->larg);
	result->right = TransformTableRefNode(root->rarg);

	if (root->usingClause && root->usingClause->length > 0) {
		// usingClause is a list of strings
		vector<string> using_column_names;
		for (auto node = root->usingClause->head; node != nullptr; node = node->next) {
			auto target = reinterpret_cast<PGNode *>(node->data.ptr_value);
			assert(target->type == T_PGString);
			auto column_name = string(reinterpret_cast<PGValue *>(target)->val.str);
			using_column_names.push_back(column_name);
		}
		assert(using_column_names.size() > 0);

		unique_ptr<ParsedExpression> join_condition = nullptr;
		for (auto column_name : using_column_names) {
			auto left_expr = make_unique<ColumnRefExpression>(column_name, get_tablename_union(result->left.get()));
			auto right_expr = make_unique<ColumnRefExpression>(column_name, get_tablename_union(result->right.get()));
			result->hidden_columns.insert(right_expr->table_name + "." + right_expr->column_name);
			auto comp_expr =
			    make_unique<ComparisonExpression>(ExpressionType::COMPARE_EQUAL, move(left_expr), move(right_expr));
			if (!join_condition) {
				join_condition = move(comp_expr);
			} else {
				join_condition = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_AND,
				                                                    move(join_condition), move(comp_expr));
			}
		}
		assert(join_condition != nullptr);
		result->condition = move(join_condition);
		return move(result);
	}

	if (!root->quals) { // CROSS PRODUCT
		auto cross = make_unique<CrossProductRef>();
		cross->left = move(result->left);
		cross->right = move(result->right);
		return move(cross);
	}

	result->condition = TransformExpression(root->quals);
	return move(result);
}



using namespace duckdb;
using namespace std;

unique_ptr<TableRef> Transformer::TransformRangeSubselect(PGRangeSubselect *root) {
	auto subquery = TransformSelectNode((PGSelectStmt *)root->subquery);
	if (!subquery) {
		return nullptr;
	}
	auto result = make_unique<SubqueryRef>(move(subquery));
	result->alias = TransformAlias(root->alias);
	if (root->alias->colnames) {
		for (auto node = root->alias->colnames->head; node != nullptr; node = node->next) {
			result->column_name_alias.push_back(reinterpret_cast<PGValue *>(node->data.ptr_value)->val.str);
		}
	}
	return move(result);
}




using namespace duckdb;
using namespace std;

unique_ptr<TableRef> Transformer::TransformRangeFunction(PGRangeFunction *root) {
	if (root->lateral) {
		throw NotImplementedException("LATERAL not implemented");
	}
	if (root->ordinality) {
		throw NotImplementedException("WITH ORDINALITY not implemented");
	}
	if (root->is_rowsfrom) {
		throw NotImplementedException("ROWS FROM() not implemented");
	}
	if (root->functions->length != 1) {
		throw NotImplementedException("Need exactly one function");
	}
	auto function_sublist = (PGList *)root->functions->head->data.ptr_value;
	assert(function_sublist->length == 2);
	auto call_tree = (PGNode *)function_sublist->head->data.ptr_value;
	auto coldef = function_sublist->head->next->data.ptr_value;

	assert(call_tree->type == T_PGFuncCall);
	if (coldef) {
		throw NotImplementedException("Explicit column definition not supported yet");
	}
	// transform the function call
	auto result = make_unique<TableFunctionRef>();
	result->function = TransformFuncCall((PGFuncCall *)call_tree);
	result->alias = TransformAlias(root->alias);
	return move(result);
}




using namespace duckdb;
using namespace std;

unique_ptr<TableRef> Transformer::TransformTableRefNode(PGNode *n) {
	switch (n->type) {
	case T_PGRangeVar:
		return TransformRangeVar(reinterpret_cast<PGRangeVar *>(n));
	case T_PGJoinExpr:
		return TransformJoin(reinterpret_cast<PGJoinExpr *>(n));
	case T_PGRangeSubselect:
		return TransformRangeSubselect(reinterpret_cast<PGRangeSubselect *>(n));
	case T_PGRangeFunction:
		return TransformRangeFunction(reinterpret_cast<PGRangeFunction *>(n));
	default:
		throw NotImplementedException("From Type %d not supported yet...", n->type);
	}
}




















using namespace duckdb;
using namespace std;

bool Transformer::TransformParseTree(PGList *tree, vector<unique_ptr<SQLStatement>> &statements) {
	for (auto entry = tree->head; entry != nullptr; entry = entry->next) {
		auto stmt = TransformStatement((PGNode *)entry->data.ptr_value);
		if (!stmt) {
			statements.clear();
			return false;
		}
		statements.push_back(move(stmt));
	}
	return true;
}

unique_ptr<SQLStatement> Transformer::TransformStatement(PGNode *stmt) {
	switch (stmt->type) {
	case T_PGRawStmt: {
		auto raw_stmt = (PGRawStmt *)stmt;
		auto result = TransformStatement(raw_stmt->stmt);
		if (result) {
			result->stmt_location = raw_stmt->stmt_location;
			result->stmt_length = raw_stmt->stmt_len;
		}
		return result;
	}
	case T_PGSelectStmt:
		return TransformSelect(stmt);
	case T_PGCreateStmt:
		return TransformCreateTable(stmt);
	case T_PGCreateSchemaStmt:
		return TransformCreateSchema(stmt);
	case T_PGViewStmt:
		return TransformCreateView(stmt);
	case T_PGCreateSeqStmt:
		return TransformCreateSequence(stmt);
	case T_PGDropStmt:
		return TransformDrop(stmt);
	case T_PGInsertStmt:
		return TransformInsert(stmt);
	case T_PGCopyStmt:
		return TransformCopy(stmt);
	case T_PGTransactionStmt:
		return TransformTransaction(stmt);
	case T_PGDeleteStmt:
		return TransformDelete(stmt);
	case T_PGUpdateStmt:
		return TransformUpdate(stmt);
	case T_PGIndexStmt:
		return TransformCreateIndex(stmt);
	case T_PGAlterTableStmt:
		return TransformAlter(stmt);
	case T_PGRenameStmt:
		return TransformRename(stmt);
	case T_PGPrepareStmt:
		return TransformPrepare(stmt);
	case T_PGExecuteStmt:
		return TransformExecute(stmt);
	case T_PGDeallocateStmt:
		return TransformDeallocate(stmt);
	case T_PGCreateTableAsStmt:
		return TransformCreateTableAs(stmt);
	case T_PGPragmaStmt:
		return TransformPragma(stmt);
	case T_PGExplainStmt:
		return TransformExplain(stmt);
	case T_PGVacuumStmt:
		return TransformVacuum(stmt);

	default:
		throw NotImplementedException(NodetypeToString(stmt->type));
	}
	return nullptr;
}





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_basetableref.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/bound_tableref.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

class BoundTableRef {
public:
	BoundTableRef(TableReferenceType type) : type(type) {
	}
	virtual ~BoundTableRef() {
	}

	//! The type of table reference
	TableReferenceType type;
};
} // namespace duckdb


namespace duckdb {
class TableCatalogEntry;

//! Represents a TableReference to a base table in the schema
class BoundBaseTableRef : public BoundTableRef {
public:
	BoundBaseTableRef(TableCatalogEntry *table, idx_t bind_index)
	    : BoundTableRef(TableReferenceType::BASE_TABLE), table(table), bind_index(bind_index) {
	}

	//! The referenced table
	TableCatalogEntry *table;
	//! The set of columns bound to this base table reference
	vector<string> bound_columns;
	//! The index in the bind context
	idx_t bind_index;
};
} // namespace duckdb




#include <algorithm>

using namespace duckdb;
using namespace std;

string BindContext::GetMatchingBinding(const string &column_name) {
	string result;
	for (auto &kv : bindings) {
		auto binding = kv.second.get();
		if (binding->HasMatchingBinding(column_name)) {
			if (!result.empty()) {
				throw BinderException("Ambiguous reference to column name \"%s\" (use: \"%s.%s\" "
				                      "or \"%s.%s\")",
				                      column_name.c_str(), result.c_str(), column_name.c_str(), kv.first.c_str(),
				                      column_name.c_str());
			}
			result = kv.first;
		}
	}
	return result;
}

Binding *BindContext::GetCTEBinding(const string &ctename) {
	auto match = cte_bindings.find(ctename);
	if (match == cte_bindings.end()) {
		return nullptr;
	}
	return match->second.get();
}

BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
	if (colref.table_name.empty()) {
		return BindResult(StringUtil::Format("Could not bind alias \"%s\"!", colref.column_name.c_str()));
	}

	auto match = bindings.find(colref.table_name);
	if (match == bindings.end()) {
		// alias not found in this BindContext
		return BindResult(StringUtil::Format("Referenced table \"%s\" not found!", colref.table_name.c_str()));
	}
	auto binding = match->second.get();
	return binding->Bind(colref, depth);
}

void BindContext::GenerateAllColumnExpressions(vector<unique_ptr<ParsedExpression>> &new_select_list,
                                               string relation_name) {
	if (bindings_list.size() == 0) {
		throw BinderException("SELECT * expression without FROM clause!");
	}
	if (relation_name == "") { // SELECT * case
		// we have to bind the tables and subqueries in order of table_index
		for (auto &entry : bindings_list) {
			auto binding = entry.second;
			binding->GenerateAllColumnExpressions(*this, new_select_list);
		}
	} else { // SELECT tbl.* case
		auto match = bindings.find(relation_name);
		if (match == bindings.end()) {
			// alias not found in this BindContext
			throw BinderException("SELECT table.* expression but can't find table");
		}
		auto binding = match->second.get();
		binding->GenerateAllColumnExpressions(*this, new_select_list);
	}
}

void BindContext::AddBinding(const string &alias, unique_ptr<Binding> binding) {
	if (bindings.find(alias) != bindings.end()) {
		throw BinderException("Duplicate alias \"%s\" in query!", alias.c_str());
	}
	bindings_list.push_back(make_pair(alias, binding.get()));
	bindings[alias] = move(binding);
}

void BindContext::AddBaseTable(BoundBaseTableRef *bound, const string &alias) {
	AddBinding(alias, make_unique<TableBinding>(alias, bound));
}

void BindContext::AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery) {
	AddBinding(alias, make_unique<SubqueryBinding>(alias, ref, subquery, index));
}

void BindContext::AddGenericBinding(idx_t index, const string &alias, vector<string> names, vector<SQLType> types) {
	AddBinding(alias, make_unique<GenericBinding>(alias, move(types), move(names), index));
}

void BindContext::AddCTEBinding(idx_t index, const string &alias, vector<string> names, vector<SQLType> types) {
	auto binding = make_shared<GenericBinding>(alias, move(types), move(names), index);

	if (cte_bindings.find(alias) != cte_bindings.end()) {
		throw BinderException("Duplicate alias \"%s\" in query!", alias.c_str());
	}
	cte_bindings[alias] = move(binding);
	cte_references[alias] = std::make_shared<idx_t>(0);
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/aggregate_binder.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The AggregateBinder is responsible for binding aggregate statements extracted from a SELECT clause (by the
//! SelectBinder)
class AggregateBinder : public ExpressionBinder {
	friend class SelectBinder;

public:
	AggregateBinder(Binder &binder, ClientContext &context);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/select_binder.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class BoundColumnRefExpression;
class WindowExpression;

class BoundSelectNode;

struct BoundGroupInformation {
	expression_map_t<idx_t> map;
	unordered_map<string, idx_t> alias_map;
	vector<SQLType> group_types;
};

//! The SELECT binder is responsible for binding an expression within the SELECT clause of a SQL statement
class SelectBinder : public ExpressionBinder {
public:
	SelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	BindResult BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function, idx_t depth) override;

	BindResult BindUnnest(FunctionExpression &function, idx_t depth) override;

	bool inside_window;

	BoundSelectNode &node;
	BoundGroupInformation &info;

protected:
	BindResult BindWindow(WindowExpression &expr, idx_t depth);

	idx_t TryBindGroup(ParsedExpression &expr, idx_t depth);
	BindResult BindGroup(ParsedExpression &expr, idx_t depth, idx_t group_index);
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/query_node/bound_select_node.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Bound equivalent of SelectNode
class BoundSelectNode : public BoundQueryNode {
public:
	BoundSelectNode() : BoundQueryNode(QueryNodeType::SELECT_NODE) {
	}

	//! The projection list
	vector<unique_ptr<Expression>> select_list;
	//! The FROM clause
	unique_ptr<BoundTableRef> from_table;
	//! The WHERE clause
	unique_ptr<Expression> where_clause;
	//! list of groups
	vector<unique_ptr<Expression>> groups;
	//! HAVING clause
	unique_ptr<Expression> having;

	//! The amount of columns in the final result
	idx_t column_count;

	//! Index used by the LogicalProjection
	idx_t projection_index;

	//! Group index used by the LogicalAggregate (only used if HasAggregation is true)
	idx_t group_index;
	//! Aggregate index used by the LogicalAggregate (only used if HasAggregation is true)
	idx_t aggregate_index;
	//! Aggregate functions to compute (only used if HasAggregation is true)
	vector<unique_ptr<Expression>> aggregates;

	//! Map from aggregate function to aggregate index (used to eliminate duplicate aggregates)
	expression_map_t<idx_t> aggregate_map;

	//! Window index used by the LogicalWindow (only used if HasWindow is true)
	idx_t window_index;
	//! Window functions to compute (only used if HasWindow is true)
	vector<unique_ptr<Expression>> windows;

	idx_t unnest_index;
	//! Unnest expression
	vector<unique_ptr<Expression>> unnests;

public:
	idx_t GetRootIndex() override {
		return projection_index;
	}
};
}; // namespace duckdb


using namespace duckdb;
using namespace std;

BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFunctionCatalogEntry *func, idx_t depth) {
	// first bind the child of the aggregate expression (if any)
	AggregateBinder aggregate_binder(binder, context);
	string error;
	for (idx_t i = 0; i < aggr.children.size(); i++) {
		aggregate_binder.BindChild(aggr.children[i], 0, error);
	}
	if (!error.empty()) {
		// failed to bind child
		if (aggregate_binder.BoundColumns()) {
			for (idx_t i = 0; i < aggr.children.size(); i++) {
				// however, we bound columns!
				// that means this aggregation belongs to this node
				// check if we have to resolve any errors by binding with parent binders
				bool success = aggregate_binder.BindCorrelatedColumns(aggr.children[i]);
				// if there is still an error after this, we could not successfully bind the aggregate
				if (!success) {
					throw BinderException(error);
				}
				auto &bound_expr = (BoundExpression &)*aggr.children[i];
				ExtractCorrelatedExpressions(binder, *bound_expr.expr);
			}
		} else {
			// we didn't bind columns, try again in children
			return BindResult(error);
		}
	}
	// all children bound successfully
	// extract the children and types
	vector<SQLType> types;
	vector<SQLType> arguments;
	vector<unique_ptr<Expression>> children;
	for (idx_t i = 0; i < aggr.children.size(); i++) {
		auto &child = (BoundExpression &)*aggr.children[i];
		types.push_back(child.sql_type);
		arguments.push_back(child.sql_type);
		children.push_back(move(child.expr));
	}

	// bind the aggregate
	idx_t best_function = Function::BindFunction(func->name, func->functions, types);
	// found a matching function!
	auto &bound_function = func->functions[best_function];
	// check if we need to add casts to the children
	bound_function.CastToFunctionArguments(children, types);

	// create the aggregate
	auto aggregate = make_unique<BoundAggregateExpression>(GetInternalType(bound_function.return_type), bound_function, aggr.distinct);
	aggregate->children = move(children);
	aggregate->arguments = arguments;

	auto return_type = bound_function.return_type;


	if (bound_function.bind) {
		aggregate->bind_info = bound_function.bind(*aggregate, context, return_type);
	}


	// check for all the aggregates if this aggregate already exists
	idx_t aggr_index;
	auto entry = node.aggregate_map.find(aggregate.get());
	if (entry == node.aggregate_map.end()) {
		// new aggregate: insert into aggregate list
		aggr_index = node.aggregates.size();
		node.aggregate_map.insert(make_pair(aggregate.get(), aggr_index));
		node.aggregates.push_back(move(aggregate));
	} else {
		// duplicate aggregate: simplify refer to this aggregate
		aggr_index = entry->second;
	}

	// now create a column reference referring to the aggregate
	auto colref = make_unique<BoundColumnRefExpression>(
	    aggr.alias.empty() ? node.aggregates[aggr_index]->ToString() : aggr.alias,
	    node.aggregates[aggr_index]->return_type, ColumnBinding(node.aggregate_index, aggr_index), depth);
	// move the aggregate expression into the set of bound aggregates
	return BindResult(move(colref), return_type);
}





using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(CaseExpression &expr, idx_t depth) {
	// first try to bind the children of the case expression
	string error;
	BindChild(expr.check, depth, error);
	BindChild(expr.result_if_true, depth, error);
	BindChild(expr.result_if_false, depth, error);
	if (!error.empty()) {
		return BindResult(error);
	}
	// the children have been successfully resolved
	// now resolve the type of the result
	auto &check = (BoundExpression &)*expr.check;
	auto &result_if_true = (BoundExpression &)*expr.result_if_true;
	auto &result_if_false = (BoundExpression &)*expr.result_if_false;
	// add a cast to BOOLEAN in the CHECK condition
	check.expr = BoundCastExpression::AddCastToType(move(check.expr), check.sql_type, SQLType(SQLTypeId::BOOLEAN));
	// now obtain the result type of the input types
	auto return_type = MaxSQLType(result_if_true.sql_type, result_if_false.sql_type);
	// add casts (if necessary)
	result_if_true.expr =
	    BoundCastExpression::AddCastToType(move(result_if_true.expr), result_if_true.sql_type, return_type);
	result_if_false.expr =
	    BoundCastExpression::AddCastToType(move(result_if_false.expr), result_if_false.sql_type, return_type);
	// now create the bound case expression
	return BindResult(
	    make_unique<BoundCaseExpression>(move(check.expr), move(result_if_true.expr), move(result_if_false.expr)),
	    return_type);
}





using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(CastExpression &expr, idx_t depth) {
	// first try to bind the child of the cast expression
	string error = Bind(&expr.child, depth);
	if (!error.empty()) {
		return BindResult(error);
	}
	// the children have been successfully resolved
	auto &child = (BoundExpression &)*expr.child;
	if (child.expr->type == ExpressionType::VALUE_PARAMETER) {
		auto &parameter = (BoundParameterExpression &)*child.expr;
		// parameter: move types into the parameter expression itself
		parameter.return_type = GetInternalType(expr.cast_type);
		parameter.sql_type = expr.cast_type;
	} else {
		// otherwise add a cast to the target type
		child.expr = BoundCastExpression::AddCastToType(move(child.expr), child.sql_type, expr.cast_type);
	}
	return BindResult(move(child.expr), expr.cast_type);
}






using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref, idx_t depth) {
	assert(!colref.column_name.empty());
	// individual column reference
	// resolve to either a base table or a subquery expression
	if (colref.table_name.empty()) {
		// no table name: find a binding that contains this
		colref.table_name = binder.bind_context.GetMatchingBinding(colref.column_name);
		if (colref.table_name.empty()) {
			return BindResult(
			    StringUtil::Format("Referenced column \"%s\" not found in FROM clause!", colref.column_name.c_str()));
		}
	}
	BindResult result = binder.bind_context.BindColumn(colref, depth);
	if (!result.HasError()) {
		bound_columns = true;
	}
	return result;
}





using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(ComparisonExpression &expr, idx_t depth) {
	// first try to bind the children of the case expression
	string error;
	BindChild(expr.left, depth, error);
	BindChild(expr.right, depth, error);
	if (!error.empty()) {
		return BindResult(error);
	}
	// the children have been successfully resolved
	auto &left = (BoundExpression &)*expr.left;
	auto &right = (BoundExpression &)*expr.right;
	// cast the input types to the same type
	// now obtain the result type of the input types
	auto input_type = MaxSQLType(left.sql_type, right.sql_type);
	if (input_type.id == SQLTypeId::VARCHAR) {
		// for comparison with strings, we prefer to bind to the numeric types
		if (left.sql_type.IsNumeric()) {
			input_type = left.sql_type;
		}
		if (right.sql_type.IsNumeric()) {
			input_type = right.sql_type;
		}
	}
	if (input_type.id == SQLTypeId::UNKNOWN) {
		throw BinderException("Could not determine type of parameters: try adding explicit type casts");
	}
	// add casts (if necessary)
	left.expr = BoundCastExpression::AddCastToType(move(left.expr), left.sql_type, input_type);
	right.expr = BoundCastExpression::AddCastToType(move(right.expr), right.sql_type, input_type);
	// now create the bound comparison expression
	return BindResult(make_unique<BoundComparisonExpression>(expr.type, move(left.expr), move(right.expr)),
	                  SQLType(SQLTypeId::BOOLEAN));
}





using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(ConjunctionExpression &expr, idx_t depth) {
	// first try to bind the children of the case expression
	string error;
	for (idx_t i = 0; i < expr.children.size(); i++) {
		BindChild(expr.children[i], depth, error);
	}
	if (!error.empty()) {
		return BindResult(error);
	}
	// the children have been successfully resolved
	// cast the input types to boolean (if necessary)
	// and construct the bound conjunction expression
	auto result = make_unique<BoundConjunctionExpression>(expr.type);
	for (auto &child_expr : expr.children) {
		auto &child = (BoundExpression &)*child_expr;
		result->children.push_back(
		    BoundCastExpression::AddCastToType(move(child.expr), child.sql_type, SQLType(SQLTypeId::BOOLEAN)));
	}
	// now create the bound conjunction expression
	return BindResult(move(result), SQLType(SQLTypeId::BOOLEAN));
}




using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(ConstantExpression &expr, idx_t depth) {
	return BindResult(make_unique<BoundConstantExpression>(expr.value), expr.sql_type);
}








using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(FunctionExpression &function, idx_t depth) {
	// lookup the function in the catalog

	if (function.function_name == "unnest" || function.function_name == "unlist") {
			// special case, not in catalog
			// TODO make sure someone does not create such a function OR
			// have unnest live in catalog, too
			return BindUnnest(function, depth);
		}


	auto func = Catalog::GetCatalog(context).GetEntry(context, CatalogType::SCALAR_FUNCTION, function.schema,
	                                                  function.function_name);
	if (func->type == CatalogType::SCALAR_FUNCTION) {
		// scalar function
		return BindFunction(function, (ScalarFunctionCatalogEntry *)func, depth);
	} else {
		// aggregate function
		return BindAggregate(function, (AggregateFunctionCatalogEntry *)func, depth);
	}
}

BindResult ExpressionBinder::BindFunction(FunctionExpression &function, ScalarFunctionCatalogEntry *func, idx_t depth) {
	// bind the children of the function expression
	string error;
	for (idx_t i = 0; i < function.children.size(); i++) {
		BindChild(function.children[i], depth, error);
	}
	if (!error.empty()) {
		return BindResult(error);
	}
	// all children bound successfully
	// extract the children and types
	vector<SQLType> arguments;
	vector<unique_ptr<Expression>> children;
	for (idx_t i = 0; i < function.children.size(); i++) {
		auto &child = (BoundExpression &)*function.children[i];
		arguments.push_back(child.sql_type);
		children.push_back(move(child.expr));
	}

	auto result = ScalarFunction::BindScalarFunction(context, *func, arguments, move(children), function.is_operator);
	auto sql_return_type = result->sql_return_type;
	return BindResult(move(result), sql_return_type);
}

BindResult ExpressionBinder::BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function,
                                           idx_t depth) {
	return BindResult(UnsupportedAggregateMessage());
}

BindResult ExpressionBinder::BindUnnest(FunctionExpression &expr,
                                           idx_t depth) {
	return BindResult(UnsupportedUnnestMessage());
}

string ExpressionBinder::UnsupportedAggregateMessage() {
	return "Aggregate functions are not supported here";
}


string ExpressionBinder::UnsupportedUnnestMessage() {
	return "UNNEST not supported here";
}





using namespace duckdb;
using namespace std;

static SQLType ResolveNotType(OperatorExpression &op, vector<BoundExpression *> &children) {
	// NOT expression, cast child to BOOLEAN
	assert(children.size() == 1);
	children[0]->expr =
	    BoundCastExpression::AddCastToType(move(children[0]->expr), children[0]->sql_type, SQLType(SQLTypeId::BOOLEAN));
	return SQLType(SQLTypeId::BOOLEAN);
}

static SQLType ResolveInType(OperatorExpression &op, vector<BoundExpression *> &children) {
	// get the maximum type from the children
	SQLType max_type = children[0]->sql_type;
	for (idx_t i = 1; i < children.size(); i++) {
		max_type = MaxSQLType(max_type, children[i]->sql_type);
	}
	// cast all children to the same type
	for (idx_t i = 0; i < children.size(); i++) {
		children[i]->expr =
		    BoundCastExpression::AddCastToType(move(children[i]->expr), children[i]->sql_type, max_type);
	}
	// (NOT) IN always returns a boolean
	return SQLType(SQLTypeId::BOOLEAN);
}

static SQLType ResolveOperatorType(OperatorExpression &op, vector<BoundExpression *> &children) {
	switch (op.type) {
	case ExpressionType::OPERATOR_IS_NULL:
	case ExpressionType::OPERATOR_IS_NOT_NULL:
		// IS (NOT) NULL always returns a boolean, and does not cast its children
		return SQLType(SQLTypeId::BOOLEAN);
	case ExpressionType::COMPARE_IN:
	case ExpressionType::COMPARE_NOT_IN:
		return ResolveInType(op, children);
	default:
		assert(op.type == ExpressionType::OPERATOR_NOT);
		return ResolveNotType(op, children);
	}
}

BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) {
	// bind the children of the operator expression
	string error;
	for (idx_t i = 0; i < op.children.size(); i++) {
		BindChild(op.children[i], depth, error);
	}
	if (!error.empty()) {
		return BindResult(error);
	}
	// all children bound successfully, extract them
	vector<BoundExpression *> children;
	for (idx_t i = 0; i < op.children.size(); i++) {
		assert(op.children[i]->expression_class == ExpressionClass::BOUND_EXPRESSION);
		children.push_back((BoundExpression *)op.children[i].get());
	}
	// now resolve the types
	SQLType result_type = ResolveOperatorType(op, children);

	auto result = make_unique<BoundOperatorExpression>(op.type, GetInternalType(result_type));
	for (auto &child : children) {
		result->children.push_back(move(child->expr));
	}
	return BindResult(move(result), result_type);
}





using namespace duckdb;
using namespace std;

BindResult ExpressionBinder::BindExpression(ParameterExpression &expr, idx_t depth) {
	auto bound_parameter = make_unique<BoundParameterExpression>(expr.parameter_nr);
	auto sql_type = bound_parameter->sql_type;
	binder.parameters->push_back(bound_parameter.get());
	return BindResult(move(bound_parameter), sql_type);
}






using namespace duckdb;
using namespace std;

class BoundSubqueryNode : public QueryNode {
public:
	BoundSubqueryNode(unique_ptr<Binder> subquery_binder, unique_ptr<BoundQueryNode> bound_node,
	                  unique_ptr<QueryNode> subquery)
	    : QueryNode(QueryNodeType::BOUND_SUBQUERY_NODE), subquery_binder(move(subquery_binder)),
	      bound_node(move(bound_node)), subquery(move(subquery)) {
	}

	unique_ptr<Binder> subquery_binder;
	unique_ptr<BoundQueryNode> bound_node;
	unique_ptr<QueryNode> subquery;

	const vector<unique_ptr<ParsedExpression>> &GetSelectList() const {
		throw Exception("Cannot get select list of bound subquery node");
	}

	unique_ptr<QueryNode> Copy() {
		throw Exception("Cannot copy bound subquery node");
	}
};

BindResult ExpressionBinder::BindExpression(SubqueryExpression &expr, idx_t depth) {
	if (expr.subquery->type != QueryNodeType::BOUND_SUBQUERY_NODE) {
		assert(depth == 0);
		// first bind the actual subquery in a new binder
		auto subquery_binder = make_unique<Binder>(context, &binder);
		// the subquery may refer to CTEs from the parent query
		subquery_binder->CTE_bindings = binder.CTE_bindings;
		auto bound_node = subquery_binder->Bind(*expr.subquery);
		// check the correlated columns of the subquery for correlated columns with depth > 1
		for (idx_t i = 0; i < subquery_binder->correlated_columns.size(); i++) {
			CorrelatedColumnInfo corr = subquery_binder->correlated_columns[i];
			if (corr.depth > 1) {
				// depth > 1, the column references the query ABOVE the current one
				// add to the set of correlated columns for THIS query
				corr.depth -= 1;
				binder.AddCorrelatedColumn(corr);
			}
		}
		if (expr.subquery_type != SubqueryType::EXISTS && bound_node->types.size() > 1) {
			throw BinderException("Subquery returns %zu columns - expected 1", bound_node->types.size());
		}
		expr.subquery = make_unique<BoundSubqueryNode>(move(subquery_binder), move(bound_node), move(expr.subquery));
	}
	// now bind the child node of the subquery
	if (expr.child) {
		// first bind the children of the subquery, if any
		string error = Bind(&expr.child, depth);
		if (!error.empty()) {
			return BindResult(error);
		}
	}
	// both binding the child and binding the subquery was successful
	assert(expr.subquery->type == QueryNodeType::BOUND_SUBQUERY_NODE);
	auto bound_subquery = (BoundSubqueryNode *)expr.subquery.get();
	auto child = (BoundExpression *)expr.child.get();
	auto subquery_binder = move(bound_subquery->subquery_binder);
	auto bound_node = move(bound_subquery->bound_node);
	SQLType return_type =
	    expr.subquery_type == SubqueryType::SCALAR ? bound_node->types[0] : SQLType(SQLTypeId::BOOLEAN);
	if (return_type.id == SQLTypeId::UNKNOWN) {
		throw BinderException("Could not determine type of parameters: try adding explicit type casts");
	}

	auto result = make_unique<BoundSubqueryExpression>(GetInternalType(return_type));
	if (expr.subquery_type == SubqueryType::ANY) {
		// ANY comparison
		// cast child and subquery child to equivalent types
		assert(bound_node->types.size() == 1);
		auto compare_type = MaxSQLType(child->sql_type, bound_node->types[0]);
		child->expr = BoundCastExpression::AddCastToType(move(child->expr), child->sql_type, compare_type);
		result->child_type = bound_node->types[0];
		result->child_target = compare_type;
	}
	result->binder = move(subquery_binder);
	result->subquery = move(bound_node);
	result->subquery_type = expr.subquery_type;
	result->child = child ? move(child->expr) : nullptr;
	result->comparison_type = expr.comparison_type;

	return BindResult(move(result), return_type);
}










using namespace duckdb;
using namespace std;

BindResult SelectBinder::BindUnnest(FunctionExpression &function, idx_t depth) {
	// bind the children of the function expression
	string error;
	if (function.children.size() != 1) {
		return BindResult("Unnest() needs exactly one child expressions");
	}
	BindChild(function.children[0], depth, error);
	if (!error.empty()) {
		return BindResult(error);
	}
	auto &child = (BoundExpression &)*function.children[0];
	if (child.sql_type.id != SQLTypeId::LIST) {
		return BindResult("Unnest() can only be applied to lists");
	}
	SQLType return_type = SQLType::ANY;
	assert(child.sql_type.child_type.size() <= 1);
	if (child.sql_type.child_type.size() == 1) {
		return_type = child.sql_type.child_type[0].second;
	}

	auto result = make_unique<BoundUnnestExpression>(return_type);
	result->child = move(child.expr);

	auto unnest_index = node.unnests.size();
	node.unnests.push_back(move(result));

	// TODO what if we have multiple unnests in the same projection list? ignore for now

	// now create a column reference referring to the aggregate
	auto colref = make_unique<BoundColumnRefExpression>(
	    function.alias.empty() ? node.unnests[unnest_index]->ToString() : function.alias,
	    node.unnests[unnest_index]->return_type, ColumnBinding(node.unnest_index, unnest_index), depth);
	// move the aggregate expression into the set of bound aggregates
	return BindResult(move(colref), return_type);
}









using namespace duckdb;
using namespace std;

static SQLType ResolveWindowExpressionType(ExpressionType window_type, SQLType child_type) {
	switch (window_type) {
	case ExpressionType::WINDOW_PERCENT_RANK:
	case ExpressionType::WINDOW_CUME_DIST:
		return SQLType(SQLTypeId::DECIMAL);
	case ExpressionType::WINDOW_ROW_NUMBER:
	case ExpressionType::WINDOW_RANK:
	case ExpressionType::WINDOW_RANK_DENSE:
	case ExpressionType::WINDOW_NTILE:
		return SQLType::BIGINT;
	case ExpressionType::WINDOW_FIRST_VALUE:
	case ExpressionType::WINDOW_LAST_VALUE:
		assert(child_type.id != SQLTypeId::INVALID); // "Window function needs an expression"
		return child_type;
	case ExpressionType::WINDOW_LEAD:
	default:
		assert(window_type == ExpressionType::WINDOW_LAG || window_type == ExpressionType::WINDOW_LEAD);
		assert(child_type.id != SQLTypeId::INVALID); // "Window function needs an expression"
		return child_type;
	}
}

static unique_ptr<Expression> GetExpression(unique_ptr<ParsedExpression> &expr) {
	if (!expr) {
		return nullptr;
	}
	assert(expr.get());
	assert(expr->expression_class == ExpressionClass::BOUND_EXPRESSION);
	return move(((BoundExpression &)*expr).expr);
}

BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) {
	if (inside_window) {
		throw BinderException("window function calls cannot be nested");
	}
	if (depth > 0) {
		throw BinderException("correlated columns in window functions not supported");
	}
	// bind inside the children of the window function
	// we set the inside_window flag to true to prevent binding nested window functions
	this->inside_window = true;
	string error;
	for (auto &child : window.children) {
		BindChild(child, depth, error);
	}
	for (auto &child : window.partitions) {
		BindChild(child, depth, error);
	}
	for (auto &order : window.orders) {
		BindChild(order.expression, depth, error);
	}
	BindChild(window.start_expr, depth, error);
	BindChild(window.end_expr, depth, error);
	BindChild(window.offset_expr, depth, error);
	BindChild(window.default_expr, depth, error);
	this->inside_window = false;
	if (!error.empty()) {
		// failed to bind children of window function
		return BindResult(error);
	}
	// successfully bound all children: create bound window function
	vector<SQLType> types;
	vector<unique_ptr<Expression>> children;
	for (auto &child : window.children) {
		assert(child.get());
		assert(child->expression_class == ExpressionClass::BOUND_EXPRESSION);
		auto &bound = (BoundExpression &)*child;
		types.push_back(bound.sql_type);
		children.push_back(GetExpression(child));
	}
	//  Determine the function type.
	SQLType sql_type;
	unique_ptr<AggregateFunction> aggregate;
	if (window.type == ExpressionType::WINDOW_AGGREGATE) {
		//  Look up the aggregate function in the catalog
		auto func =
		    (AggregateFunctionCatalogEntry *)Catalog::GetCatalog(context).GetEntry<AggregateFunctionCatalogEntry>(
		        context, window.schema, window.function_name);
		if (func->type != CatalogType::AGGREGATE_FUNCTION) {
			throw BinderException("Unknown windowed aggregate");
		}
		// bind the aggregate
		auto best_function = Function::BindFunction(func->name, func->functions, types);
		// found a matching function!
		auto &bound_function = func->functions[best_function];
		// check if we need to add casts to the children
		bound_function.CastToFunctionArguments(children, types);
		// create the aggregate
		aggregate = make_unique<AggregateFunction>(func->functions[best_function]);
		sql_type = aggregate->return_type;
	} else {
		// fetch the child of the non-aggregate window function (if any)
		sql_type = ResolveWindowExpressionType(window.type, types.empty() ? SQLType() : types[0]);
	}
	auto result = make_unique<BoundWindowExpression>(window.type, GetInternalType(sql_type), move(aggregate));
	result->children = move(children);
	for (auto &child : window.partitions) {
		result->partitions.push_back(GetExpression(child));
	}
	for (auto &order : window.orders) {
		BoundOrderByNode bound_order;
		bound_order.expression = GetExpression(order.expression);
		bound_order.type = order.type;
		result->orders.push_back(move(bound_order));
	}
	result->start_expr = GetExpression(window.start_expr);
	result->end_expr = GetExpression(window.end_expr);
	result->offset_expr = GetExpression(window.offset_expr);
	result->default_expr = GetExpression(window.default_expr);
	result->start = window.start;
	result->end = window.end;

	// create a BoundColumnRef that references this entry
	auto colref = make_unique<BoundColumnRefExpression>(window.GetName(), result->return_type,
	                                                    ColumnBinding(node.window_index, node.windows.size()), depth);
	// move the WINDOW expression into the set of bound windows
	node.windows.push_back(move(result));
	return BindResult(move(colref), sql_type);
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_cteref.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class BoundCTERef : public BoundTableRef {
public:
	BoundCTERef(idx_t bind_index, idx_t cte_index)
	    : BoundTableRef(TableReferenceType::CTE), bind_index(bind_index), cte_index(cte_index) {
	}

	//! The set of columns bound to this base table reference
	vector<string> bound_columns;
	//! The types of the values list
	vector<SQLType> types;
	//! The index in the bind context
	idx_t bind_index;
	//! The index of the cte
	idx_t cte_index;
};
} // namespace duckdb






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/query_node/bound_recursive_cte_node.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! Bound equivalent of SetOperationNode
class BoundRecursiveCTENode : public BoundQueryNode {
public:
	BoundRecursiveCTENode() : BoundQueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
	}

	//! Keep track of the CTE name this node represents
	string ctename;

	bool union_all;
	//! The left side of the set operation
	unique_ptr<BoundQueryNode> left;
	//! The right side of the set operation
	unique_ptr<BoundQueryNode> right;

	//! Index used by the set operation
	idx_t setop_index;
	//! The binder used by the left side of the set operation
	unique_ptr<Binder> left_binder;
	//! The binder used by the right side of the set operation
	unique_ptr<Binder> right_binder;

public:
	idx_t GetRootIndex() override {
		return setop_index;
	}
};

}; // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<BoundQueryNode> Binder::Bind(RecursiveCTENode &statement) {
	auto result = make_unique<BoundRecursiveCTENode>();

	// first recursively visit the recursive CTE operations
	// the left side is visited first and is added to the BindContext of the right side
	assert(statement.left);
	assert(statement.right);

	result->ctename = statement.ctename;
	result->union_all = statement.union_all;
	result->setop_index = GenerateTableIndex();

	result->left_binder = make_unique<Binder>(context, this);
	result->left = result->left_binder->Bind(*statement.left);

	// This allows the right side to reference the CTE recursively
	bind_context.AddGenericBinding(result->setop_index, statement.ctename, result->left->names, result->left->types);

	result->right_binder = make_unique<Binder>(context, this);

	// Add bindings of left side to temporary CTE bindings context
	result->right_binder->bind_context.AddCTEBinding(result->setop_index, statement.ctename, result->left->names,
	                                                 result->left->types);
	result->right = result->right_binder->Bind(*statement.right);

	// Check if there are aggregates present in the recursive term
	switch (result->right->type) {
	case QueryNodeType::SELECT_NODE:
		if (!((BoundSelectNode *)result->right.get())->aggregates.empty()) {
			throw Exception("Aggregate functions are not allowed in a recursive query's recursive term");
		}
		break;
	default:
		break;
	}

	result->names = result->left->names;

	// move the correlated expressions from the child binders to this binder
	MoveCorrelatedExpressions(*result->left_binder);
	MoveCorrelatedExpressions(*result->right_binder);

	// now both sides have been bound we can resolve types
	if (result->left->types.size() != result->right->types.size()) {
		throw Exception("Set operations can only apply to expressions with the "
		                "same number of result columns");
	}

	// figure out the types of the recursive CTE result by picking the max of both
	for (idx_t i = 0; i < result->left->types.size(); i++) {
		auto result_type = MaxSQLType(result->left->types[i], result->right->types[i]);
		result->types.push_back(result_type);
	}

	return move(result);
}





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/group_binder.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class ConstantExpression;
class ColumnRefExpression;

//! The GROUP binder is responsible for binding expressions in the GROUP BY clause
class GroupBinder : public ExpressionBinder {
public:
	GroupBinder(Binder &binder, ClientContext &context, SelectNode &node, idx_t group_index,
	            unordered_map<string, idx_t> &alias_map, unordered_map<string, idx_t> &group_alias_map);

	//! The unbound root expression
	unique_ptr<ParsedExpression> unbound_expression;
	//! The group index currently being bound
	idx_t bind_index;

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) override;

	string UnsupportedAggregateMessage() override;

	BindResult BindSelectRef(idx_t entry);
	BindResult BindColumnRef(ColumnRefExpression &expr);
	BindResult BindConstant(ConstantExpression &expr);

	SelectNode &node;
	unordered_map<string, idx_t> &alias_map;
	unordered_map<string, idx_t> &group_alias_map;
	unordered_set<idx_t> used_aliases;

	idx_t group_index;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/having_binder.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The HAVING binder is responsible for binding an expression within the HAVING clause of a SQL statement
class HavingBinder : public SelectBinder {
public:
	HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/order_binder.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
class Expression;
class SelectNode;

//! The ORDER binder is responsible for binding an expression within the ORDER BY clause of a SQL statement
class OrderBinder {
public:
	OrderBinder(idx_t projection_index, SelectNode &node, unordered_map<string, idx_t> &alias_map,
	            expression_map_t<idx_t> &projection_map, vector<unique_ptr<ParsedExpression>> &extra_select_list);

	unique_ptr<Expression> Bind(unique_ptr<ParsedExpression> expr);
	void RemapIndex(BoundColumnRefExpression &expr, idx_t index);

private:
	unique_ptr<Expression> CreateProjectionReference(ParsedExpression &expr, idx_t index);

	idx_t projection_index;
	SelectNode &node;
	unordered_map<string, idx_t> &alias_map;
	expression_map_t<idx_t> &projection_map;
	vector<unique_ptr<ParsedExpression>> &extra_select_list;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/where_binder.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement
class WhereBinder : public ExpressionBinder {
public:
	WhereBinder(Binder &binder, ClientContext &context);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

unique_ptr<BoundQueryNode> Binder::Bind(SelectNode &statement) {
	auto result = make_unique<BoundSelectNode>();
	result->projection_index = GenerateTableIndex();
	result->group_index = GenerateTableIndex();
	result->aggregate_index = GenerateTableIndex();
	result->window_index = GenerateTableIndex();
	result->unnest_index = GenerateTableIndex();

	// first bind the FROM table statement
	result->from_table = Bind(*statement.from_table);

	// visit the select list and expand any "*" statements
	vector<unique_ptr<ParsedExpression>> new_select_list;
	for (auto &select_element : statement.select_list) {
		if (select_element->GetExpressionType() == ExpressionType::STAR) {
			// * statement, expand to all columns from the FROM clause
			bind_context.GenerateAllColumnExpressions(new_select_list);
		} else if (select_element->GetExpressionType() == ExpressionType::TABLE_STAR) {
			auto table_star =
			    (TableStarExpression *)select_element.get(); // TODO this cast to explicit class is a bit dirty?
			bind_context.GenerateAllColumnExpressions(new_select_list, table_star->relation_name);
		} else {
			// regular statement, add it to the list
			new_select_list.push_back(move(select_element));
		}
	}
	statement.select_list = move(new_select_list);

	for (auto &entry : statement.select_list) {
		result->names.push_back(entry->GetName());
	}
	result->column_count = statement.select_list.size();

	// first visit the WHERE clause
	// the WHERE clause happens before the GROUP BY, PROJECTION or HAVING clauses
	if (statement.where_clause) {
		WhereBinder where_binder(*this, context);
		result->where_clause = where_binder.Bind(statement.where_clause);
	}

	// create a mapping of (alias -> index) and a mapping of (Expression -> index) for the SELECT list
	unordered_map<string, idx_t> alias_map;
	expression_map_t<idx_t> projection_map;
	for (idx_t i = 0; i < statement.select_list.size(); i++) {
		auto &expr = statement.select_list[i];
		if (!expr->alias.empty()) {
			alias_map[expr->alias] = i;
		}
		projection_map[expr.get()] = i;
	}

	// we bind the DISTINCT ON before we bind any order, aggregations or window functions
	vector<unique_ptr<ParsedExpression>> extra_select_list;
	OrderBinder order_binder(result->projection_index, statement, alias_map, projection_map, extra_select_list);
	for (idx_t i = 0; i < statement.distinct_on_targets.size(); i++) {
		// we treat the Distinct list as a order by
		auto bound_expr = order_binder.Bind(move(statement.distinct_on_targets[i]));
		if (!bound_expr) {
			// DISTINCT ON non-integer constant
			// remove the expression from the  DISTINCT ON list
			continue;
		}
		assert(bound_expr->type == ExpressionType::BOUND_COLUMN_REF);
		result->target_distincts.push_back(move(bound_expr));
	}

	// we bind the ORDER BY before we bind any aggregations or window functions
	for (idx_t i = 0; i < statement.orders.size(); i++) {
		auto bound_expr = order_binder.Bind(move(statement.orders[i].expression));
		if (!bound_expr) {
			// ORDER BY non-integer constant
			// remove the expression from the ORDER BY list
			continue;
		}
		assert(bound_expr->type == ExpressionType::BOUND_COLUMN_REF);
		BoundOrderByNode order_node;
		order_node.expression = move(bound_expr);
		order_node.type = statement.orders[i].type;
		result->orders.push_back(move(order_node));
	}

	vector<unique_ptr<ParsedExpression>> unbound_groups;
	BoundGroupInformation info;
	if (statement.groups.size() > 0) {
		// the statement has a GROUP BY clause, bind it
		unbound_groups.resize(statement.groups.size());
		GroupBinder group_binder(*this, context, statement, result->group_index, alias_map, info.alias_map);
		for (idx_t i = 0; i < statement.groups.size(); i++) {

			// we keep a copy of the unbound expression;
			// we keep the unbound copy around to check for group references in the SELECT and HAVING clause
			// the reason we want the unbound copy is because we want to figure out whether an expression
			// is a group reference BEFORE binding in the SELECT/HAVING binder
			group_binder.unbound_expression = statement.groups[i]->Copy();
			group_binder.bind_index = i;

			// bind the groups
			SQLType group_type;
			auto bound_expr = group_binder.Bind(statement.groups[i], &group_type);
			assert(bound_expr->return_type != TypeId::INVALID);
			info.group_types.push_back(group_type);
			result->groups.push_back(move(bound_expr));

			// in the unbound expression we DO bind the table names of any ColumnRefs
			// we do this to make sure that "table.a" and "a" are treated the same
			// if we wouldn't do this then (SELECT test.a FROM test GROUP BY a) would not work because "test.a" <> "a"
			// hence we convert "a" -> "test.a" in the unbound expression
			unbound_groups[i] = move(group_binder.unbound_expression);
			group_binder.BindTableNames(*unbound_groups[i]);
			info.map[unbound_groups[i].get()] = i;
		}
	}

	// bind the HAVING clause, if any
	if (statement.having) {
		HavingBinder having_binder(*this, context, *result, info);
		having_binder.BindTableNames(*statement.having);
		result->having = having_binder.Bind(statement.having);
	}

	// after that, we bind to the SELECT list
	SelectBinder select_binder(*this, context, *result, info);
	for (idx_t i = 0; i < statement.select_list.size(); i++) {
		select_binder.BindTableNames(*statement.select_list[i]);
	}
	// including the extra SELECT list from DISTINCT ON & ORDER BY
	unordered_map<idx_t, idx_t> projection_remap;
	for (idx_t i = 0; i < extra_select_list.size(); i++) {
		auto &expr = extra_select_list[i];
		select_binder.BindTableNames(*expr);
		// See if it matches an entry already in the SELECT list
		auto post_bind_index = projection_map.find(expr.get());
		idx_t newindex;
		if (post_bind_index != projection_map.end()) {
			newindex = post_bind_index->second;
		} else {
			newindex = statement.select_list.size();
			statement.select_list.push_back(move(expr));
		}
		projection_remap[result->column_count + i] = newindex;
	}
	for (idx_t i = 0; i < statement.select_list.size(); i++) {
		SQLType result_type;
		auto expr = select_binder.Bind(statement.select_list[i], &result_type);
		result->select_list.push_back(move(expr));
		if (i < result->column_count) {
			result->types.push_back(result_type);
		}
	}
	// in the normal select binder, we bind columns as if there is no aggregation
	// i.e. in the query [SELECT i, SUM(i) FROM integers;] the "i" will be bound as a normal column
	// since we have an aggregation, we need to either (1) throw an error, or (2) wrap the column in a FIRST() aggregate
	// we choose the former one [CONTROVERSIAL: this is the PostgreSQL behavior]
	if (result->groups.size() > 0 || result->aggregates.size() > 0 || statement.having) {
		if (select_binder.BoundColumns()) {
			throw BinderException("column must appear in the GROUP BY clause or be used in an aggregate function");
		}
	}

	// resolve the types of the ORDER BY clause
	for (idx_t i = 0; i < result->orders.size(); i++) {
		assert(result->orders[i].expression->type == ExpressionType::BOUND_COLUMN_REF);
		auto &order = (BoundColumnRefExpression &)*result->orders[i].expression;
		// See if the column index has been remapped in the projection
		auto entry = projection_remap.find(order.binding.column_index);
		if (entry != projection_remap.end())
			order_binder.RemapIndex(order, entry->second);
		assert(order.binding.column_index < statement.select_list.size());
		order.return_type = result->select_list[order.binding.column_index]->return_type;
		assert(order.return_type != TypeId::INVALID);
	}

	// resolve the types of the DISTINCT ON clause
	for (idx_t i = 0; i < result->target_distincts.size(); i++) {
		assert(result->target_distincts[i]->type == ExpressionType::BOUND_COLUMN_REF);
		auto &distinct = (BoundColumnRefExpression &)*result->target_distincts[i];
		// See if the column index has been remapped in the projection
		auto entry = projection_remap.find(distinct.binding.column_index);
		if (entry != projection_remap.end())
			order_binder.RemapIndex(distinct, entry->second);
		assert(distinct.binding.column_index < statement.select_list.size());
		distinct.return_type = result->select_list[distinct.binding.column_index]->return_type;
		assert(distinct.return_type != TypeId::INVALID);
	}

	return move(result);
}







//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/query_node/bound_set_operation_node.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Bound equivalent of SetOperationNode
class BoundSetOperationNode : public BoundQueryNode {
public:
	BoundSetOperationNode() : BoundQueryNode(QueryNodeType::SET_OPERATION_NODE) {
	}

	//! The type of set operation
	SetOperationType setop_type = SetOperationType::NONE;
	//! The left side of the set operation
	unique_ptr<BoundQueryNode> left;
	//! The right side of the set operation
	unique_ptr<BoundQueryNode> right;

	//! Index used by the set operation
	idx_t setop_index;
	//! The binder used by the left side of the set operation
	unique_ptr<Binder> left_binder;
	//! The binder used by the right side of the set operation
	unique_ptr<Binder> right_binder;

public:
	idx_t GetRootIndex() override {
		return setop_index;
	}
};

}; // namespace duckdb


using namespace duckdb;
using namespace std;

static void GatherAliases(QueryNode &node, unordered_map<string, idx_t> &aliases,
                          expression_map_t<idx_t> &expressions) {
	if (node.type == QueryNodeType::SET_OPERATION_NODE) {
		// setop, recurse
		auto &setop = (SetOperationNode &)node;
		GatherAliases(*setop.left, aliases, expressions);
		GatherAliases(*setop.right, aliases, expressions);
	} else {
		// query node
		assert(node.type == QueryNodeType::SELECT_NODE);
		auto &select = (SelectNode &)node;
		// fill the alias lists
		for (idx_t i = 0; i < select.select_list.size(); i++) {
			auto &expr = select.select_list[i];
			auto name = expr->GetName();
			// first check if the alias is already in there
			auto entry = aliases.find(name);
			if (entry != aliases.end()) {
				// the alias already exists
				// check if there is a conflict
				if (entry->second != i) {
					// there is a conflict
					// we place "-1" in the aliases map at this location
					// "-1" signifies that there is an ambiguous reference
					aliases[name] = INVALID_INDEX;
				}
			} else {
				// the alias is not in there yet, just assign it
				aliases[name] = i;
			}
			// now check if the node is already in the set of expressions
			auto expr_entry = expressions.find(expr.get());
			if (expr_entry != expressions.end()) {
				// the node is in there
				// repeat the same as with the alias: if there is an ambiguity we insert "-1"
				if (expr_entry->second != i) {
					expressions[expr.get()] = INVALID_INDEX;
				}
			} else {
				// not in there yet, just place it in there
				expressions[expr.get()] = i;
			}
		}
	}
}

unique_ptr<BoundQueryNode> Binder::Bind(SetOperationNode &statement) {
	auto result = make_unique<BoundSetOperationNode>();
	result->setop_type = statement.setop_type;

	// first recursively visit the set operations
	// both the left and right sides have an independent BindContext and Binder
	assert(statement.left);
	assert(statement.right);

	result->setop_index = GenerateTableIndex();

	vector<idx_t> order_references;
	if (statement.orders.size() > 0) {
		// handle the ORDER BY
		// NOTE: we handle the ORDER BY in SET OPERATIONS before binding the children
		// we do so we can perform expression comparisons BEFORE type resolution/binding

		// we recursively visit the children of this node to extract aliases and expressions that can be referenced in
		// the ORDER BY
		unordered_map<string, idx_t> alias_map;
		expression_map_t<idx_t> expression_map;
		GatherAliases(statement, alias_map, expression_map);
		// now we perform the actual resolution of the ORDER BY expressions
		for (idx_t i = 0; i < statement.orders.size(); i++) {
			auto &order = statement.orders[i].expression;
			if (order->type == ExpressionType::VALUE_CONSTANT) {
				// ORDER BY a constant
				auto &constant = (ConstantExpression &)*order;
				if (TypeIsIntegral(constant.value.type)) {
					// INTEGER constant: we use the integer as an index into the select list (e.g. ORDER BY 1)
					order_references.push_back(constant.value.GetValue<int64_t>() - 1);
					continue;
				}
			}
			if (order->type == ExpressionType::COLUMN_REF) {
				// ORDER BY column, check if it is an alias reference
				auto &colref = (ColumnRefExpression &)*order;
				if (colref.table_name.empty()) {
					auto entry = alias_map.find(colref.column_name);
					if (entry != alias_map.end()) {
						// found a matching entry
						if (entry->second == INVALID_INDEX) {
							// ambiguous reference
							throw BinderException("Ambiguous alias reference \"%s\"", colref.column_name.c_str());
						} else {
							order_references.push_back(entry->second);
							continue;
						}
					}
				}
			}
			// check if the ORDER BY clause matches any of the columns in the projection list of any of the children
			auto expr_ref = expression_map.find(order.get());
			if (expr_ref == expression_map.end()) {
				// not found
				throw BinderException("Could not ORDER BY column: add the expression/function to every SELECT, or move "
				                      "the UNION into a FROM clause.");
			}
			if (expr_ref->second == INVALID_INDEX) {
				throw BinderException("Ambiguous reference to column");
			}
			order_references.push_back(expr_ref->second);
		}
	}

	result->left_binder = make_unique<Binder>(context, this);
	result->left = result->left_binder->Bind(*statement.left);

	result->right_binder = make_unique<Binder>(context, this);
	result->right = result->right_binder->Bind(*statement.right);

	result->names = result->left->names;

	// move the correlated expressions from the child binders to this binder
	MoveCorrelatedExpressions(*result->left_binder);
	MoveCorrelatedExpressions(*result->right_binder);

	// now both sides have been bound we can resolve types
	if (result->left->types.size() != result->right->types.size()) {
		throw Exception("Set operations can only apply to expressions with the "
		                "same number of result columns");
	}

	// figure out the types of the setop result by picking the max of both
	for (idx_t i = 0; i < result->left->types.size(); i++) {
		auto result_type = MaxSQLType(result->left->types[i], result->right->types[i]);
		result->types.push_back(result_type);
	}

	// if there are ORDER BY entries we create the BoundColumnRefExpressions
	assert(order_references.size() == statement.orders.size());
	for (idx_t i = 0; i < statement.orders.size(); i++) {
		auto entry = order_references[i];
		if (entry >= result->types.size()) {
			throw BinderException("ORDER term out of range - should be between 1 and %d", (int)result->types.size());
		}
		BoundOrderByNode node;

		node.expression = make_unique<BoundColumnRefExpression>(GetInternalType(result->types[entry]),
		                                                        ColumnBinding(result->setop_index, entry));
		node.type = statement.orders[i].type;
		result->orders.push_back(move(node));
	}
	return move(result);
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_copy_statement.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_insert_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class TableCatalogEntry;

//! Bound equivalent to InsertStatement
class BoundInsertStatement : public BoundSQLStatement {
public:
	BoundInsertStatement() : BoundSQLStatement(StatementType::INSERT) {
	}

	//! The table entry to insert into
	TableCatalogEntry *table;
	//! The bound select statement (if any)
	unique_ptr<BoundSelectStatement> select_statement;
	//! The insertion map ([table_index -> index in result, or INVALID_INDEX if not specified])
	vector<idx_t> column_index_map;
	//! The expected types for the INSERT statement (obtained from the column types)
	vector<SQLType> expected_types;
	//! The default statements used by the table
	vector<unique_ptr<Expression>> bound_defaults;

public:
	vector<string> GetNames() override {
		return {"Count"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::BIGINT};
	}
};
} // namespace duckdb


namespace duckdb {
class TableCatalogEntry;

//! Bound equivalent to CopyStatement
class BoundCopyStatement : public BoundSQLStatement {
public:
	BoundCopyStatement() : BoundSQLStatement(StatementType::COPY) {
	}

	//! The CopyInfo
	unique_ptr<CopyInfo> info;
	//! The bound insert statement (only for COPY FROM)
	unique_ptr<BoundSQLStatement> bound_insert;
	//! The bound SQL statement (only for COPY TO)
	unique_ptr<BoundQueryNode> select_statement;

	idx_t table_index;
	vector<string> names;
	vector<SQLType> sql_types;

public:
	vector<string> GetNames() override {
		return {"Count"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::BIGINT};
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(CopyStatement &stmt) {
	auto result = make_unique<BoundCopyStatement>();

	if (stmt.select_statement) {
		// COPY TO a file
		result->select_statement = Bind(*stmt.select_statement);
		result->names = {"Count"};
		result->sql_types = {SQLType::BIGINT};

		auto names = result->select_statement->names;
		auto quote_list = stmt.info->force_quote_list;

		// set all columns to false
		for (idx_t i = 0; i < names.size(); i++) {
			stmt.info->force_quote.push_back(stmt.info->quote_all);
		}

		if (!quote_list.empty()) {
			// validate force_quote_list entries
			for (const auto &column : quote_list) {
				auto it = find(names.begin(), names.end(), column);
				if (it != names.end()) {
					stmt.info->force_quote[distance(names.begin(), it)] = true;
				} else {
					throw BinderException("Column %s in FORCE_QUOTE is not used in COPY", column.c_str());
				}
			}
		}

	} else {
		assert(!stmt.info->table.empty());
		// COPY FROM a file
		// generate an insert statement for the the to-be-inserted table
		InsertStatement insert;
		insert.table = stmt.info->table;
		insert.schema = stmt.info->schema;
		insert.columns = stmt.info->select_list;

		// bind the insert statement to the base table
		result->bound_insert = Bind(insert);

		auto &bound_insert = (BoundInsertStatement &)*result->bound_insert;
		// get the set of expected columns from the insert statement; these types will be parsed from the CSV
		result->sql_types = bound_insert.expected_types;

		auto table =
		    Catalog::GetCatalog(context).GetEntry<TableCatalogEntry>(context, stmt.info->schema, stmt.info->table);
		// set all columns to false
		idx_t column_count = stmt.info->select_list.empty() ? table->columns.size() : stmt.info->select_list.size();
		stmt.info->force_not_null.resize(column_count, false);

		// transform column names of force_not_null_list into force_not_null booleans
		if (!stmt.info->force_not_null_list.empty()) {
			// validate force_not_null_list entries
			for (const auto &column : stmt.info->force_not_null_list) {
				auto entry = table->name_map.find(column);
				if (entry == table->name_map.end()) {
					throw BinderException("Column %s not found in table %s", column.c_str(), table->name.c_str());
				}
				if (bound_insert.column_index_map.size() > 0) {
					auto it =
					    find(bound_insert.column_index_map.begin(), bound_insert.column_index_map.end(), entry->second);
					if (it != bound_insert.column_index_map.end()) {
						stmt.info->force_not_null[entry->second] = true;
					} else {
						throw BinderException("Column %s in FORCE_NOT_NULL is not used in COPY", column.c_str());
					}
				} else {
					stmt.info->force_not_null[entry->second] = true;
				}
			}
		}
	}
	result->info = move(stmt.info);
	return move(result);
}

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_create_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Bound equivalent to CreateStatement
class BoundCreateStatement : public BoundSQLStatement {
public:
	BoundCreateStatement() : BoundSQLStatement(StatementType::CREATE) {
	}

	// Info for element creation
	unique_ptr<BoundCreateInfo> info;

public:
	vector<string> GetNames() override {
		return {"Count"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::BIGINT};
	}
};
} // namespace duckdb





using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(CreateStatement &stmt) {
	auto result = make_unique<BoundCreateStatement>();
	result->info = BindCreateInfo(move(stmt.info));
	return move(result);
}

unique_ptr<BoundCreateInfo> Binder::BindCreateInfo(unique_ptr<CreateInfo> info) {
	unique_ptr<BoundCreateInfo> result;
	if (info->schema == INVALID_SCHEMA) {
		info->schema = info->temporary ? TEMP_SCHEMA : DEFAULT_SCHEMA;
	}

	SchemaCatalogEntry *bound_schema = nullptr;
	if (!info->temporary) {
		// non-temporary create: not read only
		if (info->schema == TEMP_SCHEMA) {
			throw ParserException("Only TEMPORARY table names can use the \"temp\" schema");
		}
		this->read_only = false;
	} else {
		if (info->schema != TEMP_SCHEMA) {
			throw ParserException("TEMPORARY table names can *only* use the \"%s\" schema", TEMP_SCHEMA);
		}
	}
	if (info->type != CatalogType::SCHEMA) {
		// fetch the schema in which we want to create the object
		bound_schema = Catalog::GetCatalog(context).GetSchema(context, info->schema);
		info->schema = bound_schema->name;
	}
	switch (info->type) {
	case CatalogType::INDEX:
		result = BindCreateIndexInfo(move(info));
		break;
	case CatalogType::TABLE:
		result = BindCreateTableInfo(move(info));
		break;
	case CatalogType::VIEW:
		result = BindCreateViewInfo(move(info));
		break;
	default:
		result = make_unique<BoundCreateInfo>(move(info));
		break;
	}
	result->schema = bound_schema;
	return result;
}

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/parsed_data/bound_create_index_info.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

struct BoundCreateIndexInfo : public BoundCreateInfo {
	BoundCreateIndexInfo(unique_ptr<CreateInfo> base) : BoundCreateInfo(move(base)) {
	}

	//! The table to index
	unique_ptr<BoundTableRef> table;
	//! Set of expressions to index by
	vector<unique_ptr<Expression>> expressions;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/index_binder.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class BoundColumnRefExpression;

//! The INDEX binder is responsible for binding an expression within an Index statement
class IndexBinder : public ExpressionBinder {
public:
	IndexBinder(Binder &binder, ClientContext &context);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb



namespace duckdb {

unique_ptr<BoundCreateInfo> Binder::BindCreateIndexInfo(unique_ptr<CreateInfo> info) {
	auto &base = (CreateIndexInfo &)*info;
	auto result = make_unique<BoundCreateIndexInfo>(move(info));

	// visit the table reference
	result->table = Bind(*base.table);
	if (result->table->type != TableReferenceType::BASE_TABLE) {
		throw BinderException("Cannot create index on a view!");
	}
	IndexBinder binder(*this, context);
	for (auto &expr : base.expressions) {
		result->expressions.push_back(binder.Bind(expr));
	}
	return move(result);
}

} // namespace duckdb



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/constraints/bound_check_constraint.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! The CheckConstraint contains an expression that must evaluate to TRUE for
//! every row in a table
class BoundCheckConstraint : public BoundConstraint {
public:
	BoundCheckConstraint() : BoundConstraint(ConstraintType::CHECK) {
	}

	//! The expression
	unique_ptr<Expression> expression;
	//! The columns used by the CHECK constraint
	unordered_set<column_t> bound_columns;
};

} // namespace duckdb





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/check_binder.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
//! The CHECK binder is responsible for binding an expression within a CHECK constraint
class CheckBinder : public ExpressionBinder {
public:
	CheckBinder(Binder &binder, ClientContext &context, string table, vector<ColumnDefinition> &columns,
	            unordered_set<column_t> &bound_columns);

	string table;
	vector<ColumnDefinition> &columns;
	unordered_set<column_t> &bound_columns;

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	BindResult BindCheckColumn(ColumnRefExpression &expr);

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/constant_binder.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The Constant binder can bind ONLY constant foldable expressions (i.e. no subqueries, column refs, etc)
class ConstantBinder : public ExpressionBinder {
public:
	ConstantBinder(Binder &binder, ClientContext &context, string clause);

	//! The location where this binder is used, used for error messages
	string clause;

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

static void CreateColumnMap(BoundCreateTableInfo &info) {
	auto &base = (CreateTableInfo &)*info.base;

	for (uint64_t oid = 0; oid < base.columns.size(); oid++) {
		auto &col = base.columns[oid];
		if (info.name_map.find(col.name) != info.name_map.end()) {
			throw CatalogException("Column with name %s already exists!", col.name.c_str());
		}

		info.name_map[col.name] = oid;
		col.oid = oid;
	}
}

static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) {
	auto &base = (CreateTableInfo &)*info.base;

	bool has_primary_key = false;
	for (idx_t i = 0; i < base.constraints.size(); i++) {
		auto &cond = base.constraints[i];
		switch (cond->type) {
		case ConstraintType::CHECK: {
			auto bound_constraint = make_unique<BoundCheckConstraint>();
			// check constraint: bind the expression
			CheckBinder check_binder(binder, binder.context, base.table, base.columns, bound_constraint->bound_columns);
			auto &check = (CheckConstraint &)*cond;
			// create a copy of the unbound expression because the binding destroys the constraint
			auto unbound_expression = check.expression->Copy();
			// now bind the constraint and create a new BoundCheckConstraint
			bound_constraint->expression = check_binder.Bind(check.expression);
			info.bound_constraints.push_back(move(bound_constraint));
			// move the unbound constraint back into the original check expression
			check.expression = move(unbound_expression);
			break;
		}
		case ConstraintType::NOT_NULL: {
			auto &not_null = (NotNullConstraint &)*cond;
			info.bound_constraints.push_back(make_unique<BoundNotNullConstraint>(not_null.index));
			break;
		}
		case ConstraintType::UNIQUE: {
			auto &unique = (UniqueConstraint &)*cond;
			// have to resolve columns of the unique constraint
			unordered_set<idx_t> keys;
			if (unique.index != INVALID_INDEX) {
				assert(unique.index < base.columns.size());
				// unique constraint is given by single index
				keys.insert(unique.index);
			} else {
				// unique constraint is given by list of names
				// have to resolve names
				assert(unique.columns.size() > 0);
				for (auto &keyname : unique.columns) {
					auto entry = info.name_map.find(keyname);
					if (entry == info.name_map.end()) {
						throw ParserException("column \"%s\" named in key does not exist", keyname.c_str());
					}
					if (find(keys.begin(), keys.end(), entry->second) != keys.end()) {
						throw ParserException("column \"%s\" appears twice in "
						                      "primary key constraint",
						                      keyname.c_str());
					}
					keys.insert(entry->second);
				}
			}

			if (unique.is_primary_key) {
				// we can only have one primary key per table
				if (has_primary_key) {
					throw ParserException("table \"%s\" has more than one primary key", base.table.c_str());
				}
				has_primary_key = true;
			}
			info.bound_constraints.push_back(make_unique<BoundUniqueConstraint>(keys, unique.is_primary_key));
			break;
		}
		default:
			throw NotImplementedException("unrecognized constraint type in bind");
		}
	}
}

void Binder::BindDefaultValues(vector<ColumnDefinition> &columns, vector<unique_ptr<Expression>> &bound_defaults) {
	for (idx_t i = 0; i < columns.size(); i++) {
		unique_ptr<Expression> bound_default;
		if (columns[i].default_value) {
			// we bind a copy of the DEFAULT value because binding is destructive
			// and we want to keep the original expression around for serialization
			auto default_copy = columns[i].default_value->Copy();
			ConstantBinder default_binder(*this, context, "DEFAULT value");
			default_binder.target_type = columns[i].type;
			bound_default = default_binder.Bind(default_copy);
		} else {
			// no default value specified: push a default value of constant null
			bound_default = make_unique<BoundConstantExpression>(Value(GetInternalType(columns[i].type)));
		}
		bound_defaults.push_back(move(bound_default));
	}
}

unique_ptr<BoundCreateInfo> Binder::BindCreateTableInfo(unique_ptr<CreateInfo> info) {
	auto &base = (CreateTableInfo &)*info;

	auto result = make_unique<BoundCreateTableInfo>(move(info));
	if (base.query) {
		// construct the result object
		result->query = unique_ptr_cast<BoundSQLStatement, BoundSelectStatement>(Bind(*base.query));
		// construct the set of columns based on the names and types of the query
		auto &names = result->query->node->names;
		auto &sql_types = result->query->node->types;
		assert(names.size() == sql_types.size());
		for (idx_t i = 0; i < names.size(); i++) {
			base.columns.push_back(ColumnDefinition(names[i], sql_types[i]));
		}
		// create the name map for the statement
		CreateColumnMap(*result);
	} else {
		// create the name map for the statement
		CreateColumnMap(*result);
		// bind any constraints
		BindConstraints(*this, *result);
		// bind the default values
		BindDefaultValues(base.columns, result->bound_defaults);
	}
	return move(result);
}





using namespace duckdb;
using namespace std;

unique_ptr<BoundCreateInfo> Binder::BindCreateViewInfo(unique_ptr<CreateInfo> info) {
	auto &base = (CreateViewInfo &)*info;
	auto result = make_unique<BoundCreateInfo>(move(info));

	// bind the view as if it were a query so we can catch errors
	// note that we bind a copy and don't actually use the bind result
	auto copy = base.query->Copy();
	auto query_node = Bind(*copy);
	if (base.aliases.size() > query_node->names.size()) {
		throw BinderException("More VIEW aliases than columns in query result");
	}
	return result;
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_delete_statement.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Bound equivalent to DeleteStatement
class BoundDeleteStatement : public BoundSQLStatement {
public:
	BoundDeleteStatement() : BoundSQLStatement(StatementType::DELETE) {
	}

	unique_ptr<Expression> condition;
	unique_ptr<BoundTableRef> table;

public:
	vector<string> GetNames() override {
		return {"Count"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::BIGINT};
	}
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(DeleteStatement &stmt) {
	auto result = make_unique<BoundDeleteStatement>();
	// visit the table reference
	result->table = Bind(*stmt.table);
	if (result->table->type != TableReferenceType::BASE_TABLE) {
		throw BinderException("Can only delete from base table!");
	}
	auto &tableref = (BoundBaseTableRef &)*result->table;
	if (!tableref.table->temporary) {
		// delete from persistent table: not read only!
		this->read_only = false;
	}
	// project any additional columns required for the condition
	if (stmt.condition) {
		WhereBinder binder(*this, context);
		result->condition = binder.Bind(stmt.condition);
	}
	return move(result);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_simple_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! BoundSimpleStatement is a bound statement used for statements that do not need to be bound but only need to transfer
//! their ParseInfo further into the plan. This is typically true for schema statements (e.g. CREATE SEQUENCE, DROP
//! TABLE, etc...)
class BoundSimpleStatement : public BoundSQLStatement {
public:
	BoundSimpleStatement(StatementType type, unique_ptr<ParseInfo> info) : BoundSQLStatement(type), info(move(info)) {
	}

	unique_ptr<ParseInfo> info;

public:
	vector<string> GetNames() override {
		return {"Success"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::BOOLEAN};
	}
};
} // namespace duckdb





using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(DropStatement &stmt) {
	switch (stmt.info->type) {
	case CatalogType::PREPARED_STATEMENT:
		// dropping prepared statements is always possible
		break;
	case CatalogType::SCHEMA:
		// dropping a schema is never read-only because there are no temporary schemas
		this->read_only = false;
		break;
	case CatalogType::VIEW:
	case CatalogType::SEQUENCE:
	case CatalogType::INDEX:
	case CatalogType::TABLE: {
		auto entry = (StandardEntry *)Catalog::GetCatalog(context).GetEntry(context, stmt.info->type, stmt.info->schema,
		                                                                    stmt.info->name, true);
		if (!entry) {
			break;
		}
		if (!entry->temporary) {
			// we can only drop temporary tables in read-only mode
			this->read_only = false;
		}
		stmt.info->schema = entry->schema->name;
		break;
	}
	default:
		throw BinderException("Unknown catalog type for drop statement!");
	}
	return make_unique<BoundSimpleStatement>(stmt.type, move(stmt.info));
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_execute_statement.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Bound equivalent to ExecuteStatement
class BoundExecuteStatement : public BoundSQLStatement {
public:
	BoundExecuteStatement() : BoundSQLStatement(StatementType::EXECUTE) {
	}

	//! The prepared statement to execute
	PreparedStatementData *prepared;
public:
	vector<string> GetNames() override {
		return prepared->names;
	}
	vector<SQLType> GetTypes() override {
		return prepared->sql_types;
	}
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(ExecuteStatement &stmt) {
	auto result = make_unique<BoundExecuteStatement>();
	// bind the prepared statement
	auto entry =
	    (PreparedStatementCatalogEntry *)context.prepared_statements->GetEntry(context.ActiveTransaction(), stmt.name);
	if (!entry || entry->deleted) {
		throw BinderException("Could not find prepared statement with that name");
	}
	result->prepared = entry->prepared.get();
	read_only = result->prepared->read_only;

	vector<Value> bind_values;
	for (idx_t i = 0; i < stmt.values.size(); i++) {
		ConstantBinder binder(*this, context, "EXECUTE statement");
		binder.target_type = result->prepared->GetType(i + 1);
		auto bound_expr = binder.Bind(stmt.values[i]);

		Value value = ExpressionExecutor::EvaluateScalar(*bound_expr);
		bind_values.push_back(move(value));
	}
	result->prepared->Bind(move(bind_values));
	return move(result);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_explain_statement.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
//! Bound equivalent to ExplainStatement
class BoundExplainStatement : public BoundSQLStatement {
public:
	BoundExplainStatement() : BoundSQLStatement(StatementType::EXPLAIN) {
	}

	//! The bound statement underlying the explain
	unique_ptr<BoundSQLStatement> bound_statement;

public:
	vector<string> GetNames() override {
		return {"explain_key", "explain_value"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::VARCHAR, SQLType::VARCHAR};
	}
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(ExplainStatement &stmt) {
	auto result = make_unique<BoundExplainStatement>();
	// bind the underlying statement
	result->bound_statement = Bind(*stmt.stmt);
	return move(result);
}






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/insert_binder.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The INSERT binder is responsible for binding expressions within the VALUES of an INSERT statement
class InsertBinder : public ExpressionBinder {
public:
	InsertBinder(Binder &binder, ClientContext &context);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb




using namespace std;

namespace duckdb {

static void CheckInsertColumnCountMismatch(int64_t expected_columns, int64_t result_columns, bool columns_provided,
                                           const char *tname) {
	if (result_columns != expected_columns) {
		string msg = StringUtil::Format(!columns_provided ? "table %s has %lld columns but %lld values were supplied"
		                                                  : "Column name/value mismatch for insert on %s: "
		                                                    "expected %lld columns but %lld values were supplied",
		                                tname, expected_columns, result_columns);
		throw BinderException(msg);
	}
}

unique_ptr<BoundSQLStatement> Binder::Bind(InsertStatement &stmt) {
	auto result = make_unique<BoundInsertStatement>();

	auto table = Catalog::GetCatalog(context).GetEntry<TableCatalogEntry>(context, stmt.schema, stmt.table);
	assert(table);

	result->table = table;
	if (!result->table->temporary) {
		// inserting into a non-temporary table: alters underlying database
		this->read_only = false;
	}

	vector<idx_t> named_column_map;
	if (stmt.columns.size() > 0) {
		// insertion statement specifies column list

		// create a mapping of (list index) -> (column index)
		unordered_map<string, idx_t> column_name_map;
		for (idx_t i = 0; i < stmt.columns.size(); i++) {
			column_name_map[stmt.columns[i]] = i;
			auto entry = table->name_map.find(stmt.columns[i]);
			if (entry == table->name_map.end()) {
				throw BinderException("Column %s not found in table %s", stmt.columns[i].c_str(), table->name.c_str());
			}
			if (entry->second == COLUMN_IDENTIFIER_ROW_ID) {
				throw BinderException("Cannot explicitly insert values into rowid column");
			}
			result->expected_types.push_back(table->columns[entry->second].type);
			named_column_map.push_back(entry->second);
		}
		for (idx_t i = 0; i < result->table->columns.size(); i++) {
			auto &col = result->table->columns[i];
			auto entry = column_name_map.find(col.name);
			if (entry == column_name_map.end()) {
				// column not specified, set index to INVALID_INDEX
				result->column_index_map.push_back(INVALID_INDEX);
			} else {
				// column was specified, set to the index
				result->column_index_map.push_back(entry->second);
			}
		}
	} else {
		for (idx_t i = 0; i < result->table->columns.size(); i++) {
			result->expected_types.push_back(table->columns[i].type);
		}
	}

	// bind the default values
	BindDefaultValues(table->columns, result->bound_defaults);
	if (!stmt.select_statement) {
		return move(result);
	}

	idx_t expected_columns = stmt.columns.size() == 0 ? result->table->columns.size() : stmt.columns.size();
	// special case: check if we are inserting from a VALUES statement
	if (stmt.select_statement->node->type == QueryNodeType::SELECT_NODE) {
		auto &node = (SelectNode &)*stmt.select_statement->node;
		if (node.from_table->type == TableReferenceType::EXPRESSION_LIST) {
			auto &expr_list = (ExpressionListRef &)*node.from_table;
			assert(expr_list.values.size() > 0);
			CheckInsertColumnCountMismatch(expected_columns, expr_list.values[0].size(), stmt.columns.size() != 0,
			                               result->table->name.c_str());

			// VALUES list!
			for (idx_t col_idx = 0; col_idx < expected_columns; col_idx++) {
				idx_t table_col_idx = stmt.columns.size() == 0 ? col_idx : named_column_map[col_idx];
				assert(table_col_idx < table->columns.size());

				// set the expected types as the types for the INSERT statement
				auto &column = table->columns[table_col_idx];
				expr_list.expected_types.push_back(column.type);
				expr_list.expected_names.push_back(column.name);

				// now replace any DEFAULT values with the corresponding default expression
				for (idx_t list_idx = 0; list_idx < expr_list.values.size(); list_idx++) {
					if (expr_list.values[list_idx][col_idx]->type == ExpressionType::VALUE_DEFAULT) {
						// DEFAULT value! replace the entry
						if (column.default_value) {
							expr_list.values[list_idx][col_idx] = column.default_value->Copy();
						} else {
							expr_list.values[list_idx][col_idx] =
							    make_unique<ConstantExpression>(column.type, Value(GetInternalType(column.type)));
						}
					}
				}
			}
		}
	}

	// bind the select statement, if any
	result->select_statement = unique_ptr_cast<BoundSQLStatement, BoundSelectStatement>(Bind(*stmt.select_statement));
	CheckInsertColumnCountMismatch(expected_columns, result->select_statement->node->types.size(),
	                               stmt.columns.size() != 0, result->table->name.c_str());

	return move(result);
}

} // namespace duckdb




using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(SelectStatement &stmt) {
	auto result = make_unique<BoundSelectStatement>();
	// first we visit the set of CTEs and add them to the bind context
	for (auto &cte_it : stmt.cte_map) {
		AddCTE(cte_it.first, cte_it.second.get());
	}
	// now visit the root node of the select statement
	result->node = Bind(*stmt.node);
	return move(result);
}







using namespace duckdb;
using namespace std;

//! This file contains the binder definitions for statements that do not need to be bound at all and only require a
//! straightforward conversion

unique_ptr<BoundSQLStatement> Binder::Bind(AlterTableStatement &stmt) {
	auto table =
	    Catalog::GetCatalog(context).GetEntry<TableCatalogEntry>(context, stmt.info->schema, stmt.info->table, true);
	if (table && !table->temporary) {
		// we can only alter temporary tables in read-only mode
		this->read_only = false;
	}
	return make_unique<BoundSimpleStatement>(stmt.type, move(stmt.info));
}

unique_ptr<BoundSQLStatement> Binder::Bind(PragmaStatement &stmt) {
	return make_unique<BoundSimpleStatement>(stmt.type, move(stmt.info));
}

unique_ptr<BoundSQLStatement> Binder::Bind(TransactionStatement &stmt) {
	return make_unique<BoundSimpleStatement>(stmt.type, move(stmt.info));
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/expression_binder/update_binder.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! The UPDATE binder is responsible for binding an expression within an UPDATE statement
class UpdateBinder : public ExpressionBinder {
public:
	UpdateBinder(Binder &binder, ClientContext &context);

protected:
	BindResult BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression = false) override;

	string UnsupportedAggregateMessage() override;
};

} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/statement/bound_update_statement.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Bound equivalent to UpdateStatement
class BoundUpdateStatement : public BoundSQLStatement {
public:
	BoundUpdateStatement() : BoundSQLStatement(StatementType::UPDATE), is_index_update(false) {
	}

	//! The condition by which to update
	unique_ptr<Expression> condition;
	//! The table to update
	unique_ptr<BoundTableRef> table;
	//! The column ids to update
	vector<column_t> column_ids;
	//! The expressions to update by
	vector<unique_ptr<Expression>> expressions;
	//! The default statements used by the table
	vector<unique_ptr<Expression>> bound_defaults;
	//! The projection index
	idx_t proj_index;
	//! Whether or not the update is an index update. Index updates are translated into insert + deletes, instead of
	//! performing an in-place update.
	bool is_index_update;

public:
	vector<string> GetNames() override {
		return {"Count"};
	}
	vector<SQLType> GetTypes() override {
		return {SQLType::BIGINT};
	}
};
} // namespace duckdb






#include <algorithm>

using namespace duckdb;
using namespace std;

static void BindExtraColumns(TableCatalogEntry &table, Binder &binder, ClientContext &context,
                             BoundUpdateStatement &result, unordered_set<column_t> &bound_columns) {
	if (bound_columns.size() <= 1) {
		return;
	}
	idx_t found_column_count = 0;
	unordered_set<idx_t> found_columns;
	for (idx_t i = 0; i < result.column_ids.size(); i++) {
		if (bound_columns.find(result.column_ids[i]) != bound_columns.end()) {
			// this column is referenced in the CHECK constraint
			found_column_count++;
			found_columns.insert(result.column_ids[i]);
		}
	}
	if (found_column_count > 0 && found_column_count != bound_columns.size()) {
		// columns in this CHECK constraint were referenced, but not all were part of the UPDATE
		// add them to the scan and update set
		for (auto &check_column_id : bound_columns) {
			if (found_columns.find(check_column_id) != found_columns.end()) {
				// column is already projected
				continue;
			}
			// column is not projected yet: project it by adding the clause "i=i" to the set of updated columns
			result.column_ids.push_back(check_column_id);
			UpdateBinder update_binder(binder, context);
			auto &column = table.columns[check_column_id];
			update_binder.target_type = column.type;
			auto unbound_expr = make_unique_base<ParsedExpression, ColumnRefExpression>(column.name, table.name);
			auto bound_expr = update_binder.Bind(unbound_expr);
			result.expressions.push_back(move(bound_expr));
		}
	}
}

static void BindUpdateConstraints(TableCatalogEntry &table, Binder &binder, ClientContext &context,
                                  BoundUpdateStatement &result) {
	// check the constraints and indexes of the table to see if we need to project any additional columns
	// we do this for indexes with multiple columns and CHECK constraints in the UPDATE clause
	// suppose we have a constraint CHECK(i + j < 10); now we need both i and j to check the constraint
	// if we are only updating one of the two columns we add the other one to the UPDATE set
	// with a "useless" update (i.e. i=i) so we can verify that the CHECK constraint is not violated
	for (auto &constraint : table.bound_constraints) {
		if (constraint->type == ConstraintType::CHECK) {
			auto &check = *reinterpret_cast<BoundCheckConstraint *>(constraint.get());
			// check constraint! check if we need to add any extra columns to the UPDATE clause
			BindExtraColumns(table, binder, context, result, check.bound_columns);
		}
	}
	// for index updates, we do the same, however, for index updates we always turn any update into an insert and a
	// delete for the insert, we thus need all the columns to be available, hence we check if the update touches any
	// index columns
	result.is_index_update = false;
	for (auto &index : table.storage->indexes) {
		if (index->IndexIsUpdated(result.column_ids)) {
			result.is_index_update = true;
		}
	}
	if (result.is_index_update) {
		// the update updates a column required by an index, push projections for all columns
		unordered_set<column_t> all_columns;
		for (idx_t i = 0; i < table.storage->types.size(); i++) {
			all_columns.insert(i);
		}
		BindExtraColumns(table, binder, context, result, all_columns);
	}
}

unique_ptr<BoundSQLStatement> Binder::Bind(UpdateStatement &stmt) {
	auto result = make_unique<BoundUpdateStatement>();
	// visit the table reference
	result->table = Bind(*stmt.table);
	if (result->table->type != TableReferenceType::BASE_TABLE) {
		throw BinderException("Can only update base table!");
	}
	auto table = ((BoundBaseTableRef &)*result->table).table;
	if (!table->temporary) {
		// update of persistent table: not read only!
		this->read_only = false;
	}
	result->proj_index = GenerateTableIndex();
	// project any additional columns required for the condition/expressions
	if (stmt.condition) {
		WhereBinder binder(*this, context);
		result->condition = binder.Bind(stmt.condition);
	}
	assert(stmt.columns.size() == stmt.expressions.size());
	for (idx_t i = 0; i < stmt.columns.size(); i++) {
		auto &colname = stmt.columns[i];
		auto &expr = stmt.expressions[i];
		if (!table->ColumnExists(colname)) {
			throw BinderException("Referenced update column %s not found in table!", colname.c_str());
		}
		auto &column = table->GetColumn(colname);
		if (std::find(result->column_ids.begin(), result->column_ids.end(), column.oid) != result->column_ids.end()) {
			throw BinderException("Multiple assignments to same column \"%s\"", colname.c_str());
		}
		result->column_ids.push_back(column.oid);

		if (expr->type == ExpressionType::VALUE_DEFAULT) {
			result->expressions.push_back(
			    make_unique<BoundDefaultExpression>(GetInternalType(column.type), column.type));
		} else {
			UpdateBinder binder(*this, context);
			binder.target_type = column.type;
			auto bound_expr = binder.Bind(expr);
			result->expressions.push_back(move(bound_expr));
		}
	}
	BindUpdateConstraints(*table, *this, context, *result);
	// bind the default values
	BindDefaultValues(table->columns, result->bound_defaults);
	return move(result);
}







using namespace duckdb;
using namespace std;

unique_ptr<BoundSQLStatement> Binder::Bind(VacuumStatement &stmt) {
	return make_unique<BoundSimpleStatement>(stmt.type, move(stmt.info));
}





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_subqueryref.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a cross product
class BoundSubqueryRef : public BoundTableRef {
public:
	BoundSubqueryRef(unique_ptr<Binder> binder, unique_ptr<BoundQueryNode> subquery)
	    : BoundTableRef(TableReferenceType::SUBQUERY), binder(move(binder)), subquery(move(subquery)) {
	}

	//! The binder used to bind the subquery
	unique_ptr<Binder> binder;
	//! The bound subquery node
	unique_ptr<BoundQueryNode> subquery;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(BaseTableRef &expr) {
	// CTEs and views are also referred to using BaseTableRefs, hence need to distinguish here
	// check if the table name refers to a CTE
	auto cte = FindCTE(expr.table_name);
	if (cte) {
		// Check if there is a CTE binding in the BindContext
		auto ctebinding = bind_context.GetCTEBinding(expr.table_name);
		if (ctebinding == nullptr) {
			// Move CTE to subquery and bind recursively
			SubqueryRef subquery(move(cte));
			subquery.alias = expr.alias.empty() ? expr.table_name : expr.alias;
			return Bind(subquery);
		} else {
			// There is a CTE binding in the BindContext.
			// This can only be the case if there is a recursive CTE present.
			auto index = GenerateTableIndex();
			auto result = make_unique<BoundCTERef>(index, ctebinding->index);
			auto b = (GenericBinding *)ctebinding;

			bind_context.AddGenericBinding(index, expr.alias.empty() ? expr.table_name : expr.alias, b->names,
			                               b->types);
			// Update references to CTE
			auto cteref = bind_context.cte_references[expr.table_name];
			(*cteref)++;

			result->types = b->types;
			result->bound_columns = b->names;
			return move(result);
		}
	}
	// not a CTE
	// extract a table or view from the catalog
	auto table_or_view =
	    Catalog::GetCatalog(context).GetEntry(context, CatalogType::TABLE, expr.schema_name, expr.table_name);
	switch (table_or_view->type) {
	case CatalogType::TABLE: {
		// base table: create the BoundBaseTableRef node
		auto table = (TableCatalogEntry *)table_or_view;
		auto table_index = GenerateTableIndex();
		auto result = make_unique<BoundBaseTableRef>(table, table_index);
		bind_context.AddBaseTable(result.get(), expr.alias.empty() ? expr.table_name : expr.alias);
		return move(result);
	}
	case CatalogType::VIEW: {
		// the node is a view: get the query that the view represents
		auto view_catalog_entry = (ViewCatalogEntry *)table_or_view;
		SubqueryRef subquery(view_catalog_entry->query->Copy());
		subquery.alias = expr.alias.empty() ? expr.table_name : expr.alias;
		subquery.column_name_alias = view_catalog_entry->aliases;
		// bind the child subquery
		return Bind(subquery);
	}
	default:
		throw NotImplementedException("Catalog entry type");
	}
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_crossproductref.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a cross product
class BoundCrossProductRef : public BoundTableRef {
public:
	BoundCrossProductRef() : BoundTableRef(TableReferenceType::CROSS_PRODUCT) {
	}

	//! The left hand side of the cross product
	unique_ptr<BoundTableRef> left;
	//! The right hand side of the cross product
	unique_ptr<BoundTableRef> right;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(CrossProductRef &ref) {
	auto result = make_unique<BoundCrossProductRef>();
	result->left = Bind(*ref.left);
	result->right = Bind(*ref.right);
	return move(result);
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_dummytableref.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

//! Represents a cross product
class BoundEmptyTableRef : public BoundTableRef {
public:
	BoundEmptyTableRef(idx_t bind_index) : BoundTableRef(TableReferenceType::EMPTY), bind_index(bind_index) {
	}
	idx_t bind_index;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(EmptyTableRef &ref) {
	return make_unique<BoundEmptyTableRef>(GenerateTableIndex());
}

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_expressionlistref.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
//! Represents a TableReference to a base table in the schema
class BoundExpressionListRef : public BoundTableRef {
public:
	BoundExpressionListRef() : BoundTableRef(TableReferenceType::EXPRESSION_LIST) {
	}

	//! The bound VALUES list
	vector<vector<unique_ptr<Expression>>> values;
	//! The generated names of the values list
	vector<string> names;
	//! The types of the values list
	vector<SQLType> types;
	//! The index in the bind context
	idx_t bind_index;
};
} // namespace duckdb




using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(ExpressionListRef &expr) {
	auto result = make_unique<BoundExpressionListRef>();
	if (expr.expected_types.size() > 0) {
		result->types = expr.expected_types;
		result->names = expr.expected_names;
	}
	// bind value list
	InsertBinder binder(*this, context);
	binder.target_type = SQLType(SQLTypeId::INVALID);
	for (idx_t list_idx = 0; list_idx < expr.values.size(); list_idx++) {
		auto &expression_list = expr.values[list_idx];
		vector<unique_ptr<Expression>> list;
		if (result->types.size() == 0) {
			// for the first list, we set the expected types as the types of these expressions
			for (idx_t val_idx = 0; val_idx < expression_list.size(); val_idx++) {
				SQLType result_type;
				auto expr = binder.Bind(expression_list[val_idx], &result_type);
				result->types.push_back(result_type);
				result->names.push_back("col" + to_string(val_idx));
				list.push_back(move(expr));
			}
		} else {
			// for subsequent lists, we apply the expected types we found in the first list
			for (idx_t val_idx = 0; val_idx < expression_list.size(); val_idx++) {
				binder.target_type = result->types[val_idx];
				list.push_back(binder.Bind(expression_list[val_idx]));
			}
		}
		result->values.push_back(move(list));
	}
	result->bind_index = GenerateTableIndex();
	bind_context.AddGenericBinding(result->bind_index, expr.alias, result->names, result->types);
	return move(result);
}



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_joinref.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Represents a join
class BoundJoinRef : public BoundTableRef {
public:
	BoundJoinRef() : BoundTableRef(TableReferenceType::JOIN) {
	}

	//! The left hand side of the join
	unique_ptr<BoundTableRef> left;
	//! The right hand side of the join
	unique_ptr<BoundTableRef> right;
	//! The join condition
	unique_ptr<Expression> condition;
	//! The join type
	JoinType type;
};
} // namespace duckdb


using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(JoinRef &ref) {
	auto result = make_unique<BoundJoinRef>();
	result->type = ref.type;
	result->left = Bind(*ref.left);
	result->right = Bind(*ref.right);

	for (auto &hidden_column : ref.hidden_columns) {
		bind_context.hidden_columns.insert(hidden_column);
	}

	WhereBinder binder(*this, context);
	result->condition = binder.Bind(ref.condition);
	return move(result);
}




using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(SubqueryRef &ref) {
	auto binder = make_unique<Binder>(context, this);
	auto subquery = binder->Bind(*ref.subquery);
	idx_t bind_index = subquery->GetRootIndex();
	auto result = make_unique<BoundSubqueryRef>(move(binder), move(subquery));

	bind_context.AddSubquery(bind_index, ref.alias, ref, *result->subquery);
	MoveCorrelatedExpressions(*result->binder);
	return move(result);
}





//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/tableref/bound_table_function.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
class TableFunctionCatalogEntry;

//! Represents a reference to a table-producing function call
class BoundTableFunction : public BoundTableRef {
public:
	BoundTableFunction(TableFunctionCatalogEntry *function, idx_t bind_index)
	    : BoundTableRef(TableReferenceType::TABLE_FUNCTION), function(function), bind_index(bind_index) {
	}

	//! The function that is called
	TableFunctionCatalogEntry *function;
	//! The bind data of the function
	unique_ptr<FunctionData> bind_data;
	//! The set of parameters to use as input to the table-producing function
	vector<Value> parameters;
	//! The set of returned sql types
	vector<SQLType> return_types;
	//! The set of returned column names
	vector<string> names;
	//! The index in the bind context
	idx_t bind_index;
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

unique_ptr<BoundTableRef> Binder::Bind(TableFunctionRef &ref) {
	auto bind_index = GenerateTableIndex();

	assert(ref.function->type == ExpressionType::FUNCTION);
	auto fexpr = (FunctionExpression *)ref.function.get();
	// parse the parameters of the function
	auto function =
	    Catalog::GetCatalog(context).GetEntry<TableFunctionCatalogEntry>(context, fexpr->schema, fexpr->function_name);

	// check if the argument lengths match
	if (fexpr->children.size() != function->function.arguments.size()) {
		throw CatalogException("Function with name %s exists, but argument length does not match! "
		                       "Expected %d arguments but got %d.",
		                       fexpr->function_name.c_str(), (int)function->function.arguments.size(),
		                       (int)fexpr->children.size());
	}
	auto result = make_unique<BoundTableFunction>(function, bind_index);
	// evalate the input parameters to the function
	for (auto &child : fexpr->children) {
		ConstantBinder binder(*this, context, "TABLE FUNCTION parameter");
		auto expr = binder.Bind(child);
		auto constant = ExpressionExecutor::EvaluateScalar(*expr);
		result->parameters.push_back(constant);
	}
	// perform the binding
	result->bind_data = function->function.bind(context, result->parameters, result->return_types, result->names);
	assert(result->return_types.size() == result->names.size());
	assert(result->return_types.size() > 0);
	// now add the table function to the bind context so its columns can be bound
	bind_context.AddGenericBinding(bind_index, ref.alias.empty() ? fexpr->function_name : ref.alias, result->names,
	                               result->return_types);
	return move(result);
}










using namespace duckdb;
using namespace std;

Binder::Binder(ClientContext &context, Binder *parent_)
    : context(context), read_only(true), parent(!parent_ ? nullptr : (parent_->parent ? parent_->parent : parent_)),
      bound_tables(0) {
	if (parent_) {
		// We have to inherit CTE bindings from the parent bind_context, if there is a parent.
		bind_context.SetCTEBindings(parent_->bind_context.GetCTEBindings());
		bind_context.cte_references = parent_->bind_context.cte_references;
	}
	if (parent) {
		parameters = parent->parameters;
		CTE_bindings = parent->CTE_bindings;
	}
}

unique_ptr<BoundSQLStatement> Binder::Bind(SQLStatement &statement) {
	switch (statement.type) {
	case StatementType::SELECT:
		return Bind((SelectStatement &)statement);
	case StatementType::INSERT:
		return Bind((InsertStatement &)statement);
	case StatementType::COPY:
		return Bind((CopyStatement &)statement);
	case StatementType::DELETE:
		return Bind((DeleteStatement &)statement);
	case StatementType::UPDATE:
		return Bind((UpdateStatement &)statement);
	case StatementType::CREATE:
		return Bind((CreateStatement &)statement);
	case StatementType::DROP:
		return Bind((DropStatement &)statement);
	case StatementType::ALTER:
		return Bind((AlterTableStatement &)statement);
	case StatementType::TRANSACTION:
		return Bind((TransactionStatement &)statement);
	case StatementType::PRAGMA:
		return Bind((PragmaStatement &)statement);
	case StatementType::EXECUTE:
		return Bind((ExecuteStatement &)statement);
	case StatementType::EXPLAIN:
		return Bind((ExplainStatement &)statement);
	case StatementType::VACUUM:
		return Bind((VacuumStatement &)statement);
	default:
		throw NotImplementedException("Unimplemented statement type \"%s\" for Bind",
		                              StatementTypeToString(statement.type).c_str());
	}
}

static int64_t BindConstant(Binder &binder, ClientContext &context, string clause, unique_ptr<ParsedExpression> &expr) {
	ConstantBinder constant_binder(binder, context, clause);
	auto bound_expr = constant_binder.Bind(expr);
	Value value = ExpressionExecutor::EvaluateScalar(*bound_expr);
	if (!TypeIsNumeric(value.type)) {
		throw BinderException("LIMIT clause can only contain numeric constants!");
	}
	int64_t limit_value = value.GetValue<int64_t>();
	if (limit_value < 0) {
		throw BinderException("LIMIT must not be negative");
	}
	return limit_value;
}

unique_ptr<BoundQueryNode> Binder::Bind(QueryNode &node) {
	unique_ptr<BoundQueryNode> result;
	switch (node.type) {
	case QueryNodeType::SELECT_NODE:
		result = Bind((SelectNode &)node);
		break;
	case QueryNodeType::RECURSIVE_CTE_NODE:
		result = Bind((RecursiveCTENode &)node);
		break;
	default:
		assert(node.type == QueryNodeType::SET_OPERATION_NODE);
		result = Bind((SetOperationNode &)node);
		break;
	}
	// DISTINCT ON select list
	result->select_distinct = node.select_distinct;
	// bind the limit nodes
	if (node.limit) {
		result->limit = BindConstant(*this, context, "LIMIT clause", node.limit);
		result->offset = 0;
	}
	if (node.offset) {
		result->offset = BindConstant(*this, context, "OFFSET clause", node.offset);
		if (!node.limit) {
			result->limit = std::numeric_limits<int64_t>::max();
		}
	}
	return result;
}

unique_ptr<BoundTableRef> Binder::Bind(TableRef &ref) {
	switch (ref.type) {
	case TableReferenceType::BASE_TABLE:
		return Bind((BaseTableRef &)ref);
	case TableReferenceType::CROSS_PRODUCT:
		return Bind((CrossProductRef &)ref);
	case TableReferenceType::JOIN:
		return Bind((JoinRef &)ref);
	case TableReferenceType::SUBQUERY:
		return Bind((SubqueryRef &)ref);
	case TableReferenceType::EMPTY:
		return Bind((EmptyTableRef &)ref);
	case TableReferenceType::TABLE_FUNCTION:
		return Bind((TableFunctionRef &)ref);
	case TableReferenceType::EXPRESSION_LIST:
		return Bind((ExpressionListRef &)ref);
	default:
		throw Exception("Unknown table ref type");
	}
}

void Binder::AddCTE(const string &name, QueryNode *cte) {
	assert(cte);
	assert(!name.empty());
	auto entry = CTE_bindings.find(name);
	if (entry != CTE_bindings.end()) {
		throw BinderException("Duplicate CTE \"%s\" in query!", name.c_str());
	}
	CTE_bindings[name] = cte;
}

unique_ptr<QueryNode> Binder::FindCTE(const string &name) {
	auto entry = CTE_bindings.find(name);
	if (entry == CTE_bindings.end()) {
		if (parent) {
			return parent->FindCTE(name);
		}
		return nullptr;
	}
	return entry->second->Copy();
}

idx_t Binder::GenerateTableIndex() {
	if (parent) {
		return parent->GenerateTableIndex();
	}
	return bound_tables++;
}

void Binder::PushExpressionBinder(ExpressionBinder *binder) {
	GetActiveBinders().push_back(binder);
}

void Binder::PopExpressionBinder() {
	assert(HasActiveBinder());
	GetActiveBinders().pop_back();
}

void Binder::SetActiveBinder(ExpressionBinder *binder) {
	assert(HasActiveBinder());
	GetActiveBinders().back() = binder;
}

ExpressionBinder *Binder::GetActiveBinder() {
	return GetActiveBinders().back();
}

bool Binder::HasActiveBinder() {
	return GetActiveBinders().size() > 0;
}

vector<ExpressionBinder *> &Binder::GetActiveBinders() {
	if (parent) {
		return parent->GetActiveBinders();
	}
	return active_binders;
}

void Binder::MoveCorrelatedExpressions(Binder &other) {
	MergeCorrelatedColumns(other.correlated_columns);
	other.correlated_columns.clear();
}

void Binder::MergeCorrelatedColumns(vector<CorrelatedColumnInfo> &other) {
	for (idx_t i = 0; i < other.size(); i++) {
		AddCorrelatedColumn(other[i]);
	}
}

void Binder::AddCorrelatedColumn(CorrelatedColumnInfo info) {
	// we only add correlated columns to the list if they are not already there
	if (std::find(correlated_columns.begin(), correlated_columns.end(), info) == correlated_columns.end()) {
		correlated_columns.push_back(info);
	}
}





using namespace duckdb;
using namespace std;

BoundAggregateExpression::BoundAggregateExpression(TypeId return_type, AggregateFunction function, bool distinct)
    : Expression(ExpressionType::BOUND_AGGREGATE, ExpressionClass::BOUND_AGGREGATE, return_type), function(function),
      distinct(distinct) {
}

string BoundAggregateExpression::ToString() const {
	string result = function.name + "(";
	if (distinct) {
		result += "DISTINCT ";
	}
	StringUtil::Join(children, children.size(), ", ",
	                 [](const unique_ptr<Expression> &child) { return child->GetName(); });
	result += ")";
	return result;
}
hash_t BoundAggregateExpression::Hash() const {
	hash_t result = Expression::Hash();
	result = CombineHash(result, duckdb::Hash(function.name.c_str()));
	result = CombineHash(result, duckdb::Hash(distinct));
	return result;
}

bool BoundAggregateExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundAggregateExpression *)other_;
	if (other->distinct != distinct) {
		return false;
	}
	if (other->function != function) {
		return false;
	}
	if (children.size() != other->children.size()) {
		return false;
	}
	for (idx_t i = 0; i < children.size(); i++) {
		if (!Expression::Equals(children[i].get(), other->children[i].get())) {
			return false;
		}
	}
	return true;
}

unique_ptr<Expression> BoundAggregateExpression::Copy() {
	auto copy = make_unique<BoundAggregateExpression>(return_type, function, distinct);
	for (auto &child : children) {
		copy->children.push_back(child->Copy());
	}
	copy->CopyProperties(*this);
	return move(copy);
}


using namespace duckdb;
using namespace std;

BoundBetweenExpression::BoundBetweenExpression(unique_ptr<Expression> input, unique_ptr<Expression> lower,
                                               unique_ptr<Expression> upper, bool lower_inclusive, bool upper_inclusive)
    : Expression(ExpressionType::COMPARE_BETWEEN, ExpressionClass::BOUND_BETWEEN, TypeId::BOOL), input(move(input)),
      lower(move(lower)), upper(move(upper)), lower_inclusive(lower_inclusive), upper_inclusive(upper_inclusive) {
}

string BoundBetweenExpression::ToString() const {
	return input->ToString() + " BETWEEN " + lower->ToString() + " AND " + upper->ToString();
}

bool BoundBetweenExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundBetweenExpression *)other_;
	if (!Expression::Equals(input.get(), other->input.get())) {
		return false;
	}
	if (!Expression::Equals(lower.get(), other->lower.get())) {
		return false;
	}
	if (!Expression::Equals(upper.get(), other->upper.get())) {
		return false;
	}
	return lower_inclusive == other->lower_inclusive && upper_inclusive == other->upper_inclusive;
}

unique_ptr<Expression> BoundBetweenExpression::Copy() {
	auto copy = make_unique<BoundBetweenExpression>(input->Copy(), lower->Copy(), upper->Copy(), lower_inclusive,
	                                                upper_inclusive);
	copy->CopyProperties(*this);
	return move(copy);
}


using namespace duckdb;
using namespace std;

BoundCaseExpression::BoundCaseExpression(unique_ptr<Expression> check, unique_ptr<Expression> res_if_true,
                                         unique_ptr<Expression> res_if_false)
    : Expression(ExpressionType::CASE_EXPR, ExpressionClass::BOUND_CASE, res_if_true->return_type), check(move(check)),
      result_if_true(move(res_if_true)), result_if_false(move(res_if_false)) {
}

string BoundCaseExpression::ToString() const {
	return "CASE WHEN (" + check->GetName() + ") THEN (" + result_if_true->GetName() + ") ELSE (" +
	       result_if_false->GetName() + ")";
}

bool BoundCaseExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundCaseExpression *)other_;
	if (!Expression::Equals(check.get(), other->check.get())) {
		return false;
	}
	if (!Expression::Equals(result_if_true.get(), other->result_if_true.get())) {
		return false;
	}
	if (!Expression::Equals(result_if_false.get(), other->result_if_false.get())) {
		return false;
	}
	return true;
}

unique_ptr<Expression> BoundCaseExpression::Copy() {
	auto new_case = make_unique<BoundCaseExpression>(check->Copy(), result_if_true->Copy(), result_if_false->Copy());
	new_case->CopyProperties(*this);
	return move(new_case);
}




using namespace duckdb;
using namespace std;

BoundCastExpression::BoundCastExpression(TypeId target, unique_ptr<Expression> child, SQLType source_type,
                                         SQLType target_type)
    : Expression(ExpressionType::OPERATOR_CAST, ExpressionClass::BOUND_CAST, target), child(move(child)),
      source_type(source_type), target_type(target_type) {
}

unique_ptr<Expression> BoundCastExpression::AddCastToType(unique_ptr<Expression> expr, SQLType source_type,
                                                          SQLType target_type) {
	assert(expr);
	if (expr->expression_class == ExpressionClass::BOUND_PARAMETER) {
		auto &parameter = (BoundParameterExpression &)*expr;
		parameter.sql_type = target_type;
		parameter.return_type = GetInternalType(target_type);
	} else if (expr->expression_class == ExpressionClass::BOUND_DEFAULT) {
		auto &def = (BoundDefaultExpression &)*expr;
		def.sql_type = target_type;
		def.return_type = GetInternalType(target_type);
	} else if (source_type != target_type) {
		return make_unique<BoundCastExpression>(GetInternalType(target_type), move(expr), source_type, target_type);
	}
	return expr;
}

string BoundCastExpression::ToString() const {
	return "CAST[" + TypeIdToString(return_type) + "](" + child->GetName() + ")";
}

bool BoundCastExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundCastExpression *)other_;
	if (!Expression::Equals(child.get(), other->child.get())) {
		return false;
	}
	if (source_type != other->source_type || target_type != other->target_type) {
		return false;
	}
	return true;
}

unique_ptr<Expression> BoundCastExpression::Copy() {
	auto copy = make_unique<BoundCastExpression>(return_type, child->Copy(), source_type, target_type);
	copy->CopyProperties(*this);
	return move(copy);
}




using namespace duckdb;
using namespace std;

BoundColumnRefExpression::BoundColumnRefExpression(string alias, TypeId type, ColumnBinding binding, idx_t depth)
    : Expression(ExpressionType::BOUND_COLUMN_REF, ExpressionClass::BOUND_COLUMN_REF, type), binding(binding),
      depth(depth) {
	this->alias = alias;
}

BoundColumnRefExpression::BoundColumnRefExpression(TypeId type, ColumnBinding binding, idx_t depth)
    : BoundColumnRefExpression(string(), type, binding, depth) {
}

unique_ptr<Expression> BoundColumnRefExpression::Copy() {
	return make_unique<BoundColumnRefExpression>(alias, return_type, binding, depth);
}

hash_t BoundColumnRefExpression::Hash() const {
	auto result = Expression::Hash();
	result = CombineHash(result, duckdb::Hash<uint64_t>(binding.column_index));
	result = CombineHash(result, duckdb::Hash<uint64_t>(binding.table_index));
	return CombineHash(result, duckdb::Hash<uint64_t>(depth));
}

bool BoundColumnRefExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundColumnRefExpression *)other_;
	return other->binding == binding && other->depth == depth;
}

string BoundColumnRefExpression::ToString() const {
	return "#[" + to_string(binding.table_index) + "." + to_string(binding.column_index) + "]";
}


using namespace duckdb;
using namespace std;

BoundComparisonExpression::BoundComparisonExpression(ExpressionType type, unique_ptr<Expression> left,
                                                     unique_ptr<Expression> right)
    : Expression(type, ExpressionClass::BOUND_COMPARISON, TypeId::BOOL), left(move(left)), right(move(right)) {
}

string BoundComparisonExpression::ToString() const {
	return left->GetName() + ExpressionTypeToOperator(type) + right->GetName();
}

bool BoundComparisonExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundComparisonExpression *)other_;
	if (!Expression::Equals(left.get(), other->left.get())) {
		return false;
	}
	if (!Expression::Equals(right.get(), other->right.get())) {
		return false;
	}
	return true;
}

unique_ptr<Expression> BoundComparisonExpression::Copy() {
	auto copy = make_unique<BoundComparisonExpression>(type, left->Copy(), right->Copy());
	copy->CopyProperties(*this);
	return move(copy);
}



using namespace duckdb;
using namespace std;

BoundConjunctionExpression::BoundConjunctionExpression(ExpressionType type)
    : Expression(type, ExpressionClass::BOUND_CONJUNCTION, TypeId::BOOL) {
}

BoundConjunctionExpression::BoundConjunctionExpression(ExpressionType type, unique_ptr<Expression> left,
                                                       unique_ptr<Expression> right)
    : Expression(type, ExpressionClass::BOUND_CONJUNCTION, TypeId::BOOL) {
	children.push_back(move(left));
	children.push_back(move(right));
}

string BoundConjunctionExpression::ToString() const {
	string result = "(" + children[0]->ToString();
	for (idx_t i = 1; i < children.size(); i++) {
		result += " " + ExpressionTypeToOperator(type) + " " + children[i]->ToString();
	}
	return result + ")";
}

bool BoundConjunctionExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundConjunctionExpression *)other_;
	return ExpressionUtil::SetEquals(children, other->children);
}

unique_ptr<Expression> BoundConjunctionExpression::Copy() {
	auto copy = make_unique<BoundConjunctionExpression>(type);
	for (auto &expr : children) {
		copy->children.push_back(expr->Copy());
	}
	copy->CopyProperties(*this);
	return move(copy);
}





using namespace duckdb;
using namespace std;

BoundConstantExpression::BoundConstantExpression(Value value)
    : Expression(ExpressionType::VALUE_CONSTANT, ExpressionClass::BOUND_CONSTANT, value.type), value(value) {
}

string BoundConstantExpression::ToString() const {
	return value.ToString();
}

bool BoundConstantExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundConstantExpression *)other_;
	return value == other->value;
}

hash_t BoundConstantExpression::Hash() const {
	hash_t result = Expression::Hash();
	return CombineHash(ValueOperations::Hash(value), result);
}

unique_ptr<Expression> BoundConstantExpression::Copy() {
	auto copy = make_unique<BoundConstantExpression>(value);
	copy->CopyProperties(*this);
	return move(copy);
}






using namespace duckdb;
using namespace std;

BoundFunctionExpression::BoundFunctionExpression(TypeId return_type, ScalarFunction bound_function, bool is_operator)
    : Expression(ExpressionType::BOUND_FUNCTION, ExpressionClass::BOUND_FUNCTION, return_type),
      function(bound_function), is_operator(is_operator) {
}

bool BoundFunctionExpression::IsFoldable() const {
	// functions with side effects cannot be folded: they have to be executed once for every row
	return function.has_side_effects ? false : Expression::IsFoldable();
}

string BoundFunctionExpression::ToString() const {
	string result = function.name + "(";
	result += StringUtil::Join(children, children.size(), ", ",
	                           [](const unique_ptr<Expression> &child) { return child->GetName(); });
	result += ")";
	return result;
}

hash_t BoundFunctionExpression::Hash() const {
	hash_t result = Expression::Hash();
	return CombineHash(result, duckdb::Hash(function.name.c_str()));
}

bool BoundFunctionExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundFunctionExpression *)other_;
	if (other->function != function) {
		return false;
	}
	if (children.size() != other->children.size()) {
		return false;
	}
	for (idx_t i = 0; i < children.size(); i++) {
		if (!Expression::Equals(children[i].get(), other->children[i].get())) {
			return false;
		}
	}
	return true;
}

unique_ptr<Expression> BoundFunctionExpression::Copy() {
	auto copy = make_unique<BoundFunctionExpression>(return_type, function, is_operator);
	for (auto &child : children) {
		copy->children.push_back(child->Copy());
	}
	copy->bind_info = bind_info ? bind_info->Copy() : nullptr;
	copy->CopyProperties(*this);
	copy->arguments = arguments;
	copy->sql_return_type = sql_return_type;
	return move(copy);
}



using namespace duckdb;
using namespace std;

BoundOperatorExpression::BoundOperatorExpression(ExpressionType type, TypeId return_type)
    : Expression(type, ExpressionClass::BOUND_OPERATOR, return_type) {
}

string BoundOperatorExpression::ToString() const {
	auto op = ExpressionTypeToOperator(type);
	if (!op.empty()) {
		// use the operator string to represent the operator
		if (children.size() == 1) {
			return op + "(" + children[0]->GetName() + ")";
		} else if (children.size() == 2) {
			return children[0]->GetName() + " " + op + " " + children[1]->GetName();
		}
	}
	// if there is no operator we render it as a function
	auto result = ExpressionTypeToString(type) + "(";
	result += StringUtil::Join(children, children.size(), ", ",
	                           [](const unique_ptr<Expression> &child) { return child->GetName(); });
	result += ")";
	return result;
}

bool BoundOperatorExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundOperatorExpression *)other_;
	if (children.size() != other->children.size()) {
		return false;
	}
	for (idx_t i = 0; i < children.size(); i++) {
		if (!Expression::Equals(children[i].get(), other->children[i].get())) {
			return false;
		}
	}
	return true;
}

unique_ptr<Expression> BoundOperatorExpression::Copy() {
	auto copy = make_unique<BoundOperatorExpression>(type, return_type);
	copy->CopyProperties(*this);
	for (auto &child : children) {
		copy->children.push_back(child->Copy());
	}
	return move(copy);
}



using namespace duckdb;
using namespace std;

BoundParameterExpression::BoundParameterExpression(idx_t parameter_nr)
    : Expression(ExpressionType::VALUE_PARAMETER, ExpressionClass::BOUND_PARAMETER, TypeId::INVALID),
      sql_type(SQLType(SQLTypeId::UNKNOWN)), parameter_nr(parameter_nr), value(nullptr) {
}

bool BoundParameterExpression::IsScalar() const {
	return true;
}
bool BoundParameterExpression::HasParameter() const {
	return true;
}
bool BoundParameterExpression::IsFoldable() const {
	return false;
}

string BoundParameterExpression::ToString() const {
	return to_string(parameter_nr);
}

bool BoundParameterExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundParameterExpression *)other_;
	return parameter_nr == other->parameter_nr;
}

hash_t BoundParameterExpression::Hash() const {
	hash_t result = Expression::Hash();
	result = CombineHash(duckdb::Hash(parameter_nr), result);
	result = CombineHash(duckdb::Hash((int)sql_type.id), result);
	return result;
}

unique_ptr<Expression> BoundParameterExpression::Copy() {
	auto result = make_unique<BoundParameterExpression>(parameter_nr);
	result->sql_type = sql_type;
	result->value = value;
	result->return_type = return_type;
	return move(result);
}





using namespace duckdb;
using namespace std;

BoundReferenceExpression::BoundReferenceExpression(string alias, TypeId type, idx_t index)
    : Expression(ExpressionType::BOUND_REF, ExpressionClass::BOUND_REF, type), index(index) {
	this->alias = alias;
}
BoundReferenceExpression::BoundReferenceExpression(TypeId type, idx_t index)
    : BoundReferenceExpression(string(), type, index) {
}

string BoundReferenceExpression::ToString() const {
	return "#" + std::to_string(index);
}

bool BoundReferenceExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundReferenceExpression *)other_;
	return other->index == index;
}

hash_t BoundReferenceExpression::Hash() const {
	return CombineHash(Expression::Hash(), duckdb::Hash<idx_t>(index));
}

unique_ptr<Expression> BoundReferenceExpression::Copy() {
	return make_unique<BoundReferenceExpression>(alias, return_type, index);
}




using namespace duckdb;
using namespace std;

BoundSubqueryExpression::BoundSubqueryExpression(TypeId return_type)
    : Expression(ExpressionType::SUBQUERY, ExpressionClass::BOUND_SUBQUERY, return_type) {
}

string BoundSubqueryExpression::ToString() const {
	return "SUBQUERY";
}

bool BoundSubqueryExpression::Equals(const BaseExpression *other_) const {
	// equality between bound subqueries not implemented currently
	return false;
}

unique_ptr<Expression> BoundSubqueryExpression::Copy() {
	throw SerializationException("Cannot copy BoundSubqueryExpression");
}





using namespace duckdb;
using namespace std;

BoundUnnestExpression::BoundUnnestExpression(SQLType sql_return_type)
    : Expression(ExpressionType::BOUND_UNNEST, ExpressionClass::BOUND_UNNEST, GetInternalType(sql_return_type)), sql_return_type(sql_return_type) {
}

bool BoundUnnestExpression::IsFoldable() const {
	return false;
}

string BoundUnnestExpression::ToString() const {
	return "UNNEST(" + child->ToString() + ")";
}

hash_t BoundUnnestExpression::Hash() const {
	hash_t result = Expression::Hash();
	return CombineHash(result, duckdb::Hash("unnest"));
}

bool BoundUnnestExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundUnnestExpression *)other_;
	if (!Expression::Equals(child.get(), other->child.get())) {
		return false;
	}
	return true;
}

unique_ptr<Expression> BoundUnnestExpression::Copy() {
	auto copy = make_unique<BoundUnnestExpression>(sql_return_type);
	copy->child = child->Copy();
	return move(copy);
}



using namespace duckdb;
using namespace std;

BoundWindowExpression::BoundWindowExpression(ExpressionType type, TypeId return_type,
                                             unique_ptr<AggregateFunction> aggregate)
    : Expression(type, ExpressionClass::BOUND_WINDOW, return_type), aggregate(move(aggregate)) {
}

string BoundWindowExpression::ToString() const {
	return "WINDOW";
}

bool BoundWindowExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (BoundWindowExpression *)other_;

	if (start != other->start || end != other->end) {
		return false;
	}
	// check if the child expressions are equivalent
	if (other->children.size() != children.size()) {
		return false;
	}
	for (idx_t i = 0; i < children.size(); i++) {
		if (!Expression::Equals(children[i].get(), other->children[i].get())) {
			return false;
		}
	}
	// check if the framing expressions are equivalent
	if (!Expression::Equals(start_expr.get(), other->start_expr.get()) ||
	    !Expression::Equals(end_expr.get(), other->end_expr.get()) ||
	    !Expression::Equals(offset_expr.get(), other->offset_expr.get()) ||
	    !Expression::Equals(default_expr.get(), other->default_expr.get())) {
		return false;
	}

	// check if the partitions are equivalent
	if (partitions.size() != other->partitions.size()) {
		return false;
	}
	for (idx_t i = 0; i < partitions.size(); i++) {
		if (!Expression::Equals(partitions[i].get(), other->partitions[i].get())) {
			return false;
		}
	}
	// check if the orderings are equivalent
	if (orders.size() != other->orders.size()) {
		return false;
	}
	for (idx_t i = 0; i < orders.size(); i++) {
		if (orders[i].type != other->orders[i].type) {
			return false;
		}
		if (!BaseExpression::Equals((BaseExpression *)orders[i].expression.get(),
		                            (BaseExpression *)other->orders[i].expression.get())) {
			return false;
		}
	}
	return true;
}

unique_ptr<Expression> BoundWindowExpression::Copy() {
	auto new_window = make_unique<BoundWindowExpression>(type, return_type, nullptr);
	new_window->CopyProperties(*this);

	if (aggregate) {
		new_window->aggregate = make_unique<AggregateFunction>(*aggregate);
	}
	for (auto &child : children) {
		new_window->children.push_back(child->Copy());
	}
	for (auto &e : partitions) {
		new_window->partitions.push_back(e->Copy());
	}

	for (auto &o : orders) {
		BoundOrderByNode node;
		node.type = o.type;
		node.expression = o.expression->Copy();
		new_window->orders.push_back(move(node));
	}

	new_window->start = start;
	new_window->end = end;
	new_window->start_expr = start_expr ? start_expr->Copy() : nullptr;
	new_window->end_expr = end_expr ? end_expr->Copy() : nullptr;
	new_window->offset_expr = offset_expr ? offset_expr->Copy() : nullptr;
	new_window->default_expr = default_expr ? default_expr->Copy() : nullptr;

	return move(new_window);
}




using namespace duckdb;
using namespace std;

CommonSubExpression::CommonSubExpression(unique_ptr<Expression> child, string alias)
    : Expression(ExpressionType::COMMON_SUBEXPRESSION, ExpressionClass::COMMON_SUBEXPRESSION, child->return_type) {
	this->child = child.get();
	this->owned_child = move(child);
	this->alias = alias;
	assert(this->child);
}

CommonSubExpression::CommonSubExpression(Expression *child, string alias)
    : Expression(ExpressionType::COMMON_SUBEXPRESSION, ExpressionClass::COMMON_SUBEXPRESSION, child->return_type),
      child(child) {
	this->alias = alias;
	assert(child);
}

string CommonSubExpression::ToString() const {
	return child->ToString();
}

bool CommonSubExpression::Equals(const BaseExpression *other_) const {
	if (!BaseExpression::Equals(other_)) {
		return false;
	}
	auto other = (CommonSubExpression *)other_;
	return other->child == child;
}

unique_ptr<Expression> CommonSubExpression::Copy() {
	throw SerializationException("CSEs cannot be copied");
}






using namespace duckdb;
using namespace std;

Expression::Expression(ExpressionType type, ExpressionClass expression_class, TypeId return_type)
    : BaseExpression(type, expression_class), return_type(return_type) {
}

bool Expression::IsAggregate() const {
	bool is_aggregate = false;
	ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) { is_aggregate |= child.IsAggregate(); });
	return is_aggregate;
}

bool Expression::IsWindow() const {
	bool is_window = false;
	ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) { is_window |= child.IsWindow(); });
	return is_window;
}

bool Expression::IsScalar() const {
	bool is_scalar = true;
	ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
		if (!child.IsScalar()) {
			is_scalar = false;
		}
	});
	return is_scalar;
}

bool Expression::IsFoldable() const {
	bool is_foldable = true;
	ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
		if (!child.IsFoldable()) {
			is_foldable = false;
		}
	});
	return is_foldable;
}

bool Expression::HasParameter() const {
	bool has_parameter = false;
	ExpressionIterator::EnumerateChildren(*this,
	                                      [&](const Expression &child) { has_parameter |= child.HasParameter(); });
	return has_parameter;
}

bool Expression::HasSubquery() const {
	bool has_subquery = false;
	ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) { has_subquery |= child.HasSubquery(); });
	return has_subquery;
}

hash_t Expression::Hash() const {
	hash_t hash = duckdb::Hash<uint32_t>((uint32_t)type);
	hash = CombineHash(hash, duckdb::Hash<uint32_t>((uint32_t)return_type));
	ExpressionIterator::EnumerateChildren(*this,
	                                      [&](const Expression &child) { hash = CombineHash(child.Hash(), hash); });
	return hash;
}




using namespace duckdb;
using namespace std;

AggregateBinder::AggregateBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context, true) {
}

BindResult AggregateBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.expression_class) {
	case ExpressionClass::WINDOW:
		throw ParserException("aggregate function calls cannot contain window function calls");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string AggregateBinder::UnsupportedAggregateMessage() {
	return "aggregate function calls cannot be nested";
}





using namespace duckdb;
using namespace std;

CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table, vector<ColumnDefinition> &columns,
                         unordered_set<column_t> &bound_columns)
    : ExpressionBinder(binder, context), table(table), columns(columns), bound_columns(bound_columns) {
	target_type = SQLType::INTEGER;
}

BindResult CheckBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.GetExpressionClass()) {
	case ExpressionClass::WINDOW:
		return BindResult("window functions are not allowed in check constraints");
	case ExpressionClass::SUBQUERY:
		return BindResult("cannot use subquery in check constraint");
	case ExpressionClass::COLUMN_REF:
		return BindCheckColumn((ColumnRefExpression &)expr);
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string CheckBinder::UnsupportedAggregateMessage() {
	return "aggregate functions are not allowed in check constraints";
}

BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) {
	if (!colref.table_name.empty() && colref.table_name != table) {
		throw BinderException("Cannot reference table %s from within check constraint for table %s!",
		                      colref.table_name.c_str(), table.c_str());
	}
	for (idx_t i = 0; i < columns.size(); i++) {
		if (colref.column_name == columns[i].name) {
			bound_columns.insert(i);
			return BindResult(make_unique<BoundReferenceExpression>(GetInternalType(columns[i].type), i),
			                  columns[i].type);
		}
	}
	throw BinderException("Table does not contain column %s referenced in check constraint!",
	                      colref.column_name.c_str());
}


using namespace duckdb;
using namespace std;

ConstantBinder::ConstantBinder(Binder &binder, ClientContext &context, string clause)
    : ExpressionBinder(binder, context), clause(clause) {
}

BindResult ConstantBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.GetExpressionClass()) {
	case ExpressionClass::COLUMN_REF:
		return BindResult(clause + " cannot contain column names");
	case ExpressionClass::SUBQUERY:
		return BindResult(clause + " cannot contain subqueries");
	case ExpressionClass::DEFAULT:
		return BindResult(clause + " cannot contain DEFAULT clause");
	case ExpressionClass::WINDOW:
		return BindResult(clause + " cannot contain window functions!");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string ConstantBinder::UnsupportedAggregateMessage() {
	return clause + "cannot contain aggregates!";
}







using namespace duckdb;
using namespace std;

GroupBinder::GroupBinder(Binder &binder, ClientContext &context, SelectNode &node, idx_t group_index,
                         unordered_map<string, idx_t> &alias_map, unordered_map<string, idx_t> &group_alias_map)
    : ExpressionBinder(binder, context), node(node), alias_map(alias_map), group_alias_map(group_alias_map),
      group_index(group_index) {
}

BindResult GroupBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	if (root_expression && depth == 0) {
		switch (expr.expression_class) {
		case ExpressionClass::COLUMN_REF:
			return BindColumnRef((ColumnRefExpression &)expr);
		case ExpressionClass::CONSTANT:
			return BindConstant((ConstantExpression &)expr);
		default:
			break;
		}
	}
	switch (expr.expression_class) {
	case ExpressionClass::DEFAULT:
		return BindResult("GROUP BY clause cannot contain DEFAULT clause");
	case ExpressionClass::WINDOW:
		return BindResult("GROUP BY clause cannot contain window functions!");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string GroupBinder::UnsupportedAggregateMessage() {
	return "GROUP BY clause cannot contain aggregates!";
}

BindResult GroupBinder::BindSelectRef(idx_t entry) {
	if (used_aliases.find(entry) != used_aliases.end()) {
		// the alias has already been bound to before!
		// this happens if we group on the same alias twice
		// e.g. GROUP BY k, k or GROUP BY 1, 1
		// in this case, we can just replace the grouping with a constant since the second grouping has no effect
		// (the constant grouping will be optimized out later)
		return BindResult(make_unique<BoundConstantExpression>(Value(42)), SQLType::INTEGER);
	}
	if (entry >= node.select_list.size()) {
		throw BinderException("GROUP BY term out of range - should be between 1 and %d", (int)node.select_list.size());
	}
	// we replace the root expression, also replace the unbound expression
	unbound_expression = node.select_list[entry]->Copy();
	// move the expression that this refers to here and bind it
	auto select_entry = move(node.select_list[entry]);
	SQLType group_type;
	auto binding = Bind(select_entry, &group_type, false);
	// now replace the original expression in the select list with a reference to this group
	group_alias_map[to_string(entry)] = bind_index;
	node.select_list[entry] = make_unique<ColumnRefExpression>(to_string(entry));
	// insert into the set of used aliases
	used_aliases.insert(entry);
	return BindResult(move(binding), group_type);
}

BindResult GroupBinder::BindConstant(ConstantExpression &constant) {
	// constant as root expression
	if (!TypeIsIntegral(constant.value.type)) {
		// non-integral expression, we just leave the constant here.
		return ExpressionBinder::BindExpression(constant, 0);
	}
	// INTEGER constant: we use the integer as an index into the select list (e.g. GROUP BY 1)
	auto index = (idx_t)constant.value.GetValue<int64_t>();
	return BindSelectRef(index - 1);
}

BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) {
	// columns in GROUP BY clauses:
	// FIRST refer to the original tables, and
	// THEN if no match is found refer to aliases in the SELECT list
	// THEN if no match is found, refer to outer queries

	// first try to bind to the base columns (original tables)
	auto result = ExpressionBinder::BindExpression(colref, 0);
	if (result.HasError()) {
		// failed to bind the column and the node is the root expression with depth = 0
		// check if refers to an alias in the select clause
		auto alias_name = colref.column_name;
		if (!colref.table_name.empty()) {
			// explicit table name: not an alias reference
			return result;
		}
		auto entry = alias_map.find(alias_name);
		if (entry == alias_map.end()) {
			// no matching alias found
			return result;
		}
		result = BindResult(BindSelectRef(entry->second));
		if (!result.HasError()) {
			group_alias_map[alias_name] = bind_index;
		}
	}
	return result;
}







using namespace duckdb;
using namespace std;

HavingBinder::HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info)
    : SelectBinder(binder, context, node, info) {
	target_type = SQLType(SQLTypeId::BOOLEAN);
}

BindResult HavingBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	// check if the expression binds to one of the groups
	auto group_index = TryBindGroup(expr, depth);
	if (group_index != INVALID_INDEX) {
		return BindGroup(expr, depth, group_index);
	}
	switch (expr.expression_class) {
	case ExpressionClass::WINDOW:
		return BindResult("HAVING clause cannot contain window functions!");
	case ExpressionClass::COLUMN_REF:
		return BindResult(
		    StringUtil::Format("column %s must appear in the GROUP BY clause or be used in an aggregate function",
		                       expr.ToString().c_str()));
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}


using namespace duckdb;
using namespace std;

IndexBinder::IndexBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
}

BindResult IndexBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.expression_class) {
	case ExpressionClass::WINDOW:
		return BindResult("window functions are not allowed in index expressions");
	case ExpressionClass::SUBQUERY:
		return BindResult("cannot use subquery in index expressions");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string IndexBinder::UnsupportedAggregateMessage() {
	return "aggregate functions are not allowed in index expressions";
}




using namespace duckdb;
using namespace std;

InsertBinder::InsertBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
}

BindResult InsertBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.GetExpressionClass()) {
	case ExpressionClass::DEFAULT:
		return BindResult("DEFAULT is not allowed here!");
	case ExpressionClass::WINDOW:
		return BindResult("INSERT statement cannot contain window functions!");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string InsertBinder::UnsupportedAggregateMessage() {
	return "INSERT statement cannot contain aggregates!";
}






using namespace duckdb;
using namespace std;

OrderBinder::OrderBinder(idx_t projection_index, SelectNode &node, unordered_map<string, idx_t> &alias_map,
                         expression_map_t<idx_t> &projection_map,
                         vector<unique_ptr<ParsedExpression>> &extra_select_list)
    : projection_index(projection_index), node(node), alias_map(alias_map), projection_map(projection_map),
      extra_select_list(extra_select_list) {
}

unique_ptr<Expression> OrderBinder::CreateProjectionReference(ParsedExpression &expr, idx_t index) {
	return make_unique<BoundColumnRefExpression>(expr.GetName(), TypeId::INVALID,
	                                             ColumnBinding(projection_index, index));
}

void OrderBinder::RemapIndex(BoundColumnRefExpression &expr, idx_t index) {
	expr.binding.column_index = index;
}

unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
	// in the ORDER BY clause we do not bind children
	// we bind ONLY to the select list
	// if there is no matching entry in the SELECT list already, we add the expression to the SELECT list and refer the
	// new expression the new entry will then be bound later during the binding of the SELECT list we also don't do type
	// resolution here: this only happens after the SELECT list has been bound
	switch (expr->expression_class) {
	case ExpressionClass::CONSTANT: {
		// ORDER BY constant
		// is the ORDER BY expression a constant integer? (e.g. ORDER BY 1)
		auto &constant = (ConstantExpression &)*expr;
		// ORDER BY a constant
		if (!TypeIsIntegral(constant.value.type)) {
			// non-integral expression, we just leave the constant here.
			// ORDER BY <constant> has no effect
			// CONTROVERSIAL: maybe we should throw an error
			return nullptr;
		}
		// INTEGER constant: we use the integer as an index into the select list (e.g. ORDER BY 1)
		auto index = (idx_t)constant.value.GetValue<int64_t>();
		if (index < 1 || index > node.select_list.size()) {
			throw BinderException("ORDER term out of range - should be between 1 and %lld",
			                      (idx_t)node.select_list.size());
		}
		return CreateProjectionReference(*expr, index - 1);
	}
	case ExpressionClass::COLUMN_REF: {
		// COLUMN REF expression
		// check if we can bind it to an alias in the select list
		auto &colref = (ColumnRefExpression &)*expr;
		// if there is an explicit table name we can't bind to an alias
		if (!colref.table_name.empty()) {
			break;
		}
		// check the alias list
		auto entry = alias_map.find(colref.column_name);
		if (entry != alias_map.end()) {
			// it does! point it to that entry
			return CreateProjectionReference(*expr, entry->second);
		}
		break;
	}
	default:
		break;
	}
	// general case
	// first check if the ORDER BY clause already points to an entry in the projection list
	auto entry = projection_map.find(expr.get());
	if (entry != projection_map.end()) {
		// there is a matching entry in the projection list
		// just point to that entry
		return CreateProjectionReference(*expr, entry->second);
	}
	if (node.select_distinct) {
		throw BinderException("for SELECT DISTINCT, ORDER BY expressions must appear in select list!");
	}
	// otherwise we need to push the ORDER BY entry into the select list
	auto result = CreateProjectionReference(*expr, node.select_list.size() + extra_select_list.size());
	extra_select_list.push_back(move(expr));
	return result;
}










using namespace duckdb;
using namespace std;

SelectBinder::SelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info)
    : ExpressionBinder(binder, context), inside_window(false), node(node), info(info) {
}

BindResult SelectBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	// check if the expression binds to one of the groups
	auto group_index = TryBindGroup(expr, depth);
	if (group_index != INVALID_INDEX) {
		return BindGroup(expr, depth, group_index);
	}
	switch (expr.expression_class) {
	case ExpressionClass::DEFAULT:
		return BindResult("SELECT clause cannot contain DEFAULT clause");
	case ExpressionClass::WINDOW:
		return BindWindow((WindowExpression &)expr, depth);
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
	// first check the group alias map, if expr is a ColumnRefExpression
	if (expr.type == ExpressionType::COLUMN_REF) {
		auto &colref = (ColumnRefExpression &)expr;
		if (colref.table_name.empty()) {
			auto alias_entry = info.alias_map.find(colref.column_name);
			if (alias_entry != info.alias_map.end()) {
				// found entry!
				return alias_entry->second;
			}
		}
	}
	// no alias reference found
	// check the list of group columns for a match
	auto entry = info.map.find(&expr);
	if (entry != info.map.end()) {
		return entry->second;
	}
#ifdef DEBUG
	for (auto entry : info.map) {
		assert(!entry.first->Equals(&expr));
		assert(!expr.Equals(entry.first));
	}
#endif
	return INVALID_INDEX;
}

BindResult SelectBinder::BindGroup(ParsedExpression &expr, idx_t depth, idx_t group_index) {
	auto &group = node.groups[group_index];

	return BindResult(make_unique<BoundColumnRefExpression>(expr.GetName(), group->return_type,
	                                                        ColumnBinding(node.group_index, group_index), depth),
	                  info.group_types[group_index]);
}


using namespace duckdb;
using namespace std;

UpdateBinder::UpdateBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
}

BindResult UpdateBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.expression_class) {
	case ExpressionClass::WINDOW:
		return BindResult("window functions are not allowed in UPDATE");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string UpdateBinder::UnsupportedAggregateMessage() {
	return "aggregate functions are not allowed in UPDATE";
}


using namespace duckdb;
using namespace std;

WhereBinder::WhereBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
	target_type = SQLType(SQLTypeId::BOOLEAN);
}

BindResult WhereBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.GetExpressionClass()) {
	case ExpressionClass::DEFAULT:
		return BindResult("WHERE clause cannot contain DEFAULT clause");
	case ExpressionClass::WINDOW:
		return BindResult("WHERE clause cannot contain window functions!");
	default:
		return ExpressionBinder::BindExpression(expr, depth);
	}
}

string WhereBinder::UnsupportedAggregateMessage() {
	return "WHERE clause cannot contain aggregates!";
}














using namespace duckdb;
using namespace std;

ExpressionBinder::ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder)
    : binder(binder), context(context), stored_binder(nullptr) {
	if (replace_binder) {
		stored_binder = binder.GetActiveBinder();
		binder.SetActiveBinder(this);
	} else {
		binder.PushExpressionBinder(this);
	}
}

ExpressionBinder::~ExpressionBinder() {
	if (binder.HasActiveBinder()) {
		if (stored_binder) {
			binder.SetActiveBinder(stored_binder);
		} else {
			binder.PopExpressionBinder();
		}
	}
}

BindResult ExpressionBinder::BindExpression(ParsedExpression &expr, idx_t depth, bool root_expression) {
	switch (expr.expression_class) {
	case ExpressionClass::CASE:
		return BindExpression((CaseExpression &)expr, depth);
	case ExpressionClass::CAST:
		return BindExpression((CastExpression &)expr, depth);
	case ExpressionClass::COLUMN_REF:
		return BindExpression((ColumnRefExpression &)expr, depth);
	case ExpressionClass::COMPARISON:
		return BindExpression((ComparisonExpression &)expr, depth);
	case ExpressionClass::CONJUNCTION:
		return BindExpression((ConjunctionExpression &)expr, depth);
	case ExpressionClass::CONSTANT:
		return BindExpression((ConstantExpression &)expr, depth);
	case ExpressionClass::FUNCTION:
		return BindExpression((FunctionExpression &)expr, depth);
	case ExpressionClass::OPERATOR:
		return BindExpression((OperatorExpression &)expr, depth);
	case ExpressionClass::SUBQUERY:
		return BindExpression((SubqueryExpression &)expr, depth);
	case ExpressionClass::PARAMETER:
		return BindExpression((ParameterExpression &)expr, depth);
	default:
		throw NotImplementedException("Unimplemented expression class");
	}
}

bool ExpressionBinder::BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr) {
	// try to bind in one of the outer queries, if the binding error occurred in a subquery
	auto &active_binders = binder.GetActiveBinders();
	// make a copy of the set of binders, so we can restore it later
	auto binders = active_binders;
	active_binders.pop_back();
	idx_t depth = 1;
	bool success = false;
	while (active_binders.size() > 0) {
		auto &next_binder = active_binders.back();
		next_binder->BindTableNames(*expr);
		auto bind_result = next_binder->Bind(&expr, depth);
		if (bind_result.empty()) {
			success = true;
			break;
		}
		depth++;
		active_binders.pop_back();
	}
	active_binders = binders;
	return success;
}

void ExpressionBinder::BindChild(unique_ptr<ParsedExpression> &expr, idx_t depth, string &error) {
	if (expr.get()) {
		string bind_error = Bind(&expr, depth);
		if (error.empty()) {
			error = bind_error;
		}
	}
}

void ExpressionBinder::ExtractCorrelatedExpressions(Binder &binder, Expression &expr) {
	if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
		auto &bound_colref = (BoundColumnRefExpression &)expr;
		if (bound_colref.depth > 0) {
			binder.AddCorrelatedColumn(CorrelatedColumnInfo(bound_colref));
		}
	}
	ExpressionIterator::EnumerateChildren(expr,
	                                      [&](Expression &child) { ExtractCorrelatedExpressions(binder, child); });
}

unique_ptr<Expression> ExpressionBinder::Bind(unique_ptr<ParsedExpression> &expr, SQLType *result_type,
                                              bool root_expression) {
	// bind the main expression
	auto error_msg = Bind(&expr, 0, root_expression);
	if (!error_msg.empty()) {
		// failed to bind: try to bind correlated columns in the expression (if any)
		bool success = BindCorrelatedColumns(expr);
		if (!success) {
			throw BinderException(error_msg);
		}
		auto bound_expr = (BoundExpression *)expr.get();
		ExtractCorrelatedExpressions(binder, *bound_expr->expr);
	}
	assert(expr->expression_class == ExpressionClass::BOUND_EXPRESSION);
	auto bound_expr = (BoundExpression *)expr.get();
	unique_ptr<Expression> result = move(bound_expr->expr);
	if (target_type.id != SQLTypeId::INVALID) {
		// the binder has a specific target type: add a cast to that type
		result = BoundCastExpression::AddCastToType(move(result), bound_expr->sql_type, target_type);
	} else {
		if (bound_expr->sql_type.id == SQLTypeId::SQLNULL) {
			// SQL NULL type is only used internally in the binder
			// cast to INTEGER if we encounter it outside of the binder
			bound_expr->sql_type = SQLType::INTEGER;
			result = BoundCastExpression::AddCastToType(move(result), bound_expr->sql_type, bound_expr->sql_type);
		}
	}
	if (result_type) {
		*result_type = bound_expr->sql_type;
	}
	return result;
}

string ExpressionBinder::Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, bool root_expression) {
	// bind the node, but only if it has not been bound yet
	auto &expression = **expr;
	auto alias = expression.alias;
	if (expression.GetExpressionClass() == ExpressionClass::BOUND_EXPRESSION) {
		// already bound, don't bind it again
		return string();
	}
	// bind the expression
	BindResult result = BindExpression(**expr, depth, root_expression);
	if (result.HasError()) {
		return result.error;
	} else {
		// successfully bound: replace the node with a BoundExpression
		*expr = make_unique<BoundExpression>(move(result.expression), move(*expr), result.sql_type);
		auto be = (BoundExpression *)expr->get();
		assert(be);
		be->alias = alias;
		if (!alias.empty()) {
			be->expr->alias = alias;
		}
		return string();
	}
}

void ExpressionBinder::BindTableNames(ParsedExpression &expr) {
	if (expr.type == ExpressionType::COLUMN_REF) {
		auto &colref = (ColumnRefExpression &)expr;
		if (colref.table_name.empty()) {
			// no table name: find a binding that contains this
			colref.table_name = binder.bind_context.GetMatchingBinding(colref.column_name);
		}
	}
	ParsedExpressionIterator::EnumerateChildren(
	    expr, [&](const ParsedExpression &child) { BindTableNames((ParsedExpression &)child); });
}















using namespace duckdb;
using namespace std;

void ExpressionIterator::EnumerateChildren(const Expression &expr, function<void(const Expression &child)> callback) {
	EnumerateChildren((Expression &)expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		callback(*child);
		return move(child);
	});
}

void ExpressionIterator::EnumerateChildren(Expression &expr, std::function<void(Expression &child)> callback) {
	EnumerateChildren(expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		callback(*child);
		return move(child);
	});
}

void ExpressionIterator::EnumerateChildren(Expression &expr,
                                           function<unique_ptr<Expression>(unique_ptr<Expression> child)> callback) {
	switch (expr.expression_class) {
	case ExpressionClass::BOUND_AGGREGATE: {
		auto &aggr_expr = (BoundAggregateExpression &)expr;
		for (auto &child : aggr_expr.children) {
			child = callback(move(child));
		}
		break;
	}
	case ExpressionClass::BOUND_BETWEEN: {
		auto &between_expr = (BoundBetweenExpression &)expr;
		between_expr.input = callback(move(between_expr.input));
		between_expr.lower = callback(move(between_expr.lower));
		between_expr.upper = callback(move(between_expr.upper));
		break;
	}
	case ExpressionClass::BOUND_CASE: {
		auto &case_expr = (BoundCaseExpression &)expr;
		case_expr.check = callback(move(case_expr.check));
		case_expr.result_if_true = callback(move(case_expr.result_if_true));
		case_expr.result_if_false = callback(move(case_expr.result_if_false));
		break;
	}
	case ExpressionClass::BOUND_CAST: {
		auto &cast_expr = (BoundCastExpression &)expr;
		cast_expr.child = callback(move(cast_expr.child));
		break;
	}
	case ExpressionClass::BOUND_COMPARISON: {
		auto &comp_expr = (BoundComparisonExpression &)expr;
		comp_expr.left = callback(move(comp_expr.left));
		comp_expr.right = callback(move(comp_expr.right));
		break;
	}
	case ExpressionClass::BOUND_CONJUNCTION: {
		auto &conj_expr = (BoundConjunctionExpression &)expr;
		for (auto &child : conj_expr.children) {
			child = callback(move(child));
		}
		break;
	}
	case ExpressionClass::BOUND_FUNCTION: {
		auto &func_expr = (BoundFunctionExpression &)expr;
		for (auto &child : func_expr.children) {
			child = callback(move(child));
		}
		break;
	}
	case ExpressionClass::BOUND_OPERATOR: {
		auto &op_expr = (BoundOperatorExpression &)expr;
		for (auto &child : op_expr.children) {
			child = callback(move(child));
		}
		break;
	}
	case ExpressionClass::BOUND_SUBQUERY: {
		auto &subquery_expr = (BoundSubqueryExpression &)expr;
		if (subquery_expr.child) {
			subquery_expr.child = callback(move(subquery_expr.child));
		}
		break;
	}
	case ExpressionClass::BOUND_WINDOW: {
		auto &window_expr = (BoundWindowExpression &)expr;
		for (auto &partition : window_expr.partitions) {
			partition = callback(move(partition));
		}
		for (auto &order : window_expr.orders) {
			order.expression = callback(move(order.expression));
		}
		for (auto &child : window_expr.children) {
			child = callback(move(child));
		}
		if (window_expr.offset_expr) {
			window_expr.offset_expr = callback(move(window_expr.offset_expr));
		}
		if (window_expr.default_expr) {
			window_expr.default_expr = callback(move(window_expr.default_expr));
		}
		break;
	}
	case ExpressionClass::BOUND_UNNEST: {
		auto &unnest_expr = (BoundUnnestExpression &)expr;
		unnest_expr.child = callback(move(unnest_expr.child));
		break;
	}
	case ExpressionClass::COMMON_SUBEXPRESSION: {
		auto &cse_expr = (CommonSubExpression &)expr;
		if (cse_expr.owned_child) {
			cse_expr.owned_child = callback(move(cse_expr.owned_child));
		}
		break;
	}
	case ExpressionClass::BOUND_COLUMN_REF:
	case ExpressionClass::BOUND_CONSTANT:
	case ExpressionClass::BOUND_DEFAULT:
	case ExpressionClass::BOUND_PARAMETER:
	case ExpressionClass::BOUND_REF:
		// these node types have no children
		break;
	default:
		// called on non BoundExpression type!
		assert(0);
		break;
	}
}

void ExpressionIterator::EnumerateExpression(unique_ptr<Expression> &expr,
                                             std::function<void(Expression &child)> callback) {
	if (!expr) {
		return;
	}
	callback(*expr);
	ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr<Expression> child) -> unique_ptr<Expression> {
		EnumerateExpression(child, callback);
		return move(child);
	});
}

void ExpressionIterator::EnumerateTableRefChildren(BoundTableRef &ref,
                                                   std::function<void(Expression &child)> callback) {
	switch (ref.type) {
	case TableReferenceType::CROSS_PRODUCT: {
		auto &bound_crossproduct = (BoundCrossProductRef &)ref;
		EnumerateTableRefChildren(*bound_crossproduct.left, callback);
		EnumerateTableRefChildren(*bound_crossproduct.right, callback);
		break;
	}
	case TableReferenceType::JOIN: {
		auto &bound_join = (BoundJoinRef &)ref;
		EnumerateExpression(bound_join.condition, callback);
		EnumerateTableRefChildren(*bound_join.left, callback);
		EnumerateTableRefChildren(*bound_join.right, callback);
		break;
	}
	case TableReferenceType::SUBQUERY: {
		auto &bound_subquery = (BoundSubqueryRef &)ref;
		EnumerateQueryNodeChildren(*bound_subquery.subquery, callback);
		break;
	}
	default:
		assert(ref.type == TableReferenceType::TABLE_FUNCTION || ref.type == TableReferenceType::BASE_TABLE ||
		       ref.type == TableReferenceType::EMPTY);
		break;
	}
}

void ExpressionIterator::EnumerateQueryNodeChildren(BoundQueryNode &node,
                                                    std::function<void(Expression &child)> callback) {
	switch (node.type) {
	case QueryNodeType::SET_OPERATION_NODE: {
		auto &bound_setop = (BoundSetOperationNode &)node;
		EnumerateQueryNodeChildren(*bound_setop.left, callback);
		EnumerateQueryNodeChildren(*bound_setop.right, callback);
		break;
	}
	default:
		assert(node.type == QueryNodeType::SELECT_NODE);
		auto &bound_select = (BoundSelectNode &)node;
		for (idx_t i = 0; i < bound_select.select_list.size(); i++) {
			EnumerateExpression(bound_select.select_list[i], callback);
		}
		EnumerateExpression(bound_select.where_clause, callback);
		for (idx_t i = 0; i < bound_select.groups.size(); i++) {
			EnumerateExpression(bound_select.groups[i], callback);
		}
		EnumerateExpression(bound_select.having, callback);
		for (idx_t i = 0; i < bound_select.aggregates.size(); i++) {
			EnumerateExpression(bound_select.aggregates[i], callback);
		}
		for (idx_t i = 0; i < bound_select.windows.size(); i++) {
			EnumerateExpression(bound_select.windows[i], callback);
		}
		if (bound_select.from_table) {
			EnumerateTableRefChildren(*bound_select.from_table, callback);
		}
		break;
	}
	for (idx_t i = 0; i < node.orders.size(); i++) {
		EnumerateExpression(node.orders[i].expression, callback);
	}
}







using namespace duckdb;
using namespace std;

unique_ptr<Expression> JoinCondition::CreateExpression(JoinCondition cond) {
	return make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
}

JoinSide JoinSide::CombineJoinSide(JoinSide left, JoinSide right) {
	if (left == JoinSide::NONE) {
		return right;
	}
	if (right == JoinSide::NONE) {
		return left;
	}
	if (left != right) {
		return JoinSide::BOTH;
	}
	return left;
}

JoinSide JoinSide::GetJoinSide(idx_t table_binding, unordered_set<idx_t> &left_bindings,
                               unordered_set<idx_t> &right_bindings) {
	if (left_bindings.find(table_binding) != left_bindings.end()) {
		// column references table on left side
		assert(right_bindings.find(table_binding) == right_bindings.end());
		return JoinSide::LEFT;
	} else {
		// column references table on right side
		assert(right_bindings.find(table_binding) != right_bindings.end());
		return JoinSide::RIGHT;
	}
}

JoinSide JoinSide::GetJoinSide(Expression &expression, unordered_set<idx_t> &left_bindings,
                               unordered_set<idx_t> &right_bindings) {
	if (expression.type == ExpressionType::BOUND_COLUMN_REF) {
		auto &colref = (BoundColumnRefExpression &)expression;
		if (colref.depth > 0) {
			throw Exception("Non-inner join on correlated columns not supported");
		}
		return GetJoinSide(colref.binding.table_index, left_bindings, right_bindings);
	}
	assert(expression.type != ExpressionType::BOUND_REF);
	if (expression.type == ExpressionType::SUBQUERY) {
		assert(expression.GetExpressionClass() == ExpressionClass::BOUND_SUBQUERY);
		auto &subquery = (BoundSubqueryExpression &)expression;
		// correlated subquery, check the side of each of correlated columns in the subquery
		JoinSide side = JoinSide::NONE;
		for (auto &corr : subquery.binder->correlated_columns) {
			if (corr.depth > 1) {
				// correlated column has depth > 1
				// it does not refer to any table in the current set of bindings
				return JoinSide::BOTH;
			}
			auto correlated_side = GetJoinSide(corr.binding.table_index, left_bindings, right_bindings);
			side = CombineJoinSide(side, correlated_side);
		}
		return side;
	}
	JoinSide join_side = JoinSide::NONE;
	ExpressionIterator::EnumerateChildren(expression, [&](Expression &child) {
		auto child_side = GetJoinSide(child, left_bindings, right_bindings);
		join_side = CombineJoinSide(child_side, join_side);
	});
	return join_side;
}

JoinSide JoinSide::GetJoinSide(unordered_set<idx_t> bindings, unordered_set<idx_t> &left_bindings,
                               unordered_set<idx_t> &right_bindings) {
	JoinSide side = JoinSide::NONE;
	for (auto binding : bindings) {
		side = CombineJoinSide(side, GetJoinSide(binding, left_bindings, right_bindings));
	}
	return side;
}





using namespace duckdb;
using namespace std;

string LogicalOperator::ParamsToString() const {
	string result = "";
	if (expressions.size() > 0) {
		result += "[";
		result += StringUtil::Join(expressions, expressions.size(), ", ",
		                           [](const unique_ptr<Expression> &expression) { return expression->GetName(); });
		result += "]";
	}

	return result;
}

void LogicalOperator::ResolveOperatorTypes() {
	// if (types.size() > 0) {
	// 	// types already resolved for this node
	// 	return;
	// }
	types.clear();
	// first resolve child types
	for (auto &child : children) {
		child->ResolveOperatorTypes();
	}
	// now resolve the types for this operator
	ResolveTypes();
}

vector<ColumnBinding> LogicalOperator::GenerateColumnBindings(idx_t table_idx, idx_t column_count) {
	vector<ColumnBinding> result;
	for (idx_t i = 0; i < column_count; i++) {
		result.push_back(ColumnBinding(table_idx, i));
	}
	return result;
}

vector<TypeId> LogicalOperator::MapTypes(vector<TypeId> types, vector<idx_t> projection_map) {
	if (projection_map.size() == 0) {
		return types;
	} else {
		vector<TypeId> result_types;
		for (auto index : projection_map) {
			result_types.push_back(types[index]);
		}
		return result_types;
	}
}

vector<ColumnBinding> LogicalOperator::MapBindings(vector<ColumnBinding> bindings, vector<idx_t> projection_map) {
	if (projection_map.size() == 0) {
		return bindings;
	} else {
		vector<ColumnBinding> result_bindings;
		for (auto index : projection_map) {
			result_bindings.push_back(bindings[index]);
		}
		return result_bindings;
	}
}

string LogicalOperator::ToString(idx_t depth) const {
	string result = LogicalOperatorToString(type);
	result += ParamsToString();
	if (children.size() > 0) {
		for (idx_t i = 0; i < children.size(); i++) {
			result += "\n" + string(depth * 4, ' ');
			auto &child = children[i];
			result += child->ToString(depth + 1);
		}
		result += "";
	}
	return result;
}

void LogicalOperator::Print() {
	Printer::Print(ToString());
}






using namespace duckdb;
using namespace std;

void LogicalOperatorVisitor::VisitOperator(LogicalOperator &op) {
	VisitOperatorChildren(op);
	VisitOperatorExpressions(op);
}

void LogicalOperatorVisitor::VisitOperatorChildren(LogicalOperator &op) {
	for (auto &child : op.children) {
		VisitOperator(*child);
	}
}

void LogicalOperatorVisitor::VisitOperatorExpressions(LogicalOperator &op) {
	switch (op.type) {
	case LogicalOperatorType::EXPRESSION_GET: {
		auto &get = (LogicalExpressionGet &)op;
		for (auto &expr_list : get.expressions) {
			for (auto &expr : expr_list) {
				VisitExpression(&expr);
			}
		}
		break;
	}
	case LogicalOperatorType::ORDER_BY: {
		auto &order = (LogicalOrder &)op;
		for (auto &node : order.orders) {
			VisitExpression(&node.expression);
		}
		break;
	}
	case LogicalOperatorType::TOP_N: {
		auto &order = (LogicalTopN &)op;
		for (auto &node : order.orders) {
			VisitExpression(&node.expression);
		}
		break;
	}
	case LogicalOperatorType::DISTINCT: {
		auto &distinct = (LogicalDistinct &)op;
		for (auto &target : distinct.distinct_targets) {
			VisitExpression(&target);
		}
		break;
	}
	case LogicalOperatorType::DELIM_JOIN:
	case LogicalOperatorType::COMPARISON_JOIN: {
		auto &join = (LogicalComparisonJoin &)op;
		for (auto &cond : join.conditions) {
			VisitExpression(&cond.left);
			VisitExpression(&cond.right);
		}
		break;
	}
	case LogicalOperatorType::ANY_JOIN: {
		auto &join = (LogicalAnyJoin &)op;
		VisitExpression(&join.condition);
		break;
	}
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY: {
		auto &aggr = (LogicalAggregate &)op;
		for (idx_t i = 0; i < aggr.groups.size(); i++) {
			VisitExpression(&aggr.groups[i]);
		}
		break;
	}
	default:
		break;
	}
	for (idx_t i = 0; i < op.expressions.size(); i++) {
		VisitExpression(&op.expressions[i]);
	}
}

void LogicalOperatorVisitor::VisitExpression(unique_ptr<Expression> *expression) {
	auto &expr = **expression;
	unique_ptr<Expression> result;
	switch (expr.GetExpressionClass()) {
	case ExpressionClass::BOUND_AGGREGATE:
		result = VisitReplace((BoundAggregateExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_BETWEEN:
		result = VisitReplace((BoundBetweenExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_CASE:
		result = VisitReplace((BoundCaseExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_CAST:
		result = VisitReplace((BoundCastExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_COLUMN_REF:
		result = VisitReplace((BoundColumnRefExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_COMPARISON:
		result = VisitReplace((BoundComparisonExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_CONJUNCTION:
		result = VisitReplace((BoundConjunctionExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_CONSTANT:
		result = VisitReplace((BoundConstantExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_FUNCTION:
		result = VisitReplace((BoundFunctionExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_SUBQUERY:
		result = VisitReplace((BoundSubqueryExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_OPERATOR:
		result = VisitReplace((BoundOperatorExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_PARAMETER:
		result = VisitReplace((BoundParameterExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_REF:
		result = VisitReplace((BoundReferenceExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_DEFAULT:
		result = VisitReplace((BoundDefaultExpression &)expr, expression);
		break;
	case ExpressionClass::COMMON_SUBEXPRESSION:
		result = VisitReplace((CommonSubExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_WINDOW:
		result = VisitReplace((BoundWindowExpression &)expr, expression);
		break;
	case ExpressionClass::BOUND_UNNEST:
		result = VisitReplace((BoundUnnestExpression &)expr, expression);
		break;
	default:
		assert(0);
	}
	if (result) {
		*expression = move(result);
	} else {
		// visit the children of this node
		VisitExpressionChildren(expr);
	}
}

void LogicalOperatorVisitor::VisitExpressionChildren(Expression &expr) {
	ExpressionIterator::EnumerateChildren(expr, [&](unique_ptr<Expression> expr) -> unique_ptr<Expression> {
		VisitExpression(&expr);
		return move(expr);
	});
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundAggregateExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundBetweenExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundCaseExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundCastExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundColumnRefExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundComparisonExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundConjunctionExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundConstantExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundDefaultExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundFunctionExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundOperatorExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundParameterExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundReferenceExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundSubqueryExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundWindowExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(BoundUnnestExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}

unique_ptr<Expression> LogicalOperatorVisitor::VisitReplace(CommonSubExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	return nullptr;
}









//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/logical_plan_generator.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {
class ClientContext;

//! The logical plan generator generates a logical query plan from a parsed SQL
//! statement
class LogicalPlanGenerator {
public:
	LogicalPlanGenerator(Binder &binder, ClientContext &context);

	unique_ptr<LogicalOperator> CreatePlan(BoundSQLStatement &statement);

	unique_ptr<LogicalOperator> CreatePlan(BoundQueryNode &node);

	//! Whether or not subqueries should be planned already
	bool plan_subquery = true;

private:
	unique_ptr<LogicalOperator> CreatePlan(BoundSelectStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundInsertStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundCopyStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundDeleteStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundUpdateStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundCreateStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundExecuteStatement &statement);

	unique_ptr<LogicalOperator> CreatePlan(BoundSimpleStatement &statement);
	unique_ptr<LogicalOperator> CreatePlan(BoundExplainStatement &stmt);

	unique_ptr<LogicalOperator> CreatePlan(BoundSelectNode &node);
	unique_ptr<LogicalOperator> CreatePlan(BoundSetOperationNode &node);
	unique_ptr<LogicalOperator> CreatePlan(BoundRecursiveCTENode &node);

	unique_ptr<LogicalOperator> VisitQueryNode(BoundQueryNode &node, unique_ptr<LogicalOperator> root);

	unique_ptr<LogicalOperator> CreatePlan(BoundTableRef &ref);

	unique_ptr<LogicalOperator> CreatePlan(BoundBaseTableRef &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundCrossProductRef &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundJoinRef &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundSubqueryRef &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundTableFunction &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundEmptyTableRef &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundExpressionListRef &ref);
	unique_ptr<LogicalOperator> CreatePlan(BoundCTERef &ref);

	void PlanSubqueries(unique_ptr<Expression> *expr, unique_ptr<LogicalOperator> *root);

	unique_ptr<LogicalOperator> CastLogicalOperatorToTypes(vector<SQLType> &source_types, vector<SQLType> &target_types,
	                                                       unique_ptr<LogicalOperator> op);

public:
	bool has_unplanned_subqueries = false;

private:
	//! A reference to the current binder
	Binder &binder;
	//! Whether or not we require row ids to be projected
	bool require_row_id = false;
	//! A reference to the client context
	ClientContext &context;
};
} // namespace duckdb


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/subquery/flatten_dependent_join.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

//! The FlattenDependentJoins class is responsible for pushing the dependent join down into the plan to create a
//! flattened subquery
struct FlattenDependentJoins {
	FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated);

	//! Detects which Logical Operators have correlated expressions that they are dependent upon, filling the
	//! has_correlated_expressions map.
	bool DetectCorrelatedExpressions(LogicalOperator *op);

	//! Push the dependent join down a LogicalOperator
	unique_ptr<LogicalOperator> PushDownDependentJoin(unique_ptr<LogicalOperator> plan);

	Binder &binder;
	ColumnBinding base_binding;
	idx_t delim_offset;
	idx_t data_offset;
	unordered_map<LogicalOperator *, bool> has_correlated_expressions;
	column_binding_map_t<idx_t> correlated_map;
	column_binding_map_t<idx_t> replacement_map;
	const vector<CorrelatedColumnInfo> &correlated_columns;
	vector<TypeId> delim_types;

private:
	unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan);
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

static unique_ptr<Expression> PlanUncorrelatedSubquery(Binder &binder, BoundSubqueryExpression &expr,
                                                       unique_ptr<LogicalOperator> &root,
                                                       unique_ptr<LogicalOperator> plan) {
	assert(!expr.IsCorrelated());
	switch (expr.subquery_type) {
	case SubqueryType::EXISTS: {
		// uncorrelated EXISTS
		// we only care about existence, hence we push a LIMIT 1 operator
		auto limit = make_unique<LogicalLimit>(1, 0);
		limit->AddChild(move(plan));
		plan = move(limit);

		// now we push a COUNT(*) aggregate onto the limit, this will be either 0 or 1 (EXISTS or NOT EXISTS)
		auto count_star = make_unique<BoundAggregateExpression>(TypeId::INT64, CountStarFun::GetFunction(), false);
		auto idx_type = count_star->return_type;
		vector<unique_ptr<Expression>> aggregate_list;
		aggregate_list.push_back(move(count_star));
		auto aggregate_index = binder.GenerateTableIndex();
		auto aggregate =
		    make_unique<LogicalAggregate>(binder.GenerateTableIndex(), aggregate_index, move(aggregate_list));
		aggregate->AddChild(move(plan));
		plan = move(aggregate);

		// now we push a projection with a comparison to 1
		auto left_child = make_unique<BoundColumnRefExpression>(idx_type, ColumnBinding(aggregate_index, 0));
		auto right_child = make_unique<BoundConstantExpression>(Value::Numeric(idx_type, 1));
		auto comparison =
		    make_unique<BoundComparisonExpression>(ExpressionType::COMPARE_EQUAL, move(left_child), move(right_child));

		vector<unique_ptr<Expression>> projection_list;
		projection_list.push_back(move(comparison));
		auto projection_index = binder.GenerateTableIndex();
		auto projection = make_unique<LogicalProjection>(projection_index, move(projection_list));
		projection->AddChild(move(plan));
		plan = move(projection);

		// we add it to the main query by adding a cross product
		// FIXME: should use something else besides cross product as we always add only one scalar constant
		auto cross_product = make_unique<LogicalCrossProduct>();
		cross_product->AddChild(move(root));
		cross_product->AddChild(move(plan));
		root = move(cross_product);

		// we replace the original subquery with a ColumnRefExpression refering to the result of the projection (either
		// TRUE or FALSE)
		return make_unique<BoundColumnRefExpression>(expr.GetName(), TypeId::BOOL, ColumnBinding(projection_index, 0));
	}
	case SubqueryType::SCALAR: {
		// uncorrelated scalar, we want to return the first entry
		// figure out the table index of the bound table of the entry which we want to return
		auto bindings = plan->GetColumnBindings();
		assert(bindings.size() == 1);
		idx_t table_idx = bindings[0].table_index;

		// in the uncorrelated case we are only interested in the first result of the query
		// hence we simply push a LIMIT 1 to get the first row of the subquery
		auto limit = make_unique<LogicalLimit>(1, 0);
		limit->AddChild(move(plan));
		plan = move(limit);

		// we push an aggregate that returns the FIRST element
		vector<unique_ptr<Expression>> expressions;
		auto bound = make_unique<BoundColumnRefExpression>(expr.return_type, ColumnBinding(table_idx, 0));
		auto first_agg = make_unique<BoundAggregateExpression>(
		    expr.return_type, FirstFun::GetFunction(SQLTypeFromInternalType(expr.return_type)), false);
		first_agg->children.push_back(move(bound));
		expressions.push_back(move(first_agg));
		auto aggr_index = binder.GenerateTableIndex();
		auto aggr = make_unique<LogicalAggregate>(binder.GenerateTableIndex(), aggr_index, move(expressions));
		aggr->AddChild(move(plan));
		plan = move(aggr);

		// in the uncorrelated case, we add the value to the main query through a cross product
		// FIXME: should use something else besides cross product as we always add only one scalar constant and cross
		// product is not optimized for this.
		assert(root);
		auto cross_product = make_unique<LogicalCrossProduct>();
		cross_product->AddChild(move(root));
		cross_product->AddChild(move(plan));
		root = move(cross_product);

		// we replace the original subquery with a BoundColumnRefExpression refering to the first result of the
		// aggregation
		return make_unique<BoundColumnRefExpression>(expr.GetName(), expr.return_type, ColumnBinding(aggr_index, 0));
	}
	default: {
		assert(expr.subquery_type == SubqueryType::ANY);
		// we generate a MARK join that results in either (TRUE, FALSE or NULL)
		// subquery has NULL values -> result is (TRUE or NULL)
		// subquery has no NULL values -> result is (TRUE, FALSE or NULL [if input is NULL])
		// fetch the column bindings
		auto plan_columns = plan->GetColumnBindings();

		// then we generate the MARK join with the subquery
		idx_t mark_index = binder.GenerateTableIndex();
		auto join = make_unique<LogicalComparisonJoin>(JoinType::MARK);
		join->mark_index = mark_index;
		join->AddChild(move(root));
		join->AddChild(move(plan));
		// create the JOIN condition
		JoinCondition cond;
		cond.left = move(expr.child);
		cond.right = BoundCastExpression::AddCastToType(
		    make_unique<BoundColumnRefExpression>(GetInternalType(expr.child_type), plan_columns[0]), expr.child_type,
		    expr.child_target);
		cond.comparison = expr.comparison_type;
		join->conditions.push_back(move(cond));
		root = move(join);

		// we replace the original subquery with a BoundColumnRefExpression refering to the mark column
		return make_unique<BoundColumnRefExpression>(expr.GetName(), expr.return_type, ColumnBinding(mark_index, 0));
	}
	}
}

static unique_ptr<LogicalDelimJoin> CreateDuplicateEliminatedJoin(vector<CorrelatedColumnInfo> &correlated_columns,
                                                                  JoinType join_type) {
	auto delim_join = make_unique<LogicalDelimJoin>(join_type);
	for (idx_t i = 0; i < correlated_columns.size(); i++) {
		auto &col = correlated_columns[i];
		delim_join->duplicate_eliminated_columns.push_back(
		    make_unique<BoundColumnRefExpression>(col.type, col.binding));
	}
	return delim_join;
}

static void CreateDelimJoinConditions(LogicalDelimJoin &delim_join, vector<CorrelatedColumnInfo> &correlated_columns,
                                      vector<ColumnBinding> bindings, idx_t base_offset) {
	for (idx_t i = 0; i < correlated_columns.size(); i++) {
		auto &col = correlated_columns[i];
		JoinCondition cond;
		cond.left = make_unique<BoundColumnRefExpression>(col.name, col.type, col.binding);
		cond.right = make_unique<BoundColumnRefExpression>(col.name, col.type, bindings[base_offset + i]);
		cond.comparison = ExpressionType::COMPARE_EQUAL;
		cond.null_values_are_equal = true;
		delim_join.conditions.push_back(move(cond));
	}
}

static unique_ptr<Expression> PlanCorrelatedSubquery(Binder &binder, BoundSubqueryExpression &expr,
                                                     unique_ptr<LogicalOperator> &root,
                                                     unique_ptr<LogicalOperator> plan) {
	auto &correlated_columns = expr.binder->correlated_columns;
	assert(expr.IsCorrelated());
	// correlated subquery
	// for a more in-depth explanation of this code, read the paper "Unnesting Arbitrary Subqueries"
	// we handle three types of correlated subqueries: Scalar, EXISTS and ANY
	// all three cases are very similar with some minor changes (mainly the type of join performed at the end)
	switch (expr.subquery_type) {
	case SubqueryType::SCALAR: {
		// correlated SCALAR query
		// first push a DUPLICATE ELIMINATED join
		// a duplicate eliminated join creates a duplicate eliminated copy of the LHS
		// and pushes it into any DUPLICATE_ELIMINATED SCAN operators on the RHS

		// in the SCALAR case, we create a SINGLE join (because we are only interested in obtaining the value)
		// NULL values are equal in this join because we join on the correlated columns ONLY
		// and e.g. in the query: SELECT (SELECT 42 FROM integers WHERE i1.i IS NULL LIMIT 1) FROM integers i1;
		// the input value NULL will generate the value 42, and we need to join NULL on the LHS with NULL on the RHS
		auto delim_join = CreateDuplicateEliminatedJoin(correlated_columns, JoinType::SINGLE);

		// the left side is the original plan
		// this is the side that will be duplicate eliminated and pushed into the RHS
		delim_join->AddChild(move(root));
		// the right side initially is a DEPENDENT join between the duplicate eliminated scan and the subquery
		// HOWEVER: we do not explicitly create the dependent join
		// instead, we eliminate the dependent join by pushing it down into the right side of the plan
		FlattenDependentJoins flatten(binder, correlated_columns);

		// first we check which logical operators have correlated expressions in the first place
		flatten.DetectCorrelatedExpressions(plan.get());
		// now we push the dependent join down
		auto dependent_join = flatten.PushDownDependentJoin(move(plan));

		// now the dependent join is fully eliminated
		// we only need to create the join conditions between the LHS and the RHS
		// fetch the set of columns
		auto plan_columns = dependent_join->GetColumnBindings();

		// now create the join conditions
		CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset);
		delim_join->AddChild(move(dependent_join));
		root = move(delim_join);
		// finally push the BoundColumnRefExpression referring to the data element returned by the join
		return make_unique<BoundColumnRefExpression>(expr.GetName(), expr.return_type,
		                                             plan_columns[flatten.data_offset]);
	}
	case SubqueryType::EXISTS: {
		// correlated EXISTS query
		// this query is similar to the correlated SCALAR query, except we use a MARK join here
		idx_t mark_index = binder.GenerateTableIndex();
		auto delim_join = CreateDuplicateEliminatedJoin(correlated_columns, JoinType::MARK);
		delim_join->mark_index = mark_index;
		// LHS
		delim_join->AddChild(move(root));
		// RHS
		FlattenDependentJoins flatten(binder, correlated_columns);
		flatten.DetectCorrelatedExpressions(plan.get());
		auto dependent_join = flatten.PushDownDependentJoin(move(plan));

		// fetch the set of columns
		auto plan_columns = dependent_join->GetColumnBindings();

		// now we create the join conditions between the dependent join and the original table
		CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset);
		delim_join->AddChild(move(dependent_join));
		root = move(delim_join);
		// finally push the BoundColumnRefExpression referring to the marker
		return make_unique<BoundColumnRefExpression>(expr.GetName(), expr.return_type, ColumnBinding(mark_index, 0));
	}
	default: {
		assert(expr.subquery_type == SubqueryType::ANY);
		// correlated ANY query
		// this query is similar to the correlated SCALAR query
		// however, in this case we push a correlated MARK join
		// note that in this join null values are NOT equal for ALL columns, but ONLY for the correlated columns
		// the correlated mark join handles this case by itself
		// as the MARK join has one extra join condition (the original condition, of the ANY expression, e.g.
		// [i=ANY(...)])
		idx_t mark_index = binder.GenerateTableIndex();
		auto delim_join = CreateDuplicateEliminatedJoin(correlated_columns, JoinType::MARK);
		delim_join->mark_index = mark_index;
		// LHS
		delim_join->AddChild(move(root));
		// RHS
		FlattenDependentJoins flatten(binder, correlated_columns);
		flatten.DetectCorrelatedExpressions(plan.get());
		auto dependent_join = flatten.PushDownDependentJoin(move(plan));

		// fetch the columns
		auto plan_columns = dependent_join->GetColumnBindings();

		// now we create the join conditions between the dependent join and the original table
		CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset);
		// add the actual condition based on the ANY/ALL predicate
		JoinCondition compare_cond;
		compare_cond.left = move(expr.child);
		compare_cond.right = BoundCastExpression::AddCastToType(
		    make_unique<BoundColumnRefExpression>(GetInternalType(expr.child_type), plan_columns[0]), expr.child_type,
		    expr.child_target);
		compare_cond.comparison = expr.comparison_type;
		delim_join->conditions.push_back(move(compare_cond));

		delim_join->AddChild(move(dependent_join));
		root = move(delim_join);
		// finally push the BoundColumnRefExpression referring to the marker
		return make_unique<BoundColumnRefExpression>(expr.GetName(), expr.return_type, ColumnBinding(mark_index, 0));
	}
	}
}

static unique_ptr<Expression> PlanSubquery(Binder &binder, ClientContext &context, BoundSubqueryExpression &expr,
                                           unique_ptr<LogicalOperator> &root);

namespace duckdb {

class RecursiveSubqueryPlanner : public LogicalOperatorVisitor {
public:
	RecursiveSubqueryPlanner(Binder &binder, ClientContext &context) : binder(binder), context(context) {
	}
	void VisitOperator(LogicalOperator &op) override {
		if (op.children.size() > 0) {
			root = move(op.children[0]);
			VisitOperatorExpressions(op);
			op.children[0] = move(root);
			for (idx_t i = 0; i < op.children.size(); i++) {
				VisitOperator(*op.children[i]);
			}
		}
	}

	unique_ptr<Expression> VisitReplace(BoundSubqueryExpression &expr, unique_ptr<Expression> *expr_ptr) override {
		return PlanSubquery(binder, context, expr, root);
	}

private:
	unique_ptr<LogicalOperator> root;
	Binder &binder;
	ClientContext &context;
};
} // namespace duckdb

unique_ptr<Expression> PlanSubquery(Binder &binder, ClientContext &context, BoundSubqueryExpression &expr,
                                    unique_ptr<LogicalOperator> &root) {
	assert(root);
	// first we translate the QueryNode of the subquery into a logical plan
	// note that we do not plan nested subqueries yet
	LogicalPlanGenerator generator(*expr.binder, context);
	generator.plan_subquery = false;
	auto subquery_root = generator.CreatePlan(*expr.subquery);
	assert(subquery_root);

	// now we actually flatten the subquery
	auto plan = move(subquery_root);
	unique_ptr<Expression> result_expression;
	if (!expr.IsCorrelated()) {
		result_expression = PlanUncorrelatedSubquery(binder, expr, root, move(plan));
	} else {
		result_expression = PlanCorrelatedSubquery(binder, expr, root, move(plan));
	}
	// finally, we recursively plan the nested subqueries (if there are any)
	if (generator.has_unplanned_subqueries) {
		RecursiveSubqueryPlanner plan(binder, context);
		plan.VisitOperator(*root);
	}
	return result_expression;
}

void LogicalPlanGenerator::PlanSubqueries(unique_ptr<Expression> *expr_ptr, unique_ptr<LogicalOperator> *root) {
	auto &expr = **expr_ptr;

	// first visit the children of the node, if any
	ExpressionIterator::EnumerateChildren(expr, [&](unique_ptr<Expression> expr) -> unique_ptr<Expression> {
		PlanSubqueries(&expr, root);
		return move(expr);
	});

	// check if this is a subquery node
	if (expr.expression_class == ExpressionClass::BOUND_SUBQUERY) {
		auto &subquery = (BoundSubqueryExpression &)expr;
		// subquery node! plan it
		if (subquery.IsCorrelated() && !plan_subquery) {
			// detected a nested correlated subquery
			// we don't plan it yet here, we are currently planning a subquery
			// nested subqueries will only be planned AFTER the current subquery has been flattened entirely
			has_unplanned_subqueries = true;
			return;
		}
		*expr_ptr = PlanSubquery(binder, context, subquery, *root);
	}
}






using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::VisitQueryNode(BoundQueryNode &node,
                                                                 unique_ptr<LogicalOperator> root) {
	assert(root);
	if (node.select_distinct) {
		unique_ptr<LogicalDistinct> distinct = nullptr;
		// DISTINCT ON should give the target list
		distinct = make_unique<LogicalDistinct>(move(node.target_distincts));
		distinct->AddChild(move(root));
		root = move(distinct);
	}

	if (node.orders.size() > 0) {
		auto order = make_unique<LogicalOrder>(move(node.orders));
		order->AddChild(move(root));
		root = move(order);
	}

	if (node.limit >= 0 || node.offset >= 0) {
		auto limit = make_unique<LogicalLimit>(node.limit, node.offset);
		limit->AddChild(move(root));
		root = move(limit);
	}
	return root;
}







using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundRecursiveCTENode &node) {
	// Generate the logical plan for the left and right sides of the set operation
	LogicalPlanGenerator generator_left(*node.left_binder, context);
	LogicalPlanGenerator generator_right(*node.right_binder, context);
	generator_left.plan_subquery = plan_subquery;
	generator_right.plan_subquery = plan_subquery;

	auto left_node = generator_left.CreatePlan(*node.left);
	auto right_node = generator_right.CreatePlan(*node.right);

	// check if there are any unplanned subqueries left in either child
	has_unplanned_subqueries = generator_left.has_unplanned_subqueries || generator_right.has_unplanned_subqueries;

	// for both the left and right sides, cast them to the same types
	left_node = CastLogicalOperatorToTypes(node.left->types, node.types, move(left_node));
	right_node = CastLogicalOperatorToTypes(node.right->types, node.types, move(right_node));

	if (node.right_binder->bind_context.cte_references[node.ctename] == 0) {
		auto root = make_unique<LogicalSetOperation>(node.setop_index, node.types.size(), move(left_node),
		                                             move(right_node), LogicalOperatorType::UNION);
		return VisitQueryNode(node, move(root));
	}
	auto root = make_unique<LogicalRecursiveCTE>(node.setop_index, node.types.size(), node.union_all, move(left_node),
	                                             move(right_node), LogicalOperatorType::RECURSIVE_CTE);

	return VisitQueryNode(node, move(root));
}





using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundSelectNode &statement) {
	unique_ptr<LogicalOperator> root;
	assert(statement.from_table);
	root = CreatePlan(*statement.from_table);
	assert(root);

	if (statement.where_clause) {
		PlanSubqueries(&statement.where_clause, &root);
		auto filter = make_unique<LogicalFilter>(move(statement.where_clause));
		filter->AddChild(move(root));
		root = move(filter);
	}

	if (statement.aggregates.size() > 0 || statement.groups.size() > 0) {
		if (statement.groups.size() > 0) {
			// visit the groups
			for (idx_t i = 0; i < statement.groups.size(); i++) {
				auto &group = statement.groups[i];
				PlanSubqueries(&group, &root);
			}
		}
		// now visit all aggregate expressions
		for (auto &expr : statement.aggregates) {
			PlanSubqueries(&expr, &root);
		}
		// finally create the aggregate node with the group_index and aggregate_index as obtained from the binder
		auto aggregate =
		    make_unique<LogicalAggregate>(statement.group_index, statement.aggregate_index, move(statement.aggregates));
		aggregate->groups = move(statement.groups);

		aggregate->AddChild(move(root));
		root = move(aggregate);
	}

	if (statement.having) {
		PlanSubqueries(&statement.having, &root);
		auto having = make_unique<LogicalFilter>(move(statement.having));

		having->AddChild(move(root));
		root = move(having);
	}

	if (statement.windows.size() > 0) {
		auto win = make_unique<LogicalWindow>(statement.window_index);
		win->expressions = move(statement.windows);
		// visit the window expressions
		for (auto &expr : win->expressions) {
			PlanSubqueries(&expr, &root);
		}
		assert(win->expressions.size() > 0);
		win->AddChild(move(root));
		root = move(win);
	}

	if (statement.unnests.size() > 0) {
		auto unnest = make_unique<LogicalUnnest>(statement.unnest_index);
		unnest->expressions = move(statement.unnests);
		// visit the window expressions
		for (auto &expr : unnest->expressions) {
			PlanSubqueries(&expr, &root);
		}
		assert(unnest->expressions.size() > 0);
		unnest->AddChild(move(root));
		root = move(unnest);
	}

	for (auto &expr : statement.select_list) {
		PlanSubqueries(&expr, &root);
	}

	// check if we need to prune extra columns that were introduced into the select list (by e.g. the ORDER BY or HAVING
	// clauses)
	bool prune_columns = statement.select_list.size() > statement.column_count;

	// create the projection
	auto proj = make_unique<LogicalProjection>(statement.projection_index, move(statement.select_list));
	proj->AddChild(move(root));
	root = move(proj);

	// finish the plan by handling the elements of the QueryNode
	root = VisitQueryNode(statement, move(root));

	// add a prune node if necessary
	if (prune_columns) {
		assert(root);
		auto prune = make_unique<LogicalPruneColumns>(statement.column_count);
		prune->AddChild(move(root));
		root = move(prune);
	}
	return root;
}







using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CastLogicalOperatorToTypes(vector<SQLType> &source_types,
                                                                             vector<SQLType> &target_types,
                                                                             unique_ptr<LogicalOperator> op) {
	assert(op);
	// first check if we even need to cast
	assert(source_types.size() == target_types.size());
	if (source_types == target_types) {
		// source and target types are equal: don't need to cast
		return op;
	}
	// otherwise add casts
	auto node = op.get();
	if (node->type == LogicalOperatorType::PROJECTION) {
		// "node" is a projection; we can just do the casts in there
		assert(node->expressions.size() == source_types.size());
		// add the casts to the selection list
		for (idx_t i = 0; i < target_types.size(); i++) {
			if (source_types[i] != target_types[i]) {
				// differing types, have to add a cast
				string alias = node->expressions[i]->alias;
				node->expressions[i] = make_unique<BoundCastExpression>(
				    GetInternalType(target_types[i]), move(node->expressions[i]), source_types[i], target_types[i]);
				node->expressions[i]->alias = alias;
			}
		}
		return op;
	} else {
		// found a non-projection operator
		// push a new projection containing the casts

		// fetch the set of column bindings
		auto setop_columns = op->GetColumnBindings();
		assert(setop_columns.size() == source_types.size());

		// now generate the expression list
		vector<unique_ptr<Expression>> select_list;
		for (idx_t i = 0; i < target_types.size(); i++) {
			unique_ptr<Expression> result =
			    make_unique<BoundColumnRefExpression>(GetInternalType(source_types[i]), setop_columns[i]);
			if (source_types[i] != target_types[i]) {
				// add a cast only if the source and target types are not equivalent
				result = make_unique<BoundCastExpression>(GetInternalType(target_types[i]), move(result),
				                                          source_types[i], target_types[i]);
			}
			select_list.push_back(move(result));
		}
		auto projection = make_unique<LogicalProjection>(binder.GenerateTableIndex(), move(select_list));
		projection->children.push_back(move(op));
		return move(projection);
	}
}

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundSetOperationNode &node) {
	// Generate the logical plan for the left and right sides of the set operation
	LogicalPlanGenerator generator_left(*node.left_binder, context);
	LogicalPlanGenerator generator_right(*node.right_binder, context);
	generator_left.plan_subquery = plan_subquery;
	generator_right.plan_subquery = plan_subquery;

	auto left_node = generator_left.CreatePlan(*node.left);
	auto right_node = generator_right.CreatePlan(*node.right);

	// check if there are any unplanned subqueries left in either child
	has_unplanned_subqueries = generator_left.has_unplanned_subqueries || generator_right.has_unplanned_subqueries;

	// for both the left and right sides, cast them to the same types
	left_node = CastLogicalOperatorToTypes(node.left->types, node.types, move(left_node));
	right_node = CastLogicalOperatorToTypes(node.right->types, node.types, move(right_node));

	// create actual logical ops for setops
	LogicalOperatorType logical_type;
	switch (node.setop_type) {
	case SetOperationType::UNION:
		logical_type = LogicalOperatorType::UNION;
		break;
	case SetOperationType::EXCEPT:
		logical_type = LogicalOperatorType::EXCEPT;
		break;
	default:
		assert(node.setop_type == SetOperationType::INTERSECT);
		logical_type = LogicalOperatorType::INTERSECT;
		break;
	}
	auto root = make_unique<LogicalSetOperation>(node.setop_index, node.types.size(), move(left_node), move(right_node),
	                                             logical_type);

	return VisitQueryNode(node, move(root));
}





using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundCopyStatement &stmt) {
	if (stmt.select_statement) {
		// COPY TO a file
		auto names = stmt.select_statement->names;
		auto types = stmt.select_statement->types;

		// first plan the query
		auto root = CreatePlan(*stmt.select_statement);
		// now create the copy information
		auto copy = make_unique<LogicalCopyToFile>(move(stmt.info));
		copy->AddChild(move(root));
		copy->names = names;
		copy->sql_types = types;

		return move(copy);
	} else {
		// COPY FROM a file
		assert(!stmt.info->table.empty());
		// first create a plan for the insert statement
		auto insert = CreatePlan(*stmt.bound_insert);
		// now create the copy statement and set it as a child of the insert statement
		auto copy = make_unique<LogicalCopyFromFile>(0, move(stmt.info), stmt.sql_types);
		insert->children.push_back(move(copy));
		return insert;
	}
}










using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundCreateStatement &stmt) {
	switch (stmt.info->base->type) {
	case CatalogType::SCHEMA:
		return make_unique<LogicalCreate>(LogicalOperatorType::CREATE_SCHEMA, move(stmt.info));
	case CatalogType::VIEW:
		return make_unique<LogicalCreate>(LogicalOperatorType::CREATE_VIEW, move(stmt.info));
	case CatalogType::SEQUENCE:
		return make_unique<LogicalCreate>(LogicalOperatorType::CREATE_SEQUENCE, move(stmt.info));
	case CatalogType::INDEX: {
		auto &info = (BoundCreateIndexInfo &)*stmt.info;
		// first we visit the base table to create the root expression
		auto root = CreatePlan(*info.table);
		// this gives us a logical table scan
		// we take the required columns from here
		assert(root->type == LogicalOperatorType::GET);
		auto &get = (LogicalGet &)*root;
		// create the logical operator
		return make_unique<LogicalCreateIndex>(*get.table, get.column_ids, move(info.expressions),
		                                       unique_ptr_cast<CreateInfo, CreateIndexInfo>(move(info.base)));
	}
	case CatalogType::TABLE: {
		auto &info = (BoundCreateTableInfo &)*stmt.info;
		unique_ptr<LogicalOperator> root;
		if (info.query) {
			// create table from query
			root = CreatePlan(*info.query);
		}
		// create the logical operator
		auto create_table = make_unique<LogicalCreateTable>(
		    info.schema, unique_ptr_cast<BoundCreateInfo, BoundCreateTableInfo>(move(stmt.info)));
		if (root) {
			create_table->children.push_back(move(root));
		}
		return move(create_table);
	}
	default:
		throw Exception("Unrecognized type!");
	}
}







using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundDeleteStatement &stmt) {
	// we require row ids for the deletion
	require_row_id = true;
	// create the table scan
	auto root = CreatePlan(*stmt.table);
	assert(root->type == LogicalOperatorType::GET);

	auto &get = (LogicalGet &)*root;
	// create the filter (if any)
	if (stmt.condition) {
		PlanSubqueries(&stmt.condition, &root);
		auto filter = make_unique<LogicalFilter>(move(stmt.condition));
		filter->AddChild(move(root));
		root = move(filter);
	}
	// create the delete node
	auto del = make_unique<LogicalDelete>(get.table);
	del->AddChild(move(root));
	// we push an BoundColumnRef binding to the row_id index
	del->expressions.push_back(make_unique<BoundColumnRefExpression>(
	    TypeId::INT64, ColumnBinding(get.table_index, get.column_ids.size() - 1)));
	return move(del);
}





using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundExecuteStatement &stmt) {
	// all set, execute
	return make_unique<LogicalExecute>(stmt.prepared);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundExplainStatement &stmt) {
	// first bind the root of the plan
	auto plan = CreatePlan(*stmt.bound_statement);
	// get the unoptimized logical plan, and create the explain statement
	auto logical_plan_unopt = plan->ToString();
	auto explain = make_unique<LogicalExplain>(move(plan));
	explain->logical_plan_unopt = logical_plan_unopt;
	return move(explain);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundInsertStatement &stmt) {
	auto table = stmt.table;

	auto insert = make_unique<LogicalInsert>(table, move(stmt.bound_defaults));
	insert->column_index_map = stmt.column_index_map;
	if (stmt.select_statement) {
		// insert from select statement
		// parse select statement and add to logical plan
		auto root = CreatePlan(*stmt.select_statement);
		root = CastLogicalOperatorToTypes(stmt.select_statement->node->types, stmt.expected_types, move(root));
		insert->AddChild(move(root));
	}
	return move(insert);
}



using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundSelectStatement &stmt) {
	return CreatePlan(*stmt.node);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundSimpleStatement &stmt) {
	LogicalOperatorType type;
	switch (stmt.type) {
	case StatementType::ALTER:
		type = LogicalOperatorType::ALTER;
		break;
	case StatementType::DROP:
		type = LogicalOperatorType::DROP;
		break;
	case StatementType::PRAGMA:
		type = LogicalOperatorType::PRAGMA;
		break;
	case StatementType::TRANSACTION:
		type = LogicalOperatorType::TRANSACTION;
		break;
	case StatementType::VACUUM:
		type = LogicalOperatorType::VACUUM;
		break;
	default:
		throw NotImplementedException("Unimplemented type for LogicalSimple!");
	}
	return make_unique<LogicalSimple>(type, move(stmt.info));
}








using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundUpdateStatement &stmt) {
	// we require row ids for the deletion
	require_row_id = true;
	// create the table scan
	auto root = CreatePlan(*stmt.table);
	assert(root->type == LogicalOperatorType::GET);

	auto &get = (LogicalGet &)*root;
	// create the filter (if any)
	if (stmt.condition) {
		PlanSubqueries(&stmt.condition, &root);
		auto filter = make_unique<LogicalFilter>(move(stmt.condition));
		filter->AddChild(move(root));
		root = move(filter);
	}
	// scan the table for the referenced columns in the update clause
	auto &table = get.table;
	vector<unique_ptr<Expression>> projection_expressions;
	for (idx_t i = 0; i < stmt.expressions.size(); i++) {
		if (stmt.expressions[i]->type != ExpressionType::VALUE_DEFAULT) {
			// plan subqueries inside the expression
			PlanSubqueries(&stmt.expressions[i], &root);
			// move the expression into the LogicalProjection
			auto expression = move(stmt.expressions[i]);
			stmt.expressions[i] = make_unique<BoundColumnRefExpression>(
			    expression->return_type, ColumnBinding(stmt.proj_index, projection_expressions.size()));
			projection_expressions.push_back(move(expression));
		}
	}
	// add the row id column to the projection list
	projection_expressions.push_back(make_unique<BoundColumnRefExpression>(
	    TypeId::INT64, ColumnBinding(get.table_index, get.column_ids.size() - 1)));
	// now create the projection
	auto proj = make_unique<LogicalProjection>(stmt.proj_index, move(projection_expressions));
	proj->AddChild(move(root));

	// create the update node
	auto update = make_unique<LogicalUpdate>(table, stmt.column_ids, move(stmt.expressions), move(stmt.bound_defaults));
	update->is_index_update = stmt.is_index_update;
	update->AddChild(move(proj));
	return move(update);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundBaseTableRef &ref) {
	auto table = ref.table;
	auto index = ref.bind_index;

	vector<column_t> column_ids;
	// look in the context for this table which columns are required
	for (auto &bound_column : ref.bound_columns) {
		column_ids.push_back(table->name_map[bound_column]);
	}
	if (require_row_id || column_ids.size() == 0) {
		// no column ids selected
		// the query is like SELECT COUNT(*) FROM table, or SELECT 42 FROM table
		// return just the row id
		column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
	}
	return make_unique<LogicalGet>(table, index, column_ids);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundCrossProductRef &expr) {
	auto cross_product = make_unique<LogicalCrossProduct>();

	auto left = CreatePlan(*expr.left);
	auto right = CreatePlan(*expr.right);

	cross_product->AddChild(move(left));
	cross_product->AddChild(move(right));

	return move(cross_product);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundCTERef &ref) {
    auto index = ref.bind_index;

    vector<TypeId> types;
    for (auto &expr : ref.types) {
        types.push_back(GetInternalType(expr.id));
    }

    return make_unique<LogicalCTERef>(index, ref.cte_index, types, ref.bound_columns);
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundEmptyTableRef &ref) {
	return make_unique<LogicalGet>(ref.bind_index);
}





using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundExpressionListRef &ref) {
	auto root = make_unique_base<LogicalOperator, LogicalGet>(0);
	// values list, first plan any subqueries in the list
	for (auto &expr_list : ref.values) {
		for (auto &expr : expr_list) {
			PlanSubqueries(&expr, &root);
		}
	}
	// now create a LogicalExpressionGet from the set of expressions
	// fetch the types
	vector<TypeId> types;
	for (auto &expr : ref.values[0]) {
		types.push_back(expr->return_type);
	}
	auto expr_get = make_unique<LogicalExpressionGet>(ref.bind_index, types, move(ref.values));
	expr_get->AddChild(move(root));
	return move(expr_get);
}














using namespace duckdb;
using namespace std;

//! Create a JoinCondition from a comparison
static bool CreateJoinCondition(Expression &expr, unordered_set<idx_t> &left_bindings,
                                unordered_set<idx_t> &right_bindings, vector<JoinCondition> &conditions) {
	// comparison
	auto &comparison = (BoundComparisonExpression &)expr;
	auto left_side = JoinSide::GetJoinSide(*comparison.left, left_bindings, right_bindings);
	auto right_side = JoinSide::GetJoinSide(*comparison.right, left_bindings, right_bindings);
	if (left_side != JoinSide::BOTH && right_side != JoinSide::BOTH) {
		// join condition can be divided in a left/right side
		JoinCondition condition;
		condition.comparison = expr.type;
		auto left = move(comparison.left);
		auto right = move(comparison.right);
		if (left_side == JoinSide::RIGHT) {
			// left = right, right = left, flip the comparison symbol and reverse sides
			swap(left, right);
			condition.comparison = FlipComparisionExpression(expr.type);
		}
		condition.left = move(left);
		condition.right = move(right);
		conditions.push_back(move(condition));
		return true;
	}
	return false;
}

unique_ptr<LogicalOperator> LogicalComparisonJoin::CreateJoin(JoinType type, unique_ptr<LogicalOperator> left_child,
                                                              unique_ptr<LogicalOperator> right_child,
                                                              unordered_set<idx_t> &left_bindings,
                                                              unordered_set<idx_t> &right_bindings,
                                                              vector<unique_ptr<Expression>> &expressions) {
	vector<JoinCondition> conditions;
	vector<unique_ptr<Expression>> arbitrary_expressions;
	// first check if we can create
	for (idx_t i = 0; i < expressions.size(); i++) {
		auto &expr = expressions[i];
		auto total_side = JoinSide::GetJoinSide(*expr, left_bindings, right_bindings);
		if (total_side != JoinSide::BOTH) {
			// join condition does not reference both sides, add it as filter under the join
			if (type == JoinType::LEFT && total_side == JoinSide::RIGHT) {
				// filter is on RHS and the join is a LEFT OUTER join, we can push it in the right child
				if (right_child->type != LogicalOperatorType::FILTER) {
					// not a filter yet, push a new empty filter
					auto filter = make_unique<LogicalFilter>();
					filter->AddChild(move(right_child));
					right_child = move(filter);
				}
				// push the expression into the filter
				auto &filter = (LogicalFilter &)*right_child;
				filter.expressions.push_back(move(expr));
				continue;
			}
		} else if (expr->type >= ExpressionType::COMPARE_EQUAL &&
		           expr->type <= ExpressionType::COMPARE_GREATERTHANOREQUALTO) {
			// comparison, check if we can create a comparison JoinCondition
			if (CreateJoinCondition(*expr, left_bindings, right_bindings, conditions)) {
				// successfully created the join condition
				continue;
			}
		} else if (expr->type == ExpressionType::OPERATOR_NOT) {
			auto &not_expr = (BoundOperatorExpression &)*expr;
			assert(not_expr.children.size() == 1);
			ExpressionType child_type = not_expr.children[0]->GetExpressionType();
			// the condition is ON NOT (EXPRESSION)
			// we can transform this to remove the NOT if the child is a Comparison
			// e.g.:
			// ON NOT (X = 3) can be turned into ON (X <> 3)
			// ON NOT (X > 3) can be turned into ON (X <= 3)
			// for non-comparison operators here we just push the filter
			if (child_type >= ExpressionType::COMPARE_EQUAL &&
			    child_type <= ExpressionType::COMPARE_GREATERTHANOREQUALTO) {
				// switcheroo the child condition
				// our join needs to compare explicit left and right sides. So we
				// invert the condition to express NOT, this way we can still use
				// equi-joins
				not_expr.children[0]->type = NegateComparisionExpression(child_type);
				if (CreateJoinCondition(*not_expr.children[0], left_bindings, right_bindings, conditions)) {
					// successfully created the join condition
					continue;
				}
			}
		}
		arbitrary_expressions.push_back(move(expr));
	}
	if (conditions.size() > 0) {
		// we successfully convertedexpressions into JoinConditions
		// create a LogicalComparisonJoin
		auto comp_join = make_unique<LogicalComparisonJoin>(type);
		comp_join->conditions = move(conditions);
		comp_join->children.push_back(move(left_child));
		comp_join->children.push_back(move(right_child));
		if (arbitrary_expressions.size() > 0) {
			// we have some arbitrary expressions as well
			// add them to a filter
			auto filter = make_unique<LogicalFilter>();
			for (auto &expr : arbitrary_expressions) {
				filter->expressions.push_back(move(expr));
			}
			LogicalFilter::SplitPredicates(filter->expressions);
			filter->children.push_back(move(comp_join));
			return move(filter);
		}
		return move(comp_join);
	} else {
		if (arbitrary_expressions.size() == 0) {
			// all conditions were pushed down, add TRUE predicate
			arbitrary_expressions.push_back(make_unique<BoundConstantExpression>(Value::BOOLEAN(true)));
		}
		// if we get here we could not create any JoinConditions
		// turn this into an arbitrary expression join
		auto any_join = make_unique<LogicalAnyJoin>(type);
		// create the condition
		any_join->children.push_back(move(left_child));
		any_join->children.push_back(move(right_child));
		// AND all the arbitrary expressions together
		// do the same with any remaining conditions
		any_join->condition = move(arbitrary_expressions[0]);
		for (idx_t i = 1; i < arbitrary_expressions.size(); i++) {
			any_join->condition = make_unique<BoundConjunctionExpression>(
			    ExpressionType::CONJUNCTION_AND, move(any_join->condition), move(arbitrary_expressions[i]));
		}
		return move(any_join);
	}
}

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundJoinRef &ref) {
	auto left = CreatePlan(*ref.left);
	auto right = CreatePlan(*ref.right);

	if (ref.type == JoinType::INNER) {
		// inner join, generate a cross product + filter
		// this will be later turned into a proper join by the join order optimizer
		auto cross_product = make_unique<LogicalCrossProduct>();

		cross_product->AddChild(move(left));
		cross_product->AddChild(move(right));

		unique_ptr<LogicalOperator> root = move(cross_product);

		auto filter = make_unique<LogicalFilter>(move(ref.condition));
		// visit the expressions in the filter
		for (idx_t i = 0; i < filter->expressions.size(); i++) {
			PlanSubqueries(&filter->expressions[i], &root);
		}
		filter->AddChild(move(root));
		return move(filter);
	}

	// split the expressions by the AND clause
	vector<unique_ptr<Expression>> expressions;
	expressions.push_back(move(ref.condition));
	LogicalFilter::SplitPredicates(expressions);

	// find the table bindings on the LHS and RHS of the join
	unordered_set<idx_t> left_bindings, right_bindings;
	LogicalJoin::GetTableReferences(*left, left_bindings);
	LogicalJoin::GetTableReferences(*right, right_bindings);
	// now create the join operator from the set of join conditions
	auto result = LogicalComparisonJoin::CreateJoin(ref.type, move(left), move(right), left_bindings, right_bindings,
	                                                expressions);

	LogicalOperator *join;
	if (result->type == LogicalOperatorType::FILTER) {
		join = result->children[0].get();
	} else {
		join = result.get();
	}

	// we visit the expressions depending on the type of join
	if (join->type == LogicalOperatorType::COMPARISON_JOIN) {
		// comparison join
		// in this join we visit the expressions on the LHS with the LHS as root node
		// and the expressions on the RHS with the RHS as root node
		auto &comp_join = (LogicalComparisonJoin &)*join;
		for (idx_t i = 0; i < comp_join.conditions.size(); i++) {
			PlanSubqueries(&comp_join.conditions[i].left, &comp_join.children[0]);
			PlanSubqueries(&comp_join.conditions[i].right, &comp_join.children[1]);
		}
	} else if (join->type == LogicalOperatorType::ANY_JOIN) {
		auto &any_join = (LogicalAnyJoin &)*join;
		// for the any join we just visit the condition
		if (any_join.condition->HasSubquery()) {
			throw NotImplementedException("Cannot perform non-inner join on subquery!");
		}
	}
	return result;
}



using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundSubqueryRef &ref) {
	// generate the logical plan for the subquery
	// this happens separately from the current LogicalPlan generation
	LogicalPlanGenerator generator(*ref.binder, context);
	generator.plan_subquery = plan_subquery;
	auto subquery = generator.CreatePlan(*ref.subquery);
	if (generator.has_unplanned_subqueries) {
		has_unplanned_subqueries = true;
	}
	return subquery;
}




using namespace duckdb;
using namespace std;

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundTableFunction &ref) {
	return make_unique<LogicalTableFunction>(ref.function, ref.bind_index, move(ref.bind_data), move(ref.parameters),
	                                         ref.return_types, ref.names);
}






using namespace duckdb;
using namespace std;

LogicalPlanGenerator::LogicalPlanGenerator(Binder &binder, ClientContext &context)
    : plan_subquery(true), has_unplanned_subqueries(false), binder(binder), require_row_id(false), context(context) {
}

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundSQLStatement &statement) {
	switch (statement.type) {
	case StatementType::SELECT:
		return CreatePlan((BoundSelectStatement &)statement);
	case StatementType::INSERT:
		return CreatePlan((BoundInsertStatement &)statement);
	case StatementType::COPY:
		return CreatePlan((BoundCopyStatement &)statement);
	case StatementType::DELETE:
		return CreatePlan((BoundDeleteStatement &)statement);
	case StatementType::UPDATE:
		return CreatePlan((BoundUpdateStatement &)statement);
	case StatementType::CREATE:
		return CreatePlan((BoundCreateStatement &)statement);
	case StatementType::DROP:
	case StatementType::ALTER:
	case StatementType::TRANSACTION:
	case StatementType::PRAGMA:
	case StatementType::VACUUM:
		return CreatePlan((BoundSimpleStatement &)statement);
	case StatementType::EXECUTE:
		return CreatePlan((BoundExecuteStatement &)statement);
	case StatementType::EXPLAIN:
		return CreatePlan((BoundExplainStatement &)statement);
	default:
		throw Exception("Unsupported bound statement type");
	}
}

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundQueryNode &node) {
	switch (node.type) {
	case QueryNodeType::SELECT_NODE:
		return CreatePlan((BoundSelectNode &)node);
	case QueryNodeType::SET_OPERATION_NODE:
		return CreatePlan((BoundSetOperationNode &)node);
	case QueryNodeType::RECURSIVE_CTE_NODE:
		return CreatePlan((BoundRecursiveCTENode &)node);
	default:
		throw Exception("Unsupported bound query node type");
	}
}

unique_ptr<LogicalOperator> LogicalPlanGenerator::CreatePlan(BoundTableRef &ref) {
	switch (ref.type) {
	case TableReferenceType::BASE_TABLE:
		return CreatePlan((BoundBaseTableRef &)ref);
	case TableReferenceType::SUBQUERY:
		return CreatePlan((BoundSubqueryRef &)ref);
	case TableReferenceType::JOIN:
		return CreatePlan((BoundJoinRef &)ref);
	case TableReferenceType::CROSS_PRODUCT:
		return CreatePlan((BoundCrossProductRef &)ref);
	case TableReferenceType::TABLE_FUNCTION:
		return CreatePlan((BoundTableFunction &)ref);
	case TableReferenceType::EMPTY:
		return CreatePlan((BoundEmptyTableRef &)ref);
	case TableReferenceType::EXPRESSION_LIST:
		return CreatePlan((BoundExpressionListRef &)ref);
	case TableReferenceType::CTE:
		return CreatePlan((BoundCTERef &)ref);
	default:
		throw Exception("Unsupported bound table ref type type");
	}
}



using namespace duckdb;
using namespace std;

LogicalAggregate::LogicalAggregate(idx_t group_index, idx_t aggregate_index, vector<unique_ptr<Expression>> select_list)
    : LogicalOperator(LogicalOperatorType::AGGREGATE_AND_GROUP_BY, move(select_list)), group_index(group_index),
      aggregate_index(aggregate_index) {
}

void LogicalAggregate::ResolveTypes() {
	for (auto &expr : groups) {
		types.push_back(expr->return_type);
	}
	// get the chunk types from the projection list
	for (auto &expr : expressions) {
		types.push_back(expr->return_type);
	}
}

vector<ColumnBinding> LogicalAggregate::GetColumnBindings() {
	vector<ColumnBinding> result;
	for (idx_t i = 0; i < groups.size(); i++) {
		result.push_back(ColumnBinding(group_index, i));
	}
	for (idx_t i = 0; i < expressions.size(); i++) {
		result.push_back(ColumnBinding(aggregate_index, i));
	}
	return result;
}

string LogicalAggregate::ParamsToString() const {
	string result = LogicalOperator::ParamsToString();
	if (groups.size() > 0) {
		result += "[";
		result += StringUtil::Join(groups, groups.size(), ", ",
		                           [](const unique_ptr<Expression> &child) { return child->GetName(); });
		result += "]";
	}

	return result;
}


using namespace duckdb;
using namespace std;

LogicalAnyJoin::LogicalAnyJoin(JoinType type) : LogicalJoin(type, LogicalOperatorType::ANY_JOIN) {
}

string LogicalAnyJoin::ParamsToString() const {
	return "[" + condition->ToString() + "]";
}



using namespace duckdb;
using namespace std;

LogicalComparisonJoin::LogicalComparisonJoin(JoinType join_type, LogicalOperatorType logical_type)
    : LogicalJoin(join_type, logical_type) {
}

string LogicalComparisonJoin::ParamsToString() const {
	string result = "[" + JoinTypeToString(join_type);
	if (conditions.size() > 0) {
		result += " ";
		result += StringUtil::Join(conditions, conditions.size(), ", ", [](const JoinCondition &condition) {
			return ExpressionTypeToString(condition.comparison) + "(" + condition.left->GetName() + ", " +
			       condition.right->GetName() + ")";
		});
		result += "]";
	}

	return result;
}


using namespace duckdb;
using namespace std;

LogicalCrossProduct::LogicalCrossProduct() : LogicalOperator(LogicalOperatorType::CROSS_PRODUCT) {
}

vector<ColumnBinding> LogicalCrossProduct::GetColumnBindings() {
	auto left_bindings = children[0]->GetColumnBindings();
	auto right_bindings = children[1]->GetColumnBindings();
	left_bindings.insert(left_bindings.end(), right_bindings.begin(), right_bindings.end());
	return left_bindings;
}

void LogicalCrossProduct::ResolveTypes() {
	types.insert(types.end(), children[0]->types.begin(), children[0]->types.end());
	types.insert(types.end(), children[1]->types.begin(), children[1]->types.end());
}



using namespace duckdb;
using namespace std;

using namespace duckdb;
using namespace std;

string LogicalDistinct::ParamsToString() const {
	string result = LogicalOperator::ParamsToString();
	if (distinct_targets.size() > 0) {
		result += "[";
		StringUtil::Join(distinct_targets, distinct_targets.size(), ", ",
		                 [](const unique_ptr<Expression> &child) { return child->GetName(); });
		result += "]";
	}

	return result;
}


using namespace duckdb;
using namespace std;

LogicalEmptyResult::LogicalEmptyResult(unique_ptr<LogicalOperator> op)
    : LogicalOperator(LogicalOperatorType::EMPTY_RESULT) {

	this->bindings = op->GetColumnBindings();

	op->ResolveOperatorTypes();
	this->return_types = op->types;
}




using namespace duckdb;
using namespace std;

LogicalFilter::LogicalFilter(unique_ptr<Expression> expression) : LogicalOperator(LogicalOperatorType::FILTER) {
	expressions.push_back(move(expression));
	SplitPredicates(expressions);
}

LogicalFilter::LogicalFilter() : LogicalOperator(LogicalOperatorType::FILTER) {
}

void LogicalFilter::ResolveTypes() {
	types = MapTypes(children[0]->types, projection_map);
}

vector<ColumnBinding> LogicalFilter::GetColumnBindings() {
	return MapBindings(children[0]->GetColumnBindings(), projection_map);
}

// Split the predicates separated by AND statements
// These are the predicates that are safe to push down because all of them MUST
// be true
bool LogicalFilter::SplitPredicates(vector<unique_ptr<Expression>> &expressions) {
	bool found_conjunction = false;
	for (idx_t i = 0; i < expressions.size(); i++) {
		if (expressions[i]->type == ExpressionType::CONJUNCTION_AND) {
			auto &conjunction = (BoundConjunctionExpression &)*expressions[i];
			found_conjunction = true;
			// AND expression, append the other children
			for (idx_t k = 1; k < conjunction.children.size(); k++) {
				expressions.push_back(move(conjunction.children[k]));
			}
			// replace this expression with the first child of the conjunction
			expressions[i] = move(conjunction.children[0]);
			// we move back by one so the right child is checked again
			// in case it is an AND expression as well
			i--;
		}
	}
	return found_conjunction;
}





using namespace duckdb;
using namespace std;

LogicalGet::LogicalGet(idx_t table_index)
    : LogicalOperator(LogicalOperatorType::GET), table(nullptr), table_index(table_index) {
}
LogicalGet::LogicalGet(TableCatalogEntry *table, idx_t table_index, vector<column_t> column_ids)
    : LogicalOperator(LogicalOperatorType::GET), table(table), table_index(table_index), column_ids(column_ids) {
}

string LogicalGet::ParamsToString() const {
	if (!table) {
		return "";
	}
	return "(" + table->name + ")";
}

vector<ColumnBinding> LogicalGet::GetColumnBindings() {
	if (!table) {
		return {ColumnBinding(INVALID_INDEX, 0)};
	}
	vector<ColumnBinding> result;
	for (idx_t i = 0; i < column_ids.size(); i++) {
		result.push_back(ColumnBinding(table_index, i));
	}
	return result;
}

void LogicalGet::ResolveTypes() {
	if (column_ids.size() == 0) {
		types = {TypeId::INT32};
	} else {
		types = table->GetTypes(column_ids);
	}
}

idx_t LogicalGet::EstimateCardinality() {
	if (table) {
		return table->storage->cardinality;
	} else {
		return 1;
	}
}





using namespace duckdb;
using namespace std;

LogicalJoin::LogicalJoin(JoinType join_type, LogicalOperatorType logical_type)
    : LogicalOperator(logical_type), join_type(join_type) {
}

vector<ColumnBinding> LogicalJoin::GetColumnBindings() {
	auto left_bindings = MapBindings(children[0]->GetColumnBindings(), left_projection_map);
	if (join_type == JoinType::SEMI || join_type == JoinType::ANTI) {
		// for SEMI and ANTI join we only project the left hand side
		return left_bindings;
	}
	if (join_type == JoinType::MARK) {
		// for MARK join we project the left hand side plus the MARK column
		left_bindings.push_back(ColumnBinding(mark_index, 0));
		return left_bindings;
	}
	// for other join types we project both the LHS and the RHS
	auto right_bindings = MapBindings(children[1]->GetColumnBindings(), right_projection_map);
	left_bindings.insert(left_bindings.end(), right_bindings.begin(), right_bindings.end());
	return left_bindings;
}

void LogicalJoin::ResolveTypes() {
	types = MapTypes(children[0]->types, left_projection_map);
	if (join_type == JoinType::SEMI || join_type == JoinType::ANTI) {
		// for SEMI and ANTI join we only project the left hand side
		return;
	}
	if (join_type == JoinType::MARK) {
		// for MARK join we project the left hand side, plus a BOOLEAN column indicating the MARK
		types.push_back(TypeId::BOOL);
		return;
	}
	// for any other join we project both sides
	auto right_types = MapTypes(children[1]->types, right_projection_map);
	types.insert(types.end(), right_types.begin(), right_types.end());
}

void LogicalJoin::GetTableReferences(LogicalOperator &op, unordered_set<idx_t> &bindings) {
	auto column_bindings = op.GetColumnBindings();
	for (auto binding : column_bindings) {
		bindings.insert(binding.table_index);
	}
}

void LogicalJoin::GetExpressionBindings(Expression &expr, unordered_set<idx_t> &bindings) {
	if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
		auto &colref = (BoundColumnRefExpression &)expr;
		assert(colref.depth == 0);
		bindings.insert(colref.binding.table_index);
	}
	ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { GetExpressionBindings(child, bindings); });
}


using namespace duckdb;
using namespace std;

LogicalProjection::LogicalProjection(idx_t table_index, vector<unique_ptr<Expression>> select_list)
    : LogicalOperator(LogicalOperatorType::PROJECTION, move(select_list)), table_index(table_index) {
}

vector<ColumnBinding> LogicalProjection::GetColumnBindings() {
	return GenerateColumnBindings(table_index, expressions.size());
}

void LogicalProjection::ResolveTypes() {
	for (auto &expr : expressions) {
		types.push_back(expr->return_type);
	}
}


using namespace duckdb;
using namespace std;

vector<ColumnBinding> LogicalPruneColumns::GetColumnBindings() {
	vector<ColumnBinding> result;
	auto child_bindings = children[0]->GetColumnBindings();
	result.insert(result.end(), child_bindings.begin(), child_bindings.begin() + column_limit);
	return result;
}

void LogicalPruneColumns::ResolveTypes() {
	types.insert(types.end(), children[0]->types.begin(), children[0]->types.begin() + column_limit);
}




using namespace duckdb;
using namespace std;

vector<ColumnBinding> LogicalTableFunction::GetColumnBindings() {
	return GenerateColumnBindings(table_index, return_types.size());
}

void LogicalTableFunction::ResolveTypes() {
	for (auto &type : return_types) {
		types.push_back(GetInternalType(type));
	}
}


using namespace duckdb;
using namespace std;

vector<ColumnBinding> LogicalUnnest::GetColumnBindings() {
	auto child_bindings = children[0]->GetColumnBindings();
	for (idx_t i = 0; i < expressions.size(); i++) {
		child_bindings.push_back(ColumnBinding(unnest_index, i));
	}
	return child_bindings;
}

void LogicalUnnest::ResolveTypes() {
	types.insert(types.end(), children[0]->types.begin(), children[0]->types.end());
	for (auto &expr : expressions) {
		types.push_back(expr->return_type);
	}
}


using namespace duckdb;
using namespace std;

vector<ColumnBinding> LogicalWindow::GetColumnBindings() {
	auto child_bindings = children[0]->GetColumnBindings();
	for (idx_t i = 0; i < expressions.size(); i++) {
		child_bindings.push_back(ColumnBinding(window_index, i));
	}
	return child_bindings;
}

void LogicalWindow::ResolveTypes() {
	types.insert(types.end(), children[0]->types.begin(), children[0]->types.end());
	for (auto &expr : expressions) {
		types.push_back(expr->return_type);
	}
}

















//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/pragma_handler.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class ClientContext;
class SQLStatement;
struct PragmaInfo;

//! Pragma handler is responsible for handling PRAGMA statements
class PragmaHandler {
public:
	PragmaHandler(ClientContext &context);

public:
	//! Handles a pragma statement, (potentially) returning a new statement to replace the current one
	unique_ptr<SQLStatement> HandlePragma(PragmaInfo &pragma);

private:
	ClientContext &context;

private:
	void ParseMemoryLimit(string limit);
};
} // namespace duckdb



using namespace duckdb;
using namespace std;

Planner::Planner(ClientContext &context) : binder(context), context(context) {
}

bool Planner::StatementRequiresValidTransaction(BoundSQLStatement &statement) {
	switch (statement.type) {
	case StatementType::DROP: {
		// dropping prepared statements also does not require a valid transaction
		auto &drop_info = (DropInfo &)(*((BoundSimpleStatement &)statement).info);
		return drop_info.type == CatalogType::PREPARED_STATEMENT;
	}
	case StatementType::PREPARE:
	case StatementType::TRANSACTION:
		// prepare and transaction statements can be executed without valid transaction
		return false;
	case StatementType::EXECUTE:
		// execute statement: look into the to-be-executed statement
		return ((BoundExecuteStatement &)statement).prepared->requires_valid_transaction;
	default:
		return true;
	}
}

void Planner::CreatePlan(SQLStatement &statement) {
	vector<BoundParameterExpression *> bound_parameters;

	// first bind the tables and columns to the catalog
	context.profiler.StartPhase("binder");
	binder.parameters = &bound_parameters;
	auto bound_statement = binder.Bind(statement);
	context.profiler.EndPhase();

	VerifyQuery(*bound_statement);

	this->read_only = binder.read_only;
	this->requires_valid_transaction = StatementRequiresValidTransaction(*bound_statement);
	this->names = bound_statement->GetNames();
	this->sql_types = bound_statement->GetTypes();

	// now create a logical query plan from the query
	context.profiler.StartPhase("logical_planner");
	LogicalPlanGenerator logical_planner(binder, context);
	this->plan = logical_planner.CreatePlan(*bound_statement);
	context.profiler.EndPhase();

	// set up a map of parameter number -> value entries
	for (auto &expr : bound_parameters) {
		// check if the type of the parameter could be resolved
		if (expr->return_type == TypeId::INVALID) {
			throw BinderException("Could not determine type of parameters: try adding explicit type casts");
		}
		auto value = make_unique<Value>(expr->return_type);
		expr->value = value.get();
		// check if the parameter number has been used before
		if (value_map.find(expr->parameter_nr) != value_map.end()) {
			throw BinderException("Duplicate parameter index. Use $1, $2 etc. to differentiate.");
		}
		PreparedValueEntry entry;
		entry.value = move(value);
		entry.target_type = expr->sql_type;
		value_map[expr->parameter_nr] = move(entry);
	}
}

void Planner::CreatePlan(unique_ptr<SQLStatement> statement) {
	assert(statement);
	switch (statement->type) {
	case StatementType::SELECT:
	case StatementType::INSERT:
	case StatementType::COPY:
	case StatementType::DELETE:
	case StatementType::UPDATE:
	case StatementType::CREATE:
	case StatementType::EXECUTE:
	case StatementType::DROP:
	case StatementType::ALTER:
	case StatementType::TRANSACTION:
	case StatementType::EXPLAIN:
	case StatementType::VACUUM:
		CreatePlan(*statement);
		break;
	case StatementType::PRAGMA: {
		auto &stmt = *reinterpret_cast<PragmaStatement *>(statement.get());
		PragmaHandler handler(context);
		// some pragma statements have a "replacement" SQL statement that will be executed instead
		// use the PragmaHandler to get the (potential) replacement SQL statement
		auto new_stmt = handler.HandlePragma(*stmt.info);
		if (new_stmt) {
			CreatePlan(move(new_stmt));
		} else {
			CreatePlan(stmt);
		}
		break;
	}
	case StatementType::PREPARE: {
		auto &stmt = *reinterpret_cast<PrepareStatement *>(statement.get());
		auto statement_type = stmt.statement->type;
		// create a plan of the underlying statement
		CreatePlan(move(stmt.statement));
		// now create the logical prepare
		auto prepared_data = make_unique<PreparedStatementData>(statement_type);
		prepared_data->names = names;
		prepared_data->sql_types = sql_types;
		prepared_data->value_map = move(value_map);
		prepared_data->read_only = this->read_only;
		prepared_data->requires_valid_transaction = this->requires_valid_transaction;

		this->read_only = true;
		this->requires_valid_transaction = false;

		auto prepare = make_unique<LogicalPrepare>(stmt.name, move(prepared_data), move(plan));
		names = {"Success"};
		sql_types = {SQLType(SQLTypeId::BOOLEAN)};
		plan = move(prepare);
		break;
	}
	default:
		throw NotImplementedException("Cannot plan statement of type %s!",
		                              StatementTypeToString(statement->type).c_str());
	}
}

void Planner::VerifyQuery(BoundSQLStatement &statement) {
	if (!context.query_verification_enabled) {
		return;
	}
	if (statement.type != StatementType::SELECT) {
		return;
	}
	auto &select = (BoundSelectStatement &)statement;
	VerifyNode(*select.node);
}

void Planner::VerifyNode(BoundQueryNode &node) {
	if (node.type == QueryNodeType::SELECT_NODE) {
		auto &select_node = (BoundSelectNode &)node;
		vector<unique_ptr<Expression>> copies;
		for (auto &expr : select_node.select_list) {
			VerifyExpression(*expr, copies);
		}
		if (select_node.where_clause) {
			VerifyExpression(*select_node.where_clause, copies);
		}
		for (auto &expr : select_node.groups) {
			VerifyExpression(*expr, copies);
		}
		if (select_node.having) {
			VerifyExpression(*select_node.having, copies);
		}
		for (auto &aggr : select_node.aggregates) {
			VerifyExpression(*aggr, copies);
		}
		for (auto &window : select_node.windows) {
			VerifyExpression(*window, copies);
		}

		// double loop to verify that (in)equality of hashes
		for (idx_t i = 0; i < copies.size(); i++) {
			auto outer_hash = copies[i]->Hash();
			for (idx_t j = 0; j < copies.size(); j++) {
				auto inner_hash = copies[j]->Hash();
				if (outer_hash != inner_hash) {
					// if hashes are not equivalent the expressions should not be equivalent
					assert(!Expression::Equals(copies[i].get(), copies[j].get()));
				}
			}
		}
	} else {
		assert(node.type == QueryNodeType::SET_OPERATION_NODE);
		auto &setop_node = (BoundSetOperationNode &)node;
		VerifyNode(*setop_node.left);
		VerifyNode(*setop_node.right);
	}
}

void Planner::VerifyExpression(Expression &expr, vector<unique_ptr<Expression>> &copies) {
	if (expr.HasSubquery()) {
		// can't copy subqueries
		return;
	}
	// verify that the copy of expressions works
	auto copy = expr.Copy();
	// copy should have identical hash and identical equality function
	assert(copy->Hash() == expr.Hash());
	assert(Expression::Equals(copy.get(), &expr));
	copies.push_back(move(copy));
}













using namespace duckdb;
using namespace std;

PragmaHandler::PragmaHandler(ClientContext &context) : context(context) {
}

unique_ptr<SQLStatement> PragmaHandler::HandlePragma(PragmaInfo &pragma) {
	string keyword = StringUtil::Lower(pragma.name);
	if (keyword == "table_info") {
		if (pragma.pragma_type != PragmaType::CALL) {
			throw ParserException("Invalid PRAGMA table_info: expected table name");
		}
		if (pragma.parameters.size() != 1) {
			throw ParserException("Invalid PRAGMA table_info: table_info takes exactly one argument");
		}
		// generate a SelectStatement that selects from the pragma_table_info function
		// i.e. SELECT * FROM pragma_table_info('table_name')
		auto select_statement = make_unique<SelectStatement>();
		auto select_node = make_unique<SelectNode>();
		select_node->select_list.push_back(make_unique<StarExpression>());

		vector<unique_ptr<ParsedExpression>> children;
		children.push_back(make_unique<ConstantExpression>(SQLTypeId::VARCHAR, pragma.parameters[0]));
		auto table_function = make_unique<TableFunctionRef>();
		table_function->function = make_unique<FunctionExpression>(DEFAULT_SCHEMA, "pragma_table_info", children);
		select_node->from_table = move(table_function);
		select_statement->node = move(select_node);
		return move(select_statement);
	}
	return nullptr;
}







//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/subquery/has_correlated_expressions.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {

//! Helper class to recursively detect correlated expressions inside a single LogicalOperator
class HasCorrelatedExpressions : public LogicalOperatorVisitor {
public:
	HasCorrelatedExpressions(const vector<CorrelatedColumnInfo> &correlated);

	void VisitOperator(LogicalOperator &op) override;

	bool has_correlated_expressions;

protected:
	unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr) override;
	unique_ptr<Expression> VisitReplace(BoundSubqueryExpression &expr, unique_ptr<Expression> *expr_ptr) override;

	const vector<CorrelatedColumnInfo> &correlated_columns;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/planner/subquery/rewrite_correlated_expressions.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! Helper class to rewrite correlated expressions within a single LogicalOperator
class RewriteCorrelatedExpressions : public LogicalOperatorVisitor {
public:
	RewriteCorrelatedExpressions(ColumnBinding base_binding, column_binding_map_t<idx_t> &correlated_map);

	void VisitOperator(LogicalOperator &op) override;

protected:
	unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr) override;
	unique_ptr<Expression> VisitReplace(BoundSubqueryExpression &expr, unique_ptr<Expression> *expr_ptr) override;

private:
	//! Helper class used to recursively rewrite correlated expressions within nested subqueries.
	class RewriteCorrelatedRecursive {
	public:
		RewriteCorrelatedRecursive(BoundSubqueryExpression &parent, ColumnBinding base_binding,
		                           column_binding_map_t<idx_t> &correlated_map);

		void RewriteCorrelatedSubquery(BoundSubqueryExpression &expr);
		void RewriteCorrelatedExpressions(Expression &child);

		BoundSubqueryExpression &parent;
		ColumnBinding base_binding;
		column_binding_map_t<idx_t> &correlated_map;
	};

private:
	ColumnBinding base_binding;
	column_binding_map_t<idx_t> &correlated_map;
};

//! Helper class that rewrites COUNT aggregates into a CASE expression turning NULL into 0 after a LEFT OUTER JOIN
class RewriteCountAggregates : public LogicalOperatorVisitor {
public:
	RewriteCountAggregates(column_binding_map_t<idx_t> &replacement_map);

	unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr) override;

	column_binding_map_t<idx_t> &replacement_map;
};

} // namespace duckdb





using namespace duckdb;
using namespace std;

FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated)
    : binder(binder), correlated_columns(correlated) {
	for (idx_t i = 0; i < correlated_columns.size(); i++) {
		auto &col = correlated_columns[i];
		correlated_map[col.binding] = i;
		delim_types.push_back(col.type);
	}
}

bool FlattenDependentJoins::DetectCorrelatedExpressions(LogicalOperator *op) {
	assert(op);
	// check if this entry has correlated expressions
	HasCorrelatedExpressions visitor(correlated_columns);
	visitor.VisitOperator(*op);
	bool has_correlation = visitor.has_correlated_expressions;
	// now visit the children of this entry and check if they have correlated expressions
	for (auto &child : op->children) {
		// we OR the property with its children such that has_correlation is true if either
		// (1) this node has a correlated expression or
		// (2) one of its children has a correlated expression
		if (DetectCorrelatedExpressions(child.get())) {
			has_correlation = true;
		}
	}
	// set the entry in the map
	has_correlated_expressions[op] = has_correlation;
	return has_correlation;
}

unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_ptr<LogicalOperator> plan) {
	auto result = PushDownDependentJoinInternal(move(plan));
	if (replacement_map.size() > 0) {
		// check if we have to replace any COUNT aggregates into "CASE WHEN X IS NULL THEN 0 ELSE COUNT END"
		RewriteCountAggregates aggr(replacement_map);
		aggr.VisitOperator(*result);
	}
	return result;
}

unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan) {
	// first check if the logical operator has correlated expressions
	auto entry = has_correlated_expressions.find(plan.get());
	assert(entry != has_correlated_expressions.end());
	if (!entry->second) {
		// we reached a node without correlated expressions
		// we can eliminate the dependent join now and create a simple cross product
		auto cross_product = make_unique<LogicalCrossProduct>();
		// now create the duplicate eliminated scan for this node
		auto delim_index = binder.GenerateTableIndex();
		this->base_binding = ColumnBinding(delim_index, 0);
		auto delim_scan = make_unique<LogicalDelimGet>(delim_index, delim_types);
		cross_product->children.push_back(move(delim_scan));
		cross_product->children.push_back(move(plan));
		return move(cross_product);
	}
	switch (plan->type) {
	case LogicalOperatorType::FILTER: {
		// filter
		// first we flatten the dependent join in the child of the filter
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		// then we replace any correlated expressions with the corresponding entry in the correlated_map
		RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
		rewriter.VisitOperator(*plan);
		return plan;
	}
	case LogicalOperatorType::PROJECTION: {
		// projection
		// first we flatten the dependent join in the child of the projection
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		// then we replace any correlated expressions with the corresponding entry in the correlated_map
		RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
		rewriter.VisitOperator(*plan);
		// now we add all the columns of the delim_scan to the projection list
		auto proj = (LogicalProjection *)plan.get();
		for (idx_t i = 0; i < correlated_columns.size(); i++) {
			auto colref = make_unique<BoundColumnRefExpression>(
			    correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i));
			plan->expressions.push_back(move(colref));
		}

		base_binding.table_index = proj->table_index;
		this->delim_offset = base_binding.column_index = plan->expressions.size() - correlated_columns.size();
		this->data_offset = 0;
		return plan;
	}
	case LogicalOperatorType::AGGREGATE_AND_GROUP_BY: {
		auto &aggr = (LogicalAggregate &)*plan;
		// aggregate and group by
		// first we flatten the dependent join in the child of the projection
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		// then we replace any correlated expressions with the corresponding entry in the correlated_map
		RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
		rewriter.VisitOperator(*plan);
		// now we add all the columns of the delim_scan to the grouping operators AND the projection list
		for (idx_t i = 0; i < correlated_columns.size(); i++) {
			auto colref = make_unique<BoundColumnRefExpression>(
			    correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i));
			aggr.groups.push_back(move(colref));
		}
		if (aggr.groups.size() == correlated_columns.size()) {
			// we have to perform a LEFT OUTER JOIN between the result of this aggregate and the delim scan
			auto left_outer_join = make_unique<LogicalComparisonJoin>(JoinType::LEFT);
			auto left_index = binder.GenerateTableIndex();
			auto delim_scan = make_unique<LogicalDelimGet>(left_index, delim_types);
			left_outer_join->children.push_back(move(delim_scan));
			left_outer_join->children.push_back(move(plan));
			for (idx_t i = 0; i < correlated_columns.size(); i++) {
				JoinCondition cond;
				cond.left =
				    make_unique<BoundColumnRefExpression>(correlated_columns[i].type, ColumnBinding(left_index, i));
				cond.right = make_unique<BoundColumnRefExpression>(
				    correlated_columns[i].type,
				    ColumnBinding(aggr.group_index, (aggr.groups.size() - correlated_columns.size()) + i));
				cond.comparison = ExpressionType::COMPARE_EQUAL;
				cond.null_values_are_equal = true;
				left_outer_join->conditions.push_back(move(cond));
			}
			// for any COUNT aggregate we replace references to the column with: CASE WHEN COUNT(*) IS NULL THEN 0
			// ELSE COUNT(*) END
			for (idx_t i = 0; i < aggr.expressions.size(); i++) {
				assert(aggr.expressions[i]->GetExpressionClass() == ExpressionClass::BOUND_AGGREGATE);
				auto bound = (BoundAggregateExpression *)&*aggr.expressions[i];
				vector<SQLType> arguments;
				if (bound->function == CountFun::GetFunction() || bound->function == CountStarFun::GetFunction()) {
					// have to replace this ColumnBinding with the CASE expression
					replacement_map[ColumnBinding(aggr.aggregate_index, i)] = i;
				}
			}
			// now we update the delim_index

			base_binding.table_index = left_index;
			this->delim_offset = base_binding.column_index = 0;
			this->data_offset = 0;
			return move(left_outer_join);
		} else {
			// update the delim_index
			base_binding.table_index = aggr.group_index;
			this->delim_offset = base_binding.column_index = aggr.groups.size() - correlated_columns.size();
			this->data_offset = aggr.groups.size();
			return plan;
		}
	}
	case LogicalOperatorType::CROSS_PRODUCT: {
		// cross product
		// push into both sides of the plan
		bool left_has_correlation = has_correlated_expressions.find(plan->children[0].get())->second;
		bool right_has_correlation = has_correlated_expressions.find(plan->children[1].get())->second;
		if (!right_has_correlation) {
			// only left has correlation: push into left
			plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
			return plan;
		}
		if (!left_has_correlation) {
			// only right has correlation: push into right
			plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
			return plan;
		}
		// both sides have correlation
		// turn into an inner join
		auto join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		auto left_binding = this->base_binding;
		plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
		// add the correlated columns to the join conditions
		for (idx_t i = 0; i < correlated_columns.size(); i++) {
			JoinCondition cond;
			cond.left = make_unique<BoundColumnRefExpression>(
			    correlated_columns[i].type, ColumnBinding(left_binding.table_index, left_binding.column_index + i));
			cond.right = make_unique<BoundColumnRefExpression>(
			    correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i));
			cond.comparison = ExpressionType::COMPARE_EQUAL;
			cond.null_values_are_equal = true;
			join->conditions.push_back(move(cond));
		}
		join->children.push_back(move(plan->children[0]));
		join->children.push_back(move(plan->children[1]));
		return move(join);
	}
	case LogicalOperatorType::COMPARISON_JOIN: {
		auto &join = (LogicalComparisonJoin &)*plan;
		assert(plan->children.size() == 2);
		// check the correlated expressions in the children of the join
		bool left_has_correlation = has_correlated_expressions.find(plan->children[0].get())->second;
		bool right_has_correlation = has_correlated_expressions.find(plan->children[1].get())->second;

		if (join.join_type == JoinType::INNER) {
			// inner join
			if (!right_has_correlation) {
				// only left has correlation: push into left
				plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
				return plan;
			}
			if (!left_has_correlation) {
				// only right has correlation: push into right
				plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
				return plan;
			}
		} else if (join.join_type == JoinType::LEFT) {
			// left outer join
			if (!right_has_correlation) {
				// only left has correlation: push into left
				plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
				return plan;
			}
		} else if (join.join_type == JoinType::MARK) {
			if (right_has_correlation) {
				throw Exception("MARK join with correlation in RHS not supported");
			}
			// push the child into the LHS
			plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
			// rewrite expressions in the join conditions
			RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
			rewriter.VisitOperator(*plan);
			return plan;
		} else {
			throw Exception("Unsupported join type for flattening correlated subquery");
		}
		// both sides have correlation
		// push into both sides
		// NOTE: for OUTER JOINS it matters what the BASE BINDING is after the join
		// for the LEFT OUTER JOIN, we want the LEFT side to be the base binding after we push
		// because the RIGHT binding might contain NULL values
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		auto left_binding = this->base_binding;
		plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
		auto right_binding = this->base_binding;
		if (join.join_type == JoinType::LEFT) {
			this->base_binding = left_binding;
		}
		// add the correlated columns to the join conditions
		for (idx_t i = 0; i < correlated_columns.size(); i++) {
			JoinCondition cond;

			cond.left = make_unique<BoundColumnRefExpression>(
			    correlated_columns[i].type, ColumnBinding(left_binding.table_index, left_binding.column_index + i));
			cond.right = make_unique<BoundColumnRefExpression>(
			    correlated_columns[i].type, ColumnBinding(right_binding.table_index, right_binding.column_index + i));
			cond.comparison = ExpressionType::COMPARE_EQUAL;
			cond.null_values_are_equal = true;
			join.conditions.push_back(move(cond));
		}
		// then we replace any correlated expressions with the corresponding entry in the correlated_map
		RewriteCorrelatedExpressions rewriter(right_binding, correlated_map);
		rewriter.VisitOperator(*plan);
		return plan;
	}
	case LogicalOperatorType::LIMIT: {
		auto &limit = (LogicalLimit &)*plan;
		if (limit.offset > 0) {
			throw ParserException("OFFSET not supported in correlated subquery");
		}
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		if (limit.limit == 0) {
			// limit = 0 means we return zero columns here
			return plan;
		} else {
			// limit > 0 does nothing
			return move(plan->children[0]);
		}
	}
	case LogicalOperatorType::WINDOW: {
		auto &window = (LogicalWindow &)*plan;
		// push into children
		plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
		// add the correlated columns to the PARTITION BY clauses in the Window
		for (auto &expr : window.expressions) {
			assert(expr->GetExpressionClass() == ExpressionClass::BOUND_WINDOW);
			auto &w = (BoundWindowExpression &)*expr;
			for (idx_t i = 0; i < correlated_columns.size(); i++) {
				w.partitions.push_back(make_unique<BoundColumnRefExpression>(
				    correlated_columns[i].type,
				    ColumnBinding(base_binding.table_index, base_binding.column_index + i)));
			}
		}
		return plan;
	}
	case LogicalOperatorType::EXCEPT:
	case LogicalOperatorType::INTERSECT:
	case LogicalOperatorType::UNION: {
		auto &setop = (LogicalSetOperation &)*plan;
		// set operator, push into both children
		plan->children[0] = PushDownDependentJoin(move(plan->children[0]));
		plan->children[1] = PushDownDependentJoin(move(plan->children[1]));
		// we have to refer to the setop index now
		base_binding.table_index = setop.table_index;
		base_binding.column_index = setop.column_count;
		setop.column_count += correlated_columns.size();
		return plan;
	}
	case LogicalOperatorType::PRUNE_COLUMNS:
	case LogicalOperatorType::DISTINCT:
		plan->children[0] = PushDownDependentJoin(move(plan->children[0]));
		return plan;
	case LogicalOperatorType::ORDER_BY:
		throw ParserException("ORDER BY not supported in correlated subquery");
	default:
		throw NotImplementedException("Logical operator type \"%s\" for dependent join",
		                              LogicalOperatorToString(plan->type).c_str());
	}
}





using namespace duckdb;
using namespace std;

HasCorrelatedExpressions::HasCorrelatedExpressions(const vector<CorrelatedColumnInfo> &correlated)
    : has_correlated_expressions(false), correlated_columns(correlated) {
}

void HasCorrelatedExpressions::VisitOperator(LogicalOperator &op) {
	//! The HasCorrelatedExpressions does not recursively visit logical operators, it only visits the current one
	VisitOperatorExpressions(op);
}

unique_ptr<Expression> HasCorrelatedExpressions::VisitReplace(BoundColumnRefExpression &expr,
                                                              unique_ptr<Expression> *expr_ptr) {
	if (expr.depth == 0) {
		return nullptr;
	}
	// correlated column reference
	assert(expr.depth == 1);
	has_correlated_expressions = true;
	return nullptr;
}

unique_ptr<Expression> HasCorrelatedExpressions::VisitReplace(BoundSubqueryExpression &expr,
                                                              unique_ptr<Expression> *expr_ptr) {
	if (!expr.IsCorrelated()) {
		return nullptr;
	}
	// check if the subquery contains any of the correlated expressions that we are concerned about in this node
	for (idx_t i = 0; i < correlated_columns.size(); i++) {
		if (std::find(expr.binder->correlated_columns.begin(), expr.binder->correlated_columns.end(),
		              correlated_columns[i]) != expr.binder->correlated_columns.end()) {
			has_correlated_expressions = true;
			break;
		}
	}
	return nullptr;
}









using namespace duckdb;
using namespace std;

RewriteCorrelatedExpressions::RewriteCorrelatedExpressions(ColumnBinding base_binding,
                                                           column_binding_map_t<idx_t> &correlated_map)
    : base_binding(base_binding), correlated_map(correlated_map) {
}

void RewriteCorrelatedExpressions::VisitOperator(LogicalOperator &op) {
	VisitOperatorExpressions(op);
}

unique_ptr<Expression> RewriteCorrelatedExpressions::VisitReplace(BoundColumnRefExpression &expr,
                                                                  unique_ptr<Expression> *expr_ptr) {
	if (expr.depth == 0) {
		return nullptr;
	}
	// correlated column reference
	// replace with the entry referring to the duplicate eliminated scan
	assert(expr.depth == 1);
	auto entry = correlated_map.find(expr.binding);
	assert(entry != correlated_map.end());

	expr.binding = ColumnBinding(base_binding.table_index, base_binding.column_index + entry->second);
	expr.depth = 0;
	return nullptr;
}

unique_ptr<Expression> RewriteCorrelatedExpressions::VisitReplace(BoundSubqueryExpression &expr,
                                                                  unique_ptr<Expression> *expr_ptr) {
	if (!expr.IsCorrelated()) {
		return nullptr;
	}
	// subquery detected within this subquery
	// recursively rewrite it using the RewriteCorrelatedRecursive class
	RewriteCorrelatedRecursive rewrite(expr, base_binding, correlated_map);
	rewrite.RewriteCorrelatedSubquery(expr);
	return nullptr;
}

RewriteCorrelatedExpressions::RewriteCorrelatedRecursive::RewriteCorrelatedRecursive(
    BoundSubqueryExpression &parent, ColumnBinding base_binding, column_binding_map_t<idx_t> &correlated_map)
    : parent(parent), base_binding(base_binding), correlated_map(correlated_map) {
}

void RewriteCorrelatedExpressions::RewriteCorrelatedRecursive::RewriteCorrelatedSubquery(
    BoundSubqueryExpression &expr) {
	// rewrite the binding in the correlated list of the subquery)
	for (auto &corr : expr.binder->correlated_columns) {
		auto entry = correlated_map.find(corr.binding);
		if (entry != correlated_map.end()) {
			corr.binding = ColumnBinding(base_binding.table_index, base_binding.column_index + entry->second);
		}
	}
	// now rewrite any correlated BoundColumnRef expressions inside the subquery
	ExpressionIterator::EnumerateQueryNodeChildren(*expr.subquery,
	                                               [&](Expression &child) { RewriteCorrelatedExpressions(child); });
}

void RewriteCorrelatedExpressions::RewriteCorrelatedRecursive::RewriteCorrelatedExpressions(Expression &child) {
	if (child.type == ExpressionType::BOUND_COLUMN_REF) {
		// bound column reference
		auto &bound_colref = (BoundColumnRefExpression &)child;
		if (bound_colref.depth == 0) {
			// not a correlated column, ignore
			return;
		}
		// correlated column
		// check the correlated map
		auto entry = correlated_map.find(bound_colref.binding);
		if (entry != correlated_map.end()) {
			// we found the column in the correlated map!
			// update the binding and reduce the depth by 1

			bound_colref.binding = ColumnBinding(base_binding.table_index, base_binding.column_index + entry->second);
			bound_colref.depth--;
		}
	} else if (child.type == ExpressionType::SUBQUERY) {
		// we encountered another subquery: rewrite recursively
		assert(child.GetExpressionClass() == ExpressionClass::BOUND_SUBQUERY);
		auto &bound_subquery = (BoundSubqueryExpression &)child;
		RewriteCorrelatedRecursive rewrite(bound_subquery, base_binding, correlated_map);
		rewrite.RewriteCorrelatedSubquery(bound_subquery);
	}
}

RewriteCountAggregates::RewriteCountAggregates(column_binding_map_t<idx_t> &replacement_map)
    : replacement_map(replacement_map) {
}

unique_ptr<Expression> RewriteCountAggregates::VisitReplace(BoundColumnRefExpression &expr,
                                                            unique_ptr<Expression> *expr_ptr) {
	auto entry = replacement_map.find(expr.binding);
	if (entry != replacement_map.end()) {
		// reference to a COUNT(*) aggregate
		// replace this with CASE WHEN COUNT(*) IS NULL THEN 0 ELSE COUNT(*) END
		auto is_null = make_unique<BoundOperatorExpression>(ExpressionType::OPERATOR_IS_NULL, TypeId::BOOL);
		is_null->children.push_back(expr.Copy());
		auto check = move(is_null);
		auto result_if_true = make_unique<BoundConstantExpression>(Value::Numeric(expr.return_type, 0));
		auto result_if_false = move(*expr_ptr);
		return make_unique<BoundCaseExpression>(move(check), move(result_if_true), move(result_if_false));
	}
	return nullptr;
}












using namespace duckdb;
using namespace std;

TableBinding::TableBinding(const string &alias, BoundBaseTableRef *bound)
    : Binding(BindingType::TABLE, alias, bound->bind_index), bound(bound) {
}

bool TableBinding::HasMatchingBinding(const string &column_name) {
	return bound->table->ColumnExists(column_name);
}

BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
	auto entry = bound->table->name_map.find(colref.column_name);
	if (entry == bound->table->name_map.end()) {
		return BindResult(StringUtil::Format("Table \"%s\" does not have a column named \"%s\"",
		                                     colref.table_name.c_str(), colref.column_name.c_str()));
	}
	// fetch the type of the column
	SQLType col_type;
	if (entry->second == COLUMN_IDENTIFIER_ROW_ID) {
		// row id: BIGINT type
		col_type = SQLType::BIGINT;
	} else {
		// normal column: fetch type from base column
		auto &col = bound->table->columns[entry->second];
		col_type = col.type;
	}
	auto &column_list = bound->bound_columns;
	// check if the entry already exists in the column list for the table
	ColumnBinding binding;

	binding.column_index = column_list.size();
	for (idx_t i = 0; i < column_list.size(); i++) {
		auto &column = column_list[i];
		if (column == colref.column_name) {
			binding.column_index = i;
			break;
		}
	}
	if (binding.column_index == column_list.size()) {
		// column binding not found: add it to the list of bindings
		column_list.push_back(colref.column_name);
	}
	binding.table_index = index;
	return BindResult(
	    make_unique<BoundColumnRefExpression>(colref.GetName(), GetInternalType(col_type), binding, depth), col_type);
}

void TableBinding::GenerateAllColumnExpressions(BindContext &context,
                                                vector<unique_ptr<ParsedExpression>> &select_list) {
	for (auto &column : bound->table->columns) {
		string column_string = alias + "." + column.name;
		if (context.hidden_columns.find(column_string) != context.hidden_columns.end()) {
			continue;
		}
		select_list.push_back(make_unique<ColumnRefExpression>(column.name, alias));
	}
}

SubqueryBinding::SubqueryBinding(const string &alias, SubqueryRef &ref, BoundQueryNode &subquery, idx_t index)
    : Binding(BindingType::SUBQUERY, alias, index), subquery(subquery) {
	if (ref.column_name_alias.size() > subquery.names.size()) {
		throw BinderException("table \"%s\" has %lld columns available but %lld columns specified", alias.c_str(),
		                      (int64_t)subquery.names.size(), (int64_t)ref.column_name_alias.size());
	}
	idx_t i;
	// use any provided aliases from the subquery
	for (i = 0; i < ref.column_name_alias.size(); i++) {
		auto &name = ref.column_name_alias[i];
		AddName(name);
	}
	// if not enough aliases were provided, use the default names
	for (; i < subquery.names.size(); i++) {
		auto &name = subquery.names[i];
		AddName(name);
	}
}

void SubqueryBinding::AddName(string &name) {
	if (name_map.find(name) != name_map.end()) {
		throw BinderException("table \"%s\" has duplicate column name \"%s\"", alias.c_str(), name.c_str());
	}
	name_map[name] = names.size();
	names.push_back(name);
}

bool SubqueryBinding::HasMatchingBinding(const string &column_name) {
	auto entry = name_map.find(column_name);
	return entry != name_map.end();
}

BindResult SubqueryBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
	auto column_entry = name_map.find(colref.column_name);
	if (column_entry == name_map.end()) {
		return BindResult(StringUtil::Format("Subquery \"%s\" does not have a column named \"%s\"", alias.c_str(),
		                                     colref.column_name.c_str()));
	}
	ColumnBinding binding;

	binding.table_index = index;
	binding.column_index = column_entry->second;
	assert(column_entry->second < subquery.types.size());
	SQLType sql_type = subquery.types[column_entry->second];
	return BindResult(
	    make_unique<BoundColumnRefExpression>(colref.GetName(), GetInternalType(sql_type), binding, depth), sql_type);
}

void SubqueryBinding::GenerateAllColumnExpressions(BindContext &context,
                                                   vector<unique_ptr<ParsedExpression>> &select_list) {
	for (auto &column_name : names) {
		select_list.push_back(make_unique<ColumnRefExpression>(column_name, alias));
	}
}

GenericBinding::GenericBinding(const string &alias, vector<SQLType> coltypes, vector<string> colnames, idx_t index)
    : Binding(BindingType::GENERIC, alias, index), types(move(coltypes)), names(move(colnames)) {
	assert(types.size() == names.size());
	for (idx_t i = 0; i < names.size(); i++) {
		auto &name = names[i];
		if (name_map.find(name) != name_map.end()) {
			throw BinderException("table \"%s\" has duplicate column name \"%s\"", alias.c_str(), name.c_str());
		}
		name_map[name] = i;
	}
}

bool GenericBinding::HasMatchingBinding(const string &column_name) {
	auto entry = name_map.find(column_name);
	return entry != name_map.end();
}

BindResult GenericBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
	auto column_entry = name_map.find(colref.column_name);
	if (column_entry == name_map.end()) {
		return BindResult(StringUtil::Format("Values list \"%s\" does not have a column named \"%s\"", alias.c_str(),
		                                     colref.column_name.c_str()));
	}
	ColumnBinding binding;
	binding.table_index = index;
	binding.column_index = column_entry->second;
	SQLType sql_type = types[column_entry->second];
	return BindResult(
	    make_unique<BoundColumnRefExpression>(colref.GetName(), GetInternalType(sql_type), binding, depth), sql_type);
}

void GenericBinding::GenerateAllColumnExpressions(BindContext &context,
                                                  vector<unique_ptr<ParsedExpression>> &select_list) {
	for (auto &column_name : names) {
		select_list.push_back(make_unique<ColumnRefExpression>(column_name, alias));
	}
}


using namespace duckdb;
using namespace std;

Block::Block(block_id_t id) : FileBuffer(FileBufferType::BLOCK, Storage::BLOCK_ALLOC_SIZE), id(id) {
}



using namespace duckdb;
using namespace std;

BufferHandle::BufferHandle(BufferManager &manager, block_id_t block_id, FileBuffer *node)
    : manager(manager), block_id(block_id), node(node) {
}

BufferHandle::~BufferHandle() {
	manager.Unpin(block_id);
}




using namespace duckdb;
using namespace std;

unique_ptr<BufferEntry> BufferList::Pop() {
	if (!root) {
		// no root: return nullptr
		return nullptr;
	}
	// fetch root
	auto entry = move(root);
	root = move(entry->next);
	if (root) {
		// new root no longer has prev pointer
		root->prev = nullptr;
	} else {
		last = nullptr;
	}
	count--;
	return entry;
}

unique_ptr<BufferEntry> BufferList::Erase(BufferEntry *entry) {
	assert(entry->prev || entry == root.get());
	assert(entry->next || entry == last);
	// first get the entry, either from the previous entry or from the root node
	auto current = entry->prev ? move(entry->prev->next) : move(root);
	auto prev = entry->prev;
	if (entry == last) {
		// entry was last entry: last is now the previous entry
		last = prev;
	}
	// now set up prev/next pointers correctly
	auto next = move(entry->next);
	if (!prev) {
		// no prev: entry was root
		root = move(next);
		if (root) {
			// new root no longer has prev pointer
			root->prev = nullptr;
		} else {
			last = nullptr;
		}
		assert(!root || !root->prev);
	} else if (prev != last) {
		assert(next);
		next->prev = prev;
		prev->next = move(next);
	}
	count--;
	return current;
}

void BufferList::Append(unique_ptr<BufferEntry> entry) {
	assert(!entry->next);
	if (!last) {
		// empty list: set as root
		entry->prev = nullptr;
		root = move(entry);
		last = root.get();
	} else {
		// non-empty list: append to last entry and set entry as last
		entry->prev = last;
		last->next = move(entry);
		last = last->next.get();
	}
	count++;
}



using namespace duckdb;
using namespace std;

ManagedBuffer::ManagedBuffer(BufferManager &manager, idx_t size, bool can_destroy, block_id_t id)
    : FileBuffer(FileBufferType::MANAGED_BUFFER, size), manager(manager), can_destroy(can_destroy), id(id) {
	assert(id >= MAXIMUM_BLOCK);
	assert(size >= Storage::BLOCK_ALLOC_SIZE);
}




using namespace duckdb;
using namespace std;

BufferManager::BufferManager(FileSystem &fs, BlockManager &manager, string tmp, idx_t maximum_memory)
    : fs(fs), manager(manager), current_memory(0), maximum_memory(maximum_memory), temp_directory(move(tmp)),
      temporary_id(MAXIMUM_BLOCK) {
	if (!temp_directory.empty()) {
		fs.CreateDirectory(temp_directory);
	}
}

BufferManager::~BufferManager() {
	if (!temp_directory.empty()) {
		fs.RemoveDirectory(temp_directory);
	}
}

unique_ptr<BufferHandle> BufferManager::Pin(block_id_t block_id, bool can_destroy) {
	// first obtain a lock on the set of blocks
	lock_guard<mutex> lock(block_lock);
	if (block_id < MAXIMUM_BLOCK) {
		return PinBlock(block_id);
	} else {
		return PinBuffer(block_id, can_destroy);
	}
}

unique_ptr<BufferHandle> BufferManager::PinBlock(block_id_t block_id) {
	// this method should only be used to pin blocks that exist in the file
	assert(block_id < MAXIMUM_BLOCK);

	// check if the block is already loaded
	Block *result_block;
	auto entry = blocks.find(block_id);
	if (entry == blocks.end()) {
		// block is not loaded, load the block
		current_memory += Storage::BLOCK_ALLOC_SIZE;
		unique_ptr<Block> block;
		if (current_memory > maximum_memory) {
			// not enough memory to hold the block: have to evict a block first
			block = EvictBlock();
			if (!block) {
				// evicted a managed buffer: no block returned
				// create a new block
				block = make_unique<Block>(block_id);
			} else {
				// take over the evicted block and use it to hold this block
				block->id = block_id;
			}
		} else {
			// enough memory to create a new block: allocate it
			block = make_unique<Block>(block_id);
		}
		manager.Read(*block);
		result_block = block.get();
		// create a new buffer entry for this block and insert it into the block list
		auto buffer_entry = make_unique<BufferEntry>(move(block));
		blocks.insert(make_pair(block_id, buffer_entry.get()));
		used_list.Append(move(buffer_entry));
	} else {
		auto buffer = entry->second->buffer.get();
		assert(buffer->type == FileBufferType::BLOCK);
		result_block = (Block *)buffer;
		// add one to the reference count
		AddReference(entry->second);
	}
	return make_unique<BufferHandle>(*this, block_id, result_block);
}

void BufferManager::AddReference(BufferEntry *entry) {
	entry->ref_count++;
	if (entry->ref_count == 1) {
		// ref count is 1, that means it used to be 0 (unused)
		// move from lru to used_list
		auto current_entry = lru.Erase(entry);
		used_list.Append(move(current_entry));
	}
}

void BufferManager::Unpin(block_id_t block_id) {
	lock_guard<mutex> lock(block_lock);
	// first find the block in the set of blocks
	auto entry = blocks.find(block_id);
	assert(entry != blocks.end());

	auto buffer_entry = entry->second;
	// then decerase the ref count
	assert(buffer_entry->ref_count > 0);
	buffer_entry->ref_count--;
	if (buffer_entry->ref_count == 0) {
		if (buffer_entry->buffer->type == FileBufferType::MANAGED_BUFFER) {
			auto managed = (ManagedBuffer *)buffer_entry->buffer.get();
			if (managed->can_destroy) {
				// this is a managed buffer that we can destroy
				// instead of adding it to the LRU list, just deallocate the managed buffer immediately
				current_memory -= managed->size;
				return;
			}
		}
		// no references left: move block out of used list and into lru list
		auto entry = used_list.Erase(buffer_entry);
		lru.Append(move(entry));
	}
}

unique_ptr<Block> BufferManager::EvictBlock() {
	if (temp_directory.empty()) {
		throw Exception("Out-of-memory: cannot evict buffer because no temporary directory is specified!\nTo enable "
		                "temporary buffer eviction set a temporary directory in the configuration");
	}
	// pop the first entry from the lru list
	auto entry = lru.Pop();
	if (!entry) {
		throw Exception("Not enough memory to complete operation!");
	}
	assert(entry->ref_count == 0);
	// erase this identifier from the set of blocks
	auto buffer = entry->buffer.get();
	if (buffer->type == FileBufferType::BLOCK) {
		// block buffer: remove the block and reuse it
		auto block = (Block *)buffer;
		blocks.erase(block->id);
		// free up the memory
		current_memory -= Storage::BLOCK_ALLOC_SIZE;
		// finally return the block obtained from the current entry
		return unique_ptr_cast<FileBuffer, Block>(move(entry->buffer));
	} else {
		// managed buffer: cannot return a block here
		auto managed = (ManagedBuffer *)buffer;
		assert(!managed->can_destroy);

		// cannot destroy this buffer: write it to disk first so it can be reloaded later
		WriteTemporaryBuffer(*managed);

		blocks.erase(managed->id);
		// free up the memory
		current_memory -= managed->size;
		return nullptr;
	}
}

unique_ptr<BufferHandle> BufferManager::Allocate(idx_t alloc_size, bool can_destroy) {
	assert(alloc_size >= Storage::BLOCK_ALLOC_SIZE);

	lock_guard<mutex> lock(block_lock);
	// first evict blocks until we have enough memory to store this buffer
	while (current_memory + alloc_size > maximum_memory) {
		EvictBlock();
	}
	// now allocate the buffer with a new temporary id
	auto temp_id = ++temporary_id;
	auto buffer = make_unique<ManagedBuffer>(*this, alloc_size, can_destroy, temp_id);
	auto managed_buffer = buffer.get();
	current_memory += buffer->AllocSize();
	// create a new entry and append it to the used list
	auto buffer_entry = make_unique<BufferEntry>(move(buffer));
	blocks.insert(make_pair(temp_id, buffer_entry.get()));
	used_list.Append(move(buffer_entry));
	// now return a handle to the entry
	return make_unique<BufferHandle>(*this, temp_id, managed_buffer);
}

void BufferManager::DestroyBuffer(block_id_t buffer_id, bool can_destroy) {
	lock_guard<mutex> lock(block_lock);

	assert(buffer_id >= MAXIMUM_BLOCK);
	// this is like unpin, except we just destroy the entry entirely instead of adding it to the LRU list
	// first find the block in the set of blocks
	auto entry = blocks.find(buffer_id);
	if (entry == blocks.end()) {
		// buffer is not currently loaded into memory
		// check if it was offloaded to disk instead
		if (!can_destroy) {
			// buffer was offloaded to disk: remove the file instead
			DeleteTemporaryFile(buffer_id);
		}
		return;
	}

	auto handle = entry->second;
	assert(handle->ref_count == 0);

	current_memory -= handle->buffer->AllocSize();
	blocks.erase(buffer_id);
	lru.Erase(handle);
}

void BufferManager::SetLimit(idx_t limit) {
	lock_guard<mutex> lock(block_lock);

	while (current_memory > limit) {
		EvictBlock();
	}
	maximum_memory = limit;
}

unique_ptr<BufferHandle> BufferManager::PinBuffer(block_id_t buffer_id, bool can_destroy) {
	assert(buffer_id >= MAXIMUM_BLOCK);
	// check if we have this buffer here
	auto entry = blocks.find(buffer_id);
	if (entry == blocks.end()) {
		if (can_destroy) {
			// buffer was destroyed: return nullptr
			return nullptr;
		} else {
			// buffer was unloaded but not destroyed: read from disk
			return ReadTemporaryBuffer(buffer_id);
		}
	}
	// we still have the buffer, add a reference to it
	auto buffer = entry->second->buffer.get();
	AddReference(entry->second);
	// now return it
	assert(buffer->type == FileBufferType::MANAGED_BUFFER);
	auto managed = (ManagedBuffer *)buffer;
	assert(managed->id == buffer_id);
	return make_unique<BufferHandle>(*this, buffer_id, managed);
}

string BufferManager::GetTemporaryPath(block_id_t id) {
	return fs.JoinPath(temp_directory, to_string(id) + ".block");
}

void BufferManager::WriteTemporaryBuffer(ManagedBuffer &buffer) {
	assert(buffer.size + Storage::BLOCK_HEADER_SIZE >= Storage::BLOCK_ALLOC_SIZE);
	// get the path to write to
	auto path = GetTemporaryPath(buffer.id);
	// create the file and write the size followed by the buffer contents
	auto handle = fs.OpenFile(path, FileFlags::WRITE | FileFlags::CREATE);
	handle->Write(&buffer.size, sizeof(idx_t), 0);
	buffer.Write(*handle, sizeof(idx_t));
}

unique_ptr<BufferHandle> BufferManager::ReadTemporaryBuffer(block_id_t id) {
	if (temp_directory.empty()) {
		throw Exception("Out-of-memory: cannot read buffer because no temporary directory is specified!\nTo enable "
		                "temporary buffer eviction set a temporary directory in the configuration");
	}
	idx_t alloc_size;
	// open the temporary file and read the size
	auto path = GetTemporaryPath(id);
	auto handle = fs.OpenFile(path, FileFlags::READ);
	handle->Read(&alloc_size, sizeof(idx_t), 0);
	// first evict blocks until we can handle the size
	while (current_memory + alloc_size > maximum_memory) {
		EvictBlock();
	}
	// now allocate a buffer of this size and read the data into that buffer
	auto buffer = make_unique<ManagedBuffer>(*this, alloc_size + Storage::BLOCK_HEADER_SIZE, false, id);
	buffer->Read(*handle, sizeof(idx_t));

	auto managed_buffer = buffer.get();
	current_memory += buffer->AllocSize();
	// create a new entry and append it to the used list
	auto buffer_entry = make_unique<BufferEntry>(move(buffer));
	blocks.insert(make_pair(id, buffer_entry.get()));
	used_list.Append(move(buffer_entry));
	// now return a handle to the entry
	return make_unique<BufferHandle>(*this, id, managed_buffer);
}

void BufferManager::DeleteTemporaryFile(block_id_t id) {
	auto path = GetTemporaryPath(id);
	if (fs.FileExists(path)) {
		fs.RemoveFile(path);
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/checkpoint/table_data_reader.hpp
//
//
//===----------------------------------------------------------------------===//



//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/checkpoint_manager.hpp
//
//
//===----------------------------------------------------------------------===//






//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/meta_block_writer.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {

//! This struct is responsible for writing metadata to disk
class MetaBlockWriter : public Serializer {
public:
	MetaBlockWriter(BlockManager &manager);
	~MetaBlockWriter();

	BlockManager &manager;
	unique_ptr<Block> block;
	idx_t offset;

public:
	void Flush();

	void WriteData(const_data_ptr_t buffer, idx_t write_size) override;
};

} // namespace duckdb


namespace duckdb {
class ClientContext;
class MetaBlockReader;
class SchemaCatalogEntry;
class SequenceCatalogEntry;
class TableCatalogEntry;
class ViewCatalogEntry;

class DataPointer {
public:
	DataPointer(){};
	double min;
	double max;
	uint64_t row_start;
	uint64_t tuple_count;
	block_id_t block_id;
	uint32_t offset;
	//! The minimum value of the segment
	data_t min_stats[8];
	//! The maximum value of the segment
	data_t max_stats[8];
};

//! CheckpointManager is responsible for checkpointing the database
class CheckpointManager {
public:
	CheckpointManager(StorageManager &manager);

	//! Checkpoint the current state of the WAL and flush it to the main storage. This should be called BEFORE any
	//! connction is available because right now the checkpointing cannot be done online. (TODO)
	void CreateCheckpoint();
	//! Load from a stored checkpoint
	void LoadFromStorage();

	//! The block manager to write the checkpoint to
	BlockManager &block_manager;
	//! The buffer manager
	BufferManager &buffer_manager;
	//! The database this storagemanager belongs to
	DuckDB &database;
	//! The metadata writer is responsible for writing schema information
	unique_ptr<MetaBlockWriter> metadata_writer;
	//! The table data writer is responsible for writing the DataPointers used by the table chunks
	unique_ptr<MetaBlockWriter> tabledata_writer;

private:
	void WriteSchema(Transaction &transaction, SchemaCatalogEntry &schema);
	void WriteTable(Transaction &transaction, TableCatalogEntry &table);
	void WriteView(ViewCatalogEntry &table);
	void WriteSequence(SequenceCatalogEntry &table);

	void ReadSchema(ClientContext &context, MetaBlockReader &reader);
	void ReadTable(ClientContext &context, MetaBlockReader &reader);
	void ReadView(ClientContext &context, MetaBlockReader &reader);
	void ReadSequence(ClientContext &context, MetaBlockReader &reader);
};

} // namespace duckdb


namespace duckdb {
struct BoundCreateTableInfo;

//! The table data reader is responsible for reading the data of a table from the block manager
class TableDataReader {
public:
	TableDataReader(CheckpointManager &manager, MetaBlockReader &reader, BoundCreateTableInfo &info);

	void ReadTableData();

private:
	CheckpointManager &manager;
	MetaBlockReader &reader;
	BoundCreateTableInfo &info;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/checkpoint/table_data_writer.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class UncompressedSegment;
class SegmentStatistics;

//! The table data writer is responsible for writing the data of a table to the block manager
class TableDataWriter {
public:
	TableDataWriter(CheckpointManager &manager, TableCatalogEntry &table);
	~TableDataWriter();

	void WriteTableData(Transaction &transaction);

private:
	void AppendData(idx_t col_idx, Vector &data, idx_t count);

	void CreateSegment(idx_t col_idx);
	void FlushSegment(idx_t col_idx);

	void WriteDataPointers();

private:
	CheckpointManager &manager;
	TableCatalogEntry &table;

	vector<unique_ptr<UncompressedSegment>> segments;
	vector<unique_ptr<SegmentStatistics>> stats;

	vector<vector<DataPointer>> data_pointers;
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/meta_block_reader.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
//! This struct is responsible for reading meta data from disk
class MetaBlockReader : public Deserializer {
public:
	MetaBlockReader(BufferManager &manager, block_id_t block);

	BufferManager &manager;
	unique_ptr<BufferHandle> handle;
	idx_t offset;
	block_id_t next_block;

public:
	//! Read content of size read_size into the buffer
	void ReadData(data_ptr_t buffer, idx_t read_size) override;

private:
	void ReadNewBlock(block_id_t id);
};
} // namespace duckdb









using namespace duckdb;
using namespace std;

TableDataReader::TableDataReader(CheckpointManager &manager, MetaBlockReader &reader, BoundCreateTableInfo &info)
    : manager(manager), reader(reader), info(info) {
	info.data = unique_ptr<vector<unique_ptr<PersistentSegment>>[]>(
	    new vector<unique_ptr<PersistentSegment>>[info.Base().columns.size()]);
}

void TableDataReader::ReadTableData() {
	auto &columns = info.Base().columns;
	assert(columns.size() > 0);

	// load the data pointers for the table
	for (idx_t col = 0; col < columns.size(); col++) {
		auto &column = columns[col];
		idx_t data_pointer_count = reader.Read<idx_t>();
		for (idx_t data_ptr = 0; data_ptr < data_pointer_count; data_ptr++) {
			// read the data pointer
			DataPointer data_pointer;
			data_pointer.min = reader.Read<double>();
			data_pointer.max = reader.Read<double>();
			data_pointer.row_start = reader.Read<idx_t>();
			data_pointer.tuple_count = reader.Read<idx_t>();
			data_pointer.block_id = reader.Read<block_id_t>();
			data_pointer.offset = reader.Read<uint32_t>();
			reader.ReadData(data_pointer.min_stats, 8);
			reader.ReadData(data_pointer.max_stats, 8);

			// create a persistent segment
			auto segment = make_unique<PersistentSegment>(
			    manager.buffer_manager, data_pointer.block_id, data_pointer.offset, GetInternalType(column.type),
			    data_pointer.row_start, data_pointer.tuple_count, data_pointer.min_stats, data_pointer.max_stats);
			info.data[col].push_back(move(segment));
		}
	}
}








//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/numeric_segment.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {

class NumericSegment : public UncompressedSegment {
public:
	NumericSegment(BufferManager &manager, TypeId type, idx_t row_start, block_id_t block_id = INVALID_BLOCK);

	//! The size of this type
	idx_t type_size;

public:
	//! Fetch a single value and append it to the vector
	void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
	              idx_t result_idx) override;

	//! Append a part of a vector to the uncompressed segment with the given append state, updating the provided stats
	//! in the process. Returns the amount of tuples appended. If this is less than `count`, the uncompressed segment is
	//! full.
	idx_t Append(SegmentStatistics &stats, Vector &data, idx_t offset, idx_t count) override;

	//! Rollback a previous update
	void RollbackUpdate(UpdateInfo *info) override;

protected:
	void Update(ColumnData &data, SegmentStatistics &stats, Transaction &transaction, Vector &update, row_t *ids,
	            idx_t count, idx_t vector_index, idx_t vector_offset, UpdateInfo *node) override;

	void FetchBaseData(ColumnScanState &state, idx_t vector_index, Vector &result) override;
	void FetchUpdateData(ColumnScanState &state, Transaction &transaction, UpdateInfo *versions,
	                     Vector &result) override;

public:
	typedef void (*append_function_t)(SegmentStatistics &stats, data_ptr_t target, idx_t target_offset, Vector &source,
	                                  idx_t offset, idx_t count);
	typedef void (*update_function_t)(SegmentStatistics &stats, UpdateInfo *info, data_ptr_t base_data, Vector &update);
	typedef void (*update_info_fetch_function_t)(Transaction &transaction, UpdateInfo *info, Vector &result);
	typedef void (*update_info_append_function_t)(Transaction &transaction, UpdateInfo *info, idx_t idx, Vector &result,
	                                              idx_t result_idx);
	typedef void (*rollback_update_function_t)(UpdateInfo *info, data_ptr_t base_data);
	typedef void (*merge_update_function_t)(SegmentStatistics &stats, UpdateInfo *node, data_ptr_t target,
	                                        Vector &update, row_t *ids, idx_t count, idx_t vector_offset);

private:
	append_function_t append_function;
	update_function_t update_function;
	update_info_fetch_function_t fetch_from_update_info;
	update_info_append_function_t append_from_update_info;
	rollback_update_function_t rollback_update;
	merge_update_function_t merge_update_function;
};

template <class F1, class F2, class F3>
static idx_t merge_loop(row_t a[], sel_t b[], idx_t acount, idx_t bcount, idx_t aoffset, F1 merge, F2 pick_a,
                        F3 pick_b) {
	idx_t aidx = 0, bidx = 0;
	idx_t count = 0;
	while (aidx < acount && bidx < bcount) {
		auto a_id = a[aidx] - aoffset;
		auto b_id = b[bidx];
		if (a_id == b_id) {
			merge(a_id, aidx, bidx, count);
			aidx++;
			bidx++;
			count++;
		} else if (a_id < b_id) {
			pick_a(a_id, aidx, count);
			aidx++;
			count++;
		} else {
			pick_b(b_id, bidx, count);
			bidx++;
			count++;
		}
	}
	for (; aidx < acount; aidx++) {
		pick_a(a[aidx] - aoffset, aidx, count);
		count++;
	}
	for (; bidx < bcount; bidx++) {
		pick_b(b[bidx], bidx, count);
		count++;
	}
	return count;
}

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/string_segment.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class OverflowStringWriter {
public:
	virtual ~OverflowStringWriter() {
	}

	virtual void WriteString(string_t string, block_id_t &result_block, int32_t &result_offset) = 0;
};

struct StringBlock {
	block_id_t block_id;
	idx_t offset;
	idx_t size;
	unique_ptr<StringBlock> next;
};

struct string_location_t {
	string_location_t(block_id_t block_id, int32_t offset) : block_id(block_id), offset(offset) {
	}
	string_location_t() {
	}
	bool IsValid() {
		return offset < Storage::BLOCK_SIZE && (block_id == INVALID_BLOCK || block_id >= MAXIMUM_BLOCK);
	}
	block_id_t block_id;
	int32_t offset;
};

struct StringUpdateInfo {
	sel_t count;
	sel_t ids[STANDARD_VECTOR_SIZE];
	block_id_t block_ids[STANDARD_VECTOR_SIZE];
	int32_t offsets[STANDARD_VECTOR_SIZE];
};

typedef unique_ptr<StringUpdateInfo> string_update_info_t;

class StringSegment : public UncompressedSegment {
public:
	StringSegment(BufferManager &manager, idx_t row_start, block_id_t block_id = INVALID_BLOCK);
	~StringSegment() override;

	//! The current dictionary offset
	idx_t dictionary_offset;
	//! The string block holding strings that do not fit in the main block
	//! FIXME: this should be replaced by a heap that also allows freeing of unused strings
	unique_ptr<StringBlock> head;
	//! Blocks that hold string updates (if any)
	unique_ptr<string_update_info_t[]> string_updates;
	//! Overflow string writer (if any), if not set overflow strings will be written to memory blocks
	unique_ptr<OverflowStringWriter> overflow_writer;

public:
	void InitializeScan(ColumnScanState &state) override;

	//! Fetch a single value and append it to the vector
	void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
	              idx_t result_idx) override;

	//! Append a part of a vector to the uncompressed segment with the given append state, updating the provided stats
	//! in the process. Returns the amount of tuples appended. If this is less than `count`, the uncompressed segment is
	//! full.
	idx_t Append(SegmentStatistics &stats, Vector &data, idx_t offset, idx_t count) override;

	//! Rollback a previous update
	void RollbackUpdate(UpdateInfo *info) override;

protected:
	void Update(ColumnData &column_data, SegmentStatistics &stats, Transaction &transaction, Vector &update, row_t *ids,
	            idx_t count, idx_t vector_index, idx_t vector_offset, UpdateInfo *node) override;

	void FetchBaseData(ColumnScanState &state, idx_t vector_index, Vector &result) override;
	void FetchUpdateData(ColumnScanState &state, Transaction &transaction, UpdateInfo *versions,
	                     Vector &result) override;

private:
	void AppendData(SegmentStatistics &stats, data_ptr_t target, data_ptr_t end, idx_t target_offset, Vector &source,
	                idx_t offset, idx_t count);

	//! Fetch all the strings of a vector from the base table and place their locations in the result vector
	void FetchBaseData(ColumnScanState &state, data_ptr_t base_data, idx_t vector_index, Vector &result, idx_t count);

	string_location_t FetchStringLocation(data_ptr_t baseptr, int32_t dict_offset);
	string_t FetchString(buffer_handle_set_t &handles, data_ptr_t baseptr, string_location_t location);
	//! Fetch a single string from the dictionary and returns it, potentially pins a buffer manager page and adds it to
	//! the set of pinned pages
	string_t FetchStringFromDict(buffer_handle_set_t &handles, data_ptr_t baseptr, int32_t dict_offset);

	//! Fetch string locations for a subset of the strings
	void FetchStringLocations(data_ptr_t baseptr, row_t *ids, idx_t vector_index, idx_t vector_offset, idx_t count,
	                          string_location_t result[]);

	void WriteString(string_t string, block_id_t &result_block, int32_t &result_offset);
	string_t ReadString(buffer_handle_set_t &handles, block_id_t block, int32_t offset);
	string_t ReadString(data_ptr_t target, int32_t offset);

	void WriteStringMemory(string_t string, block_id_t &result_block, int32_t &result_offset);

	void WriteStringMarker(data_ptr_t target, block_id_t block_id, int32_t offset);
	void ReadStringMarker(data_ptr_t target, block_id_t &block_id, int32_t &offset);

	//! Expand the string segment, adding an additional maximum vector to the segment
	void ExpandStringSegment(data_ptr_t baseptr);

	string_update_info_t CreateStringUpdate(SegmentStatistics &stats, Vector &update, row_t *ids, idx_t count,
	                                        idx_t vector_offset);
	string_update_info_t MergeStringUpdate(SegmentStatistics &stats, Vector &update, row_t *ids, idx_t count,
	                                       idx_t vector_offset, StringUpdateInfo &update_info);

	void MergeUpdateInfo(UpdateInfo *node, row_t *ids, idx_t update_count, idx_t vector_offset,
	                     string_location_t string_locations[], nullmask_t original_nullmask);

	//! The amount of bytes remaining to store in the block
	idx_t RemainingSpace() {
		return Storage::BLOCK_SIZE - dictionary_offset - max_vector_count * vector_size;
	}

private:
	//! The max string size that is allowed within a block. Strings bigger than this will be labeled as a BIG STRING and
	//! offloaded to the overflow blocks.
	static constexpr uint16_t STRING_BLOCK_LIMIT = 4096;
	//! Marker used in length field to indicate the presence of a big string
	static constexpr uint16_t BIG_STRING_MARKER = (uint16_t)-1;
	//! Base size of big string marker (block id + offset)
	static constexpr idx_t BIG_STRING_MARKER_BASE_SIZE = sizeof(block_id_t) + sizeof(int32_t);
	//! The marker size of the big string
	static constexpr idx_t BIG_STRING_MARKER_SIZE = BIG_STRING_MARKER_BASE_SIZE + sizeof(uint16_t);
};

} // namespace duckdb



using namespace duckdb;
using namespace std;

class WriteOverflowStringsToDisk : public OverflowStringWriter {
public:
	WriteOverflowStringsToDisk(CheckpointManager &manager);
	~WriteOverflowStringsToDisk();

	//! The checkpoint manager
	CheckpointManager &manager;
	//! Block handle use for writing to
	unique_ptr<BufferHandle> handle;
	//! The current block we are writing to
	block_id_t block_id;
	//! The offset within the current block
	idx_t offset;

	static constexpr idx_t STRING_SPACE = Storage::BLOCK_SIZE - sizeof(block_id_t);

public:
	void WriteString(string_t string, block_id_t &result_block, int32_t &result_offset) override;

private:
	void AllocateNewBlock(block_id_t new_block_id);
};

TableDataWriter::TableDataWriter(CheckpointManager &manager, TableCatalogEntry &table)
    : manager(manager), table(table) {
}

TableDataWriter::~TableDataWriter() {
}

void TableDataWriter::WriteTableData(Transaction &transaction) {
	// allocate segments to write the table to
	segments.resize(table.columns.size());
	data_pointers.resize(table.columns.size());
	for (idx_t i = 0; i < table.columns.size(); i++) {
		auto type_id = GetInternalType(table.columns[i].type);
		stats.push_back(make_unique<SegmentStatistics>(type_id, GetTypeIdSize(type_id)));
		CreateSegment(i);
	}

	// now start scanning the table and append the data to the uncompressed segments
	vector<column_t> column_ids;
	for (auto &column : table.columns) {
		column_ids.push_back(column.oid);
	}
	// initialize scan structures to prepare for the scan
	TableScanState state;
	table.storage->InitializeScan(transaction, state, column_ids);
	//! get all types of the table and initialize the chunk
	auto types = table.GetTypes();
	DataChunk chunk;
	chunk.Initialize(types);

	while (true) {
		chunk.Reset();
		// now scan the table to construct the blocks
		vector<TableFilter> mock;
		table.storage->Scan(transaction, chunk, state, mock);
		if (chunk.size() == 0) {
			break;
		}
		// for each column, we append whatever we can fit into the block
		for (idx_t i = 0; i < table.columns.size(); i++) {
			assert(chunk.data[i].type == GetInternalType(table.columns[i].type));
			AppendData(i, chunk.data[i], chunk.size());
		}
	}
	// flush any remaining data and write the data pointers to disk
	for (idx_t i = 0; i < table.columns.size(); i++) {
		FlushSegment(i);
	}
	WriteDataPointers();
}

void TableDataWriter::CreateSegment(idx_t col_idx) {
	auto type_id = GetInternalType(table.columns[col_idx].type);
	if (type_id == TypeId::VARCHAR) {
		auto string_segment = make_unique<StringSegment>(manager.buffer_manager, 0);
		string_segment->overflow_writer = make_unique<WriteOverflowStringsToDisk>(manager);
		segments[col_idx] = move(string_segment);
	} else {
		segments[col_idx] = make_unique<NumericSegment>(manager.buffer_manager, type_id, 0);
	}
}

void TableDataWriter::AppendData(idx_t col_idx, Vector &data, idx_t count) {
	idx_t offset = 0;
	while (offset < count) {
		idx_t appended = segments[col_idx]->Append(*stats[col_idx], data, offset, count);
		if (appended == count) {
			// appended everything: finished
			return;
		}
		// the segment is full: flush it to disk
		FlushSegment(col_idx);

		// now create a new segment and continue appending
		CreateSegment(col_idx);
		offset += appended;
		count -= appended;
	}
}

void TableDataWriter::FlushSegment(idx_t col_idx) {
	auto tuple_count = segments[col_idx]->tuple_count;
	if (tuple_count == 0) {
		return;
	}

	// get the buffer of the segment and pin it
	auto handle = manager.buffer_manager.Pin(segments[col_idx]->block_id);

	// get a free block id to write to
	auto block_id = manager.block_manager.GetFreeBlockId();

	// construct the data pointer, FIXME: add statistics as well
	DataPointer data_pointer;
	data_pointer.block_id = block_id;
	data_pointer.offset = 0;
	data_pointer.row_start = 0;
	if (data_pointers[col_idx].size() > 0) {
		auto &last_pointer = data_pointers[col_idx].back();
		data_pointer.row_start = last_pointer.row_start + last_pointer.tuple_count;
	}
	data_pointer.tuple_count = tuple_count;
	//! FIXME: Can't deal with strings yet
	idx_t type_size = stats[col_idx]->type == TypeId::VARCHAR ? 0 : stats[col_idx]->type_size;
	memcpy(&data_pointer.min_stats, stats[col_idx]->minimum.get(), type_size);
	memcpy(&data_pointer.max_stats, stats[col_idx]->maximum.get(), type_size);
	data_pointers[col_idx].push_back(move(data_pointer));
	// write the block to disk
	manager.block_manager.Write(*handle->node, block_id);
}

void TableDataWriter::WriteDataPointers() {
	for (idx_t i = 0; i < data_pointers.size(); i++) {
		// get a reference to the data column
		auto &data_pointer_list = data_pointers[i];
		manager.tabledata_writer->Write<idx_t>(data_pointer_list.size());
		// then write the data pointers themselves
		for (idx_t k = 0; k < data_pointer_list.size(); k++) {
			auto &data_pointer = data_pointer_list[k];
			manager.tabledata_writer->Write<double>(data_pointer.min);
			manager.tabledata_writer->Write<double>(data_pointer.max);
			manager.tabledata_writer->Write<idx_t>(data_pointer.row_start);
			manager.tabledata_writer->Write<idx_t>(data_pointer.tuple_count);
			manager.tabledata_writer->Write<block_id_t>(data_pointer.block_id);
			manager.tabledata_writer->Write<uint32_t>(data_pointer.offset);
			manager.tabledata_writer->WriteData(data_pointer.min_stats, 8);
			manager.tabledata_writer->WriteData(data_pointer.max_stats, 8);
		}
	}
}

WriteOverflowStringsToDisk::WriteOverflowStringsToDisk(CheckpointManager &manager)
    : manager(manager), handle(nullptr), block_id(INVALID_BLOCK), offset(0) {
}

WriteOverflowStringsToDisk::~WriteOverflowStringsToDisk() {
	if (offset > 0) {
		manager.block_manager.Write(*handle->node, block_id);
	}
}

void WriteOverflowStringsToDisk::WriteString(string_t string, block_id_t &result_block, int32_t &result_offset) {
	if (!handle) {
		handle = manager.buffer_manager.Allocate(Storage::BLOCK_ALLOC_SIZE);
	}
	// first write the length of the string
	if (block_id == INVALID_BLOCK || offset + sizeof(uint32_t) >= STRING_SPACE) {
		AllocateNewBlock(manager.block_manager.GetFreeBlockId());
	}
	result_block = block_id;
	result_offset = offset;

	// write the length field
	auto string_length = string.GetSize();
	*((uint32_t *)(handle->node->buffer + offset)) = string_length;
	offset += sizeof(uint32_t);
	// now write the remainder of the string
	auto strptr = string.GetData();
	uint32_t remaining = string_length + 1;
	while (remaining > 0) {
		uint32_t to_write = std::min((uint32_t)remaining, (uint32_t)(STRING_SPACE - offset));
		if (to_write > 0) {
			memcpy(handle->node->buffer + offset, strptr, to_write);

			remaining -= to_write;
			offset += to_write;
			strptr += to_write;
		}
		if (remaining > 0) {
			// there is still remaining stuff to write
			// first get the new block id and write it to the end of the previous block
			auto new_block_id = manager.block_manager.GetFreeBlockId();
			*((block_id_t *)(handle->node->buffer + offset)) = new_block_id;
			// now write the current block to disk and allocate a new block
			AllocateNewBlock(new_block_id);
		}
	}
}

void WriteOverflowStringsToDisk::AllocateNewBlock(block_id_t new_block_id) {
	if (block_id != INVALID_BLOCK) {
		// there is an old block, write it first
		manager.block_manager.Write(*handle->node, block_id);
	}
	offset = 0;
	block_id = new_block_id;
}





























using namespace duckdb;
using namespace std;

// constexpr uint64_t CheckpointManager::DATA_BLOCK_HEADER_SIZE;

CheckpointManager::CheckpointManager(StorageManager &manager)
    : block_manager(*manager.block_manager), buffer_manager(*manager.buffer_manager), database(manager.database) {
}

void CheckpointManager::CreateCheckpoint() {
	// assert that the checkpoint manager hasn't been used before
	assert(!metadata_writer);

	auto transaction = database.transaction_manager->StartTransaction();

	//! Set up the writers for the checkpoints
	metadata_writer = make_unique<MetaBlockWriter>(block_manager);
	tabledata_writer = make_unique<MetaBlockWriter>(block_manager);

	// get the id of the first meta block
	block_id_t meta_block = metadata_writer->block->id;

	vector<SchemaCatalogEntry *> schemas;
	// we scan the schemas
	database.catalog->schemas.Scan(*transaction,
	                               [&](CatalogEntry *entry) { schemas.push_back((SchemaCatalogEntry *)entry); });
	// write the actual data into the database
	// write the amount of schemas
	metadata_writer->Write<uint32_t>(schemas.size());
	for (auto &schema : schemas) {
		WriteSchema(*transaction, *schema);
	}
	// flush the meta data to disk
	metadata_writer->Flush();
	tabledata_writer->Flush();

	// finally write the updated header
	DatabaseHeader header;
	header.meta_block = meta_block;
	block_manager.WriteHeader(header);
}

void CheckpointManager::LoadFromStorage() {
	block_id_t meta_block = block_manager.GetMetaBlock();
	if (meta_block < 0) {
		// storage is empty
		return;
	}

	ClientContext context(database);
	context.transaction.BeginTransaction();
	// create the MetaBlockReader to read from the storage
	MetaBlockReader reader(buffer_manager, meta_block);
	uint32_t schema_count = reader.Read<uint32_t>();
	for (uint32_t i = 0; i < schema_count; i++) {
		ReadSchema(context, reader);
	}
	context.transaction.Commit();
}

//===--------------------------------------------------------------------===//
// Schema
//===--------------------------------------------------------------------===//
void CheckpointManager::WriteSchema(Transaction &transaction, SchemaCatalogEntry &schema) {
	// write the schema data
	schema.Serialize(*metadata_writer);
	// then, we fetch the tables/views/sequences information
	vector<TableCatalogEntry *> tables;
	vector<ViewCatalogEntry *> views;
	schema.tables.Scan(transaction, [&](CatalogEntry *entry) {
		if (entry->type == CatalogType::TABLE) {
			tables.push_back((TableCatalogEntry *)entry);
		} else if (entry->type == CatalogType::VIEW) {
			views.push_back((ViewCatalogEntry *)entry);
		} else {
			throw NotImplementedException("Catalog type for entries");
		}
	});
	vector<SequenceCatalogEntry *> sequences;
	schema.sequences.Scan(transaction,
	                      [&](CatalogEntry *entry) { sequences.push_back((SequenceCatalogEntry *)entry); });

	// write the sequences
	metadata_writer->Write<uint32_t>(sequences.size());
	for (auto &seq : sequences) {
		WriteSequence(*seq);
	}
	// now write the tables
	metadata_writer->Write<uint32_t>(tables.size());
	for (auto &table : tables) {
		WriteTable(transaction, *table);
	}
	// finally write the views
	metadata_writer->Write<uint32_t>(views.size());
	for (auto &view : views) {
		WriteView(*view);
	}
}

void CheckpointManager::ReadSchema(ClientContext &context, MetaBlockReader &reader) {
	// read the schema and create it in the catalog
	auto info = SchemaCatalogEntry::Deserialize(reader);
	// we set create conflict to ignore to ignore the failure of recreating the main schema
	info->on_conflict = OnCreateConflict::IGNORE;
	database.catalog->CreateSchema(context, info.get());

	// read the sequences
	uint32_t seq_count = reader.Read<uint32_t>();
	for (uint32_t i = 0; i < seq_count; i++) {
		ReadSequence(context, reader);
	}
	// read the table count and recreate the tables
	uint32_t table_count = reader.Read<uint32_t>();
	for (uint32_t i = 0; i < table_count; i++) {
		ReadTable(context, reader);
	}
	// finally read the views
	uint32_t view_count = reader.Read<uint32_t>();
	for (uint32_t i = 0; i < view_count; i++) {
		ReadView(context, reader);
	}
}

//===--------------------------------------------------------------------===//
// Views
//===--------------------------------------------------------------------===//
void CheckpointManager::WriteView(ViewCatalogEntry &view) {
	view.Serialize(*metadata_writer);
}

void CheckpointManager::ReadView(ClientContext &context, MetaBlockReader &reader) {
	auto info = ViewCatalogEntry::Deserialize(reader);

	database.catalog->CreateView(context, info.get());
}

//===--------------------------------------------------------------------===//
// Sequences
//===--------------------------------------------------------------------===//
void CheckpointManager::WriteSequence(SequenceCatalogEntry &seq) {
	seq.Serialize(*metadata_writer);
}

void CheckpointManager::ReadSequence(ClientContext &context, MetaBlockReader &reader) {
	auto info = SequenceCatalogEntry::Deserialize(reader);

	database.catalog->CreateSequence(context, info.get());
}

//===--------------------------------------------------------------------===//
// Table Metadata
//===--------------------------------------------------------------------===//
void CheckpointManager::WriteTable(Transaction &transaction, TableCatalogEntry &table) {
	// write the table meta data
	table.Serialize(*metadata_writer);
	//! write the blockId for the table info
	metadata_writer->Write<block_id_t>(tabledata_writer->block->id);
	//! and the offset to where the info starts
	metadata_writer->Write<uint64_t>(tabledata_writer->offset);
	// now we need to write the table data
	TableDataWriter writer(*this, table);
	writer.WriteTableData(transaction);
}

void CheckpointManager::ReadTable(ClientContext &context, MetaBlockReader &reader) {
	// deserialize the table meta data
	auto info = TableCatalogEntry::Deserialize(reader);
	// bind the info
	Binder binder(context);
	auto bound_info = unique_ptr_cast<BoundCreateInfo, BoundCreateTableInfo>(binder.BindCreateInfo(move(info)));

	// now read the actual table data and place it into the create table info
	auto block_id = reader.Read<block_id_t>();
	auto offset = reader.Read<uint64_t>();
	MetaBlockReader table_data_reader(buffer_manager, block_id);
	table_data_reader.offset = offset;
	TableDataReader data_reader(*this, table_data_reader, *bound_info);
	data_reader.ReadTableData();

	// finally create the table in the catalog
	database.catalog->CreateTable(context, bound_info.get());
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/table/transient_segment.hpp
//
//
//===----------------------------------------------------------------------===//








namespace duckdb {
struct ColumnAppendState;

class TransientSegment : public ColumnSegment {
public:
	TransientSegment(BufferManager &manager, TypeId type, idx_t start);

	//! The buffer manager
	BufferManager &manager;
	//! The uncompressed segment holding the data
	unique_ptr<UncompressedSegment> data;

public:
	void InitializeScan(ColumnScanState &state) override;
	//! Scan one vector from this transient segment
	void Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result) override;
	//! Scan one vector from this transient segment, throwing an exception if there are any outstanding updates
	void IndexScan(ColumnScanState &state, Vector &result) override;

	//! Fetch the base table vector index that belongs to this row
	void Fetch(ColumnScanState &state, idx_t vector_index, Vector &result) override;
	//! Fetch a value of the specific row id and append it to the result
	void FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
	              idx_t result_idx) override;

	//! Perform an update within the transient segment
	void Update(ColumnData &column_data, Transaction &transaction, Vector &updates, row_t *ids, idx_t count) override;

	//! Initialize an append of this transient segment
	void InitializeAppend(ColumnAppendState &state);
	//! Appends a (part of) vector to the transient segment, returns the amount of entries successfully appended
	idx_t Append(ColumnAppendState &state, Vector &data, idx_t offset, idx_t count);
	//! Revert an append made to this transient segment
	void RevertAppend(idx_t start_row);
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

ColumnData::ColumnData() : persistent_rows(0) {
}

void ColumnData::Initialize(vector<unique_ptr<PersistentSegment>> &segments) {
	for (auto &segment : segments) {
		persistent_rows += segment->count;
		data.AppendSegment(move(segment));
	}
}

void ColumnData::InitializeScan(ColumnScanState &state) {
	state.current = (ColumnSegment *)data.GetRootSegment();
	state.vector_index = 0;
	state.initialized = false;
}

void ColumnData::Scan(Transaction &transaction, ColumnScanState &state, Vector &result) {
	if (!state.initialized) {
		state.current->InitializeScan(state);
		state.initialized = true;
	}
	// perform a scan of this segment
	state.current->Scan(transaction, state, state.vector_index, result);
	// move over to the next vector
	state.Next();
}

void ColumnData::IndexScan(ColumnScanState &state, Vector &result) {
	if (state.vector_index == 0) {
		state.current->InitializeScan(state);
	}
	// perform a scan of this segment
	state.current->IndexScan(state, result);
	// move over to the next vector
	state.Next();
}

void ColumnScanState::Next() {
    //! There is no column segment
    if(!current){
        return;
    }
	vector_index++;
	if (vector_index * STANDARD_VECTOR_SIZE >= current->count) {
		current = (ColumnSegment *)current->next.get();
		vector_index = 0;
		initialized = false;
	}
}

void TableScanState::NextVector() {
	//! nothing to scan for this vector, skip the entire vector
	for (idx_t j = 0; j < column_ids.size(); j++) {
		auto column = column_ids[j];
		if (column != COLUMN_IDENTIFIER_ROW_ID) {
			column_scans[j].Next();
		}
	}
}

void ColumnData::InitializeAppend(ColumnAppendState &state) {
	lock_guard<mutex> tree_lock(data.node_lock);
	if (data.nodes.size() == 0) {
		// no transient segments yet, append one
		AppendTransientSegment(persistent_rows);
	}
	auto segment = (ColumnSegment *)data.GetLastSegment();
	if (segment->segment_type == ColumnSegmentType::PERSISTENT) {
		// cannot append to persistent segment, add a transient one
		AppendTransientSegment(persistent_rows);
		state.current = (TransientSegment *)data.GetLastSegment();
	} else {
		state.current = (TransientSegment *)segment;
	}
	assert(state.current->segment_type == ColumnSegmentType::TRANSIENT);
	state.current->InitializeAppend(state);
}

void ColumnData::Append(ColumnAppendState &state, Vector &vector, idx_t count) {
	idx_t offset = 0;
	while (true) {
		// append the data from the vector
		idx_t copied_elements = state.current->Append(state, vector, offset, count);
		if (copied_elements == count) {
			// finished copying everything
			break;
		}

		// we couldn't fit everything we wanted in the current column segment, create a new one
		{
			lock_guard<mutex> tree_lock(data.node_lock);
			AppendTransientSegment(state.current->start + state.current->count);
			state.current = (TransientSegment *)data.GetLastSegment();
			state.current->InitializeAppend(state);
		}
		offset += copied_elements;
		count -= copied_elements;
	}
}

void ColumnData::RevertAppend(row_t start_row) {
	lock_guard<mutex> tree_lock(data.node_lock);
	// find the segment index that the current row belongs to
	idx_t segment_index = data.GetSegmentIndex(start_row);
	auto segment = data.nodes[segment_index].node;
	auto &transient = (TransientSegment &)*segment;
	assert(transient.segment_type == ColumnSegmentType::TRANSIENT);

	// remove any segments AFTER this segment: they should be deleted entirely
	if (segment_index < data.nodes.size() - 1) {
		data.nodes.erase(data.nodes.begin() + segment_index + 1, data.nodes.end());
	}
	segment->next = nullptr;
	transient.RevertAppend(start_row);
}

void ColumnData::Update(Transaction &transaction, Vector &updates, Vector &row_ids, idx_t count) {
	// first find the segment that the update belongs to
	idx_t first_id = FlatVector::GetValue<row_t>(row_ids, 0);
	auto segment = (ColumnSegment *)data.GetSegment(first_id);
	// now perform the update within the segment
	segment->Update(*this, transaction, updates, FlatVector::GetData<row_t>(row_ids), count);
}

void ColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &result) {
	// find the segment that the row belongs to
	auto segment = (ColumnSegment *)data.GetSegment(row_id);
	auto vector_index = (row_id - segment->start) / STANDARD_VECTOR_SIZE;
	// now perform the fetch within the segment
	segment->Fetch(state, vector_index, result);
}

void ColumnData::FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
                          idx_t result_idx) {
	// find the segment the row belongs to
	auto segment = (TransientSegment *)data.GetSegment(row_id);
	// now perform the fetch within the segment
	segment->FetchRow(state, transaction, row_id, result, result_idx);
}

void ColumnData::AppendTransientSegment(idx_t start_row) {
	auto new_segment = make_unique<TransientSegment>(*table->storage.buffer_manager, type, start_row);
	data.AppendSegment(move(new_segment));
}












using namespace duckdb;
using namespace std;

DataTable::DataTable(StorageManager &storage, string schema, string table, vector<TypeId> types_,
                     unique_ptr<vector<unique_ptr<PersistentSegment>>[]> data)
    : cardinality(0), schema(schema), table(table), types(types_), storage(storage), persistent_manager(*this),
      transient_manager(*this) {
	// set up the segment trees for the column segments
	columns = unique_ptr<ColumnData[]>(new ColumnData[types.size()]);
	for (idx_t i = 0; i < types.size(); i++) {
		columns[i].type = types[i];
		columns[i].table = this;
		columns[i].column_idx = i;
	}

	// initialize the table with the existing data from disk, if any
	if (data && data[0].size() > 0) {
		// first append all the segments to the set of column segments
		for (idx_t i = 0; i < types.size(); i++) {
			columns[i].Initialize(data[i]);
			if (columns[i].persistent_rows != columns[0].persistent_rows) {
				throw Exception("Column length mismatch in table load!");
			}
		}
		persistent_manager.max_row = columns[0].persistent_rows;
		transient_manager.base_row = persistent_manager.max_row;
	}
}

//===--------------------------------------------------------------------===//
// Scan
//===--------------------------------------------------------------------===//
void DataTable::InitializeScan(TableScanState &state, vector<column_t> column_ids) {
	// initialize a column scan state for each column
	state.column_scans = unique_ptr<ColumnScanState[]>(new ColumnScanState[column_ids.size()]);
	for (idx_t i = 0; i < column_ids.size(); i++) {
		auto column = column_ids[i];
		if (column != COLUMN_IDENTIFIER_ROW_ID) {
			columns[column].InitializeScan(state.column_scans[i]);
		}
	}
	state.column_ids = move(column_ids);
	// initialize the chunk scan state
	state.offset = 0;
	state.current_persistent_row = 0;
	state.max_persistent_row = persistent_manager.max_row;
	state.current_transient_row = 0;
	state.max_transient_row = transient_manager.max_row;
}

void DataTable::InitializeScan(Transaction &transaction, TableScanState &state, vector<column_t> column_ids) {
	InitializeScan(state, move(column_ids));
	transaction.storage.InitializeScan(this, state.local_state);
}

void DataTable::Scan(Transaction &transaction, DataChunk &result, TableScanState &state,
                     vector<TableFilter> &table_filters) {
	// scan the persistent segments
	while (ScanBaseTable(transaction, result, state, state.current_persistent_row, state.max_persistent_row, 0,
	                     persistent_manager, table_filters)) {
		if (result.size() > 0) {
			return;
		}
	}
	// scan the transient segments
	while (ScanBaseTable(transaction, result, state, state.current_transient_row, state.max_transient_row,
	                     persistent_manager.max_row, transient_manager, table_filters)) {
		if (result.size() > 0) {
			return;
		}
	}

	// scan the transaction-local segments
	transaction.storage.Scan(state.local_state, state.column_ids, result);
}

template <class T> bool checkZonemap(TableScanState &state, TableFilter &table_filter, T constant) {
	T *min = (T *)state.column_scans[table_filter.column_index].current->stats.minimum.get();
	T *max = (T *)state.column_scans[table_filter.column_index].current->stats.maximum.get();
	switch (table_filter.comparison_type) {
	case ExpressionType::COMPARE_EQUAL:
		return constant >= *min && constant <= *max;
	case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
		return constant <= *max;
	case ExpressionType::COMPARE_GREATERTHAN:
		return constant < *max;
	case ExpressionType::COMPARE_LESSTHANOREQUALTO:
		return constant >= *min;
	case ExpressionType::COMPARE_LESSTHAN:
		return constant > *min;
	default:
		throw NotImplementedException("Operation not implemented");
	}
}

bool DataTable::CheckZonemap(TableScanState &state, vector<TableFilter> &table_filters, idx_t &current_row) {
	bool readSegment = true;
	for (auto &table_filter : table_filters) {
		switch (state.column_scans[table_filter.column_index].current->type) {
		case TypeId::INT8: {
			int8_t constant = table_filter.constant.value_.tinyint;
			readSegment &= checkZonemap<int8_t>(state, table_filter, constant);
			break;
		}
		case TypeId::INT16: {
			int16_t constant = table_filter.constant.value_.smallint;
			readSegment &= checkZonemap<int16_t>(state, table_filter, constant);
			break;
		}
		case TypeId::INT32: {
			int32_t constant = table_filter.constant.value_.integer;
			readSegment &= checkZonemap<int32_t>(state, table_filter, constant);
			break;
		}
		case TypeId::INT64: {
			int64_t constant = table_filter.constant.value_.bigint;
			readSegment &= checkZonemap<int64_t>(state, table_filter, constant);
			break;
		}
		case TypeId::FLOAT: {
			float constant = table_filter.constant.value_.float_;
			readSegment &= checkZonemap<float>(state, table_filter, constant);
			break;
		}
		case TypeId::DOUBLE: {
			double constant = table_filter.constant.value_.double_;
			readSegment &= checkZonemap<double>(state, table_filter, constant);
			break;
		}
		default:
			throw NotImplementedException("Unimplemented type for uncompressed segment");
		}
		if (!readSegment) {
			//! We can skip this partition
			idx_t vectorsToSkip =
			    ceil((double)(state.column_scans[table_filter.column_index].current->count +
			                  state.column_scans[table_filter.column_index].current->start - current_row) /
			         STANDARD_VECTOR_SIZE);
			for (idx_t i = 0; i < vectorsToSkip; ++i) {
				state.NextVector();
				current_row += STANDARD_VECTOR_SIZE;
			}
			return false;
		}
	}
	return true;
}

bool DataTable::ScanBaseTable(Transaction &transaction, DataChunk &result, TableScanState &state, idx_t &current_row,
                              idx_t max_row, idx_t base_row, VersionManager &manager,
                              vector<TableFilter> &table_filters) {
	if (current_row >= max_row) {
		// exceeded the amount of rows to scan
		return false;
	}
	idx_t max_count = std::min((idx_t)STANDARD_VECTOR_SIZE, max_row - current_row);
	idx_t vector_offset = current_row / STANDARD_VECTOR_SIZE;
	//! first check the zonemap if we have to scan this partition
	if (!CheckZonemap(state, table_filters, current_row)) {
		return true;
	}
	// second, scan the version chunk manager to figure out which tuples to load for this transaction
	SelectionVector valid_sel(STANDARD_VECTOR_SIZE);
	idx_t count = manager.GetSelVector(transaction, vector_offset, valid_sel, max_count);
	if (count == 0) {
		// nothing to scan for this vector, skip the entire vector
		state.NextVector();
		current_row += STANDARD_VECTOR_SIZE;
		return true;
	}

	for (idx_t i = 0; i < state.column_ids.size(); i++) {
		auto column = state.column_ids[i];
		if (column == COLUMN_IDENTIFIER_ROW_ID) {
			// scan row id
			assert(result.data[i].type == ROW_TYPE);
			result.data[i].Sequence(base_row + current_row, 1);
		} else {
			// scan actual base column
			columns[column].Scan(transaction, state.column_scans[i], result.data[i]);
		}
	}
	if (count == max_count) {
		// no deleted tuples
		result.SetCardinality(count);
	} else {
		// deleted tuples
		result.Slice(valid_sel, count);
	}

	current_row += STANDARD_VECTOR_SIZE;
	return true;
}

//===--------------------------------------------------------------------===//
// Index Scan
//===--------------------------------------------------------------------===//
void DataTable::InitializeIndexScan(Transaction &transaction, TableIndexScanState &state, Index &index,
                                    vector<column_t> column_ids) {
	state.index = &index;
	state.column_ids = move(column_ids);
	transaction.storage.InitializeScan(this, state.local_state);
}

void DataTable::InitializeIndexScan(Transaction &transaction, TableIndexScanState &state, Index &index, Value value,
                                    ExpressionType expr_type, vector<column_t> column_ids) {
	InitializeIndexScan(transaction, state, index, move(column_ids));
	state.index_state = index.InitializeScanSinglePredicate(transaction, state.column_ids, value, expr_type);
}

void DataTable::InitializeIndexScan(Transaction &transaction, TableIndexScanState &state, Index &index, Value low_value,
                                    ExpressionType low_type, Value high_value, ExpressionType high_type,
                                    vector<column_t> column_ids) {
	InitializeIndexScan(transaction, state, index, move(column_ids));
	state.index_state =
	    index.InitializeScanTwoPredicates(transaction, state.column_ids, low_value, low_type, high_value, high_type);
}

void DataTable::IndexScan(Transaction &transaction, DataChunk &result, TableIndexScanState &state) {
	// clear any previously pinned blocks
	state.fetch_state.handles.clear();
	// scan the index
	state.index->Scan(transaction, state, result);
	if (result.size() > 0) {
		return;
	}
	// scan the local structure
	transaction.storage.Scan(state.local_state, state.column_ids, result);
}

//===--------------------------------------------------------------------===//
// Fetch
//===--------------------------------------------------------------------===//
void DataTable::Fetch(Transaction &transaction, DataChunk &result, vector<column_t> &column_ids,
                      Vector &row_identifiers, idx_t fetch_count, TableIndexScanState &state) {
	// first figure out which row identifiers we should use for this transaction by looking at the VersionManagers
	row_t rows[STANDARD_VECTOR_SIZE];
	idx_t count = FetchRows(transaction, row_identifiers, fetch_count, rows);

	if (count == 0) {
		// no rows to use
		return;
	}
	// for each of the remaining rows, now fetch the data
	result.SetCardinality(count);
	for (idx_t col_idx = 0; col_idx < column_ids.size(); col_idx++) {
		auto column = column_ids[col_idx];
		if (column == COLUMN_IDENTIFIER_ROW_ID) {
			// row id column: fill in the row ids
			assert(result.data[col_idx].type == TypeId::INT64);
			result.data[col_idx].vector_type = VectorType::FLAT_VECTOR;
			auto data = FlatVector::GetData<row_t>(result.data[col_idx]);
			for (idx_t i = 0; i < count; i++) {
				data[i] = rows[i];
			}
		} else {
			// regular column: fetch data from the base column
			for (idx_t i = 0; i < count; i++) {
				auto row_id = rows[i];
				columns[column].FetchRow(state.fetch_state, transaction, row_id, result.data[col_idx], i);
			}
		}
	}
}

idx_t DataTable::FetchRows(Transaction &transaction, Vector &row_identifiers, idx_t fetch_count, row_t result_rows[]) {
	assert(row_identifiers.type == ROW_TYPE);

	// obtain a read lock on the version managers
	auto l1 = persistent_manager.lock.GetSharedLock();
	auto l2 = transient_manager.lock.GetSharedLock();

	// now iterate over the row ids and figure out which rows to use
	idx_t count = 0;

	auto row_ids = FlatVector::GetData<row_t>(row_identifiers);
	for (idx_t i = 0; i < fetch_count; i++) {
		auto row_id = row_ids[i];
		bool use_row;
		if ((idx_t)row_id < persistent_manager.max_row) {
			// persistent row: use persistent manager
			use_row = persistent_manager.Fetch(transaction, row_id);
		} else {
			// transient row: use transient manager
			use_row = transient_manager.Fetch(transaction, row_id);
		}
		if (use_row) {
			// row is not deleted; use the row
			result_rows[count++] = row_id;
		}
	}
	return count;
}

//===--------------------------------------------------------------------===//
// Append
//===--------------------------------------------------------------------===//
static void VerifyNotNullConstraint(TableCatalogEntry &table, Vector &vector, idx_t count, string &col_name) {
	if (VectorOperations::HasNull(vector, count)) {
		throw ConstraintException("NOT NULL constraint failed: %s.%s", table.name.c_str(), col_name.c_str());
	}
}

static void VerifyCheckConstraint(TableCatalogEntry &table, Expression &expr, DataChunk &chunk) {
	ExpressionExecutor executor(expr);
	Vector result(TypeId::INT32);
	try {
		executor.ExecuteExpression(chunk, result);
	} catch (Exception &ex) {
		throw ConstraintException("CHECK constraint failed: %s (Error: %s)", table.name.c_str(), ex.what());
	} catch (...) {
		throw ConstraintException("CHECK constraint failed: %s (Unknown Error)", table.name.c_str());
	}
	VectorData vdata;
	result.Orrify(chunk.size(), vdata);

	auto dataptr = (int32_t *)vdata.data;
	for (idx_t i = 0; i < chunk.size(); i++) {
		auto idx = vdata.sel->get_index(i);
		if (!(*vdata.nullmask)[idx] && dataptr[idx] == 0) {
			throw ConstraintException("CHECK constraint failed: %s", table.name.c_str());
		}
	}
}

void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, DataChunk &chunk) {
	for (auto &constraint : table.bound_constraints) {
		switch (constraint->type) {
		case ConstraintType::NOT_NULL: {
			auto &not_null = *reinterpret_cast<BoundNotNullConstraint *>(constraint.get());
			VerifyNotNullConstraint(table, chunk.data[not_null.index], chunk.size(),
			                        table.columns[not_null.index].name);
			break;
		}
		case ConstraintType::CHECK: {
			auto &check = *reinterpret_cast<BoundCheckConstraint *>(constraint.get());
			VerifyCheckConstraint(table, *check.expression, chunk);
			break;
		}
		case ConstraintType::UNIQUE: {
			//! check whether or not the chunk can be inserted into the indexes
			for (auto &index : indexes) {
				index->VerifyAppend(chunk);
			}
			break;
		}
		case ConstraintType::FOREIGN_KEY:
		default:
			throw NotImplementedException("Constraint type not implemented!");
		}
	}
}

void DataTable::Append(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk) {
	if (chunk.size() == 0) {
		return;
	}
	if (chunk.column_count() != table.columns.size()) {
		throw CatalogException("Mismatch in column count for append");
	}

	chunk.Verify();

	// verify any constraints on the new chunk
	VerifyAppendConstraints(table, chunk);

	// append to the transaction local data
	auto &transaction = Transaction::GetTransaction(context);
	transaction.storage.Append(this, chunk);
}

void DataTable::InitializeAppend(TableAppendState &state) {
	// obtain the append lock for this table
	state.append_lock = unique_lock<mutex>(append_lock);
	// obtain locks on all indexes for the table
	state.index_locks = unique_ptr<IndexLock[]>(new IndexLock[indexes.size()]);
	for (idx_t i = 0; i < indexes.size(); i++) {
		indexes[i]->InitializeLock(state.index_locks[i]);
	}
	// for each column, initialize the append state
	state.states = unique_ptr<ColumnAppendState[]>(new ColumnAppendState[types.size()]);
	for (idx_t i = 0; i < types.size(); i++) {
		columns[i].InitializeAppend(state.states[i]);
	}
	state.row_start = transient_manager.max_row;
	state.current_row = state.row_start;
}

void DataTable::Append(Transaction &transaction, transaction_t commit_id, DataChunk &chunk, TableAppendState &state) {
	assert(chunk.column_count() == types.size());
	chunk.Verify();

	// set up the inserted info in the version manager
	transient_manager.Append(transaction, state.current_row, chunk.size(), commit_id);

	// append the physical data to each of the entries
	for (idx_t i = 0; i < types.size(); i++) {
		columns[i].Append(state.states[i], chunk.data[i], chunk.size());
	}
	cardinality += chunk.size();
	state.current_row += chunk.size();
}

void DataTable::RevertAppend(TableAppendState &state) {
	if (state.row_start == state.current_row) {
		// nothing to revert!
		return;
	}
	// revert changes in the base columns
	for (idx_t i = 0; i < types.size(); i++) {
		columns[i].RevertAppend(state.row_start);
	}
	// adjust the cardinality
	cardinality -= state.current_row - state.row_start;
	transient_manager.max_row = state.row_start;
	// revert changes in the transient manager
	transient_manager.RevertAppend(state.row_start, state.current_row);
}

//===--------------------------------------------------------------------===//
// Indexes
//===--------------------------------------------------------------------===//
bool DataTable::AppendToIndexes(TableAppendState &state, DataChunk &chunk, row_t row_start) {
	if (indexes.size() == 0) {
		return true;
	}
	// first generate the vector of row identifiers
	Vector row_identifiers(ROW_TYPE);
	VectorOperations::GenerateSequence(row_identifiers, chunk.size(), row_start, 1);

	idx_t failed_index = INVALID_INDEX;
	// now append the entries to the indices
	for (idx_t i = 0; i < indexes.size(); i++) {
		if (!indexes[i]->Append(state.index_locks[i], chunk, row_identifiers)) {
			failed_index = i;
			break;
		}
	}
	if (failed_index != INVALID_INDEX) {
		// constraint violation!
		// remove any appended entries from previous indexes (if any)
		for (idx_t i = 0; i < failed_index; i++) {
			indexes[i]->Delete(state.index_locks[i], chunk, row_identifiers);
		}
		return false;
	}
	return true;
}

void DataTable::RemoveFromIndexes(TableAppendState &state, DataChunk &chunk, row_t row_start) {
	if (indexes.size() == 0) {
		return;
	}
	// first generate the vector of row identifiers
	Vector row_identifiers(ROW_TYPE);
	VectorOperations::GenerateSequence(row_identifiers, chunk.size(), row_start, 1);

	// now remove the entries from the indices
	RemoveFromIndexes(state, chunk, row_identifiers);
}

void DataTable::RemoveFromIndexes(TableAppendState &state, DataChunk &chunk, Vector &row_identifiers) {
	for (idx_t i = 0; i < indexes.size(); i++) {
		indexes[i]->Delete(state.index_locks[i], chunk, row_identifiers);
	}
}

void DataTable::RemoveFromIndexes(Vector &row_identifiers, idx_t count) {
	auto row_ids = FlatVector::GetData<row_t>(row_identifiers);
	// create a selection vector from the row_ids
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	for (idx_t i = 0; i < count; i++) {
		sel.set_index(i, row_ids[i] % STANDARD_VECTOR_SIZE);
	}

	// fetch the data for these row identifiers
	DataChunk result;
	result.Initialize(types);
	// FIXME: we do not need to fetch all columns, only the columns required by the indices!
	auto states = unique_ptr<ColumnScanState[]>(new ColumnScanState[types.size()]);
	for (idx_t i = 0; i < types.size(); i++) {
		columns[i].Fetch(states[i], row_ids[0], result.data[i]);
	}
	result.Slice(sel, count);
	for (idx_t i = 0; i < indexes.size(); i++) {
		indexes[i]->Delete(result, row_identifiers);
	}
}

//===--------------------------------------------------------------------===//
// Delete
//===--------------------------------------------------------------------===//
void DataTable::Delete(TableCatalogEntry &table, ClientContext &context, Vector &row_identifiers, idx_t count) {
	assert(row_identifiers.type == ROW_TYPE);
	if (count == 0) {
		return;
	}

	auto &transaction = Transaction::GetTransaction(context);

	row_identifiers.Normalify(count);
	auto ids = FlatVector::GetData<row_t>(row_identifiers);
	auto first_id = ids[0];

	if (first_id >= MAX_ROW_ID) {
		// deletion is in transaction-local storage: push delete into local chunk collection
		transaction.storage.Delete(this, row_identifiers, count);
	} else if ((idx_t)first_id < persistent_manager.max_row) {
		// deletion is in persistent storage: delete in the persistent version manager
		persistent_manager.Delete(transaction, row_identifiers, count);
	} else {
		// deletion is in transient storage: delete in the persistent version manager
		transient_manager.Delete(transaction, row_identifiers, count);
	}
}

//===--------------------------------------------------------------------===//
// Update
//===--------------------------------------------------------------------===//
static void CreateMockChunk(vector<TypeId> &types, vector<column_t> &column_ids, DataChunk &chunk,
                            DataChunk &mock_chunk) {
	// construct a mock DataChunk
	mock_chunk.InitializeEmpty(types);
	for (column_t i = 0; i < column_ids.size(); i++) {
		mock_chunk.data[column_ids[i]].Reference(chunk.data[i]);
	}
	mock_chunk.SetCardinality(chunk.size());
}

static bool CreateMockChunk(TableCatalogEntry &table, vector<column_t> &column_ids,
                            unordered_set<column_t> &desired_column_ids, DataChunk &chunk, DataChunk &mock_chunk) {
	idx_t found_columns = 0;
	// check whether the desired columns are present in the UPDATE clause
	for (column_t i = 0; i < column_ids.size(); i++) {
		if (desired_column_ids.find(column_ids[i]) != desired_column_ids.end()) {
			found_columns++;
		}
	}
	if (found_columns == 0) {
		// no columns were found: no need to check the constraint again
		return false;
	}
	if (found_columns != desired_column_ids.size()) {
		// FIXME: not all columns in UPDATE clause are present!
		// this should not be triggered at all as the binder should add these columns
		throw NotImplementedException(
		    "Not all columns required for the CHECK constraint are present in the UPDATED chunk!");
	}
	// construct a mock DataChunk
	auto types = table.GetTypes();
	CreateMockChunk(types, column_ids, chunk, mock_chunk);
	return true;
}

void DataTable::VerifyUpdateConstraints(TableCatalogEntry &table, DataChunk &chunk, vector<column_t> &column_ids) {
	for (auto &constraint : table.bound_constraints) {
		switch (constraint->type) {
		case ConstraintType::NOT_NULL: {
			auto &not_null = *reinterpret_cast<BoundNotNullConstraint *>(constraint.get());
			// check if the constraint is in the list of column_ids
			for (idx_t i = 0; i < column_ids.size(); i++) {
				if (column_ids[i] == not_null.index) {
					// found the column id: check the data in
					VerifyNotNullConstraint(table, chunk.data[i], chunk.size(), table.columns[not_null.index].name);
					break;
				}
			}
			break;
		}
		case ConstraintType::CHECK: {
			auto &check = *reinterpret_cast<BoundCheckConstraint *>(constraint.get());

			DataChunk mock_chunk;
			if (CreateMockChunk(table, column_ids, check.bound_columns, chunk, mock_chunk)) {
				VerifyCheckConstraint(table, *check.expression, mock_chunk);
			}
			break;
		}
		case ConstraintType::UNIQUE:
		case ConstraintType::FOREIGN_KEY:
			break;
		default:
			throw NotImplementedException("Constraint type not implemented!");
		}
	}
	// update should not be called for indexed columns!
	// instead update should have been rewritten to delete + update on higher layer
#ifdef DEBUG
	for (idx_t i = 0; i < indexes.size(); i++) {
		assert(!indexes[i]->IndexIsUpdated(column_ids));
	}
#endif
}

void DataTable::Update(TableCatalogEntry &table, ClientContext &context, Vector &row_ids, vector<column_t> &column_ids,
                       DataChunk &updates) {
	assert(row_ids.type == ROW_TYPE);

	updates.Verify();
	if (updates.size() == 0) {
		return;
	}

	// first verify that no constraints are violated
	VerifyUpdateConstraints(table, updates, column_ids);

	// now perform the actual update
	auto &transaction = Transaction::GetTransaction(context);

	updates.Normalify();
	row_ids.Normalify(updates.size());
	auto first_id = FlatVector::GetValue<row_t>(row_ids, 0);
	if (first_id >= MAX_ROW_ID) {
		// update is in transaction-local storage: push update into local storage
		transaction.storage.Update(this, row_ids, column_ids, updates);
		return;
	}

	for (idx_t i = 0; i < column_ids.size(); i++) {
		auto column = column_ids[i];
		assert(column != COLUMN_IDENTIFIER_ROW_ID);

		columns[column].Update(transaction, updates.data[i], row_ids, updates.size());
	}
}

//===--------------------------------------------------------------------===//
// Create Index Scan
//===--------------------------------------------------------------------===//
void DataTable::InitializeCreateIndexScan(CreateIndexScanState &state, vector<column_t> column_ids) {
	// we grab the append lock to make sure nothing is appended until AFTER we finish the index scan
	state.append_lock = unique_lock<mutex>(append_lock);
	// get a read lock on the VersionManagers to prevent any further deletions
	state.locks.push_back(persistent_manager.lock.GetSharedLock());
	state.locks.push_back(transient_manager.lock.GetSharedLock());

	InitializeScan(state, column_ids);
}

void DataTable::CreateIndexScan(CreateIndexScanState &state, DataChunk &result) {
	// scan the persistent segments
	if (ScanCreateIndex(state, result, state.current_persistent_row, state.max_persistent_row, 0)) {
		return;
	}
	// scan the transient segments
	if (ScanCreateIndex(state, result, state.current_transient_row, state.max_transient_row,
	                    state.max_persistent_row)) {
		return;
	}
}

bool DataTable::ScanCreateIndex(CreateIndexScanState &state, DataChunk &result, idx_t &current_row, idx_t max_row,
                                idx_t base_row) {
	if (current_row >= max_row) {
		return false;
	}
	idx_t count = std::min((idx_t)STANDARD_VECTOR_SIZE, max_row - current_row);

	// scan the base columns to fetch the actual data
	// note that we insert all data into the index, even if it is marked as deleted
	// FIXME: tuples that are already "cleaned up" do not need to be inserted into the index!
	for (idx_t i = 0; i < state.column_ids.size(); i++) {
		auto column = state.column_ids[i];
		if (column == COLUMN_IDENTIFIER_ROW_ID) {
			// scan row id
			assert(result.data[i].type == ROW_TYPE);
			result.data[i].Sequence(base_row + current_row, 1);
		} else {
			// scan actual base column
			columns[column].IndexScan(state.column_scans[i], result.data[i]);
		}
	}
	result.SetCardinality(count);

	current_row += STANDARD_VECTOR_SIZE;
	return count > 0;
}

void DataTable::AddIndex(unique_ptr<Index> index, vector<unique_ptr<Expression>> &expressions) {
	DataChunk result;
	result.Initialize(index->types);

	DataChunk intermediate;
	vector<TypeId> intermediate_types;
	auto column_ids = index->column_ids;
	column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
	for (auto &id : index->column_ids) {
		intermediate_types.push_back(types[id]);
	}
	intermediate_types.push_back(ROW_TYPE);
	intermediate.Initialize(intermediate_types);

	// initialize an index scan
	CreateIndexScanState state;
	InitializeCreateIndexScan(state, column_ids);

	// now start incrementally building the index
	IndexLock lock;
	index->InitializeLock(lock);
	ExpressionExecutor executor(expressions);
	while (true) {
		intermediate.Reset();
		// scan a new chunk from the table to index
		CreateIndexScan(state, intermediate);
		if (intermediate.size() == 0) {
			// finished scanning for index creation
			// release all locks
			break;
		}
		// resolve the expressions for this chunk
		executor.Execute(intermediate, result);

		// insert into the index
		if (!index->Insert(lock, result, intermediate.data[intermediate.column_count() - 1])) {
			throw ConstraintException("Cant create unique index, table contains duplicate data on indexed column(s)");
		}
	}
	indexes.push_back(move(index));
}

bool DataTable::IsTemporary() {
	return schema.compare(TEMP_SCHEMA) == 0;
}







using namespace duckdb;
using namespace std;

Index::Index(IndexType type, DataTable &table, vector<column_t> column_ids,
             vector<unique_ptr<Expression>> unbound_expressions)
    : type(type), table(table), column_ids(column_ids), unbound_expressions(move(unbound_expressions)) {
	for (auto &expr : this->unbound_expressions) {
		types.push_back(expr->return_type);
		bound_expressions.push_back(BindExpression(expr->Copy()));
	}
	for (auto &bound_expr : bound_expressions) {
		executor.AddExpression(*bound_expr);
	}
	for (auto column_id : column_ids) {
		column_id_set.insert(column_id);
	}
}

void Index::InitializeLock(IndexLock &state) {
	state.index_lock = unique_lock<mutex>(lock);
}

bool Index::Append(DataChunk &entries, Vector &row_identifiers) {
	IndexLock state;
	InitializeLock(state);
	return Append(state, entries, row_identifiers);
}

void Index::Delete(DataChunk &entries, Vector &row_identifiers) {
	IndexLock state;
	InitializeLock(state);
	Delete(state, entries, row_identifiers);
}

void Index::ExecuteExpressions(DataChunk &input, DataChunk &result) {
	executor.Execute(input, result);
}

unique_ptr<Expression> Index::BindExpression(unique_ptr<Expression> expr) {
	if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
		auto &bound_colref = (BoundColumnRefExpression &)*expr;
		return make_unique<BoundReferenceExpression>(expr->return_type, column_ids[bound_colref.binding.column_index]);
	}
	ExpressionIterator::EnumerateChildren(*expr,
	                                      [&](unique_ptr<Expression> expr) { return BindExpression(move(expr)); });
	return expr;
}

bool Index::IndexIsUpdated(vector<column_t> &column_ids) {
	for (auto &column : column_ids) {
		if (column_id_set.find(column) != column_id_set.end()) {
			return true;
		}
	}
	return false;
}






using namespace duckdb;
using namespace std;

LocalTableStorage::LocalTableStorage(DataTable &table) : max_row(0) {
	for (auto &index : table.indexes) {
		assert(index->type == IndexType::ART);
		auto &art = (ART &)*index;
		if (art.is_unique) {
			// unique index: create a local ART index that maintains the same unique constraint
			vector<unique_ptr<Expression>> unbound_expressions;
			for (auto &expr : art.unbound_expressions) {
				unbound_expressions.push_back(expr->Copy());
			}
			indexes.push_back(make_unique<ART>(table, art.column_ids, move(unbound_expressions), true));
		}
	}
}

LocalTableStorage::~LocalTableStorage() {
}

void LocalTableStorage::InitializeScan(LocalScanState &state) {
	state.storage = this;

	state.chunk_index = 0;
	state.max_index = collection.chunks.size() - 1;
	state.last_chunk_count = collection.chunks.back()->size();
}

void LocalTableStorage::Clear() {
	collection.chunks.clear();
	indexes.clear();
	deleted_entries.clear();
}

void LocalStorage::InitializeScan(DataTable *table, LocalScanState &state) {
	auto entry = table_storage.find(table);
	if (entry == table_storage.end()) {
		// no local storage for table: set scan to nullptr
		state.storage = nullptr;
		return;
	}
	state.storage = entry->second.get();
	state.storage->InitializeScan(state);
}

void LocalStorage::Scan(LocalScanState &state, const vector<column_t> &column_ids, DataChunk &result) {
	if (!state.storage || state.chunk_index > state.max_index) {
		// nothing left to scan
		result.Reset();
		return;
	}
	auto &chunk = *state.storage->collection.chunks[state.chunk_index];
	idx_t chunk_count = state.chunk_index == state.max_index ? state.last_chunk_count : chunk.size();
	idx_t count = chunk_count;

	// first create a selection vector from the deleted entries (if any)
	SelectionVector sel(STANDARD_VECTOR_SIZE);
	auto entry = state.storage->deleted_entries.find(state.chunk_index);
	if (entry != state.storage->deleted_entries.end()) {
		// deleted entries! create a selection vector
		auto deleted = entry->second.get();
		idx_t new_count = 0;
		for (idx_t i = 0; i < count; i++) {
			if (!deleted[i]) {
				sel.set_index(new_count++, i);
			}
		}
		if (new_count == 0 && count > 0) {
			// all entries in this chunk were deleted: continue to next chunk
			state.chunk_index++;
			Scan(state, column_ids, result);
			return;
		}
		count = new_count;
	}

	// now scan the vectors of the chunk
	for (idx_t i = 0; i < column_ids.size(); i++) {
		auto id = column_ids[i];
		if (id == COLUMN_IDENTIFIER_ROW_ID) {
			// row identifier: return a sequence of rowids starting from MAX_ROW_ID plus the row offset in the chunk
			result.data[i].Sequence(MAX_ROW_ID + state.chunk_index * STANDARD_VECTOR_SIZE, 1);
		} else {
			result.data[i].Reference(chunk.data[id]);
		}
	}
	if (count == chunk_count) {
		result.SetCardinality(count);
	} else {
		result.Slice(sel, count);
	}
	state.chunk_index++;
}

void LocalStorage::Append(DataTable *table, DataChunk &chunk) {
	auto entry = table_storage.find(table);
	LocalTableStorage *storage;
	if (entry == table_storage.end()) {
		auto new_storage = make_unique<LocalTableStorage>(*table);
		storage = new_storage.get();
		table_storage.insert(make_pair(table, move(new_storage)));
	} else {
		storage = entry->second.get();
	}
	// append to unique indices (if any)
	if (storage->indexes.size() > 0) {
		idx_t base_id = MAX_ROW_ID + storage->collection.count;

		// first generate the vector of row identifiers
		Vector row_ids(ROW_TYPE);
		VectorOperations::GenerateSequence(row_ids, chunk.size(), base_id, 1);

		// now append the entries to the indices
		for (auto &index : storage->indexes) {
			if (!index->Append(chunk, row_ids)) {
				throw ConstraintException("PRIMARY KEY or UNIQUE constraint violated: duplicated key");
			}
		}
	}

	//! Append to the chunk
	storage->collection.Append(chunk);
}

LocalTableStorage *LocalStorage::GetStorage(DataTable *table) {
	auto entry = table_storage.find(table);
	assert(entry != table_storage.end());
	return entry->second.get();
}

static idx_t GetChunk(Vector &row_ids) {
	auto ids = FlatVector::GetData<row_t>(row_ids);
	auto first_id = ids[0] - MAX_ROW_ID;

	return first_id / STANDARD_VECTOR_SIZE;
}

void LocalStorage::Delete(DataTable *table, Vector &row_ids, idx_t count) {
	auto storage = GetStorage(table);
	// figure out the chunk from which these row ids came
	idx_t chunk_idx = GetChunk(row_ids);
	assert(chunk_idx < storage->collection.chunks.size());

	// get a pointer to the deleted entries for this chunk
	bool *deleted;
	auto entry = storage->deleted_entries.find(chunk_idx);
	if (entry == storage->deleted_entries.end()) {
		// nothing deleted yet, add the deleted entries
		auto del_entries = unique_ptr<bool[]>(new bool[STANDARD_VECTOR_SIZE]);
		memset(del_entries.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE);
		deleted = del_entries.get();
		storage->deleted_entries.insert(make_pair(chunk_idx, move(del_entries)));
	} else {
		deleted = entry->second.get();
	}

	// now actually mark the entries as deleted in the deleted vector
	idx_t base_index = MAX_ROW_ID + chunk_idx * STANDARD_VECTOR_SIZE;

	auto ids = FlatVector::GetData<row_t>(row_ids);
	for (idx_t i = 0; i < count; i++) {
		auto id = ids[i] - base_index;
		deleted[id] = true;
	}
}

template <class T>
static void update_data(Vector &data_vector, Vector &update_vector, Vector &row_ids, idx_t count, idx_t base_index) {
	VectorData udata;
	update_vector.Orrify(count, udata);

	auto target = FlatVector::GetData<T>(data_vector);
	auto &nullmask = FlatVector::Nullmask(data_vector);
	auto ids = FlatVector::GetData<row_t>(row_ids);
	auto updates = (T *)udata.data;

	for (idx_t i = 0; i < count; i++) {
		auto uidx = udata.sel->get_index(i);

		auto id = ids[i] - base_index;
		target[id] = updates[uidx];
		nullmask[id] = (*udata.nullmask)[uidx];
	}
}

static void update_chunk(Vector &data, Vector &updates, Vector &row_ids, idx_t count, idx_t base_index) {
	assert(data.type == updates.type);
	assert(row_ids.type == ROW_TYPE);

	switch (data.type) {
	case TypeId::INT8:
		update_data<int8_t>(data, updates, row_ids, count, base_index);
		break;
	case TypeId::INT16:
		update_data<int16_t>(data, updates, row_ids, count, base_index);
		break;
	case TypeId::INT32:
		update_data<int32_t>(data, updates, row_ids, count, base_index);
		break;
	case TypeId::INT64:
		update_data<int64_t>(data, updates, row_ids, count, base_index);
		break;
	case TypeId::FLOAT:
		update_data<float>(data, updates, row_ids, count, base_index);
		break;
	case TypeId::DOUBLE:
		update_data<double>(data, updates, row_ids, count, base_index);
		break;
	default:
		throw Exception("Unsupported type for in-place update");
	}
}

void LocalStorage::Update(DataTable *table, Vector &row_ids, vector<column_t> &column_ids, DataChunk &data) {
	auto storage = GetStorage(table);
	// figure out the chunk from which these row ids came
	idx_t chunk_idx = GetChunk(row_ids);
	assert(chunk_idx < storage->collection.chunks.size());

	idx_t base_index = MAX_ROW_ID + chunk_idx * STANDARD_VECTOR_SIZE;

	// now perform the actual update
	auto &chunk = *storage->collection.chunks[chunk_idx];
	for (idx_t i = 0; i < column_ids.size(); i++) {
		auto col_idx = column_ids[i];
		update_chunk(chunk.data[col_idx], data.data[i], row_ids, data.size(), base_index);
	}
}

template <class T> bool LocalStorage::ScanTableStorage(DataTable *table, LocalTableStorage *storage, T &&fun) {
	vector<column_t> column_ids;
	for (idx_t i = 0; i < table->types.size(); i++) {
		column_ids.push_back(i);
	}

	DataChunk chunk;
	chunk.Initialize(table->types);

	// initialize the scan
	LocalScanState state;
	storage->InitializeScan(state);

	while (true) {
		Scan(state, column_ids, chunk);
		if (chunk.size() == 0) {
			return true;
		}
		if (!fun(chunk)) {
			return false;
		}
	}
}

void LocalStorage::Commit(LocalStorage::CommitState &commit_state, Transaction &transaction, WriteAheadLog *log,
                          transaction_t commit_id) {
	// commit local storage, iterate over all entries in the table storage map
	for (auto &entry : table_storage) {
		auto table = entry.first;
		auto storage = entry.second.get();

		// initialize the append state
		auto append_state_ptr = make_unique<TableAppendState>();
		auto &append_state = *append_state_ptr;
		// add it to the set of append states
		commit_state.append_states[table] = move(append_state_ptr);
		table->InitializeAppend(append_state);

		if (log && !table->IsTemporary()) {
			log->WriteSetTable(table->schema, table->table);
		}

		// scan all chunks in this storage
		ScanTableStorage(table, storage, [&](DataChunk &chunk) -> bool {
			// append this chunk to the indexes of the table
			if (!table->AppendToIndexes(append_state, chunk, append_state.current_row)) {
				throw ConstraintException("PRIMARY KEY or UNIQUE constraint violated: duplicated key");
			}

			// append to base table
			table->Append(transaction, commit_id, chunk, append_state);
			// if there is a WAL, write the chunk to there as well
			if (log && !table->IsTemporary()) {
				log->WriteInsert(chunk);
			}
			return true;
		});
	}
	// finished commit: clear local storage
	for (auto &entry : table_storage) {
		entry.second->Clear();
	}
	table_storage.clear();
}

void LocalStorage::RevertCommit(LocalStorage::CommitState &commit_state) {
	for (auto &entry : commit_state.append_states) {
		auto table = entry.first;
		auto storage = table_storage[table].get();
		auto &append_state = *entry.second;
		if (table->indexes.size() > 0 && !(table->schema == "temp")) {
			row_t current_row = append_state.row_start;
			// remove the data from the indexes, if there are any indexes
			ScanTableStorage(table, storage, [&](DataChunk &chunk) -> bool {
				// append this chunk to the indexes of the table
				table->RemoveFromIndexes(append_state, chunk, current_row);

				current_row += chunk.size();
				if (current_row >= append_state.current_row) {
					// finished deleting all rows from the index: abort now
					return false;
				}
				return true;
			});
		}

		table->RevertAppend(*entry.second);
	}
}


#include <cstring>

using namespace duckdb;
using namespace std;

MetaBlockReader::MetaBlockReader(BufferManager &manager, block_id_t block_id)
    : manager(manager), handle(nullptr), offset(0), next_block(-1) {
	ReadNewBlock(block_id);
}

void MetaBlockReader::ReadData(data_ptr_t buffer, idx_t read_size) {
	while (offset + read_size > handle->node->size) {
		// cannot read entire entry from block
		// first read what we can from this block
		idx_t to_read = handle->node->size - offset;
		if (to_read > 0) {
			memcpy(buffer, handle->node->buffer + offset, to_read);
			read_size -= to_read;
			buffer += to_read;
		}
		// then move to the next block
		ReadNewBlock(next_block);
	}
	// we have enough left in this block to read from the buffer
	memcpy(buffer, handle->node->buffer + offset, read_size);
	offset += read_size;
}

void MetaBlockReader::ReadNewBlock(block_id_t id) {
	handle = manager.Pin(id);

	next_block = *((block_id_t *)handle->node->buffer);
	offset = sizeof(block_id_t);
}


#include <cstring>

using namespace duckdb;
using namespace std;

MetaBlockWriter::MetaBlockWriter(BlockManager &manager) : manager(manager) {
	block = manager.CreateBlock();
	offset = sizeof(block_id_t);
}

MetaBlockWriter::~MetaBlockWriter() {
	Flush();
}

void MetaBlockWriter::Flush() {
	if (offset > sizeof(block_id_t)) {
		manager.Write(*block);
		offset = sizeof(block_id_t);
	}
}

void MetaBlockWriter::WriteData(const_data_ptr_t buffer, idx_t write_size) {
	while (offset + write_size > block->size) {
		// we need to make a new block
		// first copy what we can
		assert(offset <= block->size);
		idx_t copy_amount = block->size - offset;
		if (copy_amount > 0) {
			memcpy(block->buffer + offset, buffer, copy_amount);
			buffer += copy_amount;
			offset += copy_amount;
			write_size -= copy_amount;
		}
		// now we need to get a new block id
		block_id_t new_block_id = manager.GetFreeBlockId();
		// write the block id of the new block to the start of the current block
		*((block_id_t *)block->buffer) = new_block_id;
		// first flush the old block
		Flush();
		// now update the block id of the lbock
		block->id = new_block_id;
	}
	memcpy(block->buffer + offset, buffer, write_size);
	offset += write_size;
}




//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/update_info.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class ColumnData;
class UncompressedSegment;

struct UpdateInfo {
	//! The base ColumnData that this update affects
	ColumnData *column_data;
	//! The uncompressed segment that this update info affects
	UncompressedSegment *segment;
	//! The version number
	transaction_t version_number;
	//! The vector index within the uncompressed segment
	idx_t vector_index;
	//! The amount of updated tuples
	sel_t N;
	//! The maximum amount of tuples that can fit into this UpdateInfo
	sel_t max;
	//! The row ids of the tuples that have been updated. This should always be kept sorted!
	sel_t *tuples;
	//! The nullmask of the tuples
	nullmask_t nullmask;
	//! The data of the tuples
	data_ptr_t tuple_data;
	//! The previous update info (or nullptr if it is the base)
	UpdateInfo *prev;
	//! The next update info in the chain (or nullptr if it is the last)
	UpdateInfo *next;

	//! Loop over the update chain and execute the specified callback on all UpdateInfo's that are relevant for that
	//! transaction in-order of newest to oldest
	template <class T> static void UpdatesForTransaction(UpdateInfo *current, Transaction &transaction, T &&callback) {
		while (current) {
			if (current->version_number > transaction.start_time &&
			    current->version_number != transaction.transaction_id) {
				// these tuples were either committed AFTER this transaction started or are not committed yet, use
				// tuples stored in this version
				callback(current);
			}
			current = current->next;
		}
	}
};

} // namespace duckdb




using namespace duckdb;
using namespace std;

static NumericSegment::append_function_t GetAppendFunction(TypeId type);
static NumericSegment::update_function_t GetUpdateFunction(TypeId type);
static NumericSegment::update_info_fetch_function_t GetUpdateInfoFetchFunction(TypeId type);
static NumericSegment::rollback_update_function_t GetRollbackUpdateFunction(TypeId type);
static NumericSegment::merge_update_function_t GetMergeUpdateFunction(TypeId type);
static NumericSegment::update_info_append_function_t GetUpdateInfoAppendFunction(TypeId type);

NumericSegment::NumericSegment(BufferManager &manager, TypeId type, idx_t row_start, block_id_t block)
    : UncompressedSegment(manager, type, row_start) {
	// set up the different functions for this type of segment
	this->append_function = GetAppendFunction(type);
	this->update_function = GetUpdateFunction(type);
	this->fetch_from_update_info = GetUpdateInfoFetchFunction(type);
	this->append_from_update_info = GetUpdateInfoAppendFunction(type);
	this->rollback_update = GetRollbackUpdateFunction(type);
	this->merge_update_function = GetMergeUpdateFunction(type);

	// figure out how many vectors we want to store in this block
	this->type_size = GetTypeIdSize(type);
	this->vector_size = sizeof(nullmask_t) + type_size * STANDARD_VECTOR_SIZE;
	this->max_vector_count = Storage::BLOCK_SIZE / vector_size;

	this->block_id = block;
	if (block_id == INVALID_BLOCK) {
		// no block id specified: allocate a buffer for the uncompressed segment
		auto handle = manager.Allocate(Storage::BLOCK_ALLOC_SIZE);
		this->block_id = handle->block_id;
		// initialize nullmasks to 0 for all vectors
		for (idx_t i = 0; i < max_vector_count; i++) {
			auto mask = (nullmask_t *)(handle->node->buffer + (i * vector_size));
			mask->reset();
		}
	}
}

//===--------------------------------------------------------------------===//
// Fetch base data
//===--------------------------------------------------------------------===//
void NumericSegment::FetchBaseData(ColumnScanState &state, idx_t vector_index, Vector &result) {
	assert(vector_index < max_vector_count);
	assert(vector_index * STANDARD_VECTOR_SIZE <= tuple_count);

	// pin the buffer for this segment
	auto handle = manager.Pin(block_id);
	auto data = handle->node->buffer;

	auto offset = vector_index * vector_size;

	idx_t count = GetVectorCount(vector_index);
	auto source_nullmask = (nullmask_t *)(data + offset);
	auto source_data = data + offset + sizeof(nullmask_t);

	// fetch the nullmask and copy the data from the base table
	result.vector_type = VectorType::FLAT_VECTOR;
	FlatVector::SetNullmask(result, *source_nullmask);
	memcpy(FlatVector::GetData(result), source_data, count * type_size);
}

void NumericSegment::FetchUpdateData(ColumnScanState &state, Transaction &transaction, UpdateInfo *version,
                                     Vector &result) {
	fetch_from_update_info(transaction, version, result);
}

//===--------------------------------------------------------------------===//
// Fetch
//===--------------------------------------------------------------------===//
void NumericSegment::FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
                              idx_t result_idx) {
	auto read_lock = lock.GetSharedLock();
	auto handle = manager.Pin(block_id);

	// get the vector index
	idx_t vector_index = row_id / STANDARD_VECTOR_SIZE;
	idx_t id_in_vector = row_id - vector_index * STANDARD_VECTOR_SIZE;
	assert(vector_index < max_vector_count);

	// first fetch the data from the base table
	auto data = handle->node->buffer + vector_index * vector_size;
	auto &nullmask = *((nullmask_t *)(data));
	auto vector_ptr = data + sizeof(nullmask_t);

	FlatVector::SetNull(result, result_idx, nullmask[id_in_vector]);
	memcpy(FlatVector::GetData(result) + result_idx * type_size, vector_ptr + id_in_vector * type_size, type_size);
	if (versions && versions[vector_index]) {
		// version information: follow the version chain to find out if we need to load this tuple data from any other
		// version
		append_from_update_info(transaction, versions[vector_index], id_in_vector, result, result_idx);
	}
}

//===--------------------------------------------------------------------===//
// Append
//===--------------------------------------------------------------------===//
idx_t NumericSegment::Append(SegmentStatistics &stats, Vector &data, idx_t offset, idx_t count) {
	assert(data.type == type);
	auto handle = manager.Pin(block_id);

	idx_t initial_count = tuple_count;
	while (count > 0) {
		// get the vector index of the vector to append to and see how many tuples we can append to that vector
		idx_t vector_index = tuple_count / STANDARD_VECTOR_SIZE;
		if (vector_index == max_vector_count) {
			break;
		}
		idx_t current_tuple_count = tuple_count - vector_index * STANDARD_VECTOR_SIZE;
		idx_t append_count = std::min(STANDARD_VECTOR_SIZE - current_tuple_count, count);

		// now perform the actual append
		append_function(stats, handle->node->buffer + vector_size * vector_index, current_tuple_count, data, offset,
		                append_count);

		count -= append_count;
		offset += append_count;
		tuple_count += append_count;
	}
	return tuple_count - initial_count;
}

//===--------------------------------------------------------------------===//
// Update
//===--------------------------------------------------------------------===//
void NumericSegment::Update(ColumnData &column_data, SegmentStatistics &stats, Transaction &transaction, Vector &update,
                            row_t *ids, idx_t count, idx_t vector_index, idx_t vector_offset, UpdateInfo *node) {
	if (!node) {
		auto handle = manager.Pin(block_id);

		// create a new node in the undo buffer for this update
		node = CreateUpdateInfo(column_data, transaction, ids, count, vector_index, vector_offset, type_size);
		// now move the original data into the UpdateInfo
		update_function(stats, node, handle->node->buffer + vector_index * vector_size, update);
	} else {
		// node already exists for this transaction, we need to merge the new updates with the existing updates
		auto handle = manager.Pin(block_id);

		merge_update_function(stats, node, handle->node->buffer + vector_index * vector_size, update, ids, count,
		                      vector_offset);
	}
}

void NumericSegment::RollbackUpdate(UpdateInfo *info) {
	// obtain an exclusive lock
	auto lock_handle = lock.GetExclusiveLock();
	auto handle = manager.Pin(block_id);

	// move the data from the UpdateInfo back into the base table
	rollback_update(info, handle->node->buffer + info->vector_index * vector_size);

	CleanupUpdate(info);
}

//===--------------------------------------------------------------------===//
// Append
//===--------------------------------------------------------------------===//
template <class T> static void update_min_max(T value, T *__restrict min, T *__restrict max) {
	if (value < *min) {
		*min = value;
	}
	if (value > *max) {
		*max = value;
	}
}

template <class T>
static void append_loop(SegmentStatistics &stats, data_ptr_t target, idx_t target_offset, Vector &source, idx_t offset,
                        idx_t count) {
	auto &nullmask = *((nullmask_t *)target);
	auto min = (T *)stats.minimum.get();
	auto max = (T *)stats.maximum.get();

	VectorData adata;
	source.Orrify(count, adata);

	auto sdata = (T *)adata.data;
	auto tdata = (T *)(target + sizeof(nullmask_t));
	if (adata.nullmask->any()) {
		for (idx_t i = 0; i < count; i++) {
			auto source_idx = adata.sel->get_index(offset + i);
			auto target_idx = target_offset + i;
			bool is_null = (*adata.nullmask)[source_idx];
			if (is_null) {
				nullmask[target_idx] = true;
				stats.has_null = true;
			} else {
				update_min_max(sdata[source_idx], min, max);
				tdata[target_idx] = sdata[source_idx];
			}
		}
	} else {
		for (idx_t i = 0; i < count; i++) {
			auto source_idx = adata.sel->get_index(offset + i);
			auto target_idx = target_offset + i;
			update_min_max(sdata[source_idx], min, max);
			tdata[target_idx] = sdata[source_idx];
		}
	}
}

static NumericSegment::append_function_t GetAppendFunction(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return append_loop<int8_t>;
	case TypeId::INT16:
		return append_loop<int16_t>;
	case TypeId::INT32:
		return append_loop<int32_t>;
	case TypeId::INT64:
		return append_loop<int64_t>;
	case TypeId::FLOAT:
		return append_loop<float>;
	case TypeId::DOUBLE:
		return append_loop<double>;
	default:
		throw NotImplementedException("Unimplemented type for uncompressed segment");
	}
}

//===--------------------------------------------------------------------===//
// Update
//===--------------------------------------------------------------------===//
template <class T>
static void update_loop_null(T *__restrict undo_data, T *__restrict base_data, T *__restrict new_data,
                             nullmask_t &undo_nullmask, nullmask_t &base_nullmask, nullmask_t &new_nullmask,
                             idx_t count, sel_t *__restrict base_sel, T *__restrict min, T *__restrict max) {
	for (idx_t i = 0; i < count; i++) {
		// first move the base data into the undo buffer info
		undo_data[i] = base_data[base_sel[i]];
		undo_nullmask[base_sel[i]] = base_nullmask[base_sel[i]];
		// now move the new data in-place into the base table
		base_data[base_sel[i]] = new_data[i];
		base_nullmask[base_sel[i]] = new_nullmask[i];
		// update the min max with the new data
		update_min_max(new_data[i], min, max);
	}
}

template <class T>
static void update_loop_no_null(T *__restrict undo_data, T *__restrict base_data, T *__restrict new_data, idx_t count,
                                sel_t *__restrict base_sel, T *__restrict min, T *__restrict max) {
	for (idx_t i = 0; i < count; i++) {
		// first move the base data into the undo buffer info
		undo_data[i] = base_data[base_sel[i]];
		// now move the new data in-place into the base table
		base_data[base_sel[i]] = new_data[i];
		// update the min max with the new data
		update_min_max(new_data[i], min, max);
	}
}

template <class T>
static void update_loop(SegmentStatistics &stats, UpdateInfo *info, data_ptr_t base, Vector &update) {
	auto update_data = FlatVector::GetData<T>(update);
	auto &update_nullmask = FlatVector::Nullmask(update);
	auto nullmask = (nullmask_t *)base;
	auto base_data = (T *)(base + sizeof(nullmask_t));
	auto undo_data = (T *)info->tuple_data;
	auto min = (T *)stats.minimum.get();
	auto max = (T *)stats.maximum.get();

	if (update_nullmask.any() || nullmask->any()) {
		update_loop_null(undo_data, base_data, update_data, info->nullmask, *nullmask, update_nullmask, info->N,
		                 info->tuples, min, max);
	} else {
		update_loop_no_null(undo_data, base_data, update_data, info->N, info->tuples, min, max);
	}
}

static NumericSegment::update_function_t GetUpdateFunction(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return update_loop<int8_t>;
	case TypeId::INT16:
		return update_loop<int16_t>;
	case TypeId::INT32:
		return update_loop<int32_t>;
	case TypeId::INT64:
		return update_loop<int64_t>;
	case TypeId::FLOAT:
		return update_loop<float>;
	case TypeId::DOUBLE:
		return update_loop<double>;
	default:
		throw NotImplementedException("Unimplemented type for uncompressed segment");
	}
}

//===--------------------------------------------------------------------===//
// Merge Update
//===--------------------------------------------------------------------===//
template <class T>
static void merge_update_loop(SegmentStatistics &stats, UpdateInfo *node, data_ptr_t base, Vector &update, row_t *ids,
                              idx_t count, idx_t vector_offset) {
	auto &base_nullmask = *((nullmask_t *)base);
	auto base_data = (T *)(base + sizeof(nullmask_t));
	auto info_data = (T *)node->tuple_data;
	auto update_data = FlatVector::GetData<T>(update);
	auto &update_nullmask = FlatVector::Nullmask(update);
	auto min = (T *)stats.minimum.get();
	auto max = (T *)stats.maximum.get();
	for (idx_t i = 0; i < count; i++) {
		update_min_max<T>(update_data[i], min, max);
	}

	// first we copy the old update info into a temporary structure
	sel_t old_ids[STANDARD_VECTOR_SIZE];
	T old_data[STANDARD_VECTOR_SIZE];

	memcpy(old_ids, node->tuples, node->N * sizeof(sel_t));
	memcpy(old_data, node->tuple_data, node->N * sizeof(T));

	// now we perform a merge of the new ids with the old ids
	auto merge = [&](idx_t id, idx_t aidx, idx_t bidx, idx_t count) {
		// new_id and old_id are the same:
		// insert the new data into the base table
		base_nullmask[id] = update_nullmask[aidx];
		base_data[id] = update_data[aidx];
		// insert the old data in the UpdateInfo
		info_data[count] = old_data[bidx];
		node->tuples[count] = id;
	};
	auto pick_new = [&](idx_t id, idx_t aidx, idx_t count) {
		// new_id comes before the old id
		// insert the base table data into the update info
		info_data[count] = base_data[id];
		node->nullmask[id] = base_nullmask[id];

		// and insert the update info into the base table
		base_nullmask[id] = update_nullmask[aidx];
		base_data[id] = update_data[aidx];

		node->tuples[count] = id;
	};
	auto pick_old = [&](idx_t id, idx_t bidx, idx_t count) {
		// old_id comes before new_id, insert the old data
		info_data[count] = old_data[bidx];
		node->tuples[count] = id;
	};
	// perform the merge
	node->N = merge_loop(ids, old_ids, count, node->N, vector_offset, merge, pick_new, pick_old);
}

static NumericSegment::merge_update_function_t GetMergeUpdateFunction(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return merge_update_loop<int8_t>;
	case TypeId::INT16:
		return merge_update_loop<int16_t>;
	case TypeId::INT32:
		return merge_update_loop<int32_t>;
	case TypeId::INT64:
		return merge_update_loop<int64_t>;
	case TypeId::FLOAT:
		return merge_update_loop<float>;
	case TypeId::DOUBLE:
		return merge_update_loop<double>;
	default:
		throw NotImplementedException("Unimplemented type for uncompressed segment");
	}
}
//===--------------------------------------------------------------------===//
// Update Fetch
//===--------------------------------------------------------------------===//
template <class T> static void update_info_fetch(Transaction &transaction, UpdateInfo *info, Vector &result) {
	auto result_data = FlatVector::GetData<T>(result);
	auto &result_mask = FlatVector::Nullmask(result);
	UpdateInfo::UpdatesForTransaction(info, transaction, [&](UpdateInfo *current) {
		auto info_data = (T *)current->tuple_data;
		for (idx_t i = 0; i < current->N; i++) {
			result_data[current->tuples[i]] = info_data[i];
			result_mask[current->tuples[i]] = current->nullmask[current->tuples[i]];
		}
	});
}

static NumericSegment::update_info_fetch_function_t GetUpdateInfoFetchFunction(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return update_info_fetch<int8_t>;
	case TypeId::INT16:
		return update_info_fetch<int16_t>;
	case TypeId::INT32:
		return update_info_fetch<int32_t>;
	case TypeId::INT64:
		return update_info_fetch<int64_t>;
	case TypeId::FLOAT:
		return update_info_fetch<float>;
	case TypeId::DOUBLE:
		return update_info_fetch<double>;
	default:
		throw NotImplementedException("Unimplemented type for uncompressed segment");
	}
}

//===--------------------------------------------------------------------===//
// Update Append
//===--------------------------------------------------------------------===//
template <class T>
static void update_info_append(Transaction &transaction, UpdateInfo *info, idx_t row_id, Vector &result,
                               idx_t result_idx) {
	auto result_data = FlatVector::GetData<T>(result);
	auto &result_mask = FlatVector::Nullmask(result);
	UpdateInfo::UpdatesForTransaction(info, transaction, [&](UpdateInfo *current) {
		auto info_data = (T *)current->tuple_data;
		// loop over the tuples in this UpdateInfo
		for (idx_t i = 0; i < current->N; i++) {
			if (current->tuples[i] == row_id) {
				// found the relevant tuple
				result_data[result_idx] = info_data[i];
				result_mask[result_idx] = current->nullmask[current->tuples[i]];
				break;
			} else if (current->tuples[i] > row_id) {
				// tuples are sorted: so if the current tuple is > row_id we will not find it anymore
				break;
			}
		}
	});
}

static NumericSegment::update_info_append_function_t GetUpdateInfoAppendFunction(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return update_info_append<int8_t>;
	case TypeId::INT16:
		return update_info_append<int16_t>;
	case TypeId::INT32:
		return update_info_append<int32_t>;
	case TypeId::INT64:
		return update_info_append<int64_t>;
	case TypeId::FLOAT:
		return update_info_append<float>;
	case TypeId::DOUBLE:
		return update_info_append<double>;
	default:
		throw NotImplementedException("Unimplemented type for uncompressed segment");
	}
}

//===--------------------------------------------------------------------===//
// Rollback Update
//===--------------------------------------------------------------------===//
template <class T> static void rollback_update(UpdateInfo *info, data_ptr_t base) {
	auto &nullmask = *((nullmask_t *)base);
	auto info_data = (T *)info->tuple_data;
	auto base_data = (T *)(base + sizeof(nullmask_t));

	for (idx_t i = 0; i < info->N; i++) {
		base_data[info->tuples[i]] = info_data[i];
		nullmask[info->tuples[i]] = info->nullmask[info->tuples[i]];
	}
}

static NumericSegment::rollback_update_function_t GetRollbackUpdateFunction(TypeId type) {
	switch (type) {
	case TypeId::BOOL:
	case TypeId::INT8:
		return rollback_update<int8_t>;
	case TypeId::INT16:
		return rollback_update<int16_t>;
	case TypeId::INT32:
		return rollback_update<int32_t>;
	case TypeId::INT64:
		return rollback_update<int64_t>;
	case TypeId::FLOAT:
		return rollback_update<float>;
	case TypeId::DOUBLE:
		return rollback_update<double>;
	default:
		throw NotImplementedException("Unimplemented type for uncompressed segment");
	}
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/single_file_block_manager.hpp
//
//
//===----------------------------------------------------------------------===//









namespace duckdb {
class BufferManager;
class FileBuffer;

//! SingleFileBlockManager is an implementation for a BlockManager which manages blocks in a single file
class SingleFileBlockManager : public BlockManager {
	//! The location in the file where the block writing starts
	static constexpr uint64_t BLOCK_START = Storage::FILE_HEADER_SIZE * 3;

public:
	SingleFileBlockManager(FileSystem &fs, string path, bool read_only, bool create_new, bool use_direct_io);

	//! Creates a new Block and returns a pointer
	unique_ptr<Block> CreateBlock() override;
	//! Return the next free block id
	block_id_t GetFreeBlockId() override;
	//! Return the meta block id
	block_id_t GetMetaBlock() override;
	//! Read the content of the block from disk
	void Read(Block &block) override;
	//! Write the given block to disk
	void Write(FileBuffer &block, block_id_t block_id) override;
	//! Write the header to disk, this is the final step of the checkpointing process
	void WriteHeader(DatabaseHeader header) override;

	//! Load the free list from the file
	void LoadFreeList(BufferManager &manager);

private:
	void Initialize(DatabaseHeader &header);

private:
	//! The active DatabaseHeader, either 0 (h1) or 1 (h2)
	uint8_t active_header;
	//! The path where the file is stored
	string path;
	//! The file handle
	unique_ptr<FileHandle> handle;
	//! The buffer used to read/write to the headers
	FileBuffer header_buffer;
	//! The list of free blocks that can be written to currently
	vector<block_id_t> free_list;
	//! The list of blocks that are used by the current block manager
	unordered_set<block_id_t> used_blocks;
	//! The current meta block id
	block_id_t meta_block;
	//! The current maximum block id, this id will be given away first after the free_list runs out
	block_id_t max_block;
	//! The block id where the free list can be found
	block_id_t free_list_id;
	//! The current header iteration count
	uint64_t iteration_count;
	//! Whether or not the db is opened in read-only mode
	bool read_only;
	//! Whether or not to use Direct IO to read the blocks
	bool use_direct_io;
};
} // namespace duckdb





using namespace duckdb;
using namespace std;

SingleFileBlockManager::SingleFileBlockManager(FileSystem &fs, string path, bool read_only, bool create_new,
                                               bool use_direct_io)
    : path(path), header_buffer(FileBufferType::MANAGED_BUFFER, Storage::FILE_HEADER_SIZE), read_only(read_only),
      use_direct_io(use_direct_io) {

	uint8_t flags;
	FileLockType lock;
	if (read_only) {
		assert(!create_new);
		flags = FileFlags::READ;
		lock = FileLockType::READ_LOCK;
	} else {
		flags = FileFlags::WRITE;
		lock = FileLockType::WRITE_LOCK;
		if (create_new) {
			flags |= FileFlags::CREATE;
		}
	}
	if (use_direct_io) {
		flags |= FileFlags::DIRECT_IO;
	}
	// open the RDBMS handle
	handle = fs.OpenFile(path, flags, lock);
	if (create_new) {
		// if we create a new file, we fill the metadata of the file
		// first fill in the new header
		header_buffer.Clear();
		MainHeader *main_header = (MainHeader *)header_buffer.buffer;
		main_header->version_number = VERSION_NUMBER;
		// now write the header to the file
		header_buffer.Write(*handle, 0);
		header_buffer.Clear();

		// write the database headers
		// initialize meta_block and free_list to INVALID_BLOCK because the database file does not contain any actual
		// content yet
		DatabaseHeader *header = (DatabaseHeader *)header_buffer.buffer;
		// header 1
		header->iteration = 0;
		header->meta_block = INVALID_BLOCK;
		header->free_list = INVALID_BLOCK;
		header->block_count = 0;
		header_buffer.Write(*handle, Storage::FILE_HEADER_SIZE);
		// header 2
		header->iteration = 1;
		header_buffer.Write(*handle, Storage::FILE_HEADER_SIZE * 2);
		// ensure that writing to disk is completed before returning
		handle->Sync();
		// we start with h2 as active_header, this way our initial write will be in h1
		active_header = 1;
		max_block = 0;
	} else {
		MainHeader header;
		// otherwise, we check the metadata of the file
		header_buffer.Read(*handle, 0);
		header = *((MainHeader *)header_buffer.buffer);
		// check the version number
		if (header.version_number != VERSION_NUMBER) {
			throw IOException(
			    "Trying to read a database file with version number %lld, but we can only read version %lld",
			    header.version_number, VERSION_NUMBER);
		}
		// read the database headers from disk
		DatabaseHeader h1, h2;
		header_buffer.Read(*handle, Storage::FILE_HEADER_SIZE);
		h1 = *((DatabaseHeader *)header_buffer.buffer);
		header_buffer.Read(*handle, Storage::FILE_HEADER_SIZE * 2);
		h2 = *((DatabaseHeader *)header_buffer.buffer);
		// check the header with the highest iteration count
		if (h1.iteration > h2.iteration) {
			// h1 is active header
			active_header = 0;
			Initialize(h1);
		} else {
			// h2 is active header
			active_header = 1;
			Initialize(h2);
		}
	}
}

void SingleFileBlockManager::Initialize(DatabaseHeader &header) {
	free_list_id = header.free_list;
	meta_block = header.meta_block;
	iteration_count = header.iteration;
	max_block = header.block_count;
}

void SingleFileBlockManager::LoadFreeList(BufferManager &manager) {
	if (read_only) {
		// no need to load free list for read only db
		return;
	}
	if (free_list_id == INVALID_BLOCK) {
		// no free list
		return;
	}
	MetaBlockReader reader(manager, free_list_id);
	auto free_list_count = reader.Read<uint64_t>();
	free_list.reserve(free_list_count);
	for (idx_t i = 0; i < free_list_count; i++) {
		free_list.push_back(reader.Read<block_id_t>());
	}
}

block_id_t SingleFileBlockManager::GetFreeBlockId() {
	if (free_list.size() > 0) {
		// free list is non empty
		// take an entry from the free list
		block_id_t block = free_list.back();
		// erase the entry from the free list again
		free_list.pop_back();
		return block;
	}
	return max_block++;
}

block_id_t SingleFileBlockManager::GetMetaBlock() {
	return meta_block;
}

unique_ptr<Block> SingleFileBlockManager::CreateBlock() {
	return make_unique<Block>(GetFreeBlockId());
}

void SingleFileBlockManager::Read(Block &block) {
	assert(block.id >= 0);
	used_blocks.insert(block.id);
	block.Read(*handle, BLOCK_START + block.id * Storage::BLOCK_ALLOC_SIZE);
}

void SingleFileBlockManager::Write(FileBuffer &buffer, block_id_t block_id) {
	assert(block_id >= 0);
	buffer.Write(*handle, BLOCK_START + block_id * Storage::BLOCK_ALLOC_SIZE);
}

void SingleFileBlockManager::WriteHeader(DatabaseHeader header) {
	// set the iteration count
	header.iteration = ++iteration_count;
	header.block_count = max_block;
	// now handle the free list
	if (used_blocks.size() > 0) {
		// there are blocks in the free list
		// write them to the file
		MetaBlockWriter writer(*this);
		header.free_list = writer.block->id;
		writer.Write<uint64_t>(used_blocks.size());
		for (auto &block_id : used_blocks) {
			writer.Write<block_id_t>(block_id);
		}
		writer.Flush();
	} else {
		// no blocks in the free list
		header.free_list = INVALID_BLOCK;
	}
	if (!use_direct_io) {
		// if we are not using Direct IO we need to fsync BEFORE we write the header to ensure that all the previous
		// blocks are written as well
		handle->Sync();
	}
	// set the header inside the buffer
	header_buffer.Clear();
	*((DatabaseHeader *)header_buffer.buffer) = header;
	// now write the header to the file, active_header determines whether we write to h1 or h2
	// note that if active_header is h1 we write to h2, and vice versa
	header_buffer.Write(*handle, active_header == 1 ? Storage::FILE_HEADER_SIZE : Storage::FILE_HEADER_SIZE * 2);
	// switch active header to the other header
	active_header = 1 - active_header;
	//! Ensure the header write ends up on disk
	handle->Sync();

	// the free list is now equal to the blocks that were used by the previous iteration
	for (auto &block_id : used_blocks) {
		free_list.push_back(block_id);
	}
	used_blocks.clear();
}


using namespace duckdb;
using namespace std;

namespace duckdb {

const uint64_t VERSION_NUMBER = 1;

} // namespace duckdb



using namespace duckdb;
using namespace std;

StorageLockKey::StorageLockKey(StorageLock &lock, StorageLockType type) : lock(lock), type(type) {
}

StorageLockKey::~StorageLockKey() {
	if (type == StorageLockType::EXCLUSIVE) {
		lock.ReleaseExclusiveLock();
	} else {
		assert(type == StorageLockType::SHARED);
		lock.ReleaseSharedLock();
	}
}

StorageLock::StorageLock() : read_count(0) {
}

unique_ptr<StorageLockKey> StorageLock::GetExclusiveLock() {
	exclusive_lock.lock();
	while (read_count != 0) {
	}
	return make_unique<StorageLockKey>(*this, StorageLockType::EXCLUSIVE);
}

unique_ptr<StorageLockKey> StorageLock::GetSharedLock() {
	exclusive_lock.lock();
	read_count++;
	exclusive_lock.unlock();
	return make_unique<StorageLockKey>(*this, StorageLockType::SHARED);
}

void StorageLock::ReleaseExclusiveLock() {
	exclusive_lock.unlock();
}

void StorageLock::ReleaseSharedLock() {
	read_count--;
}


//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/storage/in_memory_block_manager.hpp
//
//
//===----------------------------------------------------------------------===//







namespace duckdb {

//! InMemoryBlockManager is an implementation for a BlockManager
class InMemoryBlockManager : public BlockManager {
public:
	unique_ptr<Block> CreateBlock() override {
		throw Exception("Cannot perform IO in in-memory database!");
	}
	block_id_t GetFreeBlockId() override {
		throw Exception("Cannot perform IO in in-memory database!");
	}
	block_id_t GetMetaBlock() override {
		throw Exception("Cannot perform IO in in-memory database!");
	}
	void Read(Block &block) override {
		throw Exception("Cannot perform IO in in-memory database!");
	}
	void Write(FileBuffer &block, block_id_t block_id) override {
		throw Exception("Cannot perform IO in in-memory database!");
	}
	void WriteHeader(DatabaseHeader header) override {
		throw Exception("Cannot perform IO in in-memory database!");
	}
};
} // namespace duckdb













using namespace duckdb;
using namespace std;

StorageManager::StorageManager(DuckDB &db, string path, bool read_only)
    : database(db), path(path), wal(db), read_only(read_only) {
}

StorageManager::~StorageManager() {
}

BufferManager &BufferManager::GetBufferManager(ClientContext &context) {
	return *context.db.storage->buffer_manager;
}

void StorageManager::Initialize() {
	bool in_memory = path.empty() || path == ":memory:";

	if (in_memory && read_only) {
		throw CatalogException("Cannot launch in-memory database in read-only mode!");
	}

	// first initialize the base system catalogs
	// these are never written to the WAL
	ClientContext context(database);
	context.transaction.BeginTransaction();

	// create the default schema
	CreateSchemaInfo info;
	info.schema = DEFAULT_SCHEMA;
	database.catalog->CreateSchema(context, &info);

	// initialize default functions
	BuiltinFunctions builtin(context, *database.catalog);
	builtin.Initialize();

	// commit transactions
	context.transaction.Commit();

	if (!in_memory) {
		// create or load the database from disk, if not in-memory mode
		LoadDatabase();
	} else {
		block_manager = make_unique<InMemoryBlockManager>();
		buffer_manager = make_unique<BufferManager>(*database.file_system, *block_manager, database.temporary_directory,
		                                            database.maximum_memory);
	}
}

void StorageManager::Checkpoint(string wal_path) {
	if (!database.file_system->FileExists(wal_path)) {
		// no WAL to checkpoint
		return;
	}
	if (read_only) {
		// cannot checkpoint in read-only system
		return;
	}
	// check the size of the WAL
	{
		BufferedFileReader reader(*database.file_system, wal_path.c_str());
		if (reader.FileSize() <= database.checkpoint_wal_size) {
			// WAL is too small
			return;
		}
	}

	// checkpoint the database
	// FIXME: we do this now by creating a new database and forcing a checkpoint in that database
	// then reloading the file again
	// this should be fixed and turned into an incremental checkpoint
	DBConfig config;
	config.checkpoint_only = true;
	DuckDB db(path, &config);
}

void StorageManager::LoadDatabase() {
	string wal_path = path + ".wal";
	// first check if the database exists
	if (!database.file_system->FileExists(path)) {
		if (read_only) {
			throw CatalogException("Cannot open database \"%s\" in read-only mode: database does not exist",
			                       path.c_str());
		}
		// check if the WAL exists
		if (database.file_system->FileExists(wal_path)) {
			// WAL file exists but database file does not
			// remove the WAL
			database.file_system->RemoveFile(wal_path);
		}
		// initialize the block manager while creating a new db file
		block_manager =
		    make_unique<SingleFileBlockManager>(*database.file_system, path, read_only, true, database.use_direct_io);
		buffer_manager = make_unique<BufferManager>(*database.file_system, *block_manager, database.temporary_directory,
		                                            database.maximum_memory);
	} else {
		if (!database.checkpoint_only) {
			Checkpoint(wal_path);
		}
		// initialize the block manager while loading the current db file
		auto sf =
		    make_unique<SingleFileBlockManager>(*database.file_system, path, read_only, false, database.use_direct_io);
		buffer_manager = make_unique<BufferManager>(*database.file_system, *sf, database.temporary_directory,
		                                            database.maximum_memory);
		sf->LoadFreeList(*buffer_manager);
		block_manager = move(sf);

		//! Load from storage
		CheckpointManager checkpointer(*this);
		checkpointer.LoadFromStorage();
		// check if the WAL file exists
		if (database.file_system->FileExists(wal_path)) {
			// replay the WAL
			WriteAheadLog::Replay(database, wal_path);
			if (database.checkpoint_only) {
				assert(!read_only);
				// checkpoint the database
				checkpointer.CreateCheckpoint();
				// remove the WAL
				database.file_system->RemoveFile(wal_path);
			}
		}
	}
	// initialize the WAL file
	if (!database.checkpoint_only && !read_only) {
		wal.Initialize(wal_path);
	}
}






using namespace duckdb;
using namespace std;

StringSegment::StringSegment(BufferManager &manager, idx_t row_start, block_id_t block)
    : UncompressedSegment(manager, TypeId::VARCHAR, row_start) {
	this->max_vector_count = 0;
	this->dictionary_offset = 0;
	// the vector_size is given in the size of the dictionary offsets
	this->vector_size = STANDARD_VECTOR_SIZE * sizeof(int32_t) + sizeof(nullmask_t);
	this->string_updates = nullptr;

	this->block_id = block;
	if (block_id == INVALID_BLOCK) {
		// start off with an empty string segment: allocate space for it
		auto handle = manager.Allocate(Storage::BLOCK_ALLOC_SIZE);
		this->block_id = handle->block_id;

		ExpandStringSegment(handle->node->buffer);
	}
}

StringSegment::~StringSegment() {
	while (head) {
		manager.DestroyBuffer(head->block_id);
		head = move(head->next);
	}
}

void StringSegment::ExpandStringSegment(data_ptr_t baseptr) {
	// clear the nullmask for this vector
	auto mask = (nullmask_t *)(baseptr + (max_vector_count * vector_size));
	mask->reset();

	max_vector_count++;
	if (versions) {
		auto new_versions = unique_ptr<UpdateInfo *[]>(new UpdateInfo *[max_vector_count]);
		memcpy(new_versions.get(), versions.get(), (max_vector_count - 1) * sizeof(UpdateInfo *));
		new_versions[max_vector_count - 1] = nullptr;
		versions = move(new_versions);
	}

	if (string_updates) {
		auto new_string_updates = unique_ptr<string_update_info_t[]>(new string_update_info_t[max_vector_count]);
		for (idx_t i = 0; i < max_vector_count - 1; i++) {
			new_string_updates[i] = move(string_updates[i]);
		}
		new_string_updates[max_vector_count - 1] = 0;
		string_updates = move(new_string_updates);
	}
}

//===--------------------------------------------------------------------===//
// Scan
//===--------------------------------------------------------------------===//
void StringSegment::InitializeScan(ColumnScanState &state) {
	// pin the primary buffer
	state.primary_handle = manager.Pin(block_id);
}

//===--------------------------------------------------------------------===//
// Fetch base data
//===--------------------------------------------------------------------===//
void StringSegment::FetchBaseData(ColumnScanState &state, idx_t vector_index, Vector &result) {
	// clear any previously locked buffers and get the primary buffer handle
	auto handle = state.primary_handle.get();
	state.handles.clear();

	// fetch the data from the base segment
	FetchBaseData(state, handle->node->buffer, vector_index, result, GetVectorCount(vector_index));
}

void StringSegment::FetchBaseData(ColumnScanState &state, data_ptr_t baseptr, idx_t vector_index, Vector &result,
                                  idx_t count) {
	auto base = baseptr + vector_index * vector_size;

	auto &base_nullmask = *((nullmask_t *)base);
	auto base_data = (int32_t *)(base + sizeof(nullmask_t));
	auto result_data = FlatVector::GetData<string_t>(result);

	if (string_updates && string_updates[vector_index]) {
		// there are updates: merge them in
		auto &info = *string_updates[vector_index];
		idx_t update_idx = 0;
		for (idx_t i = 0; i < count; i++) {
			if (update_idx < info.count && info.ids[update_idx] == i) {
				// use update info
				result_data[i] = ReadString(state.handles, info.block_ids[update_idx], info.offsets[update_idx]);
				update_idx++;
			} else {
				// use base table info
				result_data[i] = FetchStringFromDict(state.handles, baseptr, base_data[i]);
			}
		}
	} else {
		// no updates: fetch only from the string dictionary
		for (idx_t i = 0; i < count; i++) {
			result_data[i] = FetchStringFromDict(state.handles, baseptr, base_data[i]);
		}
	}
	FlatVector::SetNullmask(result, base_nullmask);
}

//===--------------------------------------------------------------------===//
// Fetch update data
//===--------------------------------------------------------------------===//
void StringSegment::FetchUpdateData(ColumnScanState &state, Transaction &transaction, UpdateInfo *info,
                                    Vector &result) {
	// fetch data from updates
	auto handle = state.primary_handle.get();

	auto result_data = FlatVector::GetData<string_t>(result);
	auto &result_mask = FlatVector::Nullmask(result);
	UpdateInfo::UpdatesForTransaction(info, transaction, [&](UpdateInfo *current) {
		auto info_data = (string_location_t *)current->tuple_data;
		for (idx_t i = 0; i < current->N; i++) {
			auto string = FetchString(state.handles, handle->node->buffer, info_data[i]);
			result_data[current->tuples[i]] = string;
			result_mask[current->tuples[i]] = current->nullmask[current->tuples[i]];
		}
	});
}

//===--------------------------------------------------------------------===//
// Fetch strings
//===--------------------------------------------------------------------===//
void StringSegment::FetchStringLocations(data_ptr_t baseptr, row_t *ids, idx_t vector_index, idx_t vector_offset,
                                         idx_t count, string_location_t result[]) {
	auto base = baseptr + vector_index * vector_size;
	auto base_data = (int32_t *)(base + sizeof(nullmask_t));

	if (string_updates && string_updates[vector_index]) {
		// there are updates: merge them in
		auto &info = *string_updates[vector_index];
		idx_t update_idx = 0;
		for (idx_t i = 0; i < count; i++) {
			auto id = ids[i] - vector_offset;
			while (update_idx < info.count && info.ids[update_idx] < id) {
				update_idx++;
			}
			if (update_idx < info.count && info.ids[update_idx] == id) {
				// use update info
				result[i].block_id = info.block_ids[update_idx];
				result[i].offset = info.offsets[update_idx];
				update_idx++;
			} else {
				// use base table info
				result[i] = FetchStringLocation(baseptr, base_data[id]);
			}
		}
	} else {
		// no updates: fetch strings from base vector
		for (idx_t i = 0; i < count; i++) {
			auto id = ids[i] - vector_offset;
			result[i] = FetchStringLocation(baseptr, base_data[id]);
		}
	}
}

string_location_t StringSegment::FetchStringLocation(data_ptr_t baseptr, int32_t dict_offset) {
	if (dict_offset == 0) {
		return string_location_t(INVALID_BLOCK, 0);
	}
	// look up result in dictionary
	auto dict_end = baseptr + Storage::BLOCK_SIZE;
	auto dict_pos = dict_end - dict_offset;
	auto string_length = *((uint16_t *)dict_pos);
	string_location_t result;
	if (string_length == BIG_STRING_MARKER) {
		ReadStringMarker(dict_pos, result.block_id, result.offset);
	} else {
		result.block_id = INVALID_BLOCK;
		result.offset = dict_offset;
	}
	return result;
}

string_t StringSegment::FetchStringFromDict(buffer_handle_set_t &handles, data_ptr_t baseptr, int32_t dict_offset) {
	// fetch base data
	string_location_t location = FetchStringLocation(baseptr, dict_offset);
	return FetchString(handles, baseptr, location);
}

string_t StringSegment::FetchString(buffer_handle_set_t &handles, data_ptr_t baseptr, string_location_t location) {
	if (location.block_id != INVALID_BLOCK) {
		// big string marker: read from separate block
		return ReadString(handles, location.block_id, location.offset);
	} else {
		if (location.offset == 0) {
			return string_t(nullptr, 0);
		}
		// normal string: read string from this block
		auto dict_end = baseptr + Storage::BLOCK_SIZE;
		auto dict_pos = dict_end - location.offset;
		auto string_length = *((uint16_t *)dict_pos);

		auto str_ptr = (char *)(dict_pos + sizeof(uint16_t));
		return string_t(str_ptr, string_length);
	}
}

void StringSegment::FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
                             idx_t result_idx) {
	auto read_lock = lock.GetSharedLock();

	idx_t vector_index = row_id / STANDARD_VECTOR_SIZE;
	idx_t id_in_vector = row_id - vector_index * STANDARD_VECTOR_SIZE;
	assert(vector_index < max_vector_count);

	data_ptr_t baseptr;

	// fetch a single row from the string segment
	// first pin the main buffer if it is not already pinned
	auto entry = state.handles.find(block_id);
	if (entry == state.handles.end()) {
		// not pinned yet: pin it
		auto handle = manager.Pin(block_id);
		baseptr = handle->node->buffer;
		state.handles[block_id] = move(handle);
	} else {
		// already pinned: use the pinned handle
		baseptr = entry->second->node->buffer;
	}

	auto base = baseptr + vector_index * vector_size;
	auto &base_nullmask = *((nullmask_t *)base);
	auto base_data = (int32_t *)(base + sizeof(nullmask_t));
	auto result_data = FlatVector::GetData<string_t>(result);
	auto &result_mask = FlatVector::Nullmask(result);

	bool found_data = false;
	// first see if there is any updated version of this tuple we must fetch
	if (versions && versions[vector_index]) {
		UpdateInfo::UpdatesForTransaction(versions[vector_index], transaction, [&](UpdateInfo *current) {
			auto info_data = (string_location_t *)current->tuple_data;
			// loop over the tuples in this UpdateInfo
			for (idx_t i = 0; i < current->N; i++) {
				if (current->tuples[i] == row_id) {
					// found the relevant tuple
					found_data = true;
					result_data[result_idx] = FetchString(state.handles, baseptr, info_data[i]);
					result_mask[result_idx] = current->nullmask[current->tuples[i]];
					break;
				} else if (current->tuples[i] > row_id) {
					// tuples are sorted: so if the current tuple is > row_id we will not find it anymore
					break;
				}
			}
		});
	}
	if (!found_data) {
		// there was no updated version to be fetched: fetch the base version instead
		if (string_updates && string_updates[vector_index]) {
			// there are updates: check if we should use them
			auto &info = *string_updates[vector_index];
			for (idx_t i = 0; i < info.count; i++) {
				if (info.ids[i] == id_in_vector) {
					// use the update
					result_data[result_idx] = ReadString(state.handles, info.block_ids[i], info.offsets[i]);
					break;
				} else if (info.ids[i] > id_in_vector) {
					break;
				}
			}
		} else {
			// no version was found yet: fetch base table version
			result_data[result_idx] = FetchStringFromDict(state.handles, baseptr, base_data[id_in_vector]);
		}
	}
	result_mask[result_idx] = base_nullmask[id_in_vector];
}

//===--------------------------------------------------------------------===//
// Append
//===--------------------------------------------------------------------===//
idx_t StringSegment::Append(SegmentStatistics &stats, Vector &data, idx_t offset, idx_t count) {
	assert(data.type == TypeId::VARCHAR);
	auto handle = manager.Pin(block_id);

	idx_t initial_count = tuple_count;
	while (count > 0) {
		// get the vector index of the vector to append to and see how many tuples we can append to that vector
		idx_t vector_index = tuple_count / STANDARD_VECTOR_SIZE;
		if (vector_index == max_vector_count) {
			// we are at the maximum vector, check if there is space to increase the maximum vector count
			// as a heuristic, we only allow another vector to be added if we have at least 32 bytes per string
			// remaining (32KB out of a 256KB block, or around 12% empty)
			if (RemainingSpace() >= STANDARD_VECTOR_SIZE * 32) {
				// we have enough remaining space to add another vector
				ExpandStringSegment(handle->node->buffer);
			} else {
				break;
			}
		}
		idx_t current_tuple_count = tuple_count - vector_index * STANDARD_VECTOR_SIZE;
		idx_t append_count = std::min(STANDARD_VECTOR_SIZE - current_tuple_count, count);

		// now perform the actual append
		AppendData(stats, handle->node->buffer + vector_size * vector_index, handle->node->buffer + Storage::BLOCK_SIZE,
		           current_tuple_count, data, offset, append_count);

		count -= append_count;
		offset += append_count;
		tuple_count += append_count;
	}
	return tuple_count - initial_count;
}

void StringSegment::AppendData(SegmentStatistics &stats, data_ptr_t target, data_ptr_t end, idx_t target_offset,
                               Vector &source, idx_t offset, idx_t count) {
	VectorData adata;
	source.Orrify(count, adata);

	auto sdata = (string_t *)adata.data;
	auto &result_nullmask = *((nullmask_t *)target);
	auto result_data = (int32_t *)(target + sizeof(nullmask_t));

	idx_t remaining_strings = STANDARD_VECTOR_SIZE - (this->tuple_count % STANDARD_VECTOR_SIZE);
	for (idx_t i = 0; i < count; i++) {
		auto source_idx = adata.sel->get_index(offset + i);
		auto target_idx = target_offset + i;
		if ((*adata.nullmask)[source_idx]) {
			// null value is stored as -1
			result_data[target_idx] = 0;
			result_nullmask[target_idx] = true;
			stats.has_null = true;
		} else {
			assert(dictionary_offset < Storage::BLOCK_SIZE);
			// non-null value, check if we can fit it within the block
			idx_t string_length = sdata[source_idx].GetSize();
			idx_t total_length = string_length + 1 + sizeof(uint16_t);

			if (string_length > stats.max_string_length) {
				stats.max_string_length = string_length;
			}
			// determine hwether or not the string needs to be stored in an overflow block
			// we never place small strings in the overflow blocks: the pointer would take more space than the
			// string itself we always place big strings (>= STRING_BLOCK_LIMIT) in the overflow blocks we also have
			// to always leave enough room for BIG_STRING_MARKER_SIZE for each of the remaining strings
			if (total_length > BIG_STRING_MARKER_BASE_SIZE &&
			    (total_length >= STRING_BLOCK_LIMIT ||
			     total_length + (remaining_strings * BIG_STRING_MARKER_SIZE) > RemainingSpace())) {
				assert(RemainingSpace() >= BIG_STRING_MARKER_SIZE);
				// string is too big for block: write to overflow blocks
				block_id_t block;
				int32_t offset;
				// write the string into the current string block
				WriteString(sdata[source_idx], block, offset);

				dictionary_offset += BIG_STRING_MARKER_SIZE;
				auto dict_pos = end - dictionary_offset;

				// write a big string marker into the dictionary
				WriteStringMarker(dict_pos, block, offset);

				stats.has_overflow_strings = true;
			} else {
				// string fits in block, append to dictionary and increment dictionary position
				assert(string_length < std::numeric_limits<uint16_t>::max());
				dictionary_offset += total_length;
				auto dict_pos = end - dictionary_offset;

				// first write the length as u16
				uint16_t string_length_u16 = string_length;
				memcpy(dict_pos, &string_length_u16, sizeof(uint16_t));
				// now write the actual string data into the dictionary
				memcpy(dict_pos + sizeof(uint16_t), sdata[source_idx].GetData(), string_length + 1);
			}
			// place the dictionary offset into the set of vectors
			result_data[target_idx] = dictionary_offset;
		}
		remaining_strings--;
	}
}

void StringSegment::WriteString(string_t string, block_id_t &result_block, int32_t &result_offset) {
	assert(strlen(string.GetData()) == string.GetSize());
	if (overflow_writer) {
		// overflow writer is set: write string there
		overflow_writer->WriteString(string, result_block, result_offset);
	} else {
		// default overflow behavior: use in-memory buffer to store the overflow string
		WriteStringMemory(string, result_block, result_offset);
	}
}

void StringSegment::WriteStringMemory(string_t string, block_id_t &result_block, int32_t &result_offset) {
	uint32_t total_length = string.GetSize() + 1 + sizeof(uint32_t);
	unique_ptr<BufferHandle> handle;
	// check if the string fits in the current block
	if (!head || head->offset + total_length >= head->size) {
		// string does not fit, allocate space for it
		// create a new string block
		idx_t alloc_size = std::max((idx_t)total_length, (idx_t)Storage::BLOCK_ALLOC_SIZE);
		auto new_block = make_unique<StringBlock>();
		new_block->offset = 0;
		new_block->size = alloc_size;
		// allocate an in-memory buffer for it
		handle = manager.Allocate(alloc_size);
		new_block->block_id = handle->block_id;
		new_block->next = move(head);
		head = move(new_block);
	} else {
		// string fits, copy it into the current block
		handle = manager.Pin(head->block_id);
	}

	result_block = head->block_id;
	result_offset = head->offset;

	// copy the string and the length there
	auto ptr = handle->node->buffer + head->offset;
	memcpy(ptr, &string.length, sizeof(uint32_t));
	ptr += sizeof(uint32_t);
	memcpy(ptr, string.GetData(), string.length + 1);
	head->offset += total_length;
}

string_t StringSegment::ReadString(buffer_handle_set_t &handles, block_id_t block, int32_t offset) {
	assert(offset < Storage::BLOCK_SIZE);
	if (block == INVALID_BLOCK) {
		return string_t(nullptr, 0);
	}
	if (block < MAXIMUM_BLOCK) {
		// read the overflow string from disk
		// pin the initial handle and read the length
		auto handle = manager.Pin(block);
		uint32_t length = *((uint32_t *)(handle->node->buffer + offset));
		uint32_t remaining = length + 1;
		offset += sizeof(uint32_t);

		// allocate a buffer to store the string
		auto alloc_size = std::max((idx_t)Storage::BLOCK_ALLOC_SIZE, (idx_t)length + 1 + sizeof(uint32_t));
		auto target_handle = manager.Allocate(alloc_size, true);
		auto target_ptr = target_handle->node->buffer;
		// write the length in this block as well
		*((uint32_t *)target_ptr) = length;
		target_ptr += sizeof(uint32_t);
		// now append the string to the single buffer
		while (remaining > 0) {
			idx_t to_write = std::min((idx_t)remaining, (idx_t)(Storage::BLOCK_SIZE - sizeof(block_id_t) - offset));
			memcpy(target_ptr, handle->node->buffer + offset, to_write);

			remaining -= to_write;
			offset += to_write;
			target_ptr += to_write;
			if (remaining > 0) {
				// read the next block
				block_id_t next_block = *((block_id_t *)(handle->node->buffer + offset));
				handle = manager.Pin(next_block);
				offset = 0;
			}
		}

		auto final_buffer = target_handle->node->buffer;
		handles.insert(make_pair(target_handle->block_id, move(target_handle)));
		return ReadString(final_buffer, 0);
	} else {
		// read the overflow string from memory
		// first pin the handle, if it is not pinned yet
		BufferHandle *handle;
		auto entry = handles.find(block);
		if (entry == handles.end()) {
			auto pinned_handle = manager.Pin(block);
			handle = pinned_handle.get();

			handles.insert(make_pair(block, move(pinned_handle)));
		} else {
			handle = entry->second.get();
		}
		return ReadString(handle->node->buffer, offset);
	}
}

string_t StringSegment::ReadString(data_ptr_t target, int32_t offset) {
	auto ptr = target + offset;
	auto str_length = *((uint32_t *)ptr);
	auto str_ptr = (char *)(ptr + sizeof(uint32_t));
	return string_t(str_ptr, str_length);
}

void StringSegment::WriteStringMarker(data_ptr_t target, block_id_t block_id, int32_t offset) {
	uint16_t length = BIG_STRING_MARKER;
	memcpy(target, &length, sizeof(uint16_t));
	target += sizeof(uint16_t);
	memcpy(target, &block_id, sizeof(block_id_t));
	target += sizeof(block_id_t);
	memcpy(target, &offset, sizeof(int32_t));
}

void StringSegment::ReadStringMarker(data_ptr_t target, block_id_t &block_id, int32_t &offset) {
	target += sizeof(uint16_t);
	memcpy(&block_id, target, sizeof(block_id_t));
	target += sizeof(block_id_t);
	memcpy(&offset, target, sizeof(int32_t));
}

//===--------------------------------------------------------------------===//
// String Update
//===--------------------------------------------------------------------===//
string_update_info_t StringSegment::CreateStringUpdate(SegmentStatistics &stats, Vector &update, row_t *ids,
                                                       idx_t count, idx_t vector_offset) {
	auto info = make_unique<StringUpdateInfo>();
	info->count = count;
	auto strings = FlatVector::GetData<string_t>(update);
	auto &update_nullmask = FlatVector::Nullmask(update);
	for (idx_t i = 0; i < count; i++) {
		info->ids[i] = ids[i] - vector_offset;
		// copy the string into the block
		if (!update_nullmask[i]) {
			WriteString(strings[i], info->block_ids[i], info->offsets[i]);
		} else {
			info->block_ids[i] = INVALID_BLOCK;
			info->offsets[i] = 0;
		}
	}
	return info;
}

string_update_info_t StringSegment::MergeStringUpdate(SegmentStatistics &stats, Vector &update, row_t *ids,
                                                      idx_t update_count, idx_t vector_offset,
                                                      StringUpdateInfo &update_info) {
	auto info = make_unique<StringUpdateInfo>();

	// perform a merge between the new and old indexes
	auto strings = FlatVector::GetData<string_t>(update);
	auto &update_nullmask = FlatVector::Nullmask(update);
	auto pick_new = [&](idx_t id, idx_t idx, idx_t count) {
		info->ids[count] = id;
		if (!update_nullmask[idx]) {
			WriteString(strings[idx], info->block_ids[count], info->offsets[count]);
		} else {
			info->block_ids[count] = INVALID_BLOCK;
			info->offsets[count] = 0;
		}
	};
	auto merge = [&](idx_t id, idx_t aidx, idx_t bidx, idx_t count) {
		// merge: only pick new entry
		pick_new(id, aidx, count);
	};
	auto pick_old = [&](idx_t id, idx_t bidx, idx_t count) {
		// pick old entry
		info->ids[count] = id;
		info->block_ids[count] = update_info.block_ids[bidx];
		info->offsets[count] = update_info.offsets[bidx];
	};

	info->count =
	    merge_loop(ids, update_info.ids, update_count, update_info.count, vector_offset, merge, pick_new, pick_old);
	return info;
}

//===--------------------------------------------------------------------===//
// Update Info
//===--------------------------------------------------------------------===//
void StringSegment::MergeUpdateInfo(UpdateInfo *node, row_t *ids, idx_t update_count, idx_t vector_offset,
                                    string_location_t base_data[], nullmask_t base_nullmask) {
	auto info_data = (string_location_t *)node->tuple_data;

	// first we copy the old update info into a temporary structure
	sel_t old_ids[STANDARD_VECTOR_SIZE];
	string_location_t old_data[STANDARD_VECTOR_SIZE];

	memcpy(old_ids, node->tuples, node->N * sizeof(sel_t));
	memcpy(old_data, node->tuple_data, node->N * sizeof(string_location_t));

	// now we perform a merge of the new ids with the old ids
	auto merge = [&](idx_t id, idx_t aidx, idx_t bidx, idx_t count) {
		// new_id and old_id are the same, insert the old data in the UpdateInfo
		assert(old_data[bidx].IsValid());
		info_data[count] = old_data[bidx];
		node->tuples[count] = id;
	};
	auto pick_new = [&](idx_t id, idx_t aidx, idx_t count) {
		// new_id comes before the old id, insert the base table data into the update info
		assert(base_data[aidx].IsValid());
		info_data[count] = base_data[aidx];
		node->nullmask[id] = base_nullmask[aidx];

		node->tuples[count] = id;
	};
	auto pick_old = [&](idx_t id, idx_t bidx, idx_t count) {
		// old_id comes before new_id, insert the old data
		assert(old_data[bidx].IsValid());
		info_data[count] = old_data[bidx];
		node->tuples[count] = id;
	};
	// perform the merge
	node->N = merge_loop(ids, old_ids, update_count, node->N, vector_offset, merge, pick_new, pick_old);
}

//===--------------------------------------------------------------------===//
// Update
//===--------------------------------------------------------------------===//
void StringSegment::Update(ColumnData &column_data, SegmentStatistics &stats, Transaction &transaction, Vector &update,
                           row_t *ids, idx_t count, idx_t vector_index, idx_t vector_offset, UpdateInfo *node) {
	if (!string_updates) {
		string_updates = unique_ptr<string_update_info_t[]>(new string_update_info_t[max_vector_count]);
	}

	// first pin the base block
	auto handle = manager.Pin(block_id);
	auto baseptr = handle->node->buffer;
	auto base = baseptr + vector_index * vector_size;
	auto &base_nullmask = *((nullmask_t *)base);

	// fetch the original string locations and copy the original nullmask
	string_location_t string_locations[STANDARD_VECTOR_SIZE];
	nullmask_t original_nullmask = base_nullmask;
	FetchStringLocations(baseptr, ids, vector_index, vector_offset, count, string_locations);

	string_update_info_t new_update_info;
	// next up: create the updates
	if (!string_updates[vector_index]) {
		// no string updates yet, allocate a block and place the updates there
		new_update_info = CreateStringUpdate(stats, update, ids, count, vector_offset);
	} else {
		// string updates already exist, merge the string updates together
		new_update_info = MergeStringUpdate(stats, update, ids, count, vector_offset, *string_updates[vector_index]);
	}

	// now update the original nullmask
	auto &update_nullmask = FlatVector::Nullmask(update);
	for (idx_t i = 0; i < count; i++) {
		base_nullmask[ids[i] - vector_offset] = update_nullmask[i];
	}

	// now that the original strings are placed in the undo buffer and the updated strings are placed in the base table
	// create the update node
	if (!node) {
		// create a new node in the undo buffer for this update
		node = CreateUpdateInfo(column_data, transaction, ids, count, vector_index, vector_offset,
		                        sizeof(string_location_t));

		// copy the string location data into the undo buffer
		node->nullmask = original_nullmask;
		memcpy(node->tuple_data, string_locations, sizeof(string_location_t) * count);
	} else {
		// node in the update info already exists, merge the new updates in
		MergeUpdateInfo(node, ids, count, vector_offset, string_locations, original_nullmask);
	}
	// finally move the string updates in place
	string_updates[vector_index] = move(new_update_info);
}

void StringSegment::RollbackUpdate(UpdateInfo *info) {
	auto lock_handle = lock.GetExclusiveLock();

	idx_t new_count = 0;
	auto &update_info = *string_updates[info->vector_index];
	auto string_locations = (string_location_t *)info->tuple_data;

	// put the previous NULL values back
	auto handle = manager.Pin(block_id);
	auto baseptr = handle->node->buffer;
	auto base = baseptr + info->vector_index * vector_size;
	auto &base_nullmask = *((nullmask_t *)base);
	for (idx_t i = 0; i < info->N; i++) {
		base_nullmask[info->tuples[i]] = info->nullmask[info->tuples[i]];
	}

	// now put the original values back into the update info
	idx_t old_idx = 0;
	for (idx_t i = 0; i < update_info.count; i++) {
		if (old_idx >= info->N || update_info.ids[i] != info->tuples[old_idx]) {
			assert(old_idx >= info->N || update_info.ids[i] < info->tuples[old_idx]);
			// this entry is not rolled back: insert entry directly
			update_info.ids[new_count] = update_info.ids[i];
			update_info.block_ids[new_count] = update_info.block_ids[i];
			update_info.offsets[new_count] = update_info.offsets[i];
			new_count++;
		} else {
			// this entry is being rolled back
			auto &old_location = string_locations[old_idx];
			if (old_location.block_id != INVALID_BLOCK) {
				// not rolled back to base table: insert entry again
				update_info.ids[new_count] = update_info.ids[i];
				update_info.block_ids[new_count] = old_location.block_id;
				update_info.offsets[new_count] = old_location.offset;
				new_count++;
			}
			old_idx++;
		}
	}

	if (new_count == 0) {
		// all updates are rolled back: delete the string update vector
		string_updates[info->vector_index].reset();
	} else {
		// set the count of the new string update vector
		update_info.count = new_count;
	}
	CleanupUpdate(info);
}



using namespace duckdb;
using namespace std;

static bool UseVersion(Transaction &transaction, transaction_t id) {
	return id < transaction.start_time || id == transaction.transaction_id;
}

//===--------------------------------------------------------------------===//
// Delete info
//===--------------------------------------------------------------------===//
ChunkDeleteInfo::ChunkDeleteInfo(VersionManager &manager, idx_t start_row, ChunkInfoType type)
    : ChunkInfo(manager, start_row, type) {
	for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
		deleted[i] = NOT_DELETED_ID;
	}
}

ChunkDeleteInfo::ChunkDeleteInfo(ChunkDeleteInfo &info, ChunkInfoType type)
    : ChunkInfo(info.manager, info.start, type) {
	for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
		deleted[i] = info.deleted[i];
	}
}

idx_t ChunkDeleteInfo::GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) {
	idx_t count = 0;
	for (idx_t i = 0; i < max_count; i++) {
		if (!UseVersion(transaction, deleted[i])) {
			sel_vector.set_index(count++, i);
		}
	}
	return count;
}

bool ChunkDeleteInfo::Fetch(Transaction &transaction, row_t row) {
	return !UseVersion(transaction, deleted[row]);
}

void ChunkDeleteInfo::Delete(Transaction &transaction, row_t rows[], idx_t count) {
	// first check the chunk for conflicts
	for (idx_t i = 0; i < count; i++) {
		if (deleted[rows[i]] != NOT_DELETED_ID) {
			// tuple was already deleted by another transaction
			throw TransactionException("Conflict on tuple deletion!");
		}
	}
	// after verifying that there are no conflicts we mark the tuples as deleted
	for (idx_t i = 0; i < count; i++) {
		deleted[rows[i]] = transaction.transaction_id;
	}
}

void ChunkDeleteInfo::CommitDelete(transaction_t commit_id, row_t rows[], idx_t count) {
	for (idx_t i = 0; i < count; i++) {
		deleted[rows[i]] = commit_id;
	}
}

//===--------------------------------------------------------------------===//
// Insert info
//===--------------------------------------------------------------------===//
ChunkInsertInfo::ChunkInsertInfo(VersionManager &manager, idx_t start_row)
    : ChunkDeleteInfo(manager, start_row, ChunkInfoType::INSERT_INFO) {
	for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
		inserted[i] = NOT_DELETED_ID;
	}
}

ChunkInsertInfo::ChunkInsertInfo(ChunkDeleteInfo &info) : ChunkDeleteInfo(info, ChunkInfoType::INSERT_INFO) {
	for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
		inserted[i] = NOT_DELETED_ID;
	}
}

idx_t ChunkInsertInfo::GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) {
	idx_t count = 0;
	for (idx_t i = 0; i < max_count; i++) {
		if (UseVersion(transaction, inserted[i]) && !UseVersion(transaction, deleted[i])) {
			sel_vector.set_index(count++, i);
		}
	}
	return count;
}

bool ChunkInsertInfo::Fetch(Transaction &transaction, row_t row) {
	return UseVersion(transaction, inserted[row]) && !UseVersion(transaction, deleted[row]);
}

#include <cstring>

using namespace duckdb;
using namespace std;

ColumnSegment::ColumnSegment(TypeId type, ColumnSegmentType segment_type, idx_t start, idx_t count)
    : SegmentBase(start, count), type(type), type_size(GetTypeIdSize(type)), segment_type(segment_type),
      stats(type, type_size) {
}

ColumnSegment::ColumnSegment(TypeId type, ColumnSegmentType segment_type, idx_t start, idx_t count, data_t stats_min[],
                             data_t stats_max[])
    : SegmentBase(start, count), type(type), type_size(GetTypeIdSize(type)), segment_type(segment_type),
      stats(type, type_size, stats_min, stats_max) {
}

SegmentStatistics::SegmentStatistics(TypeId type, idx_t type_size) : type(type), type_size(type_size) {
	Reset();
}

template <class T>
static void set_min_max(data_t min_value_p[], data_t max_value_p[], data_ptr_t min_p, data_ptr_t max_p) {
	memcpy(min_p, min_value_p, sizeof(T));
	memcpy(max_p, max_value_p, sizeof(T));
}

SegmentStatistics::SegmentStatistics(TypeId type, idx_t type_size, data_t stats_min[], data_t stats_max[])
    : type(type), type_size(type_size) {
	Reset();
	switch (type) {
	case TypeId::INT8: {
		set_min_max<int8_t>(stats_min, stats_max, minimum.get(), maximum.get());
		break;
	}
	case TypeId::INT16: {
		set_min_max<int16_t>(stats_min, stats_max, minimum.get(), maximum.get());
		break;
	}
	case TypeId::INT32: {
		set_min_max<int32_t>(stats_min, stats_max, minimum.get(), maximum.get());
		break;
	}
	case TypeId::INT64: {
		set_min_max<int64_t>(stats_min, stats_max, minimum.get(), maximum.get());
		break;
	}
	case TypeId::FLOAT: {
		set_min_max<float>(stats_min, stats_max, minimum.get(), maximum.get());
		break;
	}
	case TypeId::DOUBLE: {
		set_min_max<double>(stats_min, stats_max, minimum.get(), maximum.get());
		break;
	}

	default:
		break;
	}
}

template <class T> void initialize_max_min(data_ptr_t min, data_ptr_t max) {
	*((T *)min) = std::numeric_limits<T>::max();
	*((T *)max) = std::numeric_limits<T>::min();
}

void SegmentStatistics::Reset() {
	minimum = unique_ptr<data_t[]>(new data_t[type_size]);
	maximum = unique_ptr<data_t[]>(new data_t[type_size]);
	memset(minimum.get(), 0, type_size);
	memset(maximum.get(), 0, type_size);
	has_null = false;
	max_string_length = 0;
	has_overflow_strings = false;
	switch (type) {
	case TypeId::INT8:
		initialize_max_min<int8_t>(minimum.get(), maximum.get());
		break;
	case TypeId::INT16:
		initialize_max_min<int16_t>(minimum.get(), maximum.get());
		break;
	case TypeId::INT32:
		initialize_max_min<int32_t>(minimum.get(), maximum.get());
		break;
	case TypeId::INT64:
		initialize_max_min<int64_t>(minimum.get(), maximum.get());
		break;
	case TypeId::FLOAT:
		initialize_max_min<float>(minimum.get(), maximum.get());
		break;
	case TypeId::DOUBLE:
		initialize_max_min<double>(minimum.get(), maximum.get());
		break;
	default:
		break;
	}
}











using namespace duckdb;
using namespace std;

PersistentSegment::PersistentSegment(BufferManager &manager, block_id_t id, idx_t offset, TypeId type, idx_t start,
                                     idx_t count, data_t stats_min[], data_t stats_max[])
    : ColumnSegment(type, ColumnSegmentType::PERSISTENT, start, count, stats_min, stats_max), manager(manager),
      block_id(id), offset(offset) {
	assert(offset == 0);
	if (type == TypeId::VARCHAR) {
		data = make_unique<StringSegment>(manager, start, id);
		data->max_vector_count = count / STANDARD_VECTOR_SIZE + (count % STANDARD_VECTOR_SIZE == 0 ? 0 : 1);
	} else {
		data = make_unique<NumericSegment>(manager, type, start, id);
	}
	data->tuple_count = count;
}

void PersistentSegment::InitializeScan(ColumnScanState &state) {
	data->InitializeScan(state);
}

void PersistentSegment::Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result) {
	data->Scan(transaction, state, vector_index, result);
}

void PersistentSegment::IndexScan(ColumnScanState &state, Vector &result) {
	data->IndexScan(state, state.vector_index, result);
}

void PersistentSegment::Fetch(ColumnScanState &state, idx_t vector_index, Vector &result) {
	data->Fetch(state, vector_index, result);
}

void PersistentSegment::FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
                                 idx_t result_idx) {
	data->FetchRow(state, transaction, row_id - this->start, result, result_idx);
}

void PersistentSegment::Update(ColumnData &column_data, Transaction &transaction, Vector &updates, row_t *ids,
                               idx_t count) {
	// update of persistent segment: check if the table has been updated before
	if (block_id == data->block_id) {
		// data has not been updated before! convert the segment from one that refers to an on-disk block to one that
		// refers to a in-memory buffer
		data->ToTemporary();
	}
	data->Update(column_data, stats, transaction, updates, ids, count, this->start);
}



using namespace duckdb;
using namespace std;

SegmentBase *SegmentTree::GetRootSegment() {
	return root_node.get();
}

SegmentBase *SegmentTree::GetLastSegment() {
	return nodes.back().node;
}

SegmentBase *SegmentTree::GetSegment(idx_t row_number) {
	lock_guard<mutex> tree_lock(node_lock);
	return nodes[GetSegmentIndex(row_number)].node;
}

idx_t SegmentTree::GetSegmentIndex(idx_t row_number) {
	idx_t lower = 0;
	idx_t upper = nodes.size() - 1;
	// binary search to find the node
	while (lower <= upper) {
		idx_t index = (lower + upper) / 2;
		auto &entry = nodes[index];
		if (row_number < entry.row_start) {
			upper = index - 1;
		} else if (row_number >= entry.row_start + entry.node->count) {
			lower = index + 1;
		} else {
			return index;
		}
	}
	throw Exception("Could not find node in column segment tree!");
}

void SegmentTree::AppendSegment(unique_ptr<SegmentBase> segment) {
	// add the node to the list of nodes
	SegmentNode node;
	node.row_start = segment->start;
	node.node = segment.get();
	nodes.push_back(node);

	if (nodes.size() > 1) {
		// add the node as the next pointer of the last node
		nodes[nodes.size() - 2].node->next = move(segment);
	} else {
		root_node = move(segment);
	}
}








using namespace duckdb;
using namespace std;

TransientSegment::TransientSegment(BufferManager &manager, TypeId type, idx_t start)
    : ColumnSegment(type, ColumnSegmentType::TRANSIENT, start), manager(manager) {
	if (type == TypeId::VARCHAR) {
		data = make_unique<StringSegment>(manager, start);
	} else {
		data = make_unique<NumericSegment>(manager, type, start);
	}
}

void TransientSegment::InitializeScan(ColumnScanState &state) {
	data->InitializeScan(state);
}

void TransientSegment::Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result) {
	data->Scan(transaction, state, vector_index, result);
}

void TransientSegment::IndexScan(ColumnScanState &state, Vector &result) {
	data->IndexScan(state, state.vector_index, result);
}

void TransientSegment::Fetch(ColumnScanState &state, idx_t vector_index, Vector &result) {
	data->Fetch(state, vector_index, result);
}

void TransientSegment::FetchRow(ColumnFetchState &state, Transaction &transaction, row_t row_id, Vector &result,
                                idx_t result_idx) {
	data->FetchRow(state, transaction, row_id - this->start, result, result_idx);
}

void TransientSegment::Update(ColumnData &column_data, Transaction &transaction, Vector &updates, row_t *ids,
                              idx_t count) {
	data->Update(column_data, stats, transaction, updates, ids, count, this->start);
}

void TransientSegment::InitializeAppend(ColumnAppendState &state) {
	state.lock = data->lock.GetExclusiveLock();
}

idx_t TransientSegment::Append(ColumnAppendState &state, Vector &append_data, idx_t offset, idx_t count) {
	idx_t appended = data->Append(stats, append_data, offset, count);
	this->count += appended;
	return appended;
}

void TransientSegment::RevertAppend(idx_t start_row) {
	data->tuple_count = start_row - this->start;
	this->count = start_row - this->start;
}




using namespace duckdb;
using namespace std;

idx_t VersionManager::GetSelVector(Transaction &transaction, idx_t index, SelectionVector &sel_vector,
                                   idx_t max_count) {
	// obtain a read lock
	auto read_lock = lock.GetSharedLock();

	auto entry = info.find(index);
	if (entry == info.end()) {
		// no info, use everything
		return max_count;
	} else {
		// get the selection vector from the chunk info
		return entry->second->GetSelVector(transaction, sel_vector, max_count);
	}
}

bool VersionManager::Fetch(Transaction &transaction, idx_t row) {
	row -= base_row;
	idx_t vector_index = row / STANDARD_VECTOR_SIZE;

	auto entry = info.find(vector_index);
	if (entry == info.end()) {
		// no info, use the row
		return true;
	} else {
		// there is an info: need to figure out if we want to use the row or not
		return entry->second->Fetch(transaction, row - vector_index * STANDARD_VECTOR_SIZE);
	}
}

class VersionDeleteState {
public:
	VersionDeleteState(VersionManager &manager, Transaction &transaction, idx_t base_row)
	    : manager(manager), transaction(transaction), current_info(nullptr), current_chunk((idx_t)-1), count(0),
	      base_row(base_row) {
	}

	VersionManager &manager;
	Transaction &transaction;
	ChunkInfo *current_info;
	idx_t current_chunk;
	row_t rows[STANDARD_VECTOR_SIZE];
	idx_t count;
	idx_t base_row;
	idx_t chunk_row;

public:
	void Delete(row_t row_id);
	void Flush();
};

void VersionManager::Delete(Transaction &transaction, Vector &row_ids, idx_t count) {
	VersionDeleteState del_state(*this, transaction, base_row);

	VectorData rdata;
	row_ids.Orrify(count, rdata);
	// obtain a write lock
	auto write_lock = lock.GetExclusiveLock();
	auto ids = (row_t *)rdata.data;
	for (idx_t i = 0; i < count; i++) {
		auto ridx = rdata.sel->get_index(i);
		del_state.Delete(ids[ridx] - base_row);
	}
	del_state.Flush();
}

void VersionDeleteState::Delete(row_t row_id) {
	idx_t chunk_idx = row_id / STANDARD_VECTOR_SIZE;
	idx_t idx_in_chunk = row_id - chunk_idx * STANDARD_VECTOR_SIZE;

	// check if we are targetting a different chunk than the current chunk
	if (chunk_idx != current_chunk) {
		// if we are, first flush the previous chunk
		Flush();

		// then look up if the chunk already exists
		auto entry = manager.info.find(chunk_idx);
		if (entry == manager.info.end()) {
			// no version info yet: have to create one
			auto new_info = make_unique<ChunkDeleteInfo>(manager, chunk_idx * STANDARD_VECTOR_SIZE);
			current_info = new_info.get();
			manager.info[chunk_idx] = move(new_info);
		} else {
			// version info already exists: alter existing version info
			current_info = entry->second.get();
		}
		current_chunk = chunk_idx;
		chunk_row = chunk_idx * STANDARD_VECTOR_SIZE;
	}

	// now add the row to the set of to-be-deleted rows
	rows[count++] = idx_in_chunk;
}

void VersionDeleteState::Flush() {
	if (count == 0) {
		return;
	}
	// delete in the current info
	current_info->Delete(transaction, rows, count);
	// now push the delete into the undo buffer
	transaction.PushDelete(current_info, rows, count, base_row + chunk_row);
	count = 0;
}

void VersionManager::Append(Transaction &transaction, row_t row_start, idx_t count, transaction_t commit_id) {
	idx_t chunk_idx = row_start / STANDARD_VECTOR_SIZE;
	idx_t idx_in_chunk = row_start - chunk_idx * STANDARD_VECTOR_SIZE;

	// obtain a write lock
	auto write_lock = lock.GetExclusiveLock();
	auto current_info = GetInsertInfo(chunk_idx);
	for (idx_t i = 0; i < count; i++) {
		current_info->inserted[idx_in_chunk] = commit_id;
		idx_in_chunk++;
		if (idx_in_chunk == STANDARD_VECTOR_SIZE) {
			chunk_idx++;
			idx_in_chunk = 0;
			current_info = GetInsertInfo(chunk_idx);
		}
	}
	max_row += count;
}

ChunkInsertInfo *VersionManager::GetInsertInfo(idx_t chunk_idx) {
	auto entry = info.find(chunk_idx);
	if (entry == info.end()) {
		// no version info yet: have to create one
		auto new_info = make_unique<ChunkInsertInfo>(*this, chunk_idx * STANDARD_VECTOR_SIZE);
		auto result = new_info.get();
		info[chunk_idx] = move(new_info);
		return result;
	} else {
		// version info already exists: check if it is insert or delete info
		auto current_info = entry->second.get();
		if (current_info->type == ChunkInfoType::INSERT_INFO) {
			return (ChunkInsertInfo *)current_info;
		} else {
			assert(current_info->type == ChunkInfoType::DELETE_INFO);
			// delete info, change to insert info
			auto new_info = make_unique<ChunkInsertInfo>((ChunkDeleteInfo &)*current_info);
			auto result = new_info.get();
			info[chunk_idx] = move(new_info);
			return result;
		}
	}
}

void VersionManager::RevertAppend(row_t row_start, row_t row_end) {
	auto write_lock = lock.GetExclusiveLock();

	idx_t chunk_start = row_start / STANDARD_VECTOR_SIZE + (row_start % STANDARD_VECTOR_SIZE == 0 ? 0 : 1);
	idx_t chunk_end = row_end / STANDARD_VECTOR_SIZE;
	for (; chunk_start <= chunk_end; chunk_start++) {
		info.erase(chunk_start);
	}
}





using namespace duckdb;
using namespace std;

UncompressedSegment::UncompressedSegment(BufferManager &manager, TypeId type, idx_t row_start)
    : manager(manager), type(type), block_id(INVALID_BLOCK), max_vector_count(0), tuple_count(0), row_start(row_start),
      versions(nullptr) {
}

UncompressedSegment::~UncompressedSegment() {
	if (block_id >= MAXIMUM_BLOCK) {
		// if the uncompressed segment had an in-memory segment, destroy it when the uncompressed segment is destroyed
		manager.DestroyBuffer(block_id);
	}
}

static void CheckForConflicts(UpdateInfo *info, Transaction &transaction, row_t *ids, idx_t count, row_t offset,
                              UpdateInfo *&node) {
	if (info->version_number == transaction.transaction_id) {
		// this UpdateInfo belongs to the current transaction, set it in the node
		node = info;
	} else if (info->version_number > transaction.start_time) {
		// potential conflict, check that tuple ids do not conflict
		// as both ids and info->tuples are sorted, this is similar to a merge join
		idx_t i = 0, j = 0;
		while (true) {
			auto id = ids[i] - offset;
			if (id == info->tuples[j]) {
				throw TransactionException("Conflict on update!");
			} else if (id < info->tuples[j]) {
				// id < the current tuple in info, move to next id
				i++;
				if (i == count) {
					break;
				}
			} else {
				// id > the current tuple, move to next tuple in info
				j++;
				if (j == info->N) {
					break;
				}
			}
		}
	}
	if (info->next) {
		CheckForConflicts(info->next, transaction, ids, count, offset, node);
	}
}

void UncompressedSegment::Update(ColumnData &column_data, SegmentStatistics &stats, Transaction &transaction,
                                 Vector &update, row_t *ids, idx_t count, row_t offset) {
	// can only perform in-place updates on temporary blocks
	assert(block_id >= MAXIMUM_BLOCK);

	// obtain an exclusive lock
	auto write_lock = lock.GetExclusiveLock();

#ifdef DEBUG
	// verify that the ids are sorted and there are no duplicates
	for (idx_t i = 1; i < count; i++) {
		assert(ids[i] > ids[i - 1]);
	}
#endif

	// create the versions for this segment, if there are none yet
	if (!versions) {
		this->versions = unique_ptr<UpdateInfo *[]>(new UpdateInfo *[max_vector_count]);
		for (idx_t i = 0; i < max_vector_count; i++) {
			this->versions[i] = nullptr;
		}
	}

	// get the vector index based on the first id
	// we assert that all updates must be part of the same vector
	auto first_id = ids[0];
	idx_t vector_index = (first_id - offset) / STANDARD_VECTOR_SIZE;
	idx_t vector_offset = offset + vector_index * STANDARD_VECTOR_SIZE;

	assert(first_id >= offset);
	assert(vector_index < max_vector_count);

	// first check the version chain
	UpdateInfo *node = nullptr;
	if (versions[vector_index]) {
		// there is already a version here, check if there are any conflicts and search for the node that belongs to
		// this transaction in the version chain
		CheckForConflicts(versions[vector_index], transaction, ids, count, vector_offset, node);
	}
	Update(column_data, stats, transaction, update, ids, count, vector_index, vector_offset, node);
}

UpdateInfo *UncompressedSegment::CreateUpdateInfo(ColumnData &column_data, Transaction &transaction, row_t *ids,
                                                  idx_t count, idx_t vector_index, idx_t vector_offset,
                                                  idx_t type_size) {
	auto node = transaction.CreateUpdateInfo(type_size, STANDARD_VECTOR_SIZE);
	node->column_data = &column_data;
	node->segment = this;
	node->vector_index = vector_index;
	node->prev = nullptr;
	node->next = versions[vector_index];
	if (node->next) {
		node->next->prev = node;
	}
	versions[vector_index] = node;

	// set up the tuple ids
	node->N = count;
	for (idx_t i = 0; i < count; i++) {
		assert((idx_t)ids[i] >= vector_offset && (idx_t)ids[i] < vector_offset + STANDARD_VECTOR_SIZE);
		node->tuples[i] = ids[i] - vector_offset;
	};
	return node;
}

void UncompressedSegment::Fetch(ColumnScanState &state, idx_t vector_index, Vector &result) {
	auto read_lock = lock.GetSharedLock();

	InitializeScan(state);
	FetchBaseData(state, vector_index, result);
}

//===--------------------------------------------------------------------===//
// Scan
//===--------------------------------------------------------------------===//
void UncompressedSegment::Scan(Transaction &transaction, ColumnScanState &state, idx_t vector_index, Vector &result) {
	auto read_lock = lock.GetSharedLock();

	// first fetch the data from the base table
	FetchBaseData(state, vector_index, result);
	if (versions && versions[vector_index]) {
		// if there are any versions, check if we need to overwrite the data with the versioned data
		FetchUpdateData(state, transaction, versions[vector_index], result);
	}
}

void UncompressedSegment::IndexScan(ColumnScanState &state, idx_t vector_index, Vector &result) {
	if (vector_index == 0) {
		// vector_index = 0, obtain a shared lock on the segment that we keep until the index scan is complete
		state.locks.push_back(lock.GetSharedLock());
	}
	if (versions && versions[vector_index]) {
		throw TransactionException("Cannot create index with outstanding updates");
	}
	FetchBaseData(state, vector_index, result);
}

//===--------------------------------------------------------------------===//
// Update
//===--------------------------------------------------------------------===//
void UncompressedSegment::CleanupUpdate(UpdateInfo *info) {
	if (info->prev) {
		// there is a prev info: remove from the chain
		auto prev = info->prev;
		prev->next = info->next;
		if (prev->next) {
			prev->next->prev = prev;
		}
	} else {
		// there is no prev info: remove from base segment
		info->segment->versions[info->vector_index] = info->next;
		if (info->next) {
			info->next->prev = nullptr;
		}
	}
}

//===--------------------------------------------------------------------===//
// ToTemporary
//===--------------------------------------------------------------------===//
void UncompressedSegment::ToTemporary() {
	auto write_lock = lock.GetExclusiveLock();

	if (block_id >= MAXIMUM_BLOCK) {
		// conversion has already been performed by a different thread
		return;
	}
	// pin the current block
	auto current = manager.Pin(block_id);

	// now allocate a new block from the buffer manager
	auto handle = manager.Allocate(Storage::BLOCK_ALLOC_SIZE);
	// now copy the data over and switch to using the new block id
	memcpy(handle->node->buffer, current->node->buffer, Storage::BLOCK_SIZE);
	this->block_id = handle->block_id;
}
















using namespace duckdb;
using namespace std;

class ReplayState {
public:
	ReplayState(DuckDB &db, ClientContext &context, Deserializer &source)
	    : db(db), context(context), source(source), current_table(nullptr) {
	}

	DuckDB &db;
	ClientContext &context;
	Deserializer &source;
	TableCatalogEntry *current_table;

public:
	void ReplayEntry(WALType entry_type);

private:
	void ReplayCreateTable();
	void ReplayDropTable();
	void ReplayAlter();

	void ReplayCreateView();
	void ReplayDropView();

	void ReplayCreateSchema();
	void ReplayDropSchema();

	void ReplayCreateSequence();
	void ReplayDropSequence();
	void ReplaySequenceValue();

	void ReplayUseTable();
	void ReplayInsert();
	void ReplayDelete();
	void ReplayUpdate();
};

void WriteAheadLog::Replay(DuckDB &database, string &path) {
	BufferedFileReader reader(*database.file_system, path.c_str());

	if (reader.Finished()) {
		// WAL is empty
		return;
	}

	ClientContext context(database);
	context.transaction.SetAutoCommit(false);
	context.transaction.BeginTransaction();

	ReplayState state(database, context, reader);

	// replay the WAL
	// note that everything is wrapped inside a try/catch block here
	// there can be errors in WAL replay because of a corrupt WAL file
	// in this case we should throw a warning but startup anyway
	try {
		while (true) {
			// read the current entry
			WALType entry_type = reader.Read<WALType>();
			if (entry_type == WALType::WAL_FLUSH) {
				// flush: commit the current transaction
				context.transaction.Commit();
				context.transaction.SetAutoCommit(false);
				// check if the file is exhausted
				if (reader.Finished()) {
					// we finished reading the file: break
					break;
				}
				// otherwise we keep on reading
				context.transaction.BeginTransaction();
			} else {
				// replay the entry
				state.ReplayEntry(entry_type);
			}
		}
	} catch (std::exception &ex) {
		// FIXME: this report a proper warning in the connection
		fprintf(stderr, "Exception in WAL playback: %s\n", ex.what());
		// exception thrown in WAL replay: rollback
		context.transaction.Rollback();
	}
}

//===--------------------------------------------------------------------===//
// Replay Entries
//===--------------------------------------------------------------------===//
void ReplayState::ReplayEntry(WALType entry_type) {
	switch (entry_type) {
	case WALType::CREATE_TABLE:
		ReplayCreateTable();
		break;
	case WALType::DROP_TABLE:
		ReplayDropTable();
		break;
	case WALType::ALTER_INFO:
		ReplayAlter();
		break;
	case WALType::CREATE_VIEW:
		ReplayCreateView();
		break;
	case WALType::DROP_VIEW:
		ReplayDropView();
		break;
	case WALType::CREATE_SCHEMA:
		ReplayCreateSchema();
		break;
	case WALType::DROP_SCHEMA:
		ReplayDropSchema();
		break;
	case WALType::CREATE_SEQUENCE:
		ReplayCreateSequence();
		break;
	case WALType::DROP_SEQUENCE:
		ReplayDropSequence();
		break;
	case WALType::SEQUENCE_VALUE:
		ReplaySequenceValue();
		break;
	case WALType::USE_TABLE:
		ReplayUseTable();
		break;
	case WALType::INSERT_TUPLE:
		ReplayInsert();
		break;
	case WALType::DELETE_TUPLE:
		ReplayDelete();
		break;
	case WALType::UPDATE_TUPLE:
		ReplayUpdate();
		break;
	default:
		throw Exception("Invalid WAL entry type!");
	}
}

//===--------------------------------------------------------------------===//
// Replay Table
//===--------------------------------------------------------------------===//
void ReplayState::ReplayCreateTable() {
	auto info = TableCatalogEntry::Deserialize(source);

	// bind the constraints to the table again
	Binder binder(context);
	auto bound_info = unique_ptr_cast<BoundCreateInfo, BoundCreateTableInfo>(binder.BindCreateInfo(move(info)));

	db.catalog->CreateTable(context, bound_info.get());
}

void ReplayState::ReplayDropTable() {
	DropInfo info;

	info.type = CatalogType::TABLE;
	info.schema = source.Read<string>();
	info.name = source.Read<string>();

	db.catalog->DropEntry(context, &info);
}

void ReplayState::ReplayAlter() {
	auto info = AlterInfo::Deserialize(source);
	if (info->type != AlterType::ALTER_TABLE) {
		throw Exception("Expected ALTER TABLE!");
	}

	db.catalog->AlterTable(context, (AlterTableInfo *)info.get());
}

//===--------------------------------------------------------------------===//
// Replay View
//===--------------------------------------------------------------------===//
void ReplayState::ReplayCreateView() {
	auto entry = ViewCatalogEntry::Deserialize(source);

	db.catalog->CreateView(context, entry.get());
}

void ReplayState::ReplayDropView() {
	DropInfo info;
	info.type = CatalogType::VIEW;
	info.schema = source.Read<string>();
	info.name = source.Read<string>();
	db.catalog->DropEntry(context, &info);
}

//===--------------------------------------------------------------------===//
// Replay Schema
//===--------------------------------------------------------------------===//
void ReplayState::ReplayCreateSchema() {
	CreateSchemaInfo info;
	info.schema = source.Read<string>();

	db.catalog->CreateSchema(context, &info);
}

void ReplayState::ReplayDropSchema() {
	DropInfo info;

	info.type = CatalogType::SCHEMA;
	info.name = source.Read<string>();

	db.catalog->DropEntry(context, &info);
}

//===--------------------------------------------------------------------===//
// Replay Sequence
//===--------------------------------------------------------------------===//
void ReplayState::ReplayCreateSequence() {
	auto entry = SequenceCatalogEntry::Deserialize(source);

	db.catalog->CreateSequence(context, entry.get());
}

void ReplayState::ReplayDropSequence() {
	DropInfo info;
	info.type = CatalogType::SEQUENCE;
	info.schema = source.Read<string>();
	info.name = source.Read<string>();

	db.catalog->DropEntry(context, &info);
}

void ReplayState::ReplaySequenceValue() {
	auto schema = source.Read<string>();
	auto name = source.Read<string>();
	auto usage_count = source.Read<uint64_t>();
	auto counter = source.Read<int64_t>();

	// fetch the sequence from the catalog
	auto seq = db.catalog->GetEntry<SequenceCatalogEntry>(context, schema, name);
	if (usage_count > seq->usage_count) {
		seq->usage_count = usage_count;
		seq->counter = counter;
	}
}

//===--------------------------------------------------------------------===//
// Replay Data
//===--------------------------------------------------------------------===//
void ReplayState::ReplayUseTable() {
	auto schema_name = source.Read<string>();
	auto table_name = source.Read<string>();
	current_table = db.catalog->GetEntry<TableCatalogEntry>(context, schema_name, table_name);
}

void ReplayState::ReplayInsert() {
	if (!current_table) {
		throw Exception("Corrupt WAL: insert without table");
	}
	DataChunk chunk;
	chunk.Deserialize(source);

	// append to the current table
	current_table->storage->Append(*current_table, context, chunk);
}

void ReplayState::ReplayDelete() {
	if (!current_table) {
		throw Exception("Corrupt WAL: delete without table");
	}
	DataChunk chunk;
	chunk.Deserialize(source);

	assert(chunk.column_count() == 1 && chunk.data[0].type == ROW_TYPE);
	row_t row_ids[1];
	Vector row_identifiers(ROW_TYPE, (data_ptr_t)row_ids);

	auto source_ids = FlatVector::GetData<row_t>(chunk.data[0]);
	// delete the tuples from the current table
	for (idx_t i = 0; i < chunk.size(); i++) {
		row_ids[0] = source_ids[i];
		current_table->storage->Delete(*current_table, context, row_identifiers, 1);
	}
}

void ReplayState::ReplayUpdate() {
	if (!current_table) {
		throw Exception("Corrupt WAL: update without table");
	}

	idx_t column_index = source.Read<column_t>();

	DataChunk chunk;
	chunk.Deserialize(source);

	vector<column_t> column_ids{column_index};
	if (column_index >= current_table->columns.size()) {
		throw Exception("Corrupt WAL: column index for update out of bounds");
	}

	// remove the row id vector from the chunk
	auto row_ids = move(chunk.data.back());
	chunk.data.pop_back();

	// now perform the update
	current_table->storage->Update(*current_table, context, row_ids, column_ids, chunk);
}






#include <cstring>

using namespace duckdb;
using namespace std;

WriteAheadLog::WriteAheadLog(DuckDB &database) : initialized(false), database(database) {
}

void WriteAheadLog::Initialize(string &path) {
	writer = make_unique<BufferedFileWriter>(*database.file_system, path.c_str(), true);
	initialized = true;
}

int64_t WriteAheadLog::GetWALSize() {
	return writer->GetFileSize();
}

void WriteAheadLog::Truncate(int64_t size) {
	writer->Truncate(size);
}
//===--------------------------------------------------------------------===//
// Write Entries
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// CREATE TABLE
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteCreateTable(TableCatalogEntry *entry) {
	writer->Write<WALType>(WALType::CREATE_TABLE);
	entry->Serialize(*writer);
}

//===--------------------------------------------------------------------===//
// DROP TABLE
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteDropTable(TableCatalogEntry *entry) {
	writer->Write<WALType>(WALType::DROP_TABLE);
	writer->WriteString(entry->schema->name);
	writer->WriteString(entry->name);
}

//===--------------------------------------------------------------------===//
// CREATE SCHEMA
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteCreateSchema(SchemaCatalogEntry *entry) {
	writer->Write<WALType>(WALType::CREATE_SCHEMA);
	writer->WriteString(entry->name);
}

//===--------------------------------------------------------------------===//
// SEQUENCES
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteCreateSequence(SequenceCatalogEntry *entry) {
	writer->Write<WALType>(WALType::CREATE_SEQUENCE);
	entry->Serialize(*writer);
}

void WriteAheadLog::WriteDropSequence(SequenceCatalogEntry *entry) {
	writer->Write<WALType>(WALType::DROP_SEQUENCE);
	writer->WriteString(entry->schema->name);
	writer->WriteString(entry->name);
}

void WriteAheadLog::WriteSequenceValue(SequenceCatalogEntry *entry, SequenceValue val) {
	writer->Write<WALType>(WALType::SEQUENCE_VALUE);
	writer->WriteString(entry->schema->name);
	writer->WriteString(entry->name);
	writer->Write<uint64_t>(val.usage_count);
	writer->Write<int64_t>(val.counter);
}

//===--------------------------------------------------------------------===//
// VIEWS
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteCreateView(ViewCatalogEntry *entry) {
	writer->Write<WALType>(WALType::CREATE_VIEW);
	entry->Serialize(*writer);
}

void WriteAheadLog::WriteDropView(ViewCatalogEntry *entry) {
	writer->Write<WALType>(WALType::DROP_VIEW);
	writer->WriteString(entry->schema->name);
	writer->WriteString(entry->name);
}

//===--------------------------------------------------------------------===//
// DROP SCHEMA
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteDropSchema(SchemaCatalogEntry *entry) {
	writer->Write<WALType>(WALType::DROP_SCHEMA);
	writer->WriteString(entry->name);
}

//===--------------------------------------------------------------------===//
// DATA
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteSetTable(string &schema, string &table) {
	writer->Write<WALType>(WALType::USE_TABLE);
	writer->WriteString(schema);
	writer->WriteString(table);
}

void WriteAheadLog::WriteInsert(DataChunk &chunk) {
	assert(chunk.size() > 0);
	chunk.Verify();

	writer->Write<WALType>(WALType::INSERT_TUPLE);
	chunk.Serialize(*writer);
}

void WriteAheadLog::WriteDelete(DataChunk &chunk) {
	assert(chunk.size() > 0);
	assert(chunk.column_count() == 1 && chunk.data[0].type == ROW_TYPE);
	chunk.Verify();

	writer->Write<WALType>(WALType::DELETE_TUPLE);
	chunk.Serialize(*writer);
}

void WriteAheadLog::WriteUpdate(DataChunk &chunk, column_t col_idx) {
	assert(chunk.size() > 0);
	chunk.Verify();

	writer->Write<WALType>(WALType::UPDATE_TUPLE);
	writer->Write<column_t>(col_idx);
	chunk.Serialize(*writer);
}

//===--------------------------------------------------------------------===//
// Write ALTER Statement
//===--------------------------------------------------------------------===//
void WriteAheadLog::WriteAlter(AlterInfo &info) {
	writer->Write<WALType>(WALType::ALTER_INFO);
	info.Serialize(*writer);
}

//===--------------------------------------------------------------------===//
// FLUSH
//===--------------------------------------------------------------------===//
void WriteAheadLog::Flush() {
	// write an empty entry
	writer->Write<WALType>(WALType::WAL_FLUSH);
	// flushes all changes made to the WAL to disk
	writer->Sync();
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/cleanup_state.hpp
//
//
//===----------------------------------------------------------------------===//






namespace duckdb {
class DataTable;

struct DeleteInfo;
struct UpdateInfo;

class CleanupState {
public:
	CleanupState();
	~CleanupState();

public:
	void CleanupEntry(UndoFlags type, data_ptr_t data);

private:
	// data for index cleanup
	DataTable *current_table;
	DataChunk chunk;
	row_t row_numbers[STANDARD_VECTOR_SIZE];
	idx_t count;

private:
	void CleanupDelete(DeleteInfo *info);
	void CleanupUpdate(UpdateInfo *info);

	void Flush();
};

} // namespace duckdb

//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/delete_info.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class ChunkInfo;
class DataTable;

struct DeleteInfo {
	ChunkInfo *vinfo;
	idx_t count;
	idx_t base_row;
	row_t rows[1];

	DataTable &GetTable();
};

} // namespace duckdb









using namespace duckdb;
using namespace std;

CleanupState::CleanupState() : current_table(nullptr), count(0) {
}

CleanupState::~CleanupState() {
	Flush();
}

void CleanupState::CleanupEntry(UndoFlags type, data_ptr_t data) {
	switch (type) {
	case UndoFlags::CATALOG_ENTRY: {
		CatalogEntry *catalog_entry = *((CatalogEntry **)data);
		// destroy the backed up entry: it is no longer required
		assert(catalog_entry->parent);
		if (catalog_entry->parent->type != CatalogType::UPDATED_ENTRY) {
			if (!catalog_entry->parent->child->deleted) {
				// delete the entry from the dependency manager, if it is not deleted yet
				catalog_entry->catalog->dependency_manager.EraseObject(catalog_entry->parent->child.get());
			}
			catalog_entry->parent->child = move(catalog_entry->child);
		}
		break;
	}
	case UndoFlags::DELETE_TUPLE: {
		auto info = (DeleteInfo *)data;
		CleanupDelete(info);
		break;
	}
	case UndoFlags::UPDATE_TUPLE: {
		auto info = (UpdateInfo *)data;
		CleanupUpdate(info);
		break;
	}
	default:
		break;
	}
}

void CleanupState::CleanupUpdate(UpdateInfo *info) {
	// remove the update info from the update chain
	// first obtain an exclusive lock on the segment
	auto lock = info->segment->lock.GetExclusiveLock();
	info->segment->CleanupUpdate(info);
}

void CleanupState::CleanupDelete(DeleteInfo *info) {
	auto version_table = &info->GetTable();
	if (version_table->indexes.size() == 0) {
		// this table has no indexes: no cleanup to be done
		return;
	}
	if (current_table != version_table) {
		// table for this entry differs from previous table: flush and switch to the new table
		Flush();
		current_table = version_table;
	}
	for (idx_t i = 0; i < info->count; i++) {
		if (count == STANDARD_VECTOR_SIZE) {
			Flush();
		}
		row_numbers[count++] = info->vinfo->start + info->rows[i];
	}
}

void CleanupState::Flush() {
	if (count == 0) {
		return;
	}

	// set up the row identifiers vector
	Vector row_identifiers(ROW_TYPE, (data_ptr_t)row_numbers);

	// delete the tuples from all the indexes
	current_table->RemoveFromIndexes(row_identifiers, count);

	count = 0;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/commit_state.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class CatalogEntry;
class DataChunk;
class DataTable;
class WriteAheadLog;

struct DeleteInfo;
struct UpdateInfo;

class CommitState {
public:
	CommitState(transaction_t commit_id, WriteAheadLog *log = nullptr);

	WriteAheadLog *log;
	transaction_t commit_id;
	UndoFlags current_op;

	DataTable *current_table;
	idx_t row_identifiers[STANDARD_VECTOR_SIZE];

	unique_ptr<DataChunk> delete_chunk;
	unique_ptr<DataChunk> update_chunk;

public:
	template <bool HAS_LOG> void CommitEntry(UndoFlags type, data_ptr_t data);
	void RevertCommit(UndoFlags type, data_ptr_t data);

private:
	void SwitchTable(DataTable *table, UndoFlags new_op);

	void WriteCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data);
	void WriteDelete(DeleteInfo *info);
	void WriteUpdate(UpdateInfo *info);

	void AppendRowId(row_t rowid);
};

} // namespace duckdb










using namespace duckdb;
using namespace std;

CommitState::CommitState(transaction_t commit_id, WriteAheadLog *log)
    : log(log), commit_id(commit_id), current_table(nullptr) {
}

void CommitState::SwitchTable(DataTable *table, UndoFlags new_op) {
	if (current_table != table) {
		// write the current table to the log
		log->WriteSetTable(table->schema, table->table);
		current_table = table;
	}
}

void CommitState::WriteCatalogEntry(CatalogEntry *entry, data_ptr_t dataptr) {
	assert(log);
	// look at the type of the parent entry
	auto parent = entry->parent;
	switch (parent->type) {
	case CatalogType::TABLE:
		if (parent->temporary) {
			return;
		}
		if (entry->type == CatalogType::TABLE) {
			// ALTER TABLE statement, read the extra data after the entry
			auto extra_data_size = *((idx_t *)dataptr);
			auto extra_data = (data_ptr_t)(dataptr + sizeof(idx_t));
			// deserialize it
			BufferedDeserializer source(extra_data, extra_data_size);
			auto info = AlterInfo::Deserialize(source);
			// write the alter table in the log
			log->WriteAlter(*info);
		} else {
			// CREATE TABLE statement
			log->WriteCreateTable((TableCatalogEntry *)parent);
		}
		break;
	case CatalogType::SCHEMA:
		if (entry->type == CatalogType::SCHEMA) {
			// ALTER TABLE statement, skip it
			return;
		}
		log->WriteCreateSchema((SchemaCatalogEntry *)parent);
		break;
	case CatalogType::VIEW:
		log->WriteCreateView((ViewCatalogEntry *)parent);
		break;
	case CatalogType::SEQUENCE:
		log->WriteCreateSequence((SequenceCatalogEntry *)parent);
		break;
	case CatalogType::DELETED_ENTRY:
		if (entry->type == CatalogType::TABLE) {
			log->WriteDropTable((TableCatalogEntry *)entry);
		} else if (entry->type == CatalogType::SCHEMA) {
			log->WriteDropSchema((SchemaCatalogEntry *)entry);
		} else if (entry->type == CatalogType::VIEW) {
			log->WriteDropView((ViewCatalogEntry *)entry);
		} else if (entry->type == CatalogType::SEQUENCE) {
			log->WriteDropSequence((SequenceCatalogEntry *)entry);
		} else if (entry->type == CatalogType::PREPARED_STATEMENT) {
			// do nothing, we log the query to drop this
		} else {
			throw NotImplementedException("Don't know how to drop this type!");
		}
		break;

	case CatalogType::INDEX:
	case CatalogType::PREPARED_STATEMENT:
	case CatalogType::AGGREGATE_FUNCTION:
	case CatalogType::SCALAR_FUNCTION:
	case CatalogType::TABLE_FUNCTION:

		// do nothing, we log the query to recreate this
		break;
	default:
		throw NotImplementedException("UndoBuffer - don't know how to write this entry to the WAL");
	}
}

void CommitState::WriteDelete(DeleteInfo *info) {
	assert(log);
	// switch to the current table, if necessary
	SwitchTable(&info->GetTable(), UndoFlags::DELETE_TUPLE);

	if (!delete_chunk) {
		delete_chunk = make_unique<DataChunk>();
		vector<TypeId> delete_types = {ROW_TYPE};
		delete_chunk->Initialize(delete_types);
	}
	auto rows = FlatVector::GetData<row_t>(delete_chunk->data[0]);
	for (idx_t i = 0; i < info->count; i++) {
		rows[i] = info->base_row + info->rows[i];
	}
	delete_chunk->SetCardinality(info->count);
	log->WriteDelete(*delete_chunk);
}

void CommitState::WriteUpdate(UpdateInfo *info) {
	assert(log);
	// switch to the current table, if necessary
	SwitchTable(info->column_data->table, UndoFlags::UPDATE_TUPLE);

	update_chunk = make_unique<DataChunk>();
	vector<TypeId> update_types = {info->column_data->type, ROW_TYPE};
	update_chunk->Initialize(update_types);

	// fetch the updated values from the base table
	ColumnScanState state;
	info->segment->InitializeScan(state);
	info->segment->Fetch(state, info->vector_index, update_chunk->data[0]);

	// write the row ids into the chunk
	auto row_ids = FlatVector::GetData<row_t>(update_chunk->data[1]);
	idx_t start = info->segment->row_start + info->vector_index * STANDARD_VECTOR_SIZE;
	for (idx_t i = 0; i < info->N; i++) {
		row_ids[info->tuples[i]] = start + info->tuples[i];
	}
	SelectionVector sel(info->tuples);
	update_chunk->Slice(sel, info->N);

	log->WriteUpdate(*update_chunk, info->column_data->column_idx);
}

template <bool HAS_LOG> void CommitState::CommitEntry(UndoFlags type, data_ptr_t data) {
	switch (type) {
	case UndoFlags::CATALOG_ENTRY: {
		// set the commit timestamp of the catalog entry to the given id
		CatalogEntry *catalog_entry = *((CatalogEntry **)data);
		assert(catalog_entry->parent);
		catalog_entry->parent->timestamp = commit_id;

		if (HAS_LOG) {
			// push the catalog update to the WAL
			WriteCatalogEntry(catalog_entry, data + sizeof(CatalogEntry *));
		}
		break;
	}
	case UndoFlags::DELETE_TUPLE: {
		// deletion:
		auto info = (DeleteInfo *)data;
		info->GetTable().cardinality -= info->count;
		if (HAS_LOG && !info->GetTable().IsTemporary()) {
			WriteDelete(info);
		}
		// mark the tuples as committed
		info->vinfo->CommitDelete(commit_id, info->rows, info->count);
		break;
	}
	case UndoFlags::UPDATE_TUPLE: {
		// update:
		auto info = (UpdateInfo *)data;
		if (HAS_LOG && !info->column_data->table->IsTemporary()) {
			WriteUpdate(info);
		}
		info->version_number = commit_id;
		break;
	}
	default:
		throw NotImplementedException("UndoBuffer - don't know how to commit this type!");
	}
}

void CommitState::RevertCommit(UndoFlags type, data_ptr_t data) {
	transaction_t transaction_id = commit_id;
	switch (type) {
	case UndoFlags::CATALOG_ENTRY: {
		// set the commit timestamp of the catalog entry to the given id
		CatalogEntry *catalog_entry = *((CatalogEntry **)data);
		assert(catalog_entry->parent);
		catalog_entry->parent->timestamp = transaction_id;
		break;
	}
	case UndoFlags::DELETE_TUPLE: {
		// deletion:
		auto info = (DeleteInfo *)data;
		info->GetTable().cardinality += info->count;
		// revert the commit by writing the (uncommitted) transaction_id back into the version info
		info->vinfo->CommitDelete(transaction_id, info->rows, info->count);
		break;
	}
	case UndoFlags::UPDATE_TUPLE: {
		// update:
		auto info = (UpdateInfo *)data;
		info->version_number = transaction_id;
		break;
	}
	default:
		throw NotImplementedException("UndoBuffer - don't know how to revert commit of this type!");
	}
}

template void CommitState::CommitEntry<true>(UndoFlags type, data_ptr_t data);
template void CommitState::CommitEntry<false>(UndoFlags type, data_ptr_t data);




using namespace duckdb;
using namespace std;

DataTable &DeleteInfo::GetTable() {
	return vinfo->manager.table;
}
//===----------------------------------------------------------------------===//
//                         DuckDB
//
// duckdb/transaction/rollback_state.hpp
//
//
//===----------------------------------------------------------------------===//





namespace duckdb {
class DataChunk;
class DataTable;
class WriteAheadLog;

class RollbackState {
public:
	RollbackState() {
	}

public:
	void RollbackEntry(UndoFlags type, data_ptr_t data);
};

} // namespace duckdb










using namespace duckdb;
using namespace std;

void RollbackState::RollbackEntry(UndoFlags type, data_ptr_t data) {
	switch (type) {
	case UndoFlags::CATALOG_ENTRY: {
		// undo this catalog entry
		CatalogEntry *catalog_entry = *((CatalogEntry **)data);
		assert(catalog_entry->set);
		catalog_entry->set->Undo(catalog_entry);
		break;
	}
	case UndoFlags::DELETE_TUPLE: {
		auto info = (DeleteInfo *)data;
		// reset the deleted flag on rollback
		info->vinfo->CommitDelete(NOT_DELETED_ID, info->rows, info->count);
		break;
	}
	case UndoFlags::UPDATE_TUPLE: {
		auto info = (UpdateInfo *)data;
		info->segment->RollbackUpdate(info);
		break;
	}
	default:
		assert(type == UndoFlags::EMPTY_ENTRY);
		break;
	}
}












#include <cstring>

using namespace duckdb;
using namespace std;

Transaction &Transaction::GetTransaction(ClientContext &context) {
	return context.ActiveTransaction();
}

void Transaction::PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data, idx_t extra_data_size) {
	idx_t alloc_size = sizeof(CatalogEntry *);
	if (extra_data_size > 0) {
		alloc_size += extra_data_size + sizeof(idx_t);
	}
	auto baseptr = undo_buffer.CreateEntry(UndoFlags::CATALOG_ENTRY, alloc_size);
	// store the pointer to the catalog entry
	*((CatalogEntry **)baseptr) = entry;
	if (extra_data_size > 0) {
		// copy the extra data behind the catalog entry pointer (if any)
		baseptr += sizeof(CatalogEntry *);
		// first store the extra data size
		*((idx_t *)baseptr) = extra_data_size;
		baseptr += sizeof(idx_t);
		// then copy over the actual data
		memcpy(baseptr, extra_data, extra_data_size);
	}
}

void Transaction::PushDelete(ChunkInfo *vinfo, row_t rows[], idx_t count, idx_t base_row) {
	auto delete_info =
	    (DeleteInfo *)undo_buffer.CreateEntry(UndoFlags::DELETE_TUPLE, sizeof(DeleteInfo) + sizeof(row_t) * count);
	delete_info->vinfo = vinfo;
	delete_info->count = count;
	delete_info->base_row = base_row;
	memcpy(delete_info->rows, rows, sizeof(row_t) * count);
}

UpdateInfo *Transaction::CreateUpdateInfo(idx_t type_size, idx_t entries) {
	auto update_info = (UpdateInfo *)undo_buffer.CreateEntry(
	    UndoFlags::UPDATE_TUPLE, sizeof(UpdateInfo) + (sizeof(sel_t) + type_size) * entries);
	update_info->max = entries;
	update_info->tuples = (sel_t *)(((data_ptr_t)update_info) + sizeof(UpdateInfo));
	update_info->tuple_data = ((data_ptr_t)update_info) + sizeof(UpdateInfo) + sizeof(sel_t) * entries;
	update_info->version_number = transaction_id;
	update_info->nullmask.reset();
	return update_info;
}

string Transaction::Commit(WriteAheadLog *log, transaction_t commit_id) noexcept {
	this->commit_id = commit_id;

	UndoBuffer::IteratorState iterator_state;
	LocalStorage::CommitState commit_state;
	int64_t initial_wal_size;
	if (log) {
		initial_wal_size = log->GetWALSize();
	}
	bool changes_made = undo_buffer.ChangesMade() || storage.ChangesMade() || sequence_usage.size() > 0;
	try {
		// commit the undo buffer
		undo_buffer.Commit(iterator_state, log, commit_id);
		storage.Commit(commit_state, *this, log, commit_id);
		if (log) {
			// commit any sequences that were used to the WAL
			for (auto &entry : sequence_usage) {
				log->WriteSequenceValue(entry.first, entry.second);
			}
			// flush the WAL
			if (changes_made) {
				log->Flush();
			}
		}
		return string();
	} catch (std::exception &ex) {
		undo_buffer.RevertCommit(iterator_state, transaction_id);
		storage.RevertCommit(commit_state);
		if (log && changes_made) {
			// remove any entries written into the WAL by truncating it
			log->Truncate(initial_wal_size);
		}
		return ex.what();
	}
}






using namespace duckdb;
using namespace std;

TransactionContext::~TransactionContext() {
	if (is_invalidated) {
		return;
	}
	if (current_transaction) {
		try {
			Rollback();
		} catch (...) {
		}
	}
}

void TransactionContext::BeginTransaction() {
	assert(!current_transaction); // cannot start a transaction within a transaction
	current_transaction = transaction_manager.StartTransaction();
}

void TransactionContext::Commit() {
	assert(current_transaction); // cannot commit if there is no active transaction
	auto transaction = current_transaction;
	SetAutoCommit(true);
	current_transaction = nullptr;
	string error = transaction_manager.CommitTransaction(transaction);
	if (!error.empty()) {
		throw TransactionException("Failed to commit: %s", error.c_str());
	}
}

void TransactionContext::Rollback() {
	assert(current_transaction); // cannot rollback if there is no active transaction
	auto transaction = current_transaction;
	SetAutoCommit(true);
	current_transaction = nullptr;
	transaction_manager.RollbackTransaction(transaction);
}










using namespace duckdb;
using namespace std;

TransactionManager::TransactionManager(StorageManager &storage) : storage(storage) {
	// start timestamp starts at zero
	current_start_timestamp = 0;
	// transaction ID starts very high:
	// it should be much higher than the current start timestamp
	// if transaction_id < start_timestamp for any set of active transactions
	// uncommited data could be read by
	current_transaction_id = TRANSACTION_ID_START;
	// the current active query id
	current_query_number = 1;
}

TransactionManager::~TransactionManager() {
}

Transaction *TransactionManager::StartTransaction() {
	// obtain the transaction lock during this function
	lock_guard<mutex> lock(transaction_lock);

	if (current_start_timestamp >= TRANSACTION_ID_START) {
		throw Exception("Cannot start more transactions, ran out of "
		                "transaction identifiers!");
	}

	// obtain the start time and transaction ID of this transaction
	transaction_t start_time = current_start_timestamp++;
	transaction_t transaction_id = current_transaction_id++;
	timestamp_t start_timestamp = Timestamp::GetCurrentTimestamp();

	// create the actual transaction
	auto transaction = make_unique<Transaction>(start_time, transaction_id, start_timestamp);
	auto transaction_ptr = transaction.get();

	// store it in the set of active transactions
	active_transactions.push_back(move(transaction));
	return transaction_ptr;
}

string TransactionManager::CommitTransaction(Transaction *transaction) {
	// obtain the transaction lock during this function
	lock_guard<mutex> lock(transaction_lock);

	// obtain a commit id for the transaction
	transaction_t commit_id = current_start_timestamp++;
	// commit the UndoBuffer of the transaction
	string error = transaction->Commit(storage.GetWriteAheadLog(), commit_id);
	if (!error.empty()) {
		// commit unsuccessful: rollback the transaction instead
		transaction->commit_id = 0;
		transaction->Rollback();
	}

	// commit successful: remove the transaction id from the list of active transactions
	// potentially resulting in garbage collection
	RemoveTransaction(transaction);
	return error;
}

void TransactionManager::RollbackTransaction(Transaction *transaction) {
	// obtain the transaction lock during this function
	lock_guard<mutex> lock(transaction_lock);

	// rollback the transaction
	transaction->Rollback();

	// remove the transaction id from the list of active transactions
	// potentially resulting in garbage collection
	RemoveTransaction(transaction);
}

void TransactionManager::RemoveTransaction(Transaction *transaction) noexcept {
	// remove the transaction from the list of active transactions
	idx_t t_index = active_transactions.size();
	// check for the lowest and highest start time in the list of transactions
	transaction_t lowest_start_time = TRANSACTION_ID_START;
	transaction_t lowest_active_query = MAXIMUM_QUERY_ID;
	for (idx_t i = 0; i < active_transactions.size(); i++) {
		if (active_transactions[i].get() == transaction) {
			t_index = i;
		} else {
			lowest_start_time = std::min(lowest_start_time, active_transactions[i]->start_time);
			lowest_active_query = std::min(lowest_active_query, active_transactions[i]->active_query);
		}
	}
	transaction_t lowest_stored_query = lowest_start_time;
	assert(t_index != active_transactions.size());
	auto current_transaction = move(active_transactions[t_index]);
	if (transaction->commit_id != 0) {
		// the transaction was committed, add it to the list of recently
		// committed transactions
		recently_committed_transactions.push_back(move(current_transaction));
	} else {
		// the transaction was aborted, but we might still need its information
		// add it to the set of transactions awaiting GC
		current_transaction->highest_active_query = current_query_number;
		old_transactions.push_back(move(current_transaction));
	}
	// remove the transaction from the set of currently active transactions
	active_transactions.erase(active_transactions.begin() + t_index);
	// traverse the recently_committed transactions to see if we can remove any
	idx_t i = 0;
	for (; i < recently_committed_transactions.size(); i++) {
		assert(recently_committed_transactions[i]);
		lowest_stored_query = std::min(recently_committed_transactions[i]->start_time, lowest_stored_query);
		if (recently_committed_transactions[i]->commit_id < lowest_start_time) {
			// changes made BEFORE this transaction are no longer relevant
			// we can cleanup the undo buffer

			// HOWEVER: any currently running QUERY can still be using
			// the version information after the cleanup!

			// if we remove the UndoBuffer immediately, we have a race
			// condition

			// we can only safely do the actual memory cleanup when all the
			// currently active queries have finished running! (actually,
			// when all the currently active scans have finished running...)
			recently_committed_transactions[i]->Cleanup();
			// store the current highest active query
			recently_committed_transactions[i]->highest_active_query = current_query_number;
			// move it to the list of transactions awaiting GC
			old_transactions.push_back(move(recently_committed_transactions[i]));
		} else {
			// recently_committed_transactions is ordered on commit_id
			// implicitly thus if the current one is bigger than
			// lowest_start_time any subsequent ones are also bigger
			break;
		}
	}
	if (i > 0) {
		// we garbage collected transactions: remove them from the list
		recently_committed_transactions.erase(recently_committed_transactions.begin(),
		                                      recently_committed_transactions.begin() + i);
	}
	// check if we can free the memory of any old transactions
	i = active_transactions.size() == 0 ? old_transactions.size() : 0;
	for (; i < old_transactions.size(); i++) {
		assert(old_transactions[i]);
		assert(old_transactions[i]->highest_active_query > 0);
		if (old_transactions[i]->highest_active_query >= lowest_active_query) {
			// there is still a query running that could be using
			// this transactions' data
			break;
		}
	}
	if (i > 0) {
		// we garbage collected transactions: remove them from the list
		old_transactions.erase(old_transactions.begin(), old_transactions.begin() + i);
	}
	// check if we can free the memory of any old catalog sets
	for (i = 0; i < old_catalog_sets.size(); i++) {
		assert(old_catalog_sets[i].highest_active_query > 0);
		if (old_catalog_sets[i].highest_active_query >= lowest_stored_query) {
			// there is still a query running that could be using
			// this catalog sets' data
			break;
		}
	}
	if (i > 0) {
		// we garbage collected catalog sets: remove them from the list
		old_catalog_sets.erase(old_catalog_sets.begin(), old_catalog_sets.begin() + i);
	}
}

void TransactionManager::AddCatalogSet(ClientContext &context, unique_ptr<CatalogSet> catalog_set) {
	// remove the dependencies from all entries of the CatalogSet
	Catalog::GetCatalog(context).dependency_manager.ClearDependencies(*catalog_set);

	lock_guard<mutex> lock(transaction_lock);
	if (active_transactions.size() > 0) {
		// if there are active transactions we wait with deleting the objects
		StoredCatalogSet set;
		set.stored_set = move(catalog_set);
		set.highest_active_query = current_start_timestamp;

		old_catalog_sets.push_back(move(set));
	}
}












#include <unordered_map>

using namespace std;

namespace duckdb {
constexpr uint32_t DEFAULT_UNDO_CHUNK_SIZE = 4096 * 3;
constexpr uint32_t UNDO_ENTRY_HEADER_SIZE = sizeof(UndoFlags) + sizeof(uint32_t);

UndoBuffer::UndoBuffer() {
	head = make_unique<UndoChunk>(0);
	tail = head.get();
}

UndoChunk::UndoChunk(idx_t size) : current_position(0), maximum_size(size), prev(nullptr) {
	if (size > 0) {
		data = unique_ptr<data_t[]>(new data_t[maximum_size]);
	}
}
UndoChunk::~UndoChunk() {
	if (next) {
		auto current_next = move(next);
		while (current_next) {
			current_next = move(current_next->next);
		}
	}
}

data_ptr_t UndoChunk::WriteEntry(UndoFlags type, uint32_t len) {
	*((UndoFlags *)(data.get() + current_position)) = type;
	current_position += sizeof(UndoFlags);
	*((uint32_t *)(data.get() + current_position)) = len;
	current_position += sizeof(uint32_t);

	data_ptr_t result = data.get() + current_position;
	current_position += len;
	return result;
}

data_ptr_t UndoBuffer::CreateEntry(UndoFlags type, idx_t len) {
	assert(len <= std::numeric_limits<uint32_t>::max());
	idx_t needed_space = len + UNDO_ENTRY_HEADER_SIZE;
	if (head->current_position + needed_space >= head->maximum_size) {
		auto new_chunk =
		    make_unique<UndoChunk>(needed_space > DEFAULT_UNDO_CHUNK_SIZE ? needed_space : DEFAULT_UNDO_CHUNK_SIZE);
		head->prev = new_chunk.get();
		new_chunk->next = move(head);
		head = move(new_chunk);
	}
	return head->WriteEntry(type, len);
}

template <class T> void UndoBuffer::IterateEntries(UndoBuffer::IteratorState &state, T &&callback) {
	// iterate in insertion order: start with the tail
	state.current = tail;
	while (state.current) {
		state.start = state.current->data.get();
		state.end = state.start + state.current->current_position;
		while (state.start < state.end) {
			UndoFlags type = *((UndoFlags *)state.start);
			state.start += sizeof(UndoFlags);
			uint32_t len = *((uint32_t *)state.start);
			state.start += sizeof(uint32_t);
			callback(type, state.start);
			state.start += len;
		}
		state.current = state.current->prev;
	}
}

template <class T>
void UndoBuffer::IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback) {
	// iterate in insertion order: start with the tail
	state.current = tail;
	while (state.current) {
		state.start = state.current->data.get();
		state.end =
		    state.current == end_state.current ? end_state.start : state.start + state.current->current_position;
		while (state.start < state.end) {
			UndoFlags type = *((UndoFlags *)state.start);
			state.start += sizeof(UndoFlags);
			uint32_t len = *((uint32_t *)state.start);
			state.start += sizeof(uint32_t);
			callback(type, state.start);
			state.start += len;
		}
		if (state.current == end_state.current) {
			// finished executing until the current end state
			return;
		}
		state.current = state.current->prev;
	}
}

template <class T> void UndoBuffer::ReverseIterateEntries(T &&callback) {
	// iterate in reverse insertion order: start with the head
	auto current = head.get();
	while (current) {
		data_ptr_t start = current->data.get();
		data_ptr_t end = start + current->current_position;
		// create a vector with all nodes in this chunk
		vector<pair<UndoFlags, data_ptr_t>> nodes;
		while (start < end) {
			UndoFlags type = *((UndoFlags *)start);
			start += sizeof(UndoFlags);
			uint32_t len = *((uint32_t *)start);
			start += sizeof(uint32_t);
			nodes.push_back(make_pair(type, start));
			start += len;
		}
		// iterate over it in reverse order
		for (idx_t i = nodes.size(); i > 0; i--) {
			callback(nodes[i - 1].first, nodes[i - 1].second);
		}
		current = current->next.get();
	}
}

bool UndoBuffer::ChangesMade() {
	return head->maximum_size > 0;
}

void UndoBuffer::Cleanup() {
	// garbage collect everything in the Undo Chunk
	// this should only happen if
	//  (1) the transaction this UndoBuffer belongs to has successfully
	//  committed
	//      (on Rollback the Rollback() function should be called, that clears
	//      the chunks)
	//  (2) there is no active transaction with start_id < commit_id of this
	//  transaction
	CleanupState state;
	UndoBuffer::IteratorState iterator_state;
	IterateEntries(iterator_state, [&](UndoFlags type, data_ptr_t data) { state.CleanupEntry(type, data); });
}

void UndoBuffer::Commit(UndoBuffer::IteratorState &iterator_state, WriteAheadLog *log, transaction_t commit_id) {
	CommitState state(commit_id, log);
	if (log) {
		// commit WITH write ahead log
		IterateEntries(iterator_state, [&](UndoFlags type, data_ptr_t data) { state.CommitEntry<true>(type, data); });
	} else {
		// comit WITHOUT write ahead log
		IterateEntries(iterator_state, [&](UndoFlags type, data_ptr_t data) { state.CommitEntry<false>(type, data); });
	}
}

void UndoBuffer::RevertCommit(UndoBuffer::IteratorState &end_state, transaction_t transaction_id) {
	CommitState state(transaction_id, nullptr);
	UndoBuffer::IteratorState start_state;
	IterateEntries(start_state, end_state, [&](UndoFlags type, data_ptr_t data) { state.RevertCommit(type, data); });
}

void UndoBuffer::Rollback() noexcept {
	// rollback needs to be performed in reverse
	RollbackState state;
	ReverseIterateEntries([&](UndoFlags type, data_ptr_t data) { state.RollbackEntry(type, data); });
}
} // namespace duckdb
// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

// Formatting library for C++ - implementation
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#ifndef FMT_FORMAT_INL_H_
#define FMT_FORMAT_INL_H_



#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdarg>
#include <cstring>  // for std::memmove
#include <cwchar>
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
#  include <locale>
#endif

#if FMT_EXCEPTIONS
#  define FMT_TRY try
#  define FMT_CATCH(x) catch (x)
#else
#  define FMT_TRY if (true)
#  define FMT_CATCH(x) if (false)
#endif

#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable : 4702)  // unreachable code
#endif

// Dummy implementations of strerror_r and strerror_s called if corresponding
// system functions are not available.
inline fmt::internal::null<> strerror_r(int, char*, ...) { return {}; }
inline fmt::internal::null<> strerror_s(char*, std::size_t, ...) { return {}; }

FMT_BEGIN_NAMESPACE
namespace internal {

#ifndef _MSC_VER
#  define FMT_SNPRINTF snprintf
#else  // _MSC_VER
inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) {
  va_list args;
  va_start(args, format);
  int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
  va_end(args);
  return result;
}
#  define FMT_SNPRINTF fmt_snprintf
#endif  // _MSC_VER

using format_func = void (*)(internal::buffer<char>&, int, string_view);

// A portable thread-safe version of strerror.
// Sets buffer to point to a string describing the error code.
// This can be either a pointer to a string stored in buffer,
// or a pointer to some static immutable string.
// Returns one of the following values:
//   0      - success
//   ERANGE - buffer is not large enough to store the error message
//   other  - failure
// Buffer should be at least of size 1.
FMT_FUNC int safe_strerror(int error_code, char*& buffer,
                           std::size_t buffer_size) FMT_NOEXCEPT {
  FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer");

  class dispatcher {
   private:
    int error_code_;
    char*& buffer_;
    std::size_t buffer_size_;

    // A noop assignment operator to avoid bogus warnings.
    void operator=(const dispatcher&) {}

    // Handle the result of XSI-compliant version of strerror_r.
    int handle(int result) {
      // glibc versions before 2.13 return result in errno.
      return result == -1 ? errno : result;
    }

    // Handle the result of GNU-specific version of strerror_r.
    int handle(char* message) {
      // If the buffer is full then the message is probably truncated.
      if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
        return ERANGE;
      buffer_ = message;
      return 0;
    }

    // Handle the case when strerror_r is not available.
    int handle(internal::null<>) {
      return fallback(strerror_s(buffer_, buffer_size_, error_code_));
    }

    // Fallback to strerror_s when strerror_r is not available.
    int fallback(int result) {
      // If the buffer is full then the message is probably truncated.
      return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE
                                                                : result;
    }

#if !FMT_MSC_VER
    // Fallback to strerror if strerror_r and strerror_s are not available.
    int fallback(internal::null<>) {
      errno = 0;
      buffer_ = strerror(error_code_);
      return errno;
    }
#endif

   public:
    dispatcher(int err_code, char*& buf, std::size_t buf_size)
        : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}

    int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
  };
  return dispatcher(error_code, buffer, buffer_size).run();
}

FMT_FUNC void format_error_code(internal::buffer<char>& out, int error_code,
                                string_view message) FMT_NOEXCEPT {
  // Report error code making sure that the output fits into
  // inline_buffer_size to avoid dynamic memory allocation and potential
  // bad_alloc.
  out.resize(0);
  static const char SEP[] = ": ";
  static const char ERROR_STR[] = "error ";
  // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
  std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
  auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);
  if (internal::is_negative(error_code)) {
    abs_value = 0 - abs_value;
    ++error_code_size;
  }
  error_code_size += internal::to_unsigned(internal::count_digits(abs_value));
  internal::writer w(out);
  if (message.size() <= inline_buffer_size - error_code_size) {
    w.write(message);
    w.write(SEP);
  }
  w.write(ERROR_STR);
  w.write(error_code);
  assert(out.size() <= inline_buffer_size);
}

FMT_FUNC void report_error(format_func func, int error_code,
                           string_view message) FMT_NOEXCEPT {
  memory_buffer full_message;
  func(full_message, error_code, message);
  // Don't use fwrite_fully because the latter may throw.
  (void)std::fwrite(full_message.data(), full_message.size(), 1, stderr);
  std::fputc('\n', stderr);
}
}  // namespace internal

#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
namespace internal {

template <typename Locale>
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
  static_assert(std::is_same<Locale, std::locale>::value, "");
}

template <typename Locale> Locale locale_ref::get() const {
  static_assert(std::is_same<Locale, std::locale>::value, "");
  return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
}

template <typename Char> FMT_FUNC std::string grouping_impl(locale_ref loc) {
  return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()).grouping();
}
template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
  return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
      .thousands_sep();
}
template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
  return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
      .decimal_point();
}
}  // namespace internal
#else
template <typename Char>
FMT_FUNC std::string internal::grouping_impl(locale_ref) {
  return "\03";
}
template <typename Char>
FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
  return FMT_STATIC_THOUSANDS_SEPARATOR;
}
template <typename Char>
FMT_FUNC Char internal::decimal_point_impl(locale_ref) {
  return '.';
}
#endif

namespace internal {

template <> FMT_FUNC int count_digits<4>(internal::fallback_uintptr n) {
  // fallback_uintptr is always stored in little endian.
  int i = static_cast<int>(sizeof(void*)) - 1;
  while (i > 0 && n.value[i] == 0) --i;
  auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
  return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1;
}

template <typename T>
const char basic_data<T>::digits[] =
    "0001020304050607080910111213141516171819"
    "2021222324252627282930313233343536373839"
    "4041424344454647484950515253545556575859"
    "6061626364656667686970717273747576777879"
    "8081828384858687888990919293949596979899";

template <typename T>
const char basic_data<T>::hex_digits[] = "0123456789abcdef";

#define FMT_POWERS_OF_10(factor)                                             \
  factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
      (factor)*1000000, (factor)*10000000, (factor)*100000000,               \
      (factor)*1000000000

template <typename T>
const uint64_t basic_data<T>::powers_of_10_64[] = {
    1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
    10000000000000000000ULL};

template <typename T>
const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0,
                                                           FMT_POWERS_OF_10(1)};

template <typename T>
const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
    0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
    10000000000000000000ULL};

// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
// These are generated by support/compute-powers.py.
template <typename T>
const uint64_t basic_data<T>::pow10_significands[] = {
    0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
    0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
    0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
    0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
    0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
    0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
    0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
    0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
    0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
    0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
    0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
    0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
    0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
    0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
    0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
    0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
    0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
    0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
    0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
    0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
    0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
    0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
    0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
    0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
    0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
    0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
    0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
    0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
    0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
};

// Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
// to significands above.
template <typename T>
const int16_t basic_data<T>::pow10_exponents[] = {
    -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
    -927,  -901,  -874,  -847,  -821,  -794,  -768,  -741,  -715,  -688, -661,
    -635,  -608,  -582,  -555,  -529,  -502,  -475,  -449,  -422,  -396, -369,
    -343,  -316,  -289,  -263,  -236,  -210,  -183,  -157,  -130,  -103, -77,
    -50,   -24,   3,     30,    56,    83,    109,   136,   162,   189,  216,
    242,   269,   295,   322,   348,   375,   402,   428,   455,   481,  508,
    534,   561,   588,   614,   641,   667,   694,   720,   747,   774,  800,
    827,   853,   880,   907,   933,   960,   986,   1013,  1039,  1066};

template <typename T>
const char basic_data<T>::foreground_color[] = "\x1b[38;2;";
template <typename T>
const char basic_data<T>::background_color[] = "\x1b[48;2;";
template <typename T> const char basic_data<T>::reset_color[] = "\x1b[0m";
template <typename T> const wchar_t basic_data<T>::wreset_color[] = L"\x1b[0m";
template <typename T> const char basic_data<T>::signs[] = {0, '-', '+', ' '};

template <typename T> struct bits {
  static FMT_CONSTEXPR_DECL const int value =
      static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
};

class fp;
template <int SHIFT = 0> fp normalize(fp value);

// Lower (upper) boundary is a value half way between a floating-point value
// and its predecessor (successor). Boundaries have the same exponent as the
// value so only significands are stored.
struct boundaries {
  uint64_t lower;
  uint64_t upper;
};

// A handmade floating-point number f * pow(2, e).
class fp {
 private:
  using significand_type = uint64_t;

  // All sizes are in bits.
  // Subtract 1 to account for an implicit most significant bit in the
  // normalized form.
  static FMT_CONSTEXPR_DECL const int double_significand_size =
      std::numeric_limits<double>::digits - 1;
  static FMT_CONSTEXPR_DECL const uint64_t implicit_bit =
      1ULL << double_significand_size;

 public:
  significand_type f;
  int e;

  static FMT_CONSTEXPR_DECL const int significand_size =
      bits<significand_type>::value;

  fp() : f(0), e(0) {}
  fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}

  // Constructs fp from an IEEE754 double. It is a template to prevent compile
  // errors on platforms where double is not IEEE754.
  template <typename Double> explicit fp(Double d) { assign(d); }

  // Normalizes the value converted from double and multiplied by (1 << SHIFT).
  template <int SHIFT> friend fp normalize(fp value) {
    // Handle subnormals.
    const auto shifted_implicit_bit = fp::implicit_bit << SHIFT;
    while ((value.f & shifted_implicit_bit) == 0) {
      value.f <<= 1;
      --value.e;
    }
    // Subtract 1 to account for hidden bit.
    const auto offset =
        fp::significand_size - fp::double_significand_size - SHIFT - 1;
    value.f <<= offset;
    value.e -= offset;
    return value;
  }

  // Assigns d to this and return true iff predecessor is closer than successor.
  template <typename Double, FMT_ENABLE_IF(sizeof(Double) == sizeof(uint64_t))>
  bool assign(Double d) {
    // Assume double is in the format [sign][exponent][significand].
    using limits = std::numeric_limits<Double>;
    const int exponent_size =
        bits<Double>::value - double_significand_size - 1;  // -1 for sign
    const uint64_t significand_mask = implicit_bit - 1;
    const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask;
    const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
    auto u = bit_cast<uint64_t>(d);
    f = u & significand_mask;
    auto biased_e = (u & exponent_mask) >> double_significand_size;
    // Predecessor is closer if d is a normalized power of 2 (f == 0) other than
    // the smallest normalized number (biased_e > 1).
    bool is_predecessor_closer = f == 0 && biased_e > 1;
    if (biased_e != 0)
      f += implicit_bit;
    else
      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
    e = static_cast<int>(biased_e - exponent_bias - double_significand_size);
    return is_predecessor_closer;
  }

  template <typename Double, FMT_ENABLE_IF(sizeof(Double) != sizeof(uint64_t))>
  bool assign(Double) {
    *this = fp();
    return false;
  }

  // Assigns d to this together with computing lower and upper boundaries,
  // where a boundary is a value half way between the number and its predecessor
  // (lower) or successor (upper). The upper boundary is normalized and lower
  // has the same exponent but may be not normalized.
  template <typename Double> boundaries assign_with_boundaries(Double d) {
    bool is_lower_closer = assign(d);
    fp lower =
        is_lower_closer ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
    // 1 in normalize accounts for the exponent shift above.
    fp upper = normalize<1>(fp((f << 1) + 1, e - 1));
    lower.f <<= lower.e - upper.e;
    return boundaries{lower.f, upper.f};
  }

  template <typename Double> boundaries assign_float_with_boundaries(Double d) {
    assign(d);
    constexpr int min_normal_e = std::numeric_limits<float>::min_exponent -
                                 std::numeric_limits<double>::digits;
    significand_type half_ulp = 1 << (std::numeric_limits<double>::digits -
                                      std::numeric_limits<float>::digits - 1);
    if (min_normal_e > e) half_ulp <<= min_normal_e - e;
    fp upper = normalize<0>(fp(f + half_ulp, e));
    fp lower = fp(
        f - (half_ulp >> ((f == implicit_bit && e > min_normal_e) ? 1 : 0)), e);
    lower.f <<= lower.e - upper.e;
    return boundaries{lower.f, upper.f};
  }
};

inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; }

// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
inline uint64_t multiply(uint64_t lhs, uint64_t rhs) {
#if FMT_USE_INT128
  auto product = static_cast<__uint128_t>(lhs) * rhs;
  auto f = static_cast<uint64_t>(product >> 64);
  return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
#else
  // Multiply 32-bit parts of significands.
  uint64_t mask = (1ULL << 32) - 1;
  uint64_t a = lhs >> 32, b = lhs & mask;
  uint64_t c = rhs >> 32, d = rhs & mask;
  uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
  // Compute mid 64-bit of result and round.
  uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
  return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
#endif
}

inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; }

// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
FMT_FUNC fp get_cached_power(int min_exponent, int& pow10_exponent) {
  const uint64_t one_over_log2_10 = 0x4d104d42;  // round(pow(2, 32) / log2(10))
  int index = static_cast<int>(
      static_cast<int64_t>(
          (min_exponent + fp::significand_size - 1) * one_over_log2_10 +
          ((uint64_t(1) << 32) - 1)  // ceil
          ) >>
      32  // arithmetic shift
  );
  // Decimal exponent of the first (smallest) cached power of 10.
  const int first_dec_exp = -348;
  // Difference between 2 consecutive decimal exponents in cached powers of 10.
  const int dec_exp_step = 8;
  index = (index - first_dec_exp - 1) / dec_exp_step + 1;
  pow10_exponent = first_dec_exp + index * dec_exp_step;
  return {data::pow10_significands[index], data::pow10_exponents[index]};
}

// A simple accumulator to hold the sums of terms in bigint::square if uint128_t
// is not available.
struct accumulator {
  uint64_t lower;
  uint64_t upper;

  accumulator() : lower(0), upper(0) {}
  explicit operator uint32_t() const { return static_cast<uint32_t>(lower); }

  void operator+=(uint64_t n) {
    lower += n;
    if (lower < n) ++upper;
  }
  void operator>>=(int shift) {
    assert(shift == 32);
    (void)shift;
    lower = (upper << 32) | (lower >> 32);
    upper >>= 32;
  }
};

class bigint {
 private:
  // A bigint is stored as an array of bigits (big digits), with bigit at index
  // 0 being the least significant one.
  using bigit = uint32_t;
  using double_bigit = uint64_t;
  enum { bigits_capacity = 32 };
  basic_memory_buffer<bigit, bigits_capacity> bigits_;
  int exp_;

  static FMT_CONSTEXPR_DECL const int bigit_bits = bits<bigit>::value;

  friend struct formatter<bigint>;

  void subtract_bigits(int index, bigit other, bigit& borrow) {
    auto result = static_cast<double_bigit>(bigits_[index]) - other - borrow;
    bigits_[index] = static_cast<bigit>(result);
    borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
  }

  void remove_leading_zeros() {
    int num_bigits = static_cast<int>(bigits_.size()) - 1;
    while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits;
    bigits_.resize(num_bigits + 1);
  }

  // Computes *this -= other assuming aligned bigints and *this >= other.
  void subtract_aligned(const bigint& other) {
    FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
    FMT_ASSERT(compare(*this, other) >= 0, "");
    bigit borrow = 0;
    int i = other.exp_ - exp_;
    for (int j = 0, n = static_cast<int>(other.bigits_.size()); j != n;
         ++i, ++j) {
      subtract_bigits(i, other.bigits_[j], borrow);
    }
    while (borrow > 0) subtract_bigits(i, 0, borrow);
    remove_leading_zeros();
  }

  void multiply(uint32_t value) {
    const double_bigit wide_value = value;
    bigit carry = 0;
    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
      double_bigit result = bigits_[i] * wide_value + carry;
      bigits_[i] = static_cast<bigit>(result);
      carry = static_cast<bigit>(result >> bigit_bits);
    }
    if (carry != 0) bigits_.push_back(carry);
  }

  void multiply(uint64_t value) {
    const bigit mask = ~bigit(0);
    const double_bigit lower = value & mask;
    const double_bigit upper = value >> bigit_bits;
    double_bigit carry = 0;
    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
      double_bigit result = bigits_[i] * lower + (carry & mask);
      carry =
          bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits);
      bigits_[i] = static_cast<bigit>(result);
    }
    while (carry != 0) {
      bigits_.push_back(carry & mask);
      carry >>= bigit_bits;
    }
  }

 public:
  bigint() : exp_(0) {}
  explicit bigint(uint64_t n) { assign(n); }
  ~bigint() { assert(bigits_.capacity() <= bigits_capacity); }

  bigint(const bigint&) = delete;
  void operator=(const bigint&) = delete;

  void assign(const bigint& other) {
    bigits_.resize(other.bigits_.size());
    auto data = other.bigits_.data();
    std::copy(data, data + other.bigits_.size(), bigits_.data());
    exp_ = other.exp_;
  }

  void assign(uint64_t n) {
    int num_bigits = 0;
    do {
      bigits_[num_bigits++] = n & ~bigit(0);
      n >>= bigit_bits;
    } while (n != 0);
    bigits_.resize(num_bigits);
    exp_ = 0;
  }

  int num_bigits() const { return static_cast<int>(bigits_.size()) + exp_; }

  bigint& operator<<=(int shift) {
    assert(shift >= 0);
    exp_ += shift / bigit_bits;
    shift %= bigit_bits;
    if (shift == 0) return *this;
    bigit carry = 0;
    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
      bigit c = bigits_[i] >> (bigit_bits - shift);
      bigits_[i] = (bigits_[i] << shift) + carry;
      carry = c;
    }
    if (carry != 0) bigits_.push_back(carry);
    return *this;
  }

  template <typename Int> bigint& operator*=(Int value) {
    FMT_ASSERT(value > 0, "");
    multiply(uint32_or_64_or_128_t<Int>(value));
    return *this;
  }

  friend int compare(const bigint& lhs, const bigint& rhs) {
    int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
    if (num_lhs_bigits != num_rhs_bigits)
      return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
    int i = static_cast<int>(lhs.bigits_.size()) - 1;
    int j = static_cast<int>(rhs.bigits_.size()) - 1;
    int end = i - j;
    if (end < 0) end = 0;
    for (; i >= end; --i, --j) {
      bigit lhs_bigit = lhs.bigits_[i], rhs_bigit = rhs.bigits_[j];
      if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
    }
    if (i != j) return i > j ? 1 : -1;
    return 0;
  }

  // Returns compare(lhs1 + lhs2, rhs).
  friend int add_compare(const bigint& lhs1, const bigint& lhs2,
                         const bigint& rhs) {
    int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits());
    int num_rhs_bigits = rhs.num_bigits();
    if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
    if (max_lhs_bigits > num_rhs_bigits) return 1;
    auto get_bigit = [](const bigint& n, int i) -> bigit {
      return i >= n.exp_ && i < n.num_bigits() ? n.bigits_[i - n.exp_] : 0;
    };
    double_bigit borrow = 0;
    int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_);
    for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
      double_bigit sum =
          static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
      bigit rhs_bigit = get_bigit(rhs, i);
      if (sum > rhs_bigit + borrow) return 1;
      borrow = rhs_bigit + borrow - sum;
      if (borrow > 1) return -1;
      borrow <<= bigit_bits;
    }
    return borrow != 0 ? -1 : 0;
  }

  // Assigns pow(10, exp) to this bigint.
  void assign_pow10(int exp) {
    assert(exp >= 0);
    if (exp == 0) return assign(1);
    // Find the top bit.
    int bitmask = 1;
    while (exp >= bitmask) bitmask <<= 1;
    bitmask >>= 1;
    // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
    // repeated squaring and multiplication.
    assign(5);
    bitmask >>= 1;
    while (bitmask != 0) {
      square();
      if ((exp & bitmask) != 0) *this *= 5;
      bitmask >>= 1;
    }
    *this <<= exp;  // Multiply by pow(2, exp) by shifting.
  }

  void square() {
    basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
    int num_bigits = static_cast<int>(bigits_.size());
    int num_result_bigits = 2 * num_bigits;
    bigits_.resize(num_result_bigits);
    using accumulator_t = conditional_t<FMT_USE_INT128, uint128_t, accumulator>;
    auto sum = accumulator_t();
    for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
      // Compute bigit at position bigit_index of the result by adding
      // cross-product terms n[i] * n[j] such that i + j == bigit_index.
      for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
        // Most terms are multiplied twice which can be optimized in the future.
        sum += static_cast<double_bigit>(n[i]) * n[j];
      }
      bigits_[bigit_index] = static_cast<bigit>(sum);
      sum >>= bits<bigit>::value;  // Compute the carry.
    }
    // Do the same for the top half.
    for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
         ++bigit_index) {
      for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
        sum += static_cast<double_bigit>(n[i++]) * n[j--];
      bigits_[bigit_index] = static_cast<bigit>(sum);
      sum >>= bits<bigit>::value;
    }
    --num_result_bigits;
    remove_leading_zeros();
    exp_ *= 2;
  }

  // Divides this bignum by divisor, assigning the remainder to this and
  // returning the quotient.
  int divmod_assign(const bigint& divisor) {
    FMT_ASSERT(this != &divisor, "");
    if (compare(*this, divisor) < 0) return 0;
    int num_bigits = static_cast<int>(bigits_.size());
    FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1] != 0, "");
    int exp_difference = exp_ - divisor.exp_;
    if (exp_difference > 0) {
      // Align bigints by adding trailing zeros to simplify subtraction.
      bigits_.resize(num_bigits + exp_difference);
      for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
        bigits_[j] = bigits_[i];
      std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
      exp_ -= exp_difference;
    }
    int quotient = 0;
    do {
      subtract_aligned(divisor);
      ++quotient;
    } while (compare(*this, divisor) >= 0);
    return quotient;
  }
};

enum round_direction { unknown, up, down };

// Given the divisor (normally a power of 10), the remainder = v % divisor for
// some number v and the error, returns whether v should be rounded up, down, or
// whether the rounding direction can't be determined due to error.
// error should be less than divisor / 2.
inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder,
                                           uint64_t error) {
  FMT_ASSERT(remainder < divisor, "");  // divisor - remainder won't overflow.
  FMT_ASSERT(error < divisor, "");      // divisor - error won't overflow.
  FMT_ASSERT(error < divisor - error, "");  // error * 2 won't overflow.
  // Round down if (remainder + error) * 2 <= divisor.
  if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
    return down;
  // Round up if (remainder - error) * 2 >= divisor.
  if (remainder >= error &&
      remainder - error >= divisor - (remainder - error)) {
    return up;
  }
  return unknown;
}

namespace digits {
enum result {
  more,  // Generate more digits.
  done,  // Done generating digits.
  error  // Digit generation cancelled due to an error.
};
}

// Generates output using the Grisu digit-gen algorithm.
// error: the size of the region (lower, upper) outside of which numbers
// definitely do not round to value (Delta in Grisu3).
template <typename Handler>
FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error,
                                                  int& exp, Handler& handler) {
  const fp one(1ULL << -value.e, value.e);
  // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be
  // zero because it contains a product of two 64-bit numbers with MSB set (due
  // to normalization) - 1, shifted right by at most 60 bits.
  auto integral = static_cast<uint32_t>(value.f >> -one.e);
  FMT_ASSERT(integral != 0, "");
  FMT_ASSERT(integral == value.f >> -one.e, "");
  // The fractional part of scaled value (p2 in Grisu) c = value % one.
  uint64_t fractional = value.f & (one.f - 1);
  exp = count_digits(integral);  // kappa in Grisu.
  // Divide by 10 to prevent overflow.
  auto result = handler.on_start(data::powers_of_10_64[exp - 1] << -one.e,
                                 value.f / 10, error * 10, exp);
  if (result != digits::more) return result;
  // Generate digits for the integral part. This can produce up to 10 digits.
  do {
    uint32_t digit = 0;
    auto divmod_integral = [&](uint32_t divisor) {
      digit = integral / divisor;
      integral %= divisor;
    };
    // This optimization by Milo Yip reduces the number of integer divisions by
    // one per iteration.
    switch (exp) {
    case 10:
      divmod_integral(1000000000);
      break;
    case 9:
      divmod_integral(100000000);
      break;
    case 8:
      divmod_integral(10000000);
      break;
    case 7:
      divmod_integral(1000000);
      break;
    case 6:
      divmod_integral(100000);
      break;
    case 5:
      divmod_integral(10000);
      break;
    case 4:
      divmod_integral(1000);
      break;
    case 3:
      divmod_integral(100);
      break;
    case 2:
      divmod_integral(10);
      break;
    case 1:
      digit = integral;
      integral = 0;
      break;
    default:
      FMT_ASSERT(false, "invalid number of digits");
    }
    --exp;
    uint64_t remainder =
        (static_cast<uint64_t>(integral) << -one.e) + fractional;
    result = handler.on_digit(static_cast<char>('0' + digit),
                              data::powers_of_10_64[exp] << -one.e, remainder,
                              error, exp, true);
    if (result != digits::more) return result;
  } while (exp > 0);
  // Generate digits for the fractional part.
  for (;;) {
    fractional *= 10;
    error *= 10;
    char digit =
        static_cast<char>('0' + static_cast<char>(fractional >> -one.e));
    fractional &= one.f - 1;
    --exp;
    result = handler.on_digit(digit, one.f, fractional, error, exp, false);
    if (result != digits::more) return result;
  }
}

// The fixed precision digit handler.
struct fixed_handler {
  char* buf;
  int size;
  int precision;
  int exp10;
  bool fixed;

  digits::result on_start(uint64_t divisor, uint64_t remainder, uint64_t error,
                          int& exp) {
    // Non-fixed formats require at least one digit and no precision adjustment.
    if (!fixed) return digits::more;
    // Adjust fixed precision by exponent because it is relative to decimal
    // point.
    precision += exp + exp10;
    // Check if precision is satisfied just by leading zeros, e.g.
    // format("{:.2f}", 0.001) gives "0.00" without generating any digits.
    if (precision > 0) return digits::more;
    if (precision < 0) return digits::done;
    auto dir = get_round_direction(divisor, remainder, error);
    if (dir == unknown) return digits::error;
    buf[size++] = dir == up ? '1' : '0';
    return digits::done;
  }

  digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder,
                          uint64_t error, int, bool integral) {
    FMT_ASSERT(remainder < divisor, "");
    buf[size++] = digit;
    if (size < precision) return digits::more;
    if (!integral) {
      // Check if error * 2 < divisor with overflow prevention.
      // The check is not needed for the integral part because error = 1
      // and divisor > (1 << 32) there.
      if (error >= divisor || error >= divisor - error) return digits::error;
    } else {
      FMT_ASSERT(error == 1 && divisor > 2, "");
    }
    auto dir = get_round_direction(divisor, remainder, error);
    if (dir != up) return dir == down ? digits::done : digits::error;
    ++buf[size - 1];
    for (int i = size - 1; i > 0 && buf[i] > '9'; --i) {
      buf[i] = '0';
      ++buf[i - 1];
    }
    if (buf[0] > '9') {
      buf[0] = '1';
      buf[size++] = '0';
    }
    return digits::done;
  }
};

// The shortest representation digit handler.
struct grisu_shortest_handler {
  char* buf;
  int size;
  // Distance between scaled value and upper bound (wp_W in Grisu3).
  uint64_t diff;

  digits::result on_start(uint64_t, uint64_t, uint64_t, int&) {
    return digits::more;
  }

  // Decrement the generated number approaching value from above.
  void round(uint64_t d, uint64_t divisor, uint64_t& remainder,
             uint64_t error) {
    while (
        remainder < d && error - remainder >= divisor &&
        (remainder + divisor < d || d - remainder >= remainder + divisor - d)) {
      --buf[size - 1];
      remainder += divisor;
    }
  }

  // Implements Grisu's round_weed.
  digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder,
                          uint64_t error, int exp, bool integral) {
    buf[size++] = digit;
    if (remainder >= error) return digits::more;
    uint64_t unit = integral ? 1 : data::powers_of_10_64[-exp];
    uint64_t up = (diff - 1) * unit;  // wp_Wup
    round(up, divisor, remainder, error);
    uint64_t down = (diff + 1) * unit;  // wp_Wdown
    if (remainder < down && error - remainder >= divisor &&
        (remainder + divisor < down ||
         down - remainder > remainder + divisor - down)) {
      return digits::error;
    }
    return 2 * unit <= remainder && remainder <= error - 4 * unit
               ? digits::done
               : digits::error;
  }
};

// Formats value using a variation of the Fixed-Precision Positive
// Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
// https://fmt.dev/p372-steele.pdf.
template <typename Double>
void fallback_format(Double d, buffer<char>& buf, int& exp10) {
  bigint numerator;    // 2 * R in (FPP)^2.
  bigint denominator;  // 2 * S in (FPP)^2.
  // lower and upper are differences between value and corresponding boundaries.
  bigint lower;             // (M^- in (FPP)^2).
  bigint upper_store;       // upper's value if different from lower.
  bigint* upper = nullptr;  // (M^+ in (FPP)^2).
  fp value;
  // Shift numerator and denominator by an extra bit or two (if lower boundary
  // is closer) to make lower and upper integers. This eliminates multiplication
  // by 2 during later computations.
  // TODO: handle float
  int shift = value.assign(d) ? 2 : 1;
  uint64_t significand = value.f << shift;
  if (value.e >= 0) {
    numerator.assign(significand);
    numerator <<= value.e;
    lower.assign(1);
    lower <<= value.e;
    if (shift != 1) {
      upper_store.assign(1);
      upper_store <<= value.e + 1;
      upper = &upper_store;
    }
    denominator.assign_pow10(exp10);
    denominator <<= 1;
  } else if (exp10 < 0) {
    numerator.assign_pow10(-exp10);
    lower.assign(numerator);
    if (shift != 1) {
      upper_store.assign(numerator);
      upper_store <<= 1;
      upper = &upper_store;
    }
    numerator *= significand;
    denominator.assign(1);
    denominator <<= shift - value.e;
  } else {
    numerator.assign(significand);
    denominator.assign_pow10(exp10);
    denominator <<= shift - value.e;
    lower.assign(1);
    if (shift != 1) {
      upper_store.assign(1ULL << 1);
      upper = &upper_store;
    }
  }
  if (!upper) upper = &lower;
  // Invariant: value == (numerator / denominator) * pow(10, exp10).
  bool even = (value.f & 1) == 0;
  int num_digits = 0;
  char* data = buf.data();
  for (;;) {
    int digit = numerator.divmod_assign(denominator);
    bool low = compare(numerator, lower) - even < 0;  // numerator <[=] lower.
    // numerator + upper >[=] pow10:
    bool high = add_compare(numerator, *upper, denominator) + even > 0;
    data[num_digits++] = static_cast<char>('0' + digit);
    if (low || high) {
      if (!low) {
        ++data[num_digits - 1];
      } else if (high) {
        int result = add_compare(numerator, numerator, denominator);
        // Round half to even.
        if (result > 0 || (result == 0 && (digit % 2) != 0))
          ++data[num_digits - 1];
      }
      buf.resize(num_digits);
      exp10 -= num_digits - 1;
      return;
    }
    numerator *= 10;
    lower *= 10;
    if (upper != &lower) *upper *= 10;
  }
}

// Formats value using the Grisu algorithm
// (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf)
// if T is a IEEE754 binary32 or binary64 and snprintf otherwise.
template <typename T>
int format_float(T value, int precision, float_specs specs, buffer<char>& buf) {
  static_assert(!std::is_same<T, float>(), "");
  FMT_ASSERT(value >= 0, "value is negative");

  const bool fixed = specs.format == float_format::fixed;
  if (value <= 0) {  // <= instead of == to silence a warning.
    if (precision <= 0 || !fixed) {
      buf.push_back('0');
      return 0;
    }
    buf.resize(to_unsigned(precision));
    std::uninitialized_fill_n(buf.data(), precision, '0');
    return -precision;
  }

  if (!specs.use_grisu) return snprintf_float(value, precision, specs, buf);

  int exp = 0;
  const int min_exp = -60;  // alpha in Grisu.
  int cached_exp10 = 0;     // K in Grisu.
  if (precision != -1) {
    if (precision > 17) return snprintf_float(value, precision, specs, buf);
    fp normalized = normalize(fp(value));
    const auto cached_pow = get_cached_power(
        min_exp - (normalized.e + fp::significand_size), cached_exp10);
    normalized = normalized * cached_pow;
    fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
    if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error)
      return snprintf_float(value, precision, specs, buf);
    int num_digits = handler.size;
    if (!fixed) {
      // Remove trailing zeros.
      while (num_digits > 0 && buf[num_digits - 1] == '0') {
        --num_digits;
        ++exp;
      }
    }
    buf.resize(to_unsigned(num_digits));
  } else {
    fp fp_value;
    auto boundaries = specs.binary32
                          ? fp_value.assign_float_with_boundaries(value)
                          : fp_value.assign_with_boundaries(value);
    fp_value = normalize(fp_value);
    // Find a cached power of 10 such that multiplying value by it will bring
    // the exponent in the range [min_exp, -32].
    const fp cached_pow = get_cached_power(
        min_exp - (fp_value.e + fp::significand_size), cached_exp10);
    // Multiply value and boundaries by the cached power of 10.
    fp_value = fp_value * cached_pow;
    boundaries.lower = multiply(boundaries.lower, cached_pow.f);
    boundaries.upper = multiply(boundaries.upper, cached_pow.f);
    assert(min_exp <= fp_value.e && fp_value.e <= -32);
    --boundaries.lower;  // \tilde{M}^- - 1 ulp -> M^-_{\downarrow}.
    ++boundaries.upper;  // \tilde{M}^+ + 1 ulp -> M^+_{\uparrow}.
    // Numbers outside of (lower, upper) definitely do not round to value.
    grisu_shortest_handler handler{buf.data(), 0,
                                   boundaries.upper - fp_value.f};
    auto result =
        grisu_gen_digits(fp(boundaries.upper, fp_value.e),
                         boundaries.upper - boundaries.lower, exp, handler);
    if (result == digits::error) {
      exp += handler.size - cached_exp10 - 1;
      fallback_format(value, buf, exp);
      return exp;
    }
    buf.resize(to_unsigned(handler.size));
  }
  return exp - cached_exp10;
}

template <typename T>
int snprintf_float(T value, int precision, float_specs specs,
                   buffer<char>& buf) {
  // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
  FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
  static_assert(!std::is_same<T, float>(), "");

  // Subtract 1 to account for the difference in precision since we use %e for
  // both general and exponent format.
  if (specs.format == float_format::general ||
      specs.format == float_format::exp)
    precision = (precision >= 0 ? precision : 6) - 1;

  // Build the format string.
  enum { max_format_size = 7 };  // Ths longest format is "%#.*Le".
  char format[max_format_size];
  char* format_ptr = format;
  *format_ptr++ = '%';
  if (specs.trailing_zeros) *format_ptr++ = '#';
  if (precision >= 0) {
    *format_ptr++ = '.';
    *format_ptr++ = '*';
  }
  if (std::is_same<T, long double>()) *format_ptr++ = 'L';
  *format_ptr++ = specs.format != float_format::hex
                      ? (specs.format == float_format::fixed ? 'f' : 'e')
                      : (specs.upper ? 'A' : 'a');
  *format_ptr = '\0';

  // Format using snprintf.
  auto offset = buf.size();
  for (;;) {
    auto begin = buf.data() + offset;
    auto capacity = buf.capacity() - offset;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    if (precision > 100000)
      throw std::runtime_error(
          "fuzz mode - avoid large allocation inside snprintf");
#endif
    // Suppress the warning about a nonliteral format string.
    auto snprintf_ptr = FMT_SNPRINTF;
    int result = precision >= 0
                     ? snprintf_ptr(begin, capacity, format, precision, value)
                     : snprintf_ptr(begin, capacity, format, value);
    if (result < 0) {
      buf.reserve(buf.capacity() + 1);  // The buffer will grow exponentially.
      continue;
    }
    unsigned size = to_unsigned(result);
    // Size equal to capacity means that the last character was truncated.
    if (size >= capacity) {
      buf.reserve(size + offset + 1);  // Add 1 for the terminating '\0'.
      continue;
    }
    auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
    if (specs.format == float_format::fixed) {
      if (precision == 0) {
        buf.resize(size);
        return 0;
      }
      // Find and remove the decimal point.
      auto end = begin + size, p = end;
      do {
        --p;
      } while (is_digit(*p));
      int fraction_size = static_cast<int>(end - p - 1);
      std::memmove(p, p + 1, fraction_size);
      buf.resize(size - 1);
      return -fraction_size;
    }
    if (specs.format == float_format::hex) {
      buf.resize(size + offset);
      return 0;
    }
    // Find and parse the exponent.
    auto end = begin + size, exp_pos = end;
    do {
      --exp_pos;
    } while (*exp_pos != 'e');
    char sign = exp_pos[1];
    assert(sign == '+' || sign == '-');
    int exp = 0;
    auto p = exp_pos + 2;  // Skip 'e' and sign.
    do {
      assert(is_digit(*p));
      exp = exp * 10 + (*p++ - '0');
    } while (p != end);
    if (sign == '-') exp = -exp;
    int fraction_size = 0;
    if (exp_pos != begin + 1) {
      // Remove trailing zeros.
      auto fraction_end = exp_pos - 1;
      while (*fraction_end == '0') --fraction_end;
      // Move the fractional part left to get rid of the decimal point.
      fraction_size = static_cast<int>(fraction_end - begin - 1);
      std::memmove(begin + 1, begin + 2, fraction_size);
    }
    buf.resize(fraction_size + offset + 1);
    return exp - fraction_size;
  }
}
}  // namespace internal

template <> struct formatter<internal::bigint> {
  format_parse_context::iterator parse(format_parse_context& ctx) {
    return ctx.begin();
  }

  format_context::iterator format(const internal::bigint& n,
                                  format_context& ctx) {
    auto out = ctx.out();
    bool first = true;
    for (auto i = n.bigits_.size(); i > 0; --i) {
      auto value = n.bigits_[i - 1];
      if (first) {
        out = format_to(out, "{:x}", value);
        first = false;
        continue;
      }
      out = format_to(out, "{:08x}", value);
    }
    if (n.exp_ > 0)
      out = format_to(out, "p{}", n.exp_ * internal::bigint::bigit_bits);
    return out;
  }
};

FMT_FUNC void internal::error_handler::on_error(const char* message) {
  FMT_THROW(duckdb::Exception(message));
}

FMT_END_NAMESPACE

#ifdef _MSC_VER
#  pragma warning(pop)
#endif

#endif  // FMT_FORMAT_INL_H_


FMT_BEGIN_NAMESPACE
namespace internal {

template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
                 T value) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  if (precision > 100000)
    throw std::runtime_error(
        "fuzz mode - avoid large allocation inside snprintf");
#endif
  // Suppress the warning about nonliteral format string.
  auto snprintf_ptr = FMT_SNPRINTF;
  return precision < 0 ? snprintf_ptr(buf, size, format, value)
                       : snprintf_ptr(buf, size, format, precision, value);
}
struct sprintf_specs {
  int precision;
  char type;
  bool alt : 1;

  template <typename Char>
  constexpr sprintf_specs(basic_format_specs<Char> specs)
      : precision(specs.precision), type(specs.type), alt(specs.alt) {}

  constexpr bool has_precision() const { return precision >= 0; }
};

// This is deprecated and is kept only to preserve ABI compatibility.
template <typename Double>
char* sprintf_format(Double value, internal::buffer<char>& buf,
                     sprintf_specs specs) {
  // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
  FMT_ASSERT(buf.capacity() != 0, "empty buffer");

  // Build format string.
  enum { max_format_size = 10 };  // longest format: %#-*.*Lg
  char format[max_format_size];
  char* format_ptr = format;
  *format_ptr++ = '%';
  if (specs.alt || !specs.type) *format_ptr++ = '#';
  if (specs.precision >= 0) {
    *format_ptr++ = '.';
    *format_ptr++ = '*';
  }
  if (std::is_same<Double, long double>::value) *format_ptr++ = 'L';

  char type = specs.type;

  if (type == '%')
    type = 'f';
  else if (type == 0 || type == 'n')
    type = 'g';
#if FMT_MSC_VER
  if (type == 'F') {
    // MSVC's printf doesn't support 'F'.
    type = 'f';
  }
#endif
  *format_ptr++ = type;
  *format_ptr = '\0';

  // Format using snprintf.
  char* start = nullptr;
  char* decimal_point_pos = nullptr;
  for (;;) {
    std::size_t buffer_size = buf.capacity();
    start = &buf[0];
    int result =
        format_float(start, buffer_size, format, specs.precision, value);
    if (result >= 0) {
      unsigned n = internal::to_unsigned(result);
      if (n < buf.capacity()) {
        // Find the decimal point.
        auto p = buf.data(), end = p + n;
        if (*p == '+' || *p == '-') ++p;
        if (specs.type != 'a' && specs.type != 'A') {
          while (p < end && *p >= '0' && *p <= '9') ++p;
          if (p < end && *p != 'e' && *p != 'E') {
            decimal_point_pos = p;
            if (!specs.type) {
              // Keep only one trailing zero after the decimal point.
              ++p;
              if (*p == '0') ++p;
              while (p != end && *p >= '1' && *p <= '9') ++p;
              char* where = p;
              while (p != end && *p == '0') ++p;
              if (p == end || *p < '0' || *p > '9') {
                if (p != end) std::memmove(where, p, to_unsigned(end - p));
                n -= static_cast<unsigned>(p - where);
              }
            }
          }
        }
        buf.resize(n);
        break;  // The buffer is large enough - continue with formatting.
      }
      buf.reserve(n + 1);
    } else {
      // If result is negative we ask to increase the capacity by at least 1,
      // but as std::vector, the buffer grows exponentially.
      buf.reserve(buf.capacity() + 1);
    }
  }
  return decimal_point_pos;
}
}  // namespace internal

template FMT_API char* internal::sprintf_format(double, internal::buffer<char>&,
                                                sprintf_specs);
template FMT_API char* internal::sprintf_format(long double,
                                                internal::buffer<char>&,
                                                sprintf_specs);

template struct FMT_API internal::basic_data<void>;

// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, internal::float_specs,
                                internal::buffer<char>&) =
    internal::format_float;

#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API internal::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale internal::locale_ref::get<std::locale>() const;
#endif

// Explicit instantiations for char.

template FMT_API std::string internal::grouping_impl<char>(locale_ref);
template FMT_API char internal::thousands_sep_impl(locale_ref);
template FMT_API char internal::decimal_point_impl(locale_ref);

template FMT_API void internal::buffer<char>::append(const char*, const char*);

template FMT_API void internal::arg_map<format_context>::init(
    const basic_format_args<format_context>& args);

template FMT_API std::string internal::vformat<char>(
    string_view, basic_format_args<format_context>);

template FMT_API format_context::iterator internal::vformat_to(
    internal::buffer<char>&, string_view, basic_format_args<format_context>);

template FMT_API int internal::snprintf_float(double, int,
                                              internal::float_specs,
                                              internal::buffer<char>&);
template FMT_API int internal::snprintf_float(long double, int,
                                              internal::float_specs,
                                              internal::buffer<char>&);
template FMT_API int internal::format_float(double, int, internal::float_specs,
                                            internal::buffer<char>&);
template FMT_API int internal::format_float(long double, int,
                                            internal::float_specs,
                                            internal::buffer<char>&);

// Explicit instantiations for wchar_t.

template FMT_API std::string internal::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);
template FMT_API wchar_t internal::decimal_point_impl(locale_ref);

template FMT_API void internal::buffer<wchar_t>::append(const wchar_t*,
                                                        const wchar_t*);

template FMT_API std::wstring internal::vformat<wchar_t>(
    wstring_view, basic_format_args<wformat_context>);
FMT_END_NAMESPACE
/* hyperloglog.c - Redis HyperLogLog probabilistic cardinality approximation.
 * This file implements the algorithm and the exported Redis commands.
 *
 * Copyright (c) 2014, Salvatore Sanfilippo <antirez at gmail dot com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


/* SDSLib 2.0 -- A C dynamic strings library
 *
 * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
 * Copyright (c) 2015, Oran Agra
 * Copyright (c) 2015, Redis Labs, Inc
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __SDS_H
#define __SDS_H


#ifdef _MSC_VER
#define __attribute__(A)
#define ssize_t int64_t
#endif

#define SDS_MAX_PREALLOC (1024*1024)

#include <sys/types.h>
#include <stdarg.h>
#include <stdint.h>

typedef char *sds;

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

#define SDS_TYPE_5  0
#define SDS_TYPE_8  1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
#define SDS_TYPE_MASK 7
#define SDS_TYPE_BITS 3
#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)));
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)

static inline size_t sdslen(const sds s) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            return SDS_TYPE_5_LEN(flags);
        case SDS_TYPE_8:
            return SDS_HDR(8,s)->len;
        case SDS_TYPE_16:
            return SDS_HDR(16,s)->len;
        case SDS_TYPE_32:
            return SDS_HDR(32,s)->len;
        case SDS_TYPE_64:
            return SDS_HDR(64,s)->len;
    }
    return 0;
}

static inline size_t sdsavail(const sds s) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5: {
            return 0;
        }
        case SDS_TYPE_8: {
            SDS_HDR_VAR(8,s);
            return sh->alloc - sh->len;
        }
        case SDS_TYPE_16: {
            SDS_HDR_VAR(16,s);
            return sh->alloc - sh->len;
        }
        case SDS_TYPE_32: {
            SDS_HDR_VAR(32,s);
            return sh->alloc - sh->len;
        }
        case SDS_TYPE_64: {
            SDS_HDR_VAR(64,s);
            return sh->alloc - sh->len;
        }
    }
    return 0;
}

static inline void sdssetlen(sds s, size_t newlen) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            {
                unsigned char *fp = ((unsigned char*)s)-1;
                *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
            }
            break;
        case SDS_TYPE_8:
            SDS_HDR(8,s)->len = newlen;
            break;
        case SDS_TYPE_16:
            SDS_HDR(16,s)->len = newlen;
            break;
        case SDS_TYPE_32:
            SDS_HDR(32,s)->len = newlen;
            break;
        case SDS_TYPE_64:
            SDS_HDR(64,s)->len = newlen;
            break;
    }
}

static inline void sdsinclen(sds s, size_t inc) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            {
                unsigned char *fp = ((unsigned char*)s)-1;
                unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc;
                *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
            }
            break;
        case SDS_TYPE_8:
            SDS_HDR(8,s)->len += inc;
            break;
        case SDS_TYPE_16:
            SDS_HDR(16,s)->len += inc;
            break;
        case SDS_TYPE_32:
            SDS_HDR(32,s)->len += inc;
            break;
        case SDS_TYPE_64:
            SDS_HDR(64,s)->len += inc;
            break;
    }
}

/* sdsalloc() = sdsavail() + sdslen() */
static inline size_t sdsalloc(const sds s) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            return SDS_TYPE_5_LEN(flags);
        case SDS_TYPE_8:
            return SDS_HDR(8,s)->alloc;
        case SDS_TYPE_16:
            return SDS_HDR(16,s)->alloc;
        case SDS_TYPE_32:
            return SDS_HDR(32,s)->alloc;
        case SDS_TYPE_64:
            return SDS_HDR(64,s)->alloc;
    }
    return 0;
}

static inline void sdssetalloc(sds s, size_t newlen) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            /* Nothing to do, this type has no total allocation info. */
            break;
        case SDS_TYPE_8:
            SDS_HDR(8,s)->alloc = newlen;
            break;
        case SDS_TYPE_16:
            SDS_HDR(16,s)->alloc = newlen;
            break;
        case SDS_TYPE_32:
            SDS_HDR(32,s)->alloc = newlen;
            break;
        case SDS_TYPE_64:
            SDS_HDR(64,s)->alloc = newlen;
            break;
    }
}

sds sdsnewlen(const void *init, size_t initlen);
sds sdsnew(const char *init);
sds sdsempty(void);
sds sdsdup(const sds s);
void sdsfree(sds s);
sds sdsgrowzero(sds s, size_t len);
sds sdscatlen(sds s, const void *t, size_t len);
sds sdscat(sds s, const char *t);
sds sdscatsds(sds s, const sds t);
sds sdscpylen(sds s, const char *t, size_t len);
sds sdscpy(sds s, const char *t);

sds sdscatvprintf(sds s, const char *fmt, va_list ap);
#ifdef __GNUC__
sds sdscatprintf(sds s, const char *fmt, ...)
    __attribute__((format(printf, 2, 3)));
#else
sds sdscatprintf(sds s, const char *fmt, ...);
#endif

sds sdscatfmt(sds s, char const *fmt, ...);
sds sdstrim(sds s, const char *cset);
void sdsrange(sds s, ssize_t start, ssize_t end);
void sdsupdatelen(sds s);
void sdsclear(sds s);
int sdscmp(const sds s1, const sds s2);
sds *sdssplitlen(const char *s, ssize_t len, const char *sep, int seplen, int *count);
void sdsfreesplitres(sds *tokens, int count);
void sdstolower(sds s);
void sdstoupper(sds s);
sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, const char *p, size_t len);
sds *sdssplitargs(const char *line, int *argc);
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
sds sdsjoin(char **argv, int argc, char *sep);
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);

/* Low level functions exposed to the user API */
sds sdsMakeRoomFor(sds s, size_t addlen);
void sdsIncrLen(sds s, ssize_t incr);
sds sdsRemoveFreeSpace(sds s);
size_t sdsAllocSize(sds s);
void *sdsAllocPtr(sds s);

/* Export the allocator used by SDS to the program using SDS.
 * Sometimes the program SDS is linked to, may use a different set of
 * allocators, but may want to allocate or free things that SDS will
 * respectively free or allocate. */
void *sds_malloc(size_t size);
void *sds_realloc(void *ptr, size_t size);
void sds_free(void *ptr);

#ifdef REDIS_TEST
int sdsTest(int argc, char *argv[]);
#endif

#endif


#include <assert.h>
#include <stdint.h>
#include <math.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>

#define HLL_SPARSE_MAX_BYTES 3000

/* The Redis HyperLogLog implementation is based on the following ideas:
 *
 * * The use of a 64 bit hash function as proposed in [1], in order to don't
 *   limited to cardinalities up to 10^9, at the cost of just 1 additional
 *   bit per register.
 * * The use of 16384 6-bit registers for a great level of accuracy, using
 *   a total of 12k per key.
 * * The use of the Redis string data type. No new type is introduced.
 * * No attempt is made to compress the data structure as in [1]. Also the
 *   algorithm used is the original HyperLogLog Algorithm as in [2], with
 *   the only difference that a 64 bit hash function is used, so no correction
 *   is performed for values near 2^32 as in [1].
 *
 * [1] Heule, Nunkesser, Hall: HyperLogLog in Practice: Algorithmic
 *     Engineering of a State of The Art Cardinality Estimation Algorithm.
 *
 * [2] P. Flajolet, Éric Fusy, O. Gandouet, and F. Meunier. Hyperloglog: The
 *     analysis of a near-optimal cardinality estimation algorithm.
 *
 * Redis uses two representations:
 *
 * 1) A "dense" representation where every entry is represented by
 *    a 6-bit integer.
 * 2) A "sparse" representation using run length compression suitable
 *    for representing HyperLogLogs with many registers set to 0 in
 *    a memory efficient way.
 *
 *
 * HLL header
 * ===
 *
 * Both the dense and sparse representation have a 16 byte header as follows:
 *
 * +------+---+-----+----------+
 * | HYLL | E | N/U | Cardin.  |
 * +------+---+-----+----------+
 *
 * The first 4 bytes are a magic string set to the bytes "HYLL".
 * "E" is one byte encoding, currently set to HLL_DENSE or
 * HLL_SPARSE. N/U are three not used bytes.
 *
 * The "Cardin." field is a 64 bit integer stored in little endian format
 * with the latest cardinality computed that can be reused if the data
 * structure was not modified since the last computation (this is useful
 * because there are high probabilities that HLLADD operations don't
 * modify the actual data structure and hence the approximated cardinality).
 *
 * When the most significant bit in the most significant byte of the cached
 * cardinality is set, it means that the data structure was modified and
 * we can't reuse the cached value that must be recomputed.
 *
 * Dense representation
 * ===
 *
 * The dense representation used by Redis is the following:
 *
 * +--------+--------+--------+------//      //--+
 * |11000000|22221111|33333322|55444444 ....     |
 * +--------+--------+--------+------//      //--+
 *
 * The 6 bits counters are encoded one after the other starting from the
 * LSB to the MSB, and using the next bytes as needed.
 *
 * Sparse representation
 * ===
 *
 * The sparse representation encodes registers using a run length
 * encoding composed of three opcodes, two using one byte, and one using
 * of two bytes. The opcodes are called ZERO, XZERO and VAL.
 *
 * ZERO opcode is represented as 00xxxxxx. The 6-bit integer represented
 * by the six bits 'xxxxxx', plus 1, means that there are N registers set
 * to 0. This opcode can represent from 1 to 64 contiguous registers set
 * to the value of 0.
 *
 * XZERO opcode is represented by two bytes 01xxxxxx yyyyyyyy. The 14-bit
 * integer represented by the bits 'xxxxxx' as most significant bits and
 * 'yyyyyyyy' as least significant bits, plus 1, means that there are N
 * registers set to 0. This opcode can represent from 0 to 16384 contiguous
 * registers set to the value of 0.
 *
 * VAL opcode is represented as 1vvvvvxx. It contains a 5-bit integer
 * representing the value of a register, and a 2-bit integer representing
 * the number of contiguous registers set to that value 'vvvvv'.
 * To obtain the value and run length, the integers vvvvv and xx must be
 * incremented by one. This opcode can represent values from 1 to 32,
 * repeated from 1 to 4 times.
 *
 * The sparse representation can't represent registers with a value greater
 * than 32, however it is very unlikely that we find such a register in an
 * HLL with a cardinality where the sparse representation is still more
 * memory efficient than the dense representation. When this happens the
 * HLL is converted to the dense representation.
 *
 * The sparse representation is purely positional. For example a sparse
 * representation of an empty HLL is just: XZERO:16384.
 *
 * An HLL having only 3 non-zero registers at position 1000, 1020, 1021
 * respectively set to 2, 3, 3, is represented by the following three
 * opcodes:
 *
 * XZERO:1000 (Registers 0-999 are set to 0)
 * VAL:2,1    (1 register set to value 2, that is register 1000)
 * ZERO:19    (Registers 1001-1019 set to 0)
 * VAL:3,2    (2 registers set to value 3, that is registers 1020,1021)
 * XZERO:15362 (Registers 1022-16383 set to 0)
 *
 * In the example the sparse representation used just 7 bytes instead
 * of 12k in order to represent the HLL registers. In general for low
 * cardinality there is a big win in terms of space efficiency, traded
 * with CPU time since the sparse representation is slower to access:
 *
 * The following table shows average cardinality vs bytes used, 100
 * samples per cardinality (when the set was not representable because
 * of registers with too big value, the dense representation size was used
 * as a sample).
 *
 * 100 267
 * 200 485
 * 300 678
 * 400 859
 * 500 1033
 * 600 1205
 * 700 1375
 * 800 1544
 * 900 1713
 * 1000 1882
 * 2000 3480
 * 3000 4879
 * 4000 6089
 * 5000 7138
 * 6000 8042
 * 7000 8823
 * 8000 9500
 * 9000 10088
 * 10000 10591
 *
 * The dense representation uses 12288 bytes, so there is a big win up to
 * a cardinality of ~2000-3000. For bigger cardinalities the constant times
 * involved in updating the sparse representation is not justified by the
 * memory savings. The exact maximum length of the sparse representation
 * when this implementation switches to the dense representation is
 * configured via the define server.hll_sparse_max_bytes.
 */

struct hllhdr {
    char magic[4];      /* "HYLL" */
    uint8_t encoding;   /* HLL_DENSE or HLL_SPARSE. */
    uint8_t notused[3]; /* Reserved for future use, must be zero. */
    uint8_t card[8];    /* Cached cardinality, little endian. */
    uint8_t registers[]; /* Data bytes. */
};

/* The cached cardinality MSB is used to signal validity of the cached value. */
#define HLL_INVALIDATE_CACHE(hdr) (hdr)->card[7] |= (1<<7)
#define HLL_VALID_CACHE(hdr) (((hdr)->card[7] & (1<<7)) == 0)

#define HLL_P 14 /* The greater is P, the smaller the error. */
#define HLL_Q (64-HLL_P) /* The number of bits of the hash value used for
                            determining the number of leading zeros. */
#define HLL_REGISTERS (1<<HLL_P) /* With P=14, 16384 registers. */
#define HLL_P_MASK (HLL_REGISTERS-1) /* Mask to index register. */
#define HLL_BITS 6 /* Enough to count up to 63 leading zeroes. */
#define HLL_REGISTER_MAX ((1<<HLL_BITS)-1)
#define HLL_HDR_SIZE sizeof(struct hllhdr)
#define HLL_DENSE_SIZE (HLL_HDR_SIZE+((HLL_REGISTERS*HLL_BITS+7)/8))
#define HLL_DENSE 0 /* Dense encoding. */
#define HLL_SPARSE 1 /* Sparse encoding. */
#define HLL_RAW 255 /* Only used internally, never exposed. */
#define HLL_MAX_ENCODING 1

/* =========================== Low level bit macros ========================= */

/* Macros to access the dense representation.
 *
 * We need to get and set 6 bit counters in an array of 8 bit bytes.
 * We use macros to make sure the code is inlined since speed is critical
 * especially in order to compute the approximated cardinality in
 * HLLCOUNT where we need to access all the registers at once.
 * For the same reason we also want to avoid conditionals in this code path.
 *
 * +--------+--------+--------+------//
 * |11000000|22221111|33333322|55444444
 * +--------+--------+--------+------//
 *
 * Note: in the above representation the most significant bit (MSB)
 * of every byte is on the left. We start using bits from the LSB to MSB,
 * and so forth passing to the next byte.
 *
 * Example, we want to access to counter at pos = 1 ("111111" in the
 * illustration above).
 *
 * The index of the first byte b0 containing our data is:
 *
 *  b0 = 6 * pos / 8 = 0
 *
 *   +--------+
 *   |11000000|  <- Our byte at b0
 *   +--------+
 *
 * The position of the first bit (counting from the LSB = 0) in the byte
 * is given by:
 *
 *  fb = 6 * pos % 8 -> 6
 *
 * Right shift b0 of 'fb' bits.
 *
 *   +--------+
 *   |11000000|  <- Initial value of b0
 *   |00000011|  <- After right shift of 6 pos.
 *   +--------+
 *
 * Left shift b1 of bits 8-fb bits (2 bits)
 *
 *   +--------+
 *   |22221111|  <- Initial value of b1
 *   |22111100|  <- After left shift of 2 bits.
 *   +--------+
 *
 * OR the two bits, and finally AND with 111111 (63 in decimal) to
 * clean the higher order bits we are not interested in:
 *
 *   +--------+
 *   |00000011|  <- b0 right shifted
 *   |22111100|  <- b1 left shifted
 *   |22111111|  <- b0 OR b1
 *   |  111111|  <- (b0 OR b1) AND 63, our value.
 *   +--------+
 *
 * We can try with a different example, like pos = 0. In this case
 * the 6-bit counter is actually contained in a single byte.
 *
 *  b0 = 6 * pos / 8 = 0
 *
 *   +--------+
 *   |11000000|  <- Our byte at b0
 *   +--------+
 *
 *  fb = 6 * pos % 8 = 0
 *
 *  So we right shift of 0 bits (no shift in practice) and
 *  left shift the next byte of 8 bits, even if we don't use it,
 *  but this has the effect of clearing the bits so the result
 *  will not be affacted after the OR.
 *
 * -------------------------------------------------------------------------
 *
 * Setting the register is a bit more complex, let's assume that 'val'
 * is the value we want to set, already in the right range.
 *
 * We need two steps, in one we need to clear the bits, and in the other
 * we need to bitwise-OR the new bits.
 *
 * Let's try with 'pos' = 1, so our first byte at 'b' is 0,
 *
 * "fb" is 6 in this case.
 *
 *   +--------+
 *   |11000000|  <- Our byte at b0
 *   +--------+
 *
 * To create a AND-mask to clear the bits about this position, we just
 * initialize the mask with the value 63, left shift it of "fs" bits,
 * and finally invert the result.
 *
 *   +--------+
 *   |00111111|  <- "mask" starts at 63
 *   |11000000|  <- "mask" after left shift of "ls" bits.
 *   |00111111|  <- "mask" after invert.
 *   +--------+
 *
 * Now we can bitwise-AND the byte at "b" with the mask, and bitwise-OR
 * it with "val" left-shifted of "ls" bits to set the new bits.
 *
 * Now let's focus on the next byte b1:
 *
 *   +--------+
 *   |22221111|  <- Initial value of b1
 *   +--------+
 *
 * To build the AND mask we start again with the 63 value, right shift
 * it by 8-fb bits, and invert it.
 *
 *   +--------+
 *   |00111111|  <- "mask" set at 2&6-1
 *   |00001111|  <- "mask" after the right shift by 8-fb = 2 bits
 *   |11110000|  <- "mask" after bitwise not.
 *   +--------+
 *
 * Now we can mask it with b+1 to clear the old bits, and bitwise-OR
 * with "val" left-shifted by "rs" bits to set the new value.
 */

/* Note: if we access the last counter, we will also access the b+1 byte
 * that is out of the array, but sds strings always have an implicit null
 * term, so the byte exists, and we can skip the conditional (or the need
 * to allocate 1 byte more explicitly). */

/* Store the value of the register at position 'regnum' into variable 'target'.
 * 'p' is an array of unsigned bytes. */
#define HLL_DENSE_GET_REGISTER(target,p,regnum) do { \
    uint8_t *_p = (uint8_t*) p; \
    unsigned long _byte = regnum*HLL_BITS/8; \
    unsigned long _fb = regnum*HLL_BITS&7; \
    unsigned long _fb8 = 8 - _fb; \
    unsigned long b0 = _p[_byte]; \
    unsigned long b1 = _p[_byte+1]; \
    target = ((b0 >> _fb) | (b1 << _fb8)) & HLL_REGISTER_MAX; \
} while(0)

/* Set the value of the register at position 'regnum' to 'val'.
 * 'p' is an array of unsigned bytes. */
#define HLL_DENSE_SET_REGISTER(p,regnum,val) do { \
    uint8_t *_p = (uint8_t*) p; \
    unsigned long _byte = regnum*HLL_BITS/8; \
    unsigned long _fb = regnum*HLL_BITS&7; \
    unsigned long _fb8 = 8 - _fb; \
    unsigned long _v = val; \
    _p[_byte] &= ~(HLL_REGISTER_MAX << _fb); \
    _p[_byte] |= _v << _fb; \
    _p[_byte+1] &= ~(HLL_REGISTER_MAX >> _fb8); \
    _p[_byte+1] |= _v >> _fb8; \
} while(0)

/* Macros to access the sparse representation.
 * The macros parameter is expected to be an uint8_t pointer. */
#define HLL_SPARSE_XZERO_BIT 0x40 /* 01xxxxxx */
#define HLL_SPARSE_VAL_BIT 0x80 /* 1vvvvvxx */
#define HLL_SPARSE_IS_ZERO(p) (((*(p)) & 0xc0) == 0) /* 00xxxxxx */
#define HLL_SPARSE_IS_XZERO(p) (((*(p)) & 0xc0) == HLL_SPARSE_XZERO_BIT)
#define HLL_SPARSE_IS_VAL(p) ((*(p)) & HLL_SPARSE_VAL_BIT)
#define HLL_SPARSE_ZERO_LEN(p) (((*(p)) & 0x3f)+1)
#define HLL_SPARSE_XZERO_LEN(p) (((((*(p)) & 0x3f) << 8) | (*((p)+1)))+1)
#define HLL_SPARSE_VAL_VALUE(p) ((((*(p)) >> 2) & 0x1f)+1)
#define HLL_SPARSE_VAL_LEN(p) (((*(p)) & 0x3)+1)
#define HLL_SPARSE_VAL_MAX_VALUE 32
#define HLL_SPARSE_VAL_MAX_LEN 4
#define HLL_SPARSE_ZERO_MAX_LEN 64
#define HLL_SPARSE_XZERO_MAX_LEN 16384
#define HLL_SPARSE_VAL_SET(p,val,len) do { \
    *(p) = (((val)-1)<<2|((len)-1))|HLL_SPARSE_VAL_BIT; \
} while(0)
#define HLL_SPARSE_ZERO_SET(p,len) do { \
    *(p) = (len)-1; \
} while(0)
#define HLL_SPARSE_XZERO_SET(p,len) do { \
    int _l = (len)-1; \
    *(p) = (_l>>8) | HLL_SPARSE_XZERO_BIT; \
    *((p)+1) = (_l&0xff); \
} while(0)
#define HLL_ALPHA_INF 0.721347520444481703680 /* constant for 0.5/ln(2) */

/* ========================= HyperLogLog algorithm  ========================= */

/* Our hash function is MurmurHash2, 64 bit version.
 * It was modified for Redis in order to provide the same result in
 * big and little endian archs (endian neutral). */
uint64_t MurmurHash64A (const void * key, int len, unsigned int seed) {
    const uint64_t m = 0xc6a4a7935bd1e995;
    const int r = 47;
    uint64_t h = seed ^ (len * m);
    const uint8_t *data = (const uint8_t *)key;
    const uint8_t *end = data + (len-(len&7));

    while(data != end) {
        uint64_t k;

#if (BYTE_ORDER == LITTLE_ENDIAN)
    #ifdef USE_ALIGNED_ACCESS
        memcpy(&k,data,sizeof(uint64_t));
    #else
        k = *((uint64_t*)data);
    #endif
#else
        k = (uint64_t) data[0];
        k |= (uint64_t) data[1] << 8;
        k |= (uint64_t) data[2] << 16;
        k |= (uint64_t) data[3] << 24;
        k |= (uint64_t) data[4] << 32;
        k |= (uint64_t) data[5] << 40;
        k |= (uint64_t) data[6] << 48;
        k |= (uint64_t) data[7] << 56;
#endif

        k *= m;
        k ^= k >> r;
        k *= m;
        h ^= k;
        h *= m;
        data += 8;
    }

    switch(len & 7) {
    case 7: h ^= (uint64_t)data[6] << 48; /* fall-thru */
    case 6: h ^= (uint64_t)data[5] << 40; /* fall-thru */
    case 5: h ^= (uint64_t)data[4] << 32; /* fall-thru */
    case 4: h ^= (uint64_t)data[3] << 24; /* fall-thru */
    case 3: h ^= (uint64_t)data[2] << 16; /* fall-thru */
    case 2: h ^= (uint64_t)data[1] << 8; /* fall-thru */
    case 1: h ^= (uint64_t)data[0];
            h *= m; /* fall-thru */
    };

    h ^= h >> r;
    h *= m;
    h ^= h >> r;
    return h;
}

/* Given a string element to add to the HyperLogLog, returns the length
 * of the pattern 000..1 of the element hash. As a side effect 'regp' is
 * set to the register index this element hashes to. */
int hllPatLen(unsigned char *ele, size_t elesize, long *regp) {
    uint64_t hash, bit, index;
    int count;

    /* Count the number of zeroes starting from bit HLL_REGISTERS
     * (that is a power of two corresponding to the first bit we don't use
     * as index). The max run can be 64-P+1 = Q+1 bits.
     *
     * Note that the final "1" ending the sequence of zeroes must be
     * included in the count, so if we find "001" the count is 3, and
     * the smallest count possible is no zeroes at all, just a 1 bit
     * at the first position, that is a count of 1.
     *
     * This may sound like inefficient, but actually in the average case
     * there are high probabilities to find a 1 after a few iterations. */
    hash = MurmurHash64A(ele,elesize,0xadc83b19ULL);
    index = hash & HLL_P_MASK; /* Register index. */
    hash >>= HLL_P; /* Remove bits used to address the register. */
    hash |= ((uint64_t)1<<HLL_Q); /* Make sure the loop terminates
                                     and count will be <= Q+1. */
    bit = 1;
    count = 1; /* Initialized to 1 since we count the "00000...1" pattern. */
    while((hash & bit) == 0) {
        count++;
        bit <<= 1;
    }
    *regp = (int) index;
    return count;
}

/* ================== Dense representation implementation  ================== */

/* Low level function to set the dense HLL register at 'index' to the
 * specified value if the current value is smaller than 'count'.
 *
 * 'registers' is expected to have room for HLL_REGISTERS plus an
 * additional byte on the right. This requirement is met by sds strings
 * automatically since they are implicitly null terminated.
 *
 * The function always succeed, however if as a result of the operation
 * the approximated cardinality changed, 1 is returned. Otherwise 0
 * is returned. */
int hllDenseSet(uint8_t *registers, long index, uint8_t count) {
    uint8_t oldcount;

    HLL_DENSE_GET_REGISTER(oldcount,registers,index);
    if (count > oldcount) {
        HLL_DENSE_SET_REGISTER(registers,index,count);
        return 1;
    } else {
        return 0;
    }
}

/* "Add" the element in the dense hyperloglog data structure.
 * Actually nothing is added, but the max 0 pattern counter of the subset
 * the element belongs to is incremented if needed.
 *
 * This is just a wrapper to hllDenseSet(), performing the hashing of the
 * element in order to retrieve the index and zero-run count. */
int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) {
    long index;
    uint8_t count = hllPatLen(ele,elesize,&index);
    /* Update the register if this element produced a longer run of zeroes. */
    return hllDenseSet(registers,index,count);
}

/* Compute the register histogram in the dense representation. */
void hllDenseRegHisto(uint8_t *registers, int* reghisto) {
    int j;

    /* Redis default is to use 16384 registers 6 bits each. The code works
     * with other values by modifying the defines, but for our target value
     * we take a faster path with unrolled loops. */
    if (HLL_REGISTERS == 16384 && HLL_BITS == 6) {
        uint8_t *r = registers;
        unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9,
                      r10, r11, r12, r13, r14, r15;
        for (j = 0; j < 1024; j++) {
            /* Handle 16 registers per iteration. */
            r0 = r[0] & 63;
            r1 = (r[0] >> 6 | r[1] << 2) & 63;
            r2 = (r[1] >> 4 | r[2] << 4) & 63;
            r3 = (r[2] >> 2) & 63;
            r4 = r[3] & 63;
            r5 = (r[3] >> 6 | r[4] << 2) & 63;
            r6 = (r[4] >> 4 | r[5] << 4) & 63;
            r7 = (r[5] >> 2) & 63;
            r8 = r[6] & 63;
            r9 = (r[6] >> 6 | r[7] << 2) & 63;
            r10 = (r[7] >> 4 | r[8] << 4) & 63;
            r11 = (r[8] >> 2) & 63;
            r12 = r[9] & 63;
            r13 = (r[9] >> 6 | r[10] << 2) & 63;
            r14 = (r[10] >> 4 | r[11] << 4) & 63;
            r15 = (r[11] >> 2) & 63;

            reghisto[r0]++;
            reghisto[r1]++;
            reghisto[r2]++;
            reghisto[r3]++;
            reghisto[r4]++;
            reghisto[r5]++;
            reghisto[r6]++;
            reghisto[r7]++;
            reghisto[r8]++;
            reghisto[r9]++;
            reghisto[r10]++;
            reghisto[r11]++;
            reghisto[r12]++;
            reghisto[r13]++;
            reghisto[r14]++;
            reghisto[r15]++;

            r += 12;
        }
    } else {
        for(j = 0; j < HLL_REGISTERS; j++) {
            unsigned long reg;
            HLL_DENSE_GET_REGISTER(reg,registers,j);
            reghisto[reg]++;
        }
    }
}

/* ================== Sparse representation implementation  ================= */

/* Convert the HLL with sparse representation given as input in its dense
 * representation. Both representations are represented by SDS strings, and
 * the input representation is freed as a side effect.
 *
 * The function returns C_OK if the sparse representation was valid,
 * otherwise C_ERR is returned if the representation was corrupted. */
int hllSparseToDense(robj *o) {
    sds sparse = (sds) o->ptr, dense;
    struct hllhdr *hdr, *oldhdr = (struct hllhdr*)sparse;
    int idx = 0, runlen, regval;
    uint8_t *p = (uint8_t*)sparse, *end = p+sdslen(sparse);

    /* If the representation is already the right one return ASAP. */
    hdr = (struct hllhdr*) sparse;
    if (hdr->encoding == HLL_DENSE) return C_OK;

    /* Create a string of the right size filled with zero bytes.
     * Note that the cached cardinality is set to 0 as a side effect
     * that is exactly the cardinality of an empty HLL. */
    dense = sdsnewlen(NULL,HLL_DENSE_SIZE);
    hdr = (struct hllhdr*) dense;
    *hdr = *oldhdr; /* This will copy the magic and cached cardinality. */
    hdr->encoding = HLL_DENSE;

    /* Now read the sparse representation and set non-zero registers
     * accordingly. */
    p += HLL_HDR_SIZE;
    while(p < end) {
        if (HLL_SPARSE_IS_ZERO(p)) {
            runlen = HLL_SPARSE_ZERO_LEN(p);
            idx += runlen;
            p++;
        } else if (HLL_SPARSE_IS_XZERO(p)) {
            runlen = HLL_SPARSE_XZERO_LEN(p);
            idx += runlen;
            p += 2;
        } else {
            runlen = HLL_SPARSE_VAL_LEN(p);
            regval = HLL_SPARSE_VAL_VALUE(p);
            while(runlen--) {
                HLL_DENSE_SET_REGISTER(hdr->registers,idx,regval);
                idx++;
            }
            p++;
        }
    }

    /* If the sparse representation was valid, we expect to find idx
     * set to HLL_REGISTERS. */
    if (idx != HLL_REGISTERS) {
        sdsfree(dense);
        return C_ERR;
    }

    /* Free the old representation and set the new one. */
    sdsfree((sds) o->ptr);
    o->ptr = dense;
    return C_OK;
}

/* Low level function to set the sparse HLL register at 'index' to the
 * specified value if the current value is smaller than 'count'.
 *
 * The object 'o' is the String object holding the HLL. The function requires
 * a reference to the object in order to be able to enlarge the string if
 * needed.
 *
 * On success, the function returns 1 if the cardinality changed, or 0
 * if the register for this element was not updated.
 * On error (if the representation is invalid) -1 is returned.
 *
 * As a side effect the function may promote the HLL representation from
 * sparse to dense: this happens when a register requires to be set to a value
 * not representable with the sparse representation, or when the resulting
 * size would be greater than server.hll_sparse_max_bytes. */
int hllSparseSet(robj *o, long index, uint8_t count) {
    struct hllhdr *hdr;
    uint8_t oldcount, *sparse, *end, *p, *prev, *next;
    long first, span;
    long is_zero = 0, is_xzero = 0, is_val = 0, runlen = 0;
    uint8_t seq[5], *n;
    int last;
    int len;
    int seqlen;
    int oldlen;
    int deltalen;

    /* If the count is too big to be representable by the sparse representation
     * switch to dense representation. */
    if (count > HLL_SPARSE_VAL_MAX_VALUE) goto promote;

    /* When updating a sparse representation, sometimes we may need to
     * enlarge the buffer for up to 3 bytes in the worst case (XZERO split
     * into XZERO-VAL-XZERO). Make sure there is enough space right now
     * so that the pointers we take during the execution of the function
     * will be valid all the time. */
    o->ptr = (sds) sdsMakeRoomFor((sds) o->ptr,3);

    /* Step 1: we need to locate the opcode we need to modify to check
     * if a value update is actually needed. */
    sparse = p = ((uint8_t*)o->ptr) + HLL_HDR_SIZE;
    end = p + sdslen((sds) o->ptr) - HLL_HDR_SIZE;

    first = 0;
    prev = NULL; /* Points to previous opcode at the end of the loop. */
    next = NULL; /* Points to the next opcode at the end of the loop. */
    span = 0;
    while(p < end) {
        long oplen;

        /* Set span to the number of registers covered by this opcode.
         *
         * This is the most performance critical loop of the sparse
         * representation. Sorting the conditionals from the most to the
         * least frequent opcode in many-bytes sparse HLLs is faster. */
        oplen = 1;
        if (HLL_SPARSE_IS_ZERO(p)) {
            span = HLL_SPARSE_ZERO_LEN(p);
        } else if (HLL_SPARSE_IS_VAL(p)) {
            span = HLL_SPARSE_VAL_LEN(p);
        } else { /* XZERO. */
            span = HLL_SPARSE_XZERO_LEN(p);
            oplen = 2;
        }
        /* Break if this opcode covers the register as 'index'. */
        if (index <= first+span-1) break;
        prev = p;
        p += oplen;
        first += span;
    }
    if (span == 0) return -1; /* Invalid format. */

    next = HLL_SPARSE_IS_XZERO(p) ? p+2 : p+1;
    if (next >= end) next = NULL;

    /* Cache current opcode type to avoid using the macro again and
     * again for something that will not change.
     * Also cache the run-length of the opcode. */
    if (HLL_SPARSE_IS_ZERO(p)) {
        is_zero = 1;
        runlen = HLL_SPARSE_ZERO_LEN(p);
    } else if (HLL_SPARSE_IS_XZERO(p)) {
        is_xzero = 1;
        runlen = HLL_SPARSE_XZERO_LEN(p);
    } else {
        is_val = 1;
        runlen = HLL_SPARSE_VAL_LEN(p);
    }

    /* Step 2: After the loop:
     *
     * 'first' stores to the index of the first register covered
     *  by the current opcode, which is pointed by 'p'.
     *
     * 'next' ad 'prev' store respectively the next and previous opcode,
     *  or NULL if the opcode at 'p' is respectively the last or first.
     *
     * 'span' is set to the number of registers covered by the current
     *  opcode.
     *
     * There are different cases in order to update the data structure
     * in place without generating it from scratch:
     *
     * A) If it is a VAL opcode already set to a value >= our 'count'
     *    no update is needed, regardless of the VAL run-length field.
     *    In this case PFADD returns 0 since no changes are performed.
     *
     * B) If it is a VAL opcode with len = 1 (representing only our
     *    register) and the value is less than 'count', we just update it
     *    since this is a trivial case. */
    if (is_val) {
        oldcount = HLL_SPARSE_VAL_VALUE(p);
        /* Case A. */
        if (oldcount >= count) return 0;

        /* Case B. */
        if (runlen == 1) {
            HLL_SPARSE_VAL_SET(p,count,1);
            goto updated;
        }
    }

    /* C) Another trivial to handle case is a ZERO opcode with a len of 1.
     * We can just replace it with a VAL opcode with our value and len of 1. */
    if (is_zero && runlen == 1) {
        HLL_SPARSE_VAL_SET(p,count,1);
        goto updated;
    }

    /* D) General case.
     *
     * The other cases are more complex: our register requires to be updated
     * and is either currently represented by a VAL opcode with len > 1,
     * by a ZERO opcode with len > 1, or by an XZERO opcode.
     *
     * In those cases the original opcode must be split into multiple
     * opcodes. The worst case is an XZERO split in the middle resuling into
     * XZERO - VAL - XZERO, so the resulting sequence max length is
     * 5 bytes.
     *
     * We perform the split writing the new sequence into the 'new' buffer
     * with 'newlen' as length. Later the new sequence is inserted in place
     * of the old one, possibly moving what is on the right a few bytes
     * if the new sequence is longer than the older one. */
    n = seq;
    last = first+span-1; /* Last register covered by the sequence. */

    if (is_zero || is_xzero) {
        /* Handle splitting of ZERO / XZERO. */
        if (index != first) {
            len = index-first;
            if (len > HLL_SPARSE_ZERO_MAX_LEN) {
                HLL_SPARSE_XZERO_SET(n,len);
                n += 2;
            } else {
                HLL_SPARSE_ZERO_SET(n,len);
                n++;
            }
        }
        HLL_SPARSE_VAL_SET(n,count,1);
        n++;
        if (index != last) {
            len = last-index;
            if (len > HLL_SPARSE_ZERO_MAX_LEN) {
                HLL_SPARSE_XZERO_SET(n,len);
                n += 2;
            } else {
                HLL_SPARSE_ZERO_SET(n,len);
                n++;
            }
        }
    } else {
        /* Handle splitting of VAL. */
        int curval = HLL_SPARSE_VAL_VALUE(p);

        if (index != first) {
            len = index-first;
            HLL_SPARSE_VAL_SET(n,curval,len);
            n++;
        }
        HLL_SPARSE_VAL_SET(n,count,1);
        n++;
        if (index != last) {
            len = last-index;
            HLL_SPARSE_VAL_SET(n,curval,len);
            n++;
        }
    }

    /* Step 3: substitute the new sequence with the old one.
     *
     * Note that we already allocated space on the sds string
     * calling sdsMakeRoomFor(). */
     seqlen = n-seq;
     oldlen = is_xzero ? 2 : 1;
     deltalen = seqlen-oldlen;

     if (deltalen > 0 &&
         sdslen((sds) o->ptr)+deltalen > HLL_SPARSE_MAX_BYTES) goto promote;
     if (deltalen && next) memmove(next+deltalen,next,end-next);
     sdsIncrLen((sds) o->ptr,deltalen);
     memcpy(p,seq,seqlen);
     end += deltalen;

updated: {
    /* Step 4: Merge adjacent values if possible.
     *
     * The representation was updated, however the resulting representation
     * may not be optimal: adjacent VAL opcodes can sometimes be merged into
     * a single one. */
    p = prev ? prev : sparse;
    int scanlen = 5; /* Scan up to 5 upcodes starting from prev. */
    while (p < end && scanlen--) {
        if (HLL_SPARSE_IS_XZERO(p)) {
            p += 2;
            continue;
        } else if (HLL_SPARSE_IS_ZERO(p)) {
            p++;
            continue;
        }
        /* We need two adjacent VAL opcodes to try a merge, having
         * the same value, and a len that fits the VAL opcode max len. */
        if (p+1 < end && HLL_SPARSE_IS_VAL(p+1)) {
            int v1 = HLL_SPARSE_VAL_VALUE(p);
            int v2 = HLL_SPARSE_VAL_VALUE(p+1);
            if (v1 == v2) {
                int len = HLL_SPARSE_VAL_LEN(p)+HLL_SPARSE_VAL_LEN(p+1);
                if (len <= HLL_SPARSE_VAL_MAX_LEN) {
                    HLL_SPARSE_VAL_SET(p+1,v1,len);
                    memmove(p,p+1,end-p);
                    sdsIncrLen((sds) o->ptr,-1);
                    end--;
                    /* After a merge we reiterate without incrementing 'p'
                     * in order to try to merge the just merged value with
                     * a value on its right. */
                    continue;
                }
            }
        }
        p++;
    }

    /* Invalidate the cached cardinality. */
    hdr = (struct hllhdr *) o->ptr;
    HLL_INVALIDATE_CACHE(hdr);
    return 1;
}
promote: /* Promote to dense representation. */
    if (hllSparseToDense(o) == C_ERR) return -1; /* Corrupted HLL. */
    hdr = (struct hllhdr *) o->ptr;

    /* We need to call hllDenseAdd() to perform the operation after the
     * conversion. However the result must be 1, since if we need to
     * convert from sparse to dense a register requires to be updated.
     *
     * Note that this in turn means that PFADD will make sure the command
     * is propagated to slaves / AOF, so if there is a sparse -> dense
     * conversion, it will be performed in all the slaves as well. */
    int dense_retval = hllDenseSet(hdr->registers,index,count);
    assert(dense_retval == 1);
    return dense_retval;
}

/* "Add" the element in the sparse hyperloglog data structure.
 * Actually nothing is added, but the max 0 pattern counter of the subset
 * the element belongs to is incremented if needed.
 *
 * This function is actually a wrapper for hllSparseSet(), it only performs
 * the hashshing of the elmenet to obtain the index and zeros run length. */
int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) {
    long index;
    uint8_t count = hllPatLen(ele,elesize,&index);
    /* Update the register if this element produced a longer run of zeroes. */
    return hllSparseSet(o,index,count);
}

/* Compute the register histogram in the sparse representation. */
void hllSparseRegHisto(uint8_t *sparse, int sparselen, int *invalid, int* reghisto) {
    int idx = 0, runlen, regval;
    uint8_t *end = sparse+sparselen, *p = sparse;

    while(p < end) {
        if (HLL_SPARSE_IS_ZERO(p)) {
            runlen = HLL_SPARSE_ZERO_LEN(p);
            idx += runlen;
            reghisto[0] += runlen;
            p++;
        } else if (HLL_SPARSE_IS_XZERO(p)) {
            runlen = HLL_SPARSE_XZERO_LEN(p);
            idx += runlen;
            reghisto[0] += runlen;
            p += 2;
        } else {
            runlen = HLL_SPARSE_VAL_LEN(p);
            regval = HLL_SPARSE_VAL_VALUE(p);
            idx += runlen;
            reghisto[regval] += runlen;
            p++;
        }
    }
    if (idx != HLL_REGISTERS && invalid) *invalid = 1;
}

/* ========================= HyperLogLog Count ==============================
 * This is the core of the algorithm where the approximated count is computed.
 * The function uses the lower level hllDenseRegHisto() and hllSparseRegHisto()
 * functions as helpers to compute histogram of register values part of the
 * computation, which is representation-specific, while all the rest is common. */

/* Implements the register histogram calculation for uint8_t data type
 * which is only used internally as speedup for PFCOUNT with multiple keys. */
void hllRawRegHisto(uint8_t *registers, int* reghisto) {
    uint64_t *word = (uint64_t*) registers;
    uint8_t *bytes;
    int j;

    for (j = 0; j < HLL_REGISTERS/8; j++) {
        if (*word == 0) {
            reghisto[0] += 8;
        } else {
            bytes = (uint8_t*) word;
            reghisto[bytes[0]]++;
            reghisto[bytes[1]]++;
            reghisto[bytes[2]]++;
            reghisto[bytes[3]]++;
            reghisto[bytes[4]]++;
            reghisto[bytes[5]]++;
            reghisto[bytes[6]]++;
            reghisto[bytes[7]]++;
        }
        word++;
    }
}

// somehow this is missing on some platforms
#ifndef INFINITY
// from math.h
#define INFINITY 1e50f
#endif


/* Helper function sigma as defined in
 * "New cardinality estimation algorithms for HyperLogLog sketches"
 * Otmar Ertl, arXiv:1702.01284 */
double hllSigma(double x) {
    if (x == 1.) return INFINITY;
    double zPrime;
    double y = 1;
    double z = x;
    do {
        x *= x;
        zPrime = z;
        z += x * y;
        y += y;
    } while(zPrime != z);
    return z;
}

/* Helper function tau as defined in
 * "New cardinality estimation algorithms for HyperLogLog sketches"
 * Otmar Ertl, arXiv:1702.01284 */
double hllTau(double x) {
    if (x == 0. || x == 1.) return 0.;
    double zPrime;
    double y = 1.0;
    double z = 1 - x;
    do {
        x = sqrt(x);
        zPrime = z;
        y *= 0.5;
        z -= pow(1 - x, 2)*y;
    } while(zPrime != z);
    return z / 3;
}

/* Return the approximated cardinality of the set based on the harmonic
 * mean of the registers values. 'hdr' points to the start of the SDS
 * representing the String object holding the HLL representation.
 *
 * If the sparse representation of the HLL object is not valid, the integer
 * pointed by 'invalid' is set to non-zero, otherwise it is left untouched.
 *
 * hllCount() supports a special internal-only encoding of HLL_RAW, that
 * is, hdr->registers will point to an uint8_t array of HLL_REGISTERS element.
 * This is useful in order to speedup PFCOUNT when called against multiple
 * keys (no need to work with 6-bit integers encoding). */
uint64_t hllCount(struct hllhdr *hdr, int *invalid) {
    double m = HLL_REGISTERS;
    double E;
    int j;
    int reghisto[HLL_Q+2] = {0};

    /* Compute register histogram */
    if (hdr->encoding == HLL_DENSE) {
        hllDenseRegHisto(hdr->registers,reghisto);
    } else if (hdr->encoding == HLL_SPARSE) {
        hllSparseRegHisto(hdr->registers,
                         sdslen((sds)hdr)-HLL_HDR_SIZE,invalid,reghisto);
    } else if (hdr->encoding == HLL_RAW) {
        hllRawRegHisto(hdr->registers,reghisto);
    } else {
		*invalid = 1;
		return 0;
        //serverPanic("Unknown HyperLogLog encoding in hllCount()");
    }

    /* Estimate cardinality form register histogram. See:
     * "New cardinality estimation algorithms for HyperLogLog sketches"
     * Otmar Ertl, arXiv:1702.01284 */
    double z = m * hllTau((m-reghisto[HLL_Q+1])/(double)m);
    for (j = HLL_Q; j >= 1; --j) {
        z += reghisto[j];
        z *= 0.5;
    }
    z += m * hllSigma(reghisto[0]/(double)m);
    E = llroundl(HLL_ALPHA_INF*m*m/z);

    return (uint64_t) E;
}

/* Call hllDenseAdd() or hllSparseAdd() according to the HLL encoding. */
int hll_add(robj *o, unsigned char *ele, size_t elesize) {
    struct hllhdr *hdr = (struct hllhdr *) o->ptr;
    switch(hdr->encoding) {
    case HLL_DENSE: return hllDenseAdd(hdr->registers,ele,elesize);
    case HLL_SPARSE: return hllSparseAdd(o,ele,elesize);
    default: return -1; /* Invalid representation. */
    }
}

/* Merge by computing MAX(registers[i],hll[i]) the HyperLogLog 'hll'
 * with an array of uint8_t HLL_REGISTERS registers pointed by 'max'.
 *
 * The hll object must be already validated via isHLLObjectOrReply()
 * or in some other way.
 *
 * If the HyperLogLog is sparse and is found to be invalid, C_ERR
 * is returned, otherwise the function always succeeds. */
int hllMerge(uint8_t *max, robj *hll) {
    struct hllhdr *hdr = (struct hllhdr *) hll->ptr;
    int i;

    if (hdr->encoding == HLL_DENSE) {
        uint8_t val;

        for (i = 0; i < HLL_REGISTERS; i++) {
            HLL_DENSE_GET_REGISTER(val,hdr->registers,i);
            if (val > max[i]) max[i] = val;
        }
    } else {
        uint8_t *p = (uint8_t *) hll->ptr, *end = p + sdslen((sds) hll->ptr);
        long runlen, regval;

        p += HLL_HDR_SIZE;
        i = 0;
        while(p < end) {
            if (HLL_SPARSE_IS_ZERO(p)) {
                runlen = HLL_SPARSE_ZERO_LEN(p);
                i += runlen;
                p++;
            } else if (HLL_SPARSE_IS_XZERO(p)) {
                runlen = HLL_SPARSE_XZERO_LEN(p);
                i += runlen;
                p += 2;
            } else {
                runlen = HLL_SPARSE_VAL_LEN(p);
                regval = HLL_SPARSE_VAL_VALUE(p);
                while(runlen--) {
                    if (regval > max[i]) max[i] = regval;
                    i++;
                }
                p++;
            }
        }
        if (i != HLL_REGISTERS) return C_ERR;
    }
    return C_OK;
}

/* ========================== robj creation ========================== */
robj *createObject(void *ptr) {
	robj *result = (robj*) malloc(sizeof(robj));
	result->ptr = ptr;
	return result;
}

void destroyObject(robj *obj) {
	free(obj);
}

/* ========================== HyperLogLog commands ========================== */

/* Create an HLL object. We always create the HLL using sparse encoding.
 * This will be upgraded to the dense representation as needed. */
robj *hll_create(void) {
    robj *o;
    struct hllhdr *hdr;
    sds s;
    uint8_t *p;
    int sparselen = HLL_HDR_SIZE +
                    (((HLL_REGISTERS+(HLL_SPARSE_XZERO_MAX_LEN-1)) /
                     HLL_SPARSE_XZERO_MAX_LEN)*2);
    int aux;

    /* Populate the sparse representation with as many XZERO opcodes as
     * needed to represent all the registers. */
    aux = HLL_REGISTERS;
    s = sdsnewlen(NULL,sparselen);
    p = (uint8_t*)s + HLL_HDR_SIZE;
    while(aux) {
        int xzero = HLL_SPARSE_XZERO_MAX_LEN;
        if (xzero > aux) xzero = aux;
        HLL_SPARSE_XZERO_SET(p,xzero);
        p += 2;
        aux -= xzero;
    }
    assert((p-(uint8_t*)s) == sparselen);

    /* Create the actual object. */
    o = createObject(s);
    hdr = (struct hllhdr *) o->ptr;
    memcpy(hdr->magic,"HYLL",4);
    hdr->encoding = HLL_SPARSE;
    return o;
}

void hll_destroy(robj *obj) {
	if (!obj) {
		return;
	}
	sdsfree((sds) obj->ptr);
	destroyObject(obj);
}



int hll_count(robj *o, size_t *result) {
	int invalid = 0;
	*result = hllCount((struct hllhdr*) o->ptr, &invalid);
	return invalid == 0 ? C_OK : C_ERR;
}

robj *hll_merge(robj **hlls, size_t hll_count) {
    uint8_t max[HLL_REGISTERS];
    struct hllhdr *hdr;
    size_t j;
	 /* Use dense representation as target? */
    int use_dense = 0;

    /* Compute an HLL with M[i] = MAX(M[i]_j).
     * We store the maximum into the max array of registers. We'll write
     * it to the target variable later. */
    memset(max, 0, sizeof(max));
    for (j = 0; j < hll_count; j++) {
        /* Check type and size. */
        robj *o = hlls[j];
        if (o == NULL) continue; /* Assume empty HLL for non existing var. */

        /* If at least one involved HLL is dense, use the dense representation
         * as target ASAP to save time and avoid the conversion step. */
        hdr = (struct hllhdr *) o->ptr;
        if (hdr->encoding == HLL_DENSE) use_dense = 1;

        /* Merge with this HLL with our 'max' HHL by setting max[i]
         * to MAX(max[i],hll[i]). */
        if (hllMerge(max, o) == C_ERR) {
            return NULL;
        }
    }

    /* Create the destination key's value. */
    robj *result = hll_create();
	if (!result) {
		return NULL;
	}

    /* Convert the destination object to dense representation if at least
     * one of the inputs was dense. */
    if (use_dense && hllSparseToDense(result) == C_ERR) {
		hll_destroy(result);
        return NULL;
    }

    /* Write the resulting HLL to the destination HLL registers and
     * invalidate the cached value. */
    for (j = 0; j < HLL_REGISTERS; j++) {
        if (max[j] == 0) continue;
        hdr = (struct hllhdr *) result->ptr;
        switch(hdr->encoding) {
        case HLL_DENSE: hllDenseSet(hdr->registers,j,max[j]); break;
        case HLL_SPARSE: hllSparseSet(result,j,max[j]); break;
        }
    }
	return result;
}
/* SDSLib 2.0 -- A C dynamic strings library
 *
 * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
 * Copyright (c) 2015, Oran Agra
 * Copyright (c) 2015, Redis Labs, Inc
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>


static inline int sdsHdrSize(char type) {
    switch(type&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            return sizeof(struct sdshdr5);
        case SDS_TYPE_8:
            return sizeof(struct sdshdr8);
        case SDS_TYPE_16:
            return sizeof(struct sdshdr16);
        case SDS_TYPE_32:
            return sizeof(struct sdshdr32);
        case SDS_TYPE_64:
            return sizeof(struct sdshdr64);
    }
    return 0;
}

static inline char sdsReqType(size_t string_size) {
    if (string_size < 1<<5)
        return SDS_TYPE_5;
    if (string_size < 1<<8)
        return SDS_TYPE_8;
    if (string_size < 1<<16)
        return SDS_TYPE_16;
#if (LONG_MAX == LLONG_MAX)
    if (string_size < 1ll<<32)
        return SDS_TYPE_32;
    return SDS_TYPE_64;
#else
    return SDS_TYPE_32;
#endif
}

/* Create a new sds string with the content specified by the 'init' pointer
 * and 'initlen'.
 * If NULL is used for 'init' the string is initialized with zero bytes.
 * If SDS_NOINIT is used, the buffer is left uninitialized;
 *
 * The string is always null-termined (all the sds strings are, always) so
 * even if you create an sds string with:
 *
 * mystring = sdsnewlen("abc",3);
 *
 * You can print the string with printf() as there is an implicit \0 at the
 * end of the string. However the string is binary safe and can contain
 * \0 characters in the middle, as the length is stored in the sds header. */
sds sdsnewlen(const void *init, size_t initlen) {
    void *sh;
    sds s;
    char type = sdsReqType(initlen);
    /* Empty strings are usually created in order to append. Use type 8
     * since type 5 is not good at this. */
    if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8;
    int hdrlen = sdsHdrSize(type);
    unsigned char *fp; /* flags pointer. */

    sh = malloc(hdrlen+initlen+1);
    if (!init)
        memset(sh, 0, hdrlen+initlen+1);
    if (sh == NULL) return NULL;
    s = (char*)sh+hdrlen;
    fp = ((unsigned char*)s)-1;
    switch(type) {
        case SDS_TYPE_5: {
            *fp = type | (initlen << SDS_TYPE_BITS);
            break;
        }
        case SDS_TYPE_8: {
            SDS_HDR_VAR(8,s);
            sh->len = initlen;
            sh->alloc = initlen;
            *fp = type;
            break;
        }
        case SDS_TYPE_16: {
            SDS_HDR_VAR(16,s);
            sh->len = initlen;
            sh->alloc = initlen;
            *fp = type;
            break;
        }
        case SDS_TYPE_32: {
            SDS_HDR_VAR(32,s);
            sh->len = initlen;
            sh->alloc = initlen;
            *fp = type;
            break;
        }
        case SDS_TYPE_64: {
            SDS_HDR_VAR(64,s);
            sh->len = initlen;
            sh->alloc = initlen;
            *fp = type;
            break;
        }
    }
    if (initlen && init)
        memcpy(s, init, initlen);
    s[initlen] = '\0';
    return s;
}

/* Create an empty (zero length) sds string. Even in this case the string
 * always has an implicit null term. */
sds sdsempty(void) {
    return sdsnewlen("",0);
}

/* Create a new sds string starting from a null terminated C string. */
sds sdsnew(const char *init) {
    size_t initlen = (init == NULL) ? 0 : strlen(init);
    return sdsnewlen(init, initlen);
}

/* Duplicate an sds string. */
sds sdsdup(const sds s) {
    return sdsnewlen(s, sdslen(s));
}

/* Free an sds string. No operation is performed if 's' is NULL. */
void sdsfree(sds s) {
    if (s == NULL) return;
    free((char*)s-sdsHdrSize(s[-1]));
}

/* Set the sds string length to the length as obtained with strlen(), so
 * considering as content only up to the first null term character.
 *
 * This function is useful when the sds string is hacked manually in some
 * way, like in the following example:
 *
 * s = sdsnew("foobar");
 * s[2] = '\0';
 * sdsupdatelen(s);
 * printf("%d\n", sdslen(s));
 *
 * The output will be "2", but if we comment out the call to sdsupdatelen()
 * the output will be "6" as the string was modified but the logical length
 * remains 6 bytes. */
void sdsupdatelen(sds s) {
    size_t reallen = strlen(s);
    sdssetlen(s, reallen);
}

/* Modify an sds string in-place to make it empty (zero length).
 * However all the existing buffer is not discarded but set as free space
 * so that next append operations will not require allocations up to the
 * number of bytes previously available. */
void sdsclear(sds s) {
    sdssetlen(s, 0);
    s[0] = '\0';
}

/* Enlarge the free space at the end of the sds string so that the caller
 * is sure that after calling this function can overwrite up to addlen
 * bytes after the end of the string, plus one more byte for nul term.
 *
 * Note: this does not change the *length* of the sds string as returned
 * by sdslen(), but only the free buffer space we have. */
sds sdsMakeRoomFor(sds s, size_t addlen) {
    void *sh, *newsh;
    size_t avail = sdsavail(s);
    size_t len, newlen;
    char type, oldtype = s[-1] & SDS_TYPE_MASK;
    int hdrlen;

    /* Return ASAP if there is enough space left. */
    if (avail >= addlen) return s;

    len = sdslen(s);
    sh = (char*)s-sdsHdrSize(oldtype);
    newlen = (len+addlen);
    if (newlen < SDS_MAX_PREALLOC)
        newlen *= 2;
    else
        newlen += SDS_MAX_PREALLOC;

    type = sdsReqType(newlen);

    /* Don't use type 5: the user is appending to the string and type 5 is
     * not able to remember empty space, so sdsMakeRoomFor() must be called
     * at every appending operation. */
    if (type == SDS_TYPE_5) type = SDS_TYPE_8;

    hdrlen = sdsHdrSize(type);
    if (oldtype==type) {
        newsh = realloc(sh, hdrlen+newlen+1);
        if (newsh == NULL) return NULL;
        s = (char*)newsh+hdrlen;
    } else {
        /* Since the header size changes, need to move the string forward,
         * and can't use realloc */
        newsh = malloc(hdrlen+newlen+1);
        if (newsh == NULL) return NULL;
        memcpy((char*)newsh+hdrlen, s, len+1);
        free(sh);
        s = (char*)newsh+hdrlen;
        s[-1] = type;
        sdssetlen(s, len);
    }
    sdssetalloc(s, newlen);
    return s;
}

/* Reallocate the sds string so that it has no free space at the end. The
 * contained string remains not altered, but next concatenation operations
 * will require a reallocation.
 *
 * After the call, the passed sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sdsRemoveFreeSpace(sds s) {
    void *sh, *newsh;
    char type, oldtype = s[-1] & SDS_TYPE_MASK;
    int hdrlen, oldhdrlen = sdsHdrSize(oldtype);
    size_t len = sdslen(s);
    sh = (char*)s-oldhdrlen;

    /* Check what would be the minimum SDS header that is just good enough to
     * fit this string. */
    type = sdsReqType(len);
    hdrlen = sdsHdrSize(type);

    /* If the type is the same, or at least a large enough type is still
     * required, we just realloc(), letting the allocator to do the copy
     * only if really needed. Otherwise if the change is huge, we manually
     * reallocate the string to use the different header type. */
    if (oldtype==type || type > SDS_TYPE_8) {
        newsh = realloc(sh, oldhdrlen+len+1);
        if (newsh == NULL) return NULL;
        s = (char*)newsh+oldhdrlen;
    } else {
        newsh = malloc(hdrlen+len+1);
        if (newsh == NULL) return NULL;
        memcpy((char*)newsh+hdrlen, s, len+1);
        free(sh);
        s = (char*)newsh+hdrlen;
        s[-1] = type;
        sdssetlen(s, len);
    }
    sdssetalloc(s, len);
    return s;
}

/* Return the total size of the allocation of the specified sds string,
 * including:
 * 1) The sds header before the pointer.
 * 2) The string.
 * 3) The free buffer at the end if any.
 * 4) The implicit null term.
 */
size_t sdsAllocSize(sds s) {
    size_t alloc = sdsalloc(s);
    return sdsHdrSize(s[-1])+alloc+1;
}

/* Return the pointer of the actual SDS allocation (normally SDS strings
 * are referenced by the start of the string buffer). */
void *sdsAllocPtr(sds s) {
    return (void*) (s-sdsHdrSize(s[-1]));
}

/* Increment the sds length and decrements the left free space at the
 * end of the string according to 'incr'. Also set the null term
 * in the new end of the string.
 *
 * This function is used in order to fix the string length after the
 * user calls sdsMakeRoomFor(), writes something after the end of
 * the current string, and finally needs to set the new length.
 *
 * Note: it is possible to use a negative increment in order to
 * right-trim the string.
 *
 * Usage example:
 *
 * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the
 * following schema, to cat bytes coming from the kernel to the end of an
 * sds string without copying into an intermediate buffer:
 *
 * oldlen = sdslen(s);
 * s = sdsMakeRoomFor(s, BUFFER_SIZE);
 * nread = read(fd, s+oldlen, BUFFER_SIZE);
 * ... check for nread <= 0 and handle it ...
 * sdsIncrLen(s, nread);
 */
void sdsIncrLen(sds s, ssize_t incr) {
    unsigned char flags = s[-1];
    size_t len;
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5: {
            unsigned char *fp = ((unsigned char*)s)-1;
            unsigned char oldlen = SDS_TYPE_5_LEN(flags);
            assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr)));
            *fp = SDS_TYPE_5 | ((oldlen+incr) << SDS_TYPE_BITS);
            len = oldlen+incr;
            break;
        }
        case SDS_TYPE_8: {
            SDS_HDR_VAR(8,s);
            assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
            len = (sh->len += incr);
            break;
        }
        case SDS_TYPE_16: {
            SDS_HDR_VAR(16,s);
            assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
            len = (sh->len += incr);
            break;
        }
        case SDS_TYPE_32: {
            SDS_HDR_VAR(32,s);
            assert((incr >= 0 && sh->alloc-sh->len >= (unsigned int)incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
            len = (sh->len += incr);
            break;
        }
        case SDS_TYPE_64: {
            SDS_HDR_VAR(64,s);
            assert((incr >= 0 && sh->alloc-sh->len >= (uint64_t)incr) || (incr < 0 && sh->len >= (uint64_t)(-incr)));
            len = (sh->len += incr);
            break;
        }
        default: len = 0; /* Just to avoid compilation warnings. */
    }
    s[len] = '\0';
}

/* Grow the sds to have the specified length. Bytes that were not part of
 * the original length of the sds will be set to zero.
 *
 * if the specified length is smaller than the current length, no operation
 * is performed. */
sds sdsgrowzero(sds s, size_t len) {
    size_t curlen = sdslen(s);

    if (len <= curlen) return s;
    s = sdsMakeRoomFor(s,len-curlen);
    if (s == NULL) return NULL;

    /* Make sure added region doesn't contain garbage */
    memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
    sdssetlen(s, len);
    return s;
}

/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the
 * end of the specified sds string 's'.
 *
 * After the call, the passed sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sdscatlen(sds s, const void *t, size_t len) {
    size_t curlen = sdslen(s);

    s = sdsMakeRoomFor(s,len);
    if (s == NULL) return NULL;
    memcpy(s+curlen, t, len);
    sdssetlen(s, curlen+len);
    s[curlen+len] = '\0';
    return s;
}

/* Append the specified null termianted C string to the sds string 's'.
 *
 * After the call, the passed sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sdscat(sds s, const char *t) {
    return sdscatlen(s, t, strlen(t));
}

/* Append the specified sds 't' to the existing sds 's'.
 *
 * After the call, the modified sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sdscatsds(sds s, const sds t) {
    return sdscatlen(s, t, sdslen(t));
}

/* Destructively modify the sds string 's' to hold the specified binary
 * safe string pointed by 't' of length 'len' bytes. */
sds sdscpylen(sds s, const char *t, size_t len) {
    if (sdsalloc(s) < len) {
        s = sdsMakeRoomFor(s,len-sdslen(s));
        if (s == NULL) return NULL;
    }
    memcpy(s, t, len);
    s[len] = '\0';
    sdssetlen(s, len);
    return s;
}

/* Like sdscpylen() but 't' must be a null-termined string so that the length
 * of the string is obtained with strlen(). */
sds sdscpy(sds s, const char *t) {
    return sdscpylen(s, t, strlen(t));
}

/* Helper for sdscatlonglong() doing the actual number -> string
 * conversion. 's' must point to a string with room for at least
 * SDS_LLSTR_SIZE bytes.
 *
 * The function returns the length of the null-terminated string
 * representation stored at 's'. */
#define SDS_LLSTR_SIZE 21
int sdsll2str(char *s, long long value) {
    char *p, aux;
    unsigned long long v;
    size_t l;

    /* Generate the string representation, this method produces
     * an reversed string. */
    v = (value < 0) ? -value : value;
    p = s;
    do {
        *p++ = '0'+(v%10);
        v /= 10;
    } while(v);
    if (value < 0) *p++ = '-';

    /* Compute length and add null term. */
    l = p-s;
    *p = '\0';

    /* Reverse the string. */
    p--;
    while(s < p) {
        aux = *s;
        *s = *p;
        *p = aux;
        s++;
        p--;
    }
    return l;
}

/* Identical sdsll2str(), but for unsigned long long type. */
int sdsull2str(char *s, unsigned long long v) {
    char *p, aux;
    size_t l;

    /* Generate the string representation, this method produces
     * an reversed string. */
    p = s;
    do {
        *p++ = '0'+(v%10);
        v /= 10;
    } while(v);

    /* Compute length and add null term. */
    l = p-s;
    *p = '\0';

    /* Reverse the string. */
    p--;
    while(s < p) {
        aux = *s;
        *s = *p;
        *p = aux;
        s++;
        p--;
    }
    return l;
}

/* Create an sds string from a long long value. It is much faster than:
 *
 * sdscatprintf(sdsempty(),"%lld\n", value);
 */
sds sdsfromlonglong(long long value) {
    char buf[SDS_LLSTR_SIZE];
    int len = sdsll2str(buf,value);

    return sdsnewlen(buf,len);
}

/* Like sdscatprintf() but gets va_list instead of being variadic. */
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
    va_list cpy;
    char staticbuf[1024], *buf = staticbuf, *t;
    size_t buflen = strlen(fmt)*2;

    /* We try to start using a static buffer for speed.
     * If not possible we revert to heap allocation. */
    if (buflen > sizeof(staticbuf)) {
        buf = (char*) malloc(buflen);
        if (buf == NULL) return NULL;
    } else {
        buflen = sizeof(staticbuf);
    }

    /* Try with buffers two times bigger every time we fail to
     * fit the string in the current buffer size. */
    while(1) {
        buf[buflen-2] = '\0';
        va_copy(cpy,ap);
        vsnprintf(buf, buflen, fmt, cpy);
        va_end(cpy);
        if (buf[buflen-2] != '\0') {
            if (buf != staticbuf) free(buf);
            buflen *= 2;
            buf = (char*) malloc(buflen);
            if (buf == NULL) return NULL;
            continue;
        }
        break;
    }

    /* Finally concat the obtained string to the SDS string and return it. */
    t = sdscat(s, buf);
    if (buf != staticbuf) free(buf);
    return t;
}

/* Append to the sds string 's' a string obtained using printf-alike format
 * specifier.
 *
 * After the call, the modified sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call.
 *
 * Example:
 *
 * s = sdsnew("Sum is: ");
 * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b).
 *
 * Often you need to create a string from scratch with the printf-alike
 * format. When this is the need, just use sdsempty() as the target string:
 *
 * s = sdscatprintf(sdsempty(), "... your format ...", args);
 */
sds sdscatprintf(sds s, const char *fmt, ...) {
    va_list ap;
    char *t;
    va_start(ap, fmt);
    t = sdscatvprintf(s,fmt,ap);
    va_end(ap);
    return t;
}

/* This function is similar to sdscatprintf, but much faster as it does
 * not rely on sprintf() family functions implemented by the libc that
 * are often very slow. Moreover directly handling the sds string as
 * new data is concatenated provides a performance improvement.
 *
 * However this function only handles an incompatible subset of printf-alike
 * format specifiers:
 *
 * %s - C String
 * %S - SDS string
 * %i - signed int
 * %I - 64 bit signed integer (long long, int64_t)
 * %u - unsigned int
 * %U - 64 bit unsigned integer (unsigned long long, uint64_t)
 * %% - Verbatim "%" character.
 */
sds sdscatfmt(sds s, char const *fmt, ...) {
    size_t initlen = sdslen(s);
    const char *f = fmt;
    long i;
    va_list ap;

    va_start(ap,fmt);
    f = fmt;    /* Next format specifier byte to process. */
    i = initlen; /* Position of the next byte to write to dest str. */
    while(*f) {
        char next, *str;
        size_t l;
        long long num;
        unsigned long long unum;

        /* Make sure there is always space for at least 1 char. */
        if (sdsavail(s)==0) {
            s = sdsMakeRoomFor(s,1);
        }

        switch(*f) {
        case '%':
            next = *(f+1);
            f++;
            switch(next) {
            case 's':
            case 'S':
                str = va_arg(ap,char*);
                l = (next == 's') ? strlen(str) : sdslen(str);
                if (sdsavail(s) < l) {
                    s = sdsMakeRoomFor(s,l);
                }
                memcpy(s+i,str,l);
                sdsinclen(s,l);
                i += l;
                break;
            case 'i':
            case 'I':
                if (next == 'i')
                    num = va_arg(ap,int);
                else
                    num = va_arg(ap,long long);
                {
                    char buf[SDS_LLSTR_SIZE];
                    l = sdsll2str(buf,num);
                    if (sdsavail(s) < l) {
                        s = sdsMakeRoomFor(s,l);
                    }
                    memcpy(s+i,buf,l);
                    sdsinclen(s,l);
                    i += l;
                }
                break;
            case 'u':
            case 'U':
                if (next == 'u')
                    unum = va_arg(ap,unsigned int);
                else
                    unum = va_arg(ap,unsigned long long);
                {
                    char buf[SDS_LLSTR_SIZE];
                    l = sdsull2str(buf,unum);
                    if (sdsavail(s) < l) {
                        s = sdsMakeRoomFor(s,l);
                    }
                    memcpy(s+i,buf,l);
                    sdsinclen(s,l);
                    i += l;
                }
                break;
            default: /* Handle %% and generally %<unknown>. */
                s[i++] = next;
                sdsinclen(s,1);
                break;
            }
            break;
        default:
            s[i++] = *f;
            sdsinclen(s,1);
            break;
        }
        f++;
    }
    va_end(ap);

    /* Add null-term */
    s[i] = '\0';
    return s;
}

/* Remove the part of the string from left and from right composed just of
 * contiguous characters found in 'cset', that is a null terminted C string.
 *
 * After the call, the modified sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call.
 *
 * Example:
 *
 * s = sdsnew("AA...AA.a.aa.aHelloWorld     :::");
 * s = sdstrim(s,"Aa. :");
 * printf("%s\n", s);
 *
 * Output will be just "Hello World".
 */
sds sdstrim(sds s, const char *cset) {
    char *start, *end, *sp, *ep;
    size_t len;

    sp = start = s;
    ep = end = s+sdslen(s)-1;
    while(sp <= end && strchr(cset, *sp)) sp++;
    while(ep > sp && strchr(cset, *ep)) ep--;
    len = (sp > ep) ? 0 : ((ep-sp)+1);
    if (s != sp) memmove(s, sp, len);
    s[len] = '\0';
    sdssetlen(s,len);
    return s;
}

/* Turn the string into a smaller (or equal) string containing only the
 * substring specified by the 'start' and 'end' indexes.
 *
 * start and end can be negative, where -1 means the last character of the
 * string, -2 the penultimate character, and so forth.
 *
 * The interval is inclusive, so the start and end characters will be part
 * of the resulting string.
 *
 * The string is modified in-place.
 *
 * Example:
 *
 * s = sdsnew("Hello World");
 * sdsrange(s,1,-1); => "ello World"
 */
void sdsrange(sds s, ssize_t start, ssize_t end) {
    size_t newlen, len = sdslen(s);

    if (len == 0) return;
    if (start < 0) {
        start = len+start;
        if (start < 0) start = 0;
    }
    if (end < 0) {
        end = len+end;
        if (end < 0) end = 0;
    }
    newlen = (start > end) ? 0 : (end-start)+1;
    if (newlen != 0) {
        if (start >= (ssize_t)len) {
            newlen = 0;
        } else if (end >= (ssize_t)len) {
            end = len-1;
            newlen = (start > end) ? 0 : (end-start)+1;
        }
    } else {
        start = 0;
    }
    if (start && newlen) memmove(s, s+start, newlen);
    s[newlen] = 0;
    sdssetlen(s,newlen);
}

/* Apply tolower() to every character of the sds string 's'. */
void sdstolower(sds s) {
    size_t len = sdslen(s), j;

    for (j = 0; j < len; j++) s[j] = tolower(s[j]);
}

/* Apply toupper() to every character of the sds string 's'. */
void sdstoupper(sds s) {
    size_t len = sdslen(s), j;

    for (j = 0; j < len; j++) s[j] = toupper(s[j]);
}

/* Compare two sds strings s1 and s2 with memcmp().
 *
 * Return value:
 *
 *     positive if s1 > s2.
 *     negative if s1 < s2.
 *     0 if s1 and s2 are exactly the same binary string.
 *
 * If two strings share exactly the same prefix, but one of the two has
 * additional characters, the longer string is considered to be greater than
 * the smaller one. */
int sdscmp(const sds s1, const sds s2) {
    size_t l1, l2, minlen;
    int cmp;

    l1 = sdslen(s1);
    l2 = sdslen(s2);
    minlen = (l1 < l2) ? l1 : l2;
    cmp = memcmp(s1,s2,minlen);
    if (cmp == 0) return l1>l2? 1: (l1<l2? -1: 0);
    return cmp;
}

/* Split 's' with separator in 'sep'. An array
 * of sds strings is returned. *count will be set
 * by reference to the number of tokens returned.
 *
 * On out of memory, zero length string, zero length
 * separator, NULL is returned.
 *
 * Note that 'sep' is able to split a string using
 * a multi-character separator. For example
 * sdssplit("foo_-_bar","_-_"); will return two
 * elements "foo" and "bar".
 *
 * This version of the function is binary-safe but
 * requires length arguments. sdssplit() is just the
 * same function but for zero-terminated strings.
 */
sds *sdssplitlen(const char *s, ssize_t len, const char *sep, int seplen, int *count) {
    int elements = 0, slots = 5;
    long start = 0, j;
    sds *tokens;

    if (seplen < 1 || len < 0) return NULL;

    tokens = (sds*) malloc(sizeof(sds)*slots);
    if (tokens == NULL) return NULL;

    if (len == 0) {
        *count = 0;
        return tokens;
    }
    for (j = 0; j < (len-(seplen-1)); j++) {
        /* make sure there is room for the next element and the final one */
        if (slots < elements+2) {
            sds *newtokens;

            slots *= 2;
            newtokens = (sds*) realloc(tokens,sizeof(sds)*slots);
            if (newtokens == NULL) goto cleanup;
            tokens = newtokens;
        }
        /* search the separator */
        if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
            tokens[elements] = sdsnewlen(s+start,j-start);
            if (tokens[elements] == NULL) goto cleanup;
            elements++;
            start = j+seplen;
            j = j+seplen-1; /* skip the separator */
        }
    }
    /* Add the final element. We are sure there is room in the tokens array. */
    tokens[elements] = sdsnewlen(s+start,len-start);
    if (tokens[elements] == NULL) goto cleanup;
    elements++;
    *count = elements;
    return tokens;

cleanup:
    {
        int i;
        for (i = 0; i < elements; i++) sdsfree(tokens[i]);
        free(tokens);
        *count = 0;
        return NULL;
    }
}

/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */
void sdsfreesplitres(sds *tokens, int count) {
    if (!tokens) return;
    while(count--)
        sdsfree(tokens[count]);
    free(tokens);
}

/* Append to the sds string "s" an escaped string representation where
 * all the non-printable characters (tested with isprint()) are turned into
 * escapes in the form "\n\r\a...." or "\x<hex-number>".
 *
 * After the call, the modified sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sdscatrepr(sds s, const char *p, size_t len) {
    s = sdscatlen(s,"\"",1);
    while(len--) {
        switch(*p) {
        case '\\':
        case '"':
            s = sdscatprintf(s,"\\%c",*p);
            break;
        case '\n': s = sdscatlen(s,"\\n",2); break;
        case '\r': s = sdscatlen(s,"\\r",2); break;
        case '\t': s = sdscatlen(s,"\\t",2); break;
        case '\a': s = sdscatlen(s,"\\a",2); break;
        case '\b': s = sdscatlen(s,"\\b",2); break;
        default:
            if (isprint(*p))
                s = sdscatprintf(s,"%c",*p);
            else
                s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
            break;
        }
        p++;
    }
    return sdscatlen(s,"\"",1);
}

/* Helper function for sdssplitargs() that returns non zero if 'c'
 * is a valid hex digit. */
int is_hex_digit(char c) {
    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
           (c >= 'A' && c <= 'F');
}

/* Helper function for sdssplitargs() that converts a hex digit into an
 * integer from 0 to 15 */
int hex_digit_to_int(char c) {
    switch(c) {
    case '0': return 0;
    case '1': return 1;
    case '2': return 2;
    case '3': return 3;
    case '4': return 4;
    case '5': return 5;
    case '6': return 6;
    case '7': return 7;
    case '8': return 8;
    case '9': return 9;
    case 'a': case 'A': return 10;
    case 'b': case 'B': return 11;
    case 'c': case 'C': return 12;
    case 'd': case 'D': return 13;
    case 'e': case 'E': return 14;
    case 'f': case 'F': return 15;
    default: return 0;
    }
}

/* Split a line into arguments, where every argument can be in the
 * following programming-language REPL-alike form:
 *
 * foo bar "newline are supported\n" and "\xff\x00otherstuff"
 *
 * The number of arguments is stored into *argc, and an array
 * of sds is returned.
 *
 * The caller should free the resulting array of sds strings with
 * sdsfreesplitres().
 *
 * Note that sdscatrepr() is able to convert back a string into
 * a quoted string in the same format sdssplitargs() is able to parse.
 *
 * The function returns the allocated tokens on success, even when the
 * input string is empty, or NULL if the input contains unbalanced
 * quotes or closed quotes followed by non space characters
 * as in: "foo"bar or "foo'
 */
sds *sdssplitargs(const char *line, int *argc) {
    const char *p = line;
    char *current = NULL;
    char **vector = NULL;

    *argc = 0;
    while(1) {
        /* skip blanks */
        while(*p && isspace(*p)) p++;
        if (*p) {
            /* get a token */
            int inq=0;  /* set to 1 if we are in "quotes" */
            int insq=0; /* set to 1 if we are in 'single quotes' */
            int done=0;

            if (current == NULL) current = sdsempty();
            while(!done) {
                if (inq) {
                    if (*p == '\\' && *(p+1) == 'x' &&
                                             is_hex_digit(*(p+2)) &&
                                             is_hex_digit(*(p+3)))
                    {
                        unsigned char byte;

                        byte = (hex_digit_to_int(*(p+2))*16)+
                                hex_digit_to_int(*(p+3));
                        current = sdscatlen(current,(char*)&byte,1);
                        p += 3;
                    } else if (*p == '\\' && *(p+1)) {
                        char c;

                        p++;
                        switch(*p) {
                        case 'n': c = '\n'; break;
                        case 'r': c = '\r'; break;
                        case 't': c = '\t'; break;
                        case 'b': c = '\b'; break;
                        case 'a': c = '\a'; break;
                        default: c = *p; break;
                        }
                        current = sdscatlen(current,&c,1);
                    } else if (*p == '"') {
                        /* closing quote must be followed by a space or
                         * nothing at all. */
                        if (*(p+1) && !isspace(*(p+1))) goto err;
                        done=1;
                    } else if (!*p) {
                        /* unterminated quotes */
                        goto err;
                    } else {
                        current = sdscatlen(current,p,1);
                    }
                } else if (insq) {
                    if (*p == '\\' && *(p+1) == '\'') {
                        p++;
                        current = sdscatlen(current,"'",1);
                    } else if (*p == '\'') {
                        /* closing quote must be followed by a space or
                         * nothing at all. */
                        if (*(p+1) && !isspace(*(p+1))) goto err;
                        done=1;
                    } else if (!*p) {
                        /* unterminated quotes */
                        goto err;
                    } else {
                        current = sdscatlen(current,p,1);
                    }
                } else {
                    switch(*p) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                    case '\0':
                        done=1;
                        break;
                    case '"':
                        inq=1;
                        break;
                    case '\'':
                        insq=1;
                        break;
                    default:
                        current = sdscatlen(current,p,1);
                        break;
                    }
                }
                if (*p) p++;
            }
            /* add the token to the vector */
            vector = (char**) realloc(vector,((*argc)+1)*sizeof(char*));
            vector[*argc] = current;
            (*argc)++;
            current = NULL;
        } else {
            /* Even on empty input string return something not NULL. */
            if (vector == NULL) vector = (char**) malloc(sizeof(void*));
            return vector;
        }
    }

err:
    while((*argc)--)
        sdsfree(vector[*argc]);
    free(vector);
    if (current) sdsfree(current);
    *argc = 0;
    return NULL;
}

/* Modify the string substituting all the occurrences of the set of
 * characters specified in the 'from' string to the corresponding character
 * in the 'to' array.
 *
 * For instance: sdsmapchars(mystring, "ho", "01", 2)
 * will have the effect of turning the string "hello" into "0ell1".
 *
 * The function returns the sds string pointer, that is always the same
 * as the input pointer since no resize is needed. */
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
    size_t j, i, l = sdslen(s);

    for (j = 0; j < l; j++) {
        for (i = 0; i < setlen; i++) {
            if (s[j] == from[i]) {
                s[j] = to[i];
                break;
            }
        }
    }
    return s;
}

/* Join an array of C strings using the specified separator (also a C string).
 * Returns the result as an sds string. */
sds sdsjoin(char **argv, int argc, char *sep) {
    sds join = sdsempty();
    int j;

    for (j = 0; j < argc; j++) {
        join = sdscat(join, argv[j]);
        if (j != argc-1) join = sdscat(join,sep);
    }
    return join;
}

/* Like sdsjoin, but joins an array of SDS strings. */
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
    sds join = sdsempty();
    int j;

    for (j = 0; j < argc; j++) {
        join = sdscatsds(join, argv[j]);
        if (j != argc-1) join = sdscatlen(join,sep,seplen);
    }
    return join;
}

/* Wrappers to the allocators used by SDS. Note that SDS will actually
 * just use the macros defined into sdsalloc.h in order to avoid to pay
 * the overhead of function calls. Here we define these wrappers only for
 * the programs SDS is linked to, if they want to touch the SDS internals
 * even if they use a different allocator. */
void *sdmalloc(size_t size) { return malloc(size); }
void *sdrealloc(void *ptr, size_t size) { return realloc(ptr,size); }
void sdfree(void *ptr) { free(ptr); }
/**************************************************************************
 *
 * Copyright 2013-2014 RAD Game Tools and Valve Software
 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/



typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];

#ifdef __cplusplus
extern "C" {
#endif

/* ------------------- zlib-style API's */

mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
{
    mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
    size_t block_len = buf_len % 5552;
    if (!ptr)
        return MZ_ADLER32_INIT;
    while (buf_len)
    {
        for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
        {
            s1 += ptr[0], s2 += s1;
            s1 += ptr[1], s2 += s1;
            s1 += ptr[2], s2 += s1;
            s1 += ptr[3], s2 += s1;
            s1 += ptr[4], s2 += s1;
            s1 += ptr[5], s2 += s1;
            s1 += ptr[6], s2 += s1;
            s1 += ptr[7], s2 += s1;
        }
        for (; i < block_len; ++i)
            s1 += *ptr++, s2 += s1;
        s1 %= 65521U, s2 %= 65521U;
        buf_len -= block_len;
        block_len = 5552;
    }
    return (s2 << 16) + s1;
}

/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */
#if 0
    mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
    {
        static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
                                               0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
        mz_uint32 crcu32 = (mz_uint32)crc;
        if (!ptr)
            return MZ_CRC32_INIT;
        crcu32 = ~crcu32;
        while (buf_len--)
        {
            mz_uint8 b = *ptr++;
            crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
            crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
        }
        return ~crcu32;
    }
#else
/* Faster, but larger CPU cache footprint.
 */
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
{
    static const mz_uint32 s_crc_table[256] =
        {
          0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
          0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
          0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
          0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
          0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
          0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
          0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
          0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
          0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
          0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
          0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
          0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
          0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
          0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
          0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
          0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
          0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
          0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
          0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
          0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
          0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
          0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
          0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
          0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
          0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
          0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
          0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
          0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
          0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
          0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
          0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
          0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
          0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
          0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
          0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
          0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
          0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
        };

    mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
    const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;

    while (buf_len >= 4)
    {
        crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
        crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
        crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
        crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
        pByte_buf += 4;
        buf_len -= 4;
    }

    while (buf_len)
    {
        crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
        ++pByte_buf;
        --buf_len;
    }

    return ~crc32;
}
#endif

void mz_free(void *p)
{
    MZ_FREE(p);
}

void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
{
    (void)opaque, (void)items, (void)size;
    return MZ_MALLOC(items * size);
}
void miniz_def_free_func(void *opaque, void *address)
{
    (void)opaque, (void)address;
    MZ_FREE(address);
}
void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
{
    (void)opaque, (void)address, (void)items, (void)size;
    return MZ_REALLOC(address, items * size);
}

const char *mz_version(void)
{
    return MZ_VERSION;
}

#ifndef MINIZ_NO_ZLIB_APIS

int mz_deflateInit(mz_streamp pStream, int level)
{
    return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
}

int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
{
    tdefl_compressor *pComp;
    mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);

    if (!pStream)
        return MZ_STREAM_ERROR;
    if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
        return MZ_PARAM_ERROR;

    pStream->data_type = 0;
    pStream->adler = MZ_ADLER32_INIT;
    pStream->msg = NULL;
    pStream->reserved = 0;
    pStream->total_in = 0;
    pStream->total_out = 0;
    if (!pStream->zalloc)
        pStream->zalloc = miniz_def_alloc_func;
    if (!pStream->zfree)
        pStream->zfree = miniz_def_free_func;

    pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
    if (!pComp)
        return MZ_MEM_ERROR;

    pStream->state = (struct mz_internal_state *)pComp;

    if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
    {
        mz_deflateEnd(pStream);
        return MZ_PARAM_ERROR;
    }

    return MZ_OK;
}

int mz_deflateReset(mz_streamp pStream)
{
    if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
        return MZ_STREAM_ERROR;
    pStream->total_in = pStream->total_out = 0;
    tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
    return MZ_OK;
}

int mz_deflate(mz_streamp pStream, int flush)
{
    size_t in_bytes, out_bytes;
    mz_ulong orig_total_in, orig_total_out;
    int mz_status = MZ_OK;

    if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
        return MZ_STREAM_ERROR;
    if (!pStream->avail_out)
        return MZ_BUF_ERROR;

    if (flush == MZ_PARTIAL_FLUSH)
        flush = MZ_SYNC_FLUSH;

    if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
        return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;

    orig_total_in = pStream->total_in;
    orig_total_out = pStream->total_out;
    for (;;)
    {
        tdefl_status defl_status;
        in_bytes = pStream->avail_in;
        out_bytes = pStream->avail_out;

        defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
        pStream->next_in += (mz_uint)in_bytes;
        pStream->avail_in -= (mz_uint)in_bytes;
        pStream->total_in += (mz_uint)in_bytes;
        pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);

        pStream->next_out += (mz_uint)out_bytes;
        pStream->avail_out -= (mz_uint)out_bytes;
        pStream->total_out += (mz_uint)out_bytes;

        if (defl_status < 0)
        {
            mz_status = MZ_STREAM_ERROR;
            break;
        }
        else if (defl_status == TDEFL_STATUS_DONE)
        {
            mz_status = MZ_STREAM_END;
            break;
        }
        else if (!pStream->avail_out)
            break;
        else if ((!pStream->avail_in) && (flush != MZ_FINISH))
        {
            if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
                break;
            return MZ_BUF_ERROR; /* Can't make forward progress without some input.
 */
        }
    }
    return mz_status;
}

int mz_deflateEnd(mz_streamp pStream)
{
    if (!pStream)
        return MZ_STREAM_ERROR;
    if (pStream->state)
    {
        pStream->zfree(pStream->opaque, pStream->state);
        pStream->state = NULL;
    }
    return MZ_OK;
}

mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
{
    (void)pStream;
    /* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */
    return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
}

int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
{
    int status;
    mz_stream stream;
    memset(&stream, 0, sizeof(stream));

    /* In case mz_ulong is 64-bits (argh I hate longs). */
    if ((source_len | *pDest_len) > 0xFFFFFFFFU)
        return MZ_PARAM_ERROR;

    stream.next_in = pSource;
    stream.avail_in = (mz_uint32)source_len;
    stream.next_out = pDest;
    stream.avail_out = (mz_uint32)*pDest_len;

    status = mz_deflateInit(&stream, level);
    if (status != MZ_OK)
        return status;

    status = mz_deflate(&stream, MZ_FINISH);
    if (status != MZ_STREAM_END)
    {
        mz_deflateEnd(&stream);
        return (status == MZ_OK) ? MZ_BUF_ERROR : status;
    }

    *pDest_len = stream.total_out;
    return mz_deflateEnd(&stream);
}

int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
{
    return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
}

mz_ulong mz_compressBound(mz_ulong source_len)
{
    return mz_deflateBound(NULL, source_len);
}

typedef struct
{
    tinfl_decompressor m_decomp;
    mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
    int m_window_bits;
    mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
    tinfl_status m_last_status;
} inflate_state;

int mz_inflateInit2(mz_streamp pStream, int window_bits)
{
    inflate_state *pDecomp;
    if (!pStream)
        return MZ_STREAM_ERROR;
    if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
        return MZ_PARAM_ERROR;

    pStream->data_type = 0;
    pStream->adler = 0;
    pStream->msg = NULL;
    pStream->total_in = 0;
    pStream->total_out = 0;
    pStream->reserved = 0;
    if (!pStream->zalloc)
        pStream->zalloc = miniz_def_alloc_func;
    if (!pStream->zfree)
        pStream->zfree = miniz_def_free_func;

    pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
    if (!pDecomp)
        return MZ_MEM_ERROR;

    pStream->state = (struct mz_internal_state *)pDecomp;

    tinfl_init(&pDecomp->m_decomp);
    pDecomp->m_dict_ofs = 0;
    pDecomp->m_dict_avail = 0;
    pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
    pDecomp->m_first_call = 1;
    pDecomp->m_has_flushed = 0;
    pDecomp->m_window_bits = window_bits;

    return MZ_OK;
}

int mz_inflateInit(mz_streamp pStream)
{
    return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
}

int mz_inflate(mz_streamp pStream, int flush)
{
    inflate_state *pState;
    mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
    size_t in_bytes, out_bytes, orig_avail_in;
    tinfl_status status;

    if ((!pStream) || (!pStream->state))
        return MZ_STREAM_ERROR;
    if (flush == MZ_PARTIAL_FLUSH)
        flush = MZ_SYNC_FLUSH;
    if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
        return MZ_STREAM_ERROR;

    pState = (inflate_state *)pStream->state;
    if (pState->m_window_bits > 0)
        decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
    orig_avail_in = pStream->avail_in;

    first_call = pState->m_first_call;
    pState->m_first_call = 0;
    if (pState->m_last_status < 0)
        return MZ_DATA_ERROR;

    if (pState->m_has_flushed && (flush != MZ_FINISH))
        return MZ_STREAM_ERROR;
    pState->m_has_flushed |= (flush == MZ_FINISH);

    if ((flush == MZ_FINISH) && (first_call))
    {
        /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
        decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
        in_bytes = pStream->avail_in;
        out_bytes = pStream->avail_out;
        status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
        pState->m_last_status = status;
        pStream->next_in += (mz_uint)in_bytes;
        pStream->avail_in -= (mz_uint)in_bytes;
        pStream->total_in += (mz_uint)in_bytes;
        pStream->adler = tinfl_get_adler32(&pState->m_decomp);
        pStream->next_out += (mz_uint)out_bytes;
        pStream->avail_out -= (mz_uint)out_bytes;
        pStream->total_out += (mz_uint)out_bytes;

        if (status < 0)
            return MZ_DATA_ERROR;
        else if (status != TINFL_STATUS_DONE)
        {
            pState->m_last_status = TINFL_STATUS_FAILED;
            return MZ_BUF_ERROR;
        }
        return MZ_STREAM_END;
    }
    /* flush != MZ_FINISH then we must assume there's more input. */
    if (flush != MZ_FINISH)
        decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;

    if (pState->m_dict_avail)
    {
        n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
        memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
        pStream->next_out += n;
        pStream->avail_out -= n;
        pStream->total_out += n;
        pState->m_dict_avail -= n;
        pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
        return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
    }

    for (;;)
    {
        in_bytes = pStream->avail_in;
        out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;

        status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
        pState->m_last_status = status;

        pStream->next_in += (mz_uint)in_bytes;
        pStream->avail_in -= (mz_uint)in_bytes;
        pStream->total_in += (mz_uint)in_bytes;
        pStream->adler = tinfl_get_adler32(&pState->m_decomp);

        pState->m_dict_avail = (mz_uint)out_bytes;

        n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
        memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
        pStream->next_out += n;
        pStream->avail_out -= n;
        pStream->total_out += n;
        pState->m_dict_avail -= n;
        pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);

        if (status < 0)
            return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
        else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
            return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
        else if (flush == MZ_FINISH)
        {
            /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
            if (status == TINFL_STATUS_DONE)
                return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
            /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
            else if (!pStream->avail_out)
                return MZ_BUF_ERROR;
        }
        else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
            break;
    }

    return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
}

int mz_inflateEnd(mz_streamp pStream)
{
    if (!pStream)
        return MZ_STREAM_ERROR;
    if (pStream->state)
    {
        pStream->zfree(pStream->opaque, pStream->state);
        pStream->state = NULL;
    }
    return MZ_OK;
}

int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
{
    mz_stream stream;
    int status;
    memset(&stream, 0, sizeof(stream));

    /* In case mz_ulong is 64-bits (argh I hate longs). */
    if ((source_len | *pDest_len) > 0xFFFFFFFFU)
        return MZ_PARAM_ERROR;

    stream.next_in = pSource;
    stream.avail_in = (mz_uint32)source_len;
    stream.next_out = pDest;
    stream.avail_out = (mz_uint32)*pDest_len;

    status = mz_inflateInit(&stream);
    if (status != MZ_OK)
        return status;

    status = mz_inflate(&stream, MZ_FINISH);
    if (status != MZ_STREAM_END)
    {
        mz_inflateEnd(&stream);
        return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
    }
    *pDest_len = stream.total_out;

    return mz_inflateEnd(&stream);
}

const char *mz_error(int err)
{
    static struct
    {
        int m_err;
        const char *m_pDesc;
    } s_error_descs[] =
        {
          { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
        };
    mz_uint i;
    for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
        if (s_error_descs[i].m_err == err)
            return s_error_descs[i].m_pDesc;
    return NULL;
}

#endif /*MINIZ_NO_ZLIB_APIS */

#ifdef __cplusplus
}
#endif

/*
  This is free and unencumbered software released into the public domain.

  Anyone is free to copy, modify, publish, use, compile, sell, or
  distribute this software, either in source code form or as a compiled
  binary, for any purpose, commercial or non-commercial, and by any
  means.

  In jurisdictions that recognize copyright laws, the author or authors
  of this software dedicate any and all copyright interest in the
  software to the public domain. We make this dedication for the benefit
  of the public at large and to the detriment of our heirs and
  successors. We intend this dedication to be an overt act of
  relinquishment in perpetuity of all present and future rights to this
  software under copyright law.

  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 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.

  For more information, please refer to <http://unlicense.org/>
*/
/**************************************************************************
 *
 * Copyright 2013-2014 RAD Game Tools and Valve Software
 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/




#ifdef __cplusplus
extern "C" {
#endif

/* ------------------- Low-level Compression (independent from all decompression API's) */

/* Purposely making these tables static for faster init and thread safety. */
static const mz_uint16 s_tdefl_len_sym[256] =
    {
      257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
      273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
      277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
      279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
      281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
      282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
      283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
      284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285
    };

static const mz_uint8 s_tdefl_len_extra[256] =
    {
      0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
      4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
      5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
      5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
    };

static const mz_uint8 s_tdefl_small_dist_sym[512] =
    {
      0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
      11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
      13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
      14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
      14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
      15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
      17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
      17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
      17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17
    };

static const mz_uint8 s_tdefl_small_dist_extra[512] =
    {
      0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
      5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
      6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
      6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7
    };

static const mz_uint8 s_tdefl_large_dist_sym[128] =
    {
      0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
      26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
      28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
    };

static const mz_uint8 s_tdefl_large_dist_extra[128] =
    {
      0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
      12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
      13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13
    };

/* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */
typedef struct
{
    mz_uint16 m_key, m_sym_index;
} tdefl_sym_freq;
static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1)
{
    mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
    tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
    MZ_CLEAR_OBJ(hist);
    for (i = 0; i < num_syms; i++)
    {
        mz_uint freq = pSyms0[i].m_key;
        hist[freq & 0xFF]++;
        hist[256 + ((freq >> 8) & 0xFF)]++;
    }
    while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
        total_passes--;
    for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
    {
        const mz_uint32 *pHist = &hist[pass << 8];
        mz_uint offsets[256], cur_ofs = 0;
        for (i = 0; i < 256; i++)
        {
            offsets[i] = cur_ofs;
            cur_ofs += pHist[i];
        }
        for (i = 0; i < num_syms; i++)
            pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
        {
            tdefl_sym_freq *t = pCur_syms;
            pCur_syms = pNew_syms;
            pNew_syms = t;
        }
    }
    return pCur_syms;
}

/* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */
static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
{
    int root, leaf, next, avbl, used, dpth;
    if (n == 0)
        return;
    else if (n == 1)
    {
        A[0].m_key = 1;
        return;
    }
    A[0].m_key += A[1].m_key;
    root = 0;
    leaf = 2;
    for (next = 1; next < n - 1; next++)
    {
        if (leaf >= n || A[root].m_key < A[leaf].m_key)
        {
            A[next].m_key = A[root].m_key;
            A[root++].m_key = (mz_uint16)next;
        }
        else
            A[next].m_key = A[leaf++].m_key;
        if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key))
        {
            A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
            A[root++].m_key = (mz_uint16)next;
        }
        else
            A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
    }
    A[n - 2].m_key = 0;
    for (next = n - 3; next >= 0; next--)
        A[next].m_key = A[A[next].m_key].m_key + 1;
    avbl = 1;
    used = dpth = 0;
    root = n - 2;
    next = n - 1;
    while (avbl > 0)
    {
        while (root >= 0 && (int)A[root].m_key == dpth)
        {
            used++;
            root--;
        }
        while (avbl > used)
        {
            A[next--].m_key = (mz_uint16)(dpth);
            avbl--;
        }
        avbl = 2 * used;
        dpth++;
        used = 0;
    }
}

/* Limits canonical Huffman code table's max code size. */
enum
{
    TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32
};
static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
{
    int i;
    mz_uint32 total = 0;
    if (code_list_len <= 1)
        return;
    for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
        pNum_codes[max_code_size] += pNum_codes[i];
    for (i = max_code_size; i > 0; i--)
        total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
    while (total != (1UL << max_code_size))
    {
        pNum_codes[max_code_size]--;
        for (i = max_code_size - 1; i > 0; i--)
            if (pNum_codes[i])
            {
                pNum_codes[i]--;
                pNum_codes[i + 1] += 2;
                break;
            }
        total--;
    }
}

static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
{
    int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
    mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
    MZ_CLEAR_OBJ(num_codes);
    if (static_table)
    {
        for (i = 0; i < table_len; i++)
            num_codes[d->m_huff_code_sizes[table_num][i]]++;
    }
    else
    {
        tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
        int num_used_syms = 0;
        const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
        for (i = 0; i < table_len; i++)
            if (pSym_count[i])
            {
                syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
                syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
            }

        pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
        tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);

        for (i = 0; i < num_used_syms; i++)
            num_codes[pSyms[i].m_key]++;

        tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);

        MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
        MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
        for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
            for (l = num_codes[i]; l > 0; l--)
                d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
    }

    next_code[1] = 0;
    for (j = 0, i = 2; i <= code_size_limit; i++)
        next_code[i] = j = ((j + num_codes[i - 1]) << 1);

    for (i = 0; i < table_len; i++)
    {
        mz_uint rev_code = 0, code, code_size;
        if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
            continue;
        code = next_code[code_size]++;
        for (l = code_size; l > 0; l--, code >>= 1)
            rev_code = (rev_code << 1) | (code & 1);
        d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
    }
}

#define TDEFL_PUT_BITS(b, l)                                       \
    do                                                             \
    {                                                              \
        mz_uint bits = b;                                          \
        mz_uint len = l;                                           \
        MZ_ASSERT(bits <= ((1U << len) - 1U));                     \
        d->m_bit_buffer |= (bits << d->m_bits_in);                 \
        d->m_bits_in += len;                                       \
        while (d->m_bits_in >= 8)                                  \
        {                                                          \
            if (d->m_pOutput_buf < d->m_pOutput_buf_end)           \
                *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
            d->m_bit_buffer >>= 8;                                 \
            d->m_bits_in -= 8;                                     \
        }                                                          \
    }                                                              \
    MZ_MACRO_END

#define TDEFL_RLE_PREV_CODE_SIZE()                                                                                       \
    {                                                                                                                    \
        if (rle_repeat_count)                                                                                            \
        {                                                                                                                \
            if (rle_repeat_count < 3)                                                                                    \
            {                                                                                                            \
                d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
                while (rle_repeat_count--)                                                                               \
                    packed_code_sizes[num_packed_code_sizes++] = prev_code_size;                                         \
            }                                                                                                            \
            else                                                                                                         \
            {                                                                                                            \
                d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1);                                        \
                packed_code_sizes[num_packed_code_sizes++] = 16;                                                         \
                packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3);                           \
            }                                                                                                            \
            rle_repeat_count = 0;                                                                                        \
        }                                                                                                                \
    }

#define TDEFL_RLE_ZERO_CODE_SIZE()                                                         \
    {                                                                                      \
        if (rle_z_count)                                                                   \
        {                                                                                  \
            if (rle_z_count < 3)                                                           \
            {                                                                              \
                d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count);  \
                while (rle_z_count--)                                                      \
                    packed_code_sizes[num_packed_code_sizes++] = 0;                        \
            }                                                                              \
            else if (rle_z_count <= 10)                                                    \
            {                                                                              \
                d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1);          \
                packed_code_sizes[num_packed_code_sizes++] = 17;                           \
                packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3);  \
            }                                                                              \
            else                                                                           \
            {                                                                              \
                d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1);          \
                packed_code_sizes[num_packed_code_sizes++] = 18;                           \
                packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
            }                                                                              \
            rle_z_count = 0;                                                               \
        }                                                                                  \
    }

static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };

static void tdefl_start_dynamic_block(tdefl_compressor *d)
{
    int num_lit_codes, num_dist_codes, num_bit_lengths;
    mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
    mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;

    d->m_huff_count[0][256] = 1;

    tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
    tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);

    for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
        if (d->m_huff_code_sizes[0][num_lit_codes - 1])
            break;
    for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
        if (d->m_huff_code_sizes[1][num_dist_codes - 1])
            break;

    memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
    memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
    total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
    num_packed_code_sizes = 0;
    rle_z_count = 0;
    rle_repeat_count = 0;

    memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
    for (i = 0; i < total_code_sizes_to_pack; i++)
    {
        mz_uint8 code_size = code_sizes_to_pack[i];
        if (!code_size)
        {
            TDEFL_RLE_PREV_CODE_SIZE();
            if (++rle_z_count == 138)
            {
                TDEFL_RLE_ZERO_CODE_SIZE();
            }
        }
        else
        {
            TDEFL_RLE_ZERO_CODE_SIZE();
            if (code_size != prev_code_size)
            {
                TDEFL_RLE_PREV_CODE_SIZE();
                d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1);
                packed_code_sizes[num_packed_code_sizes++] = code_size;
            }
            else if (++rle_repeat_count == 6)
            {
                TDEFL_RLE_PREV_CODE_SIZE();
            }
        }
        prev_code_size = code_size;
    }
    if (rle_repeat_count)
    {
        TDEFL_RLE_PREV_CODE_SIZE();
    }
    else
    {
        TDEFL_RLE_ZERO_CODE_SIZE();
    }

    tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);

    TDEFL_PUT_BITS(2, 2);

    TDEFL_PUT_BITS(num_lit_codes - 257, 5);
    TDEFL_PUT_BITS(num_dist_codes - 1, 5);

    for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
        if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
            break;
    num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
    TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
    for (i = 0; (int)i < num_bit_lengths; i++)
        TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);

    for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;)
    {
        mz_uint code = packed_code_sizes[packed_code_sizes_index++];
        MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
        TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
        if (code >= 16)
            TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
    }
}

static void tdefl_start_static_block(tdefl_compressor *d)
{
    mz_uint i;
    mz_uint8 *p = &d->m_huff_code_sizes[0][0];

    for (i = 0; i <= 143; ++i)
        *p++ = 8;
    for (; i <= 255; ++i)
        *p++ = 9;
    for (; i <= 279; ++i)
        *p++ = 7;
    for (; i <= 287; ++i)
        *p++ = 8;

    memset(d->m_huff_code_sizes[1], 5, 32);

    tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
    tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);

    TDEFL_PUT_BITS(1, 2);
}

static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };

#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
{
    mz_uint flags;
    mz_uint8 *pLZ_codes;
    mz_uint8 *pOutput_buf = d->m_pOutput_buf;
    mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
    mz_uint64 bit_buffer = d->m_bit_buffer;
    mz_uint bits_in = d->m_bits_in;

#define TDEFL_PUT_BITS_FAST(b, l)                    \
    {                                                \
        bit_buffer |= (((mz_uint64)(b)) << bits_in); \
        bits_in += (l);                              \
    }

    flags = 1;
    for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
    {
        if (flags == 1)
            flags = *pLZ_codes++ | 0x100;

        if (flags & 1)
        {
            mz_uint s0, s1, n0, n1, sym, num_extra_bits;
            mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1);
            pLZ_codes += 3;

            MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
            TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
            TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);

            /* This sequence coaxes MSVC into using cmov's vs. jmp's. */
            s0 = s_tdefl_small_dist_sym[match_dist & 511];
            n0 = s_tdefl_small_dist_extra[match_dist & 511];
            s1 = s_tdefl_large_dist_sym[match_dist >> 8];
            n1 = s_tdefl_large_dist_extra[match_dist >> 8];
            sym = (match_dist < 512) ? s0 : s1;
            num_extra_bits = (match_dist < 512) ? n0 : n1;

            MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
            TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
            TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
        }
        else
        {
            mz_uint lit = *pLZ_codes++;
            MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
            TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);

            if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
            {
                flags >>= 1;
                lit = *pLZ_codes++;
                MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
                TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);

                if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
                {
                    flags >>= 1;
                    lit = *pLZ_codes++;
                    MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
                    TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
                }
            }
        }

        if (pOutput_buf >= d->m_pOutput_buf_end)
            return MZ_FALSE;

        *(mz_uint64 *)pOutput_buf = bit_buffer;
        pOutput_buf += (bits_in >> 3);
        bit_buffer >>= (bits_in & ~7);
        bits_in &= 7;
    }

#undef TDEFL_PUT_BITS_FAST

    d->m_pOutput_buf = pOutput_buf;
    d->m_bits_in = 0;
    d->m_bit_buffer = 0;

    while (bits_in)
    {
        mz_uint32 n = MZ_MIN(bits_in, 16);
        TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
        bit_buffer >>= n;
        bits_in -= n;
    }

    TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);

    return (d->m_pOutput_buf < d->m_pOutput_buf_end);
}
#else
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
{
    mz_uint flags;
    mz_uint8 *pLZ_codes;

    flags = 1;
    for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
    {
        if (flags == 1)
            flags = *pLZ_codes++ | 0x100;
        if (flags & 1)
        {
            mz_uint sym, num_extra_bits;
            mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
            pLZ_codes += 3;

            MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
            TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
            TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);

            if (match_dist < 512)
            {
                sym = s_tdefl_small_dist_sym[match_dist];
                num_extra_bits = s_tdefl_small_dist_extra[match_dist];
            }
            else
            {
                sym = s_tdefl_large_dist_sym[match_dist >> 8];
                num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
            }
            MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
            TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
            TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
        }
        else
        {
            mz_uint lit = *pLZ_codes++;
            MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
            TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
        }
    }

    TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);

    return (d->m_pOutput_buf < d->m_pOutput_buf_end);
}
#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */

static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
{
    if (static_block)
        tdefl_start_static_block(d);
    else
        tdefl_start_dynamic_block(d);
    return tdefl_compress_lz_codes(d);
}

static int tdefl_flush_block(tdefl_compressor *d, int flush)
{
    mz_uint saved_bit_buf, saved_bits_in;
    mz_uint8 *pSaved_output_buf;
    mz_bool comp_block_succeeded = MZ_FALSE;
    int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
    mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;

    d->m_pOutput_buf = pOutput_buf_start;
    d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;

    MZ_ASSERT(!d->m_output_flush_remaining);
    d->m_output_flush_ofs = 0;
    d->m_output_flush_remaining = 0;

    *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
    d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);

    if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
    {
        TDEFL_PUT_BITS(0x78, 8);
        TDEFL_PUT_BITS(0x01, 8);
    }

    TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);

    pSaved_output_buf = d->m_pOutput_buf;
    saved_bit_buf = d->m_bit_buffer;
    saved_bits_in = d->m_bits_in;

    if (!use_raw_block)
        comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));

    /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */
    if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
        ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size))
    {
        mz_uint i;
        d->m_pOutput_buf = pSaved_output_buf;
        d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
        TDEFL_PUT_BITS(0, 2);
        if (d->m_bits_in)
        {
            TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
        }
        for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
        {
            TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
        }
        for (i = 0; i < d->m_total_lz_bytes; ++i)
        {
            TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
        }
    }
    /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */
    else if (!comp_block_succeeded)
    {
        d->m_pOutput_buf = pSaved_output_buf;
        d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
        tdefl_compress_block(d, MZ_TRUE);
    }

    if (flush)
    {
        if (flush == TDEFL_FINISH)
        {
            if (d->m_bits_in)
            {
                TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
            }
            if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER)
            {
                mz_uint i, a = d->m_adler32;
                for (i = 0; i < 4; i++)
                {
                    TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
                    a <<= 8;
                }
            }
        }
        else
        {
            mz_uint i, z = 0;
            TDEFL_PUT_BITS(0, 3);
            if (d->m_bits_in)
            {
                TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
            }
            for (i = 2; i; --i, z ^= 0xFFFF)
            {
                TDEFL_PUT_BITS(z & 0xFFFF, 16);
            }
        }
    }

    MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);

    memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
    memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);

    d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
    d->m_pLZ_flags = d->m_lz_code_buf;
    d->m_num_flags_left = 8;
    d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
    d->m_total_lz_bytes = 0;
    d->m_block_index++;

    if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
    {
        if (d->m_pPut_buf_func)
        {
            *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
            if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
                return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
        }
        else if (pOutput_buf_start == d->m_output_buf)
        {
            int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
            memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
            d->m_out_buf_ofs += bytes_to_copy;
            if ((n -= bytes_to_copy) != 0)
            {
                d->m_output_flush_ofs = bytes_to_copy;
                d->m_output_flush_remaining = n;
            }
        }
        else
        {
            d->m_out_buf_ofs += n;
        }
    }

    return d->m_output_flush_remaining;
}

#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
static inline mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p)
{
	mz_uint16 ret;
	memcpy(&ret, p, sizeof(mz_uint16));
	return ret;
}
static inline mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p)
{
	mz_uint16 ret;
	memcpy(&ret, p, sizeof(mz_uint16));
	return ret;
}
#else
#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
#endif
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
{
    mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
    mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
    const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
    mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD2(s);
    MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
    if (max_match_len <= match_len)
        return;
    for (;;)
    {
        for (;;)
        {
            if (--num_probes_left == 0)
                return;
#define TDEFL_PROBE                                                                             \
    next_probe_pos = d->m_next[probe_pos];                                                      \
    if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
        return;                                                                                 \
    probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK;                                       \
    if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01)                \
        break;
            TDEFL_PROBE;
            TDEFL_PROBE;
            TDEFL_PROBE;
        }
        if (!dist)
            break;
        q = (const mz_uint16 *)(d->m_dict + probe_pos);
        if (TDEFL_READ_UNALIGNED_WORD2(q) != s01)
            continue;
        p = s;
        probe_len = 32;
        do
        {
        } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
                 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
        if (!probe_len)
        {
            *pMatch_dist = dist;
            *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN);
            break;
        }
        else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len)
        {
            *pMatch_dist = dist;
            if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len)
                break;
            c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
        }
    }
}
#else
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
{
    mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
    mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
    const mz_uint8 *s = d->m_dict + pos, *p, *q;
    mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
    MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
    if (max_match_len <= match_len)
        return;
    for (;;)
    {
        for (;;)
        {
            if (--num_probes_left == 0)
                return;
#define TDEFL_PROBE                                                                               \
    next_probe_pos = d->m_next[probe_pos];                                                        \
    if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist))   \
        return;                                                                                   \
    probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK;                                         \
    if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \
        break;
            TDEFL_PROBE;
            TDEFL_PROBE;
            TDEFL_PROBE;
        }
        if (!dist)
            break;
        p = s;
        q = d->m_dict + probe_pos;
        for (probe_len = 0; probe_len < max_match_len; probe_len++)
            if (*p++ != *q++)
                break;
        if (probe_len > match_len)
        {
            *pMatch_dist = dist;
            if ((*pMatch_len = match_len = probe_len) == max_match_len)
                return;
            c0 = d->m_dict[pos + match_len];
            c1 = d->m_dict[pos + match_len - 1];
        }
    }
}
#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */

#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
static mz_bool tdefl_compress_fast(tdefl_compressor *d)
{
    /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */
    mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
    mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
    mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;

    while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
    {
        const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
        mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
        mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
        d->m_src_buf_left -= num_bytes_to_process;
        lookahead_size += num_bytes_to_process;

        while (num_bytes_to_process)
        {
            mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
            memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
            if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
                memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
            d->m_pSrc += n;
            dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
            num_bytes_to_process -= n;
        }

        dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
        if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
            break;

        while (lookahead_size >= 4)
        {
            mz_uint cur_match_dist, cur_match_len = 1;
            mz_uint8 *pCur_dict = d->m_dict + cur_pos;
            mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
            mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
            mz_uint probe_pos = d->m_hash[hash];
            d->m_hash[hash] = (mz_uint16)lookahead_pos;

            if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
            {
                const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
                const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
                mz_uint32 probe_len = 32;
                do
                {
                } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
                         (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
                cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
                if (!probe_len)
                    cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;

                if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)))
                {
                    cur_match_len = 1;
                    *pLZ_code_buf++ = (mz_uint8)first_trigram;
                    *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
                    d->m_huff_count[0][(mz_uint8)first_trigram]++;
                }
                else
                {
                    mz_uint32 s0, s1;
                    cur_match_len = MZ_MIN(cur_match_len, lookahead_size);

                    MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));

                    cur_match_dist--;

                    pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
                    *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
                    pLZ_code_buf += 3;
                    *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);

                    s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
                    s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
                    d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;

                    d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
                }
            }
            else
            {
                *pLZ_code_buf++ = (mz_uint8)first_trigram;
                *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
                d->m_huff_count[0][(mz_uint8)first_trigram]++;
            }

            if (--num_flags_left == 0)
            {
                num_flags_left = 8;
                pLZ_flags = pLZ_code_buf++;
            }

            total_lz_bytes += cur_match_len;
            lookahead_pos += cur_match_len;
            dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE);
            cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
            MZ_ASSERT(lookahead_size >= cur_match_len);
            lookahead_size -= cur_match_len;

            if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
            {
                int n;
                d->m_lookahead_pos = lookahead_pos;
                d->m_lookahead_size = lookahead_size;
                d->m_dict_size = dict_size;
                d->m_total_lz_bytes = total_lz_bytes;
                d->m_pLZ_code_buf = pLZ_code_buf;
                d->m_pLZ_flags = pLZ_flags;
                d->m_num_flags_left = num_flags_left;
                if ((n = tdefl_flush_block(d, 0)) != 0)
                    return (n < 0) ? MZ_FALSE : MZ_TRUE;
                total_lz_bytes = d->m_total_lz_bytes;
                pLZ_code_buf = d->m_pLZ_code_buf;
                pLZ_flags = d->m_pLZ_flags;
                num_flags_left = d->m_num_flags_left;
            }
        }

        while (lookahead_size)
        {
            mz_uint8 lit = d->m_dict[cur_pos];

            total_lz_bytes++;
            *pLZ_code_buf++ = lit;
            *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
            if (--num_flags_left == 0)
            {
                num_flags_left = 8;
                pLZ_flags = pLZ_code_buf++;
            }

            d->m_huff_count[0][lit]++;

            lookahead_pos++;
            dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE);
            cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
            lookahead_size--;

            if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
            {
                int n;
                d->m_lookahead_pos = lookahead_pos;
                d->m_lookahead_size = lookahead_size;
                d->m_dict_size = dict_size;
                d->m_total_lz_bytes = total_lz_bytes;
                d->m_pLZ_code_buf = pLZ_code_buf;
                d->m_pLZ_flags = pLZ_flags;
                d->m_num_flags_left = num_flags_left;
                if ((n = tdefl_flush_block(d, 0)) != 0)
                    return (n < 0) ? MZ_FALSE : MZ_TRUE;
                total_lz_bytes = d->m_total_lz_bytes;
                pLZ_code_buf = d->m_pLZ_code_buf;
                pLZ_flags = d->m_pLZ_flags;
                num_flags_left = d->m_num_flags_left;
            }
        }
    }

    d->m_lookahead_pos = lookahead_pos;
    d->m_lookahead_size = lookahead_size;
    d->m_dict_size = dict_size;
    d->m_total_lz_bytes = total_lz_bytes;
    d->m_pLZ_code_buf = pLZ_code_buf;
    d->m_pLZ_flags = pLZ_flags;
    d->m_num_flags_left = num_flags_left;
    return MZ_TRUE;
}
#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */

static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
{
    d->m_total_lz_bytes++;
    *d->m_pLZ_code_buf++ = lit;
    *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
    if (--d->m_num_flags_left == 0)
    {
        d->m_num_flags_left = 8;
        d->m_pLZ_flags = d->m_pLZ_code_buf++;
    }
    d->m_huff_count[0][lit]++;
}

static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
{
    mz_uint32 s0, s1;

    MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));

    d->m_total_lz_bytes += match_len;

    d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);

    match_dist -= 1;
    d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
    d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
    d->m_pLZ_code_buf += 3;

    *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
    if (--d->m_num_flags_left == 0)
    {
        d->m_num_flags_left = 8;
        d->m_pLZ_flags = d->m_pLZ_code_buf++;
    }

    s0 = s_tdefl_small_dist_sym[match_dist & 511];
    s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
    d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;

    if (match_len >= TDEFL_MIN_MATCH_LEN)
        d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
}

static mz_bool tdefl_compress_normal(tdefl_compressor *d)
{
    const mz_uint8 *pSrc = d->m_pSrc;
    size_t src_buf_left = d->m_src_buf_left;
    tdefl_flush flush = d->m_flush;

    while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
    {
        mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
        /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */
        if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
        {
            mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
            mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
            mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
            const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
            src_buf_left -= num_bytes_to_process;
            d->m_lookahead_size += num_bytes_to_process;
            while (pSrc != pSrc_end)
            {
                mz_uint8 c = *pSrc++;
                d->m_dict[dst_pos] = c;
                if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
                    d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
                hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
                d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
                d->m_hash[hash] = (mz_uint16)(ins_pos);
                dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
                ins_pos++;
            }
        }
        else
        {
            while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
            {
                mz_uint8 c = *pSrc++;
                mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
                src_buf_left--;
                d->m_dict[dst_pos] = c;
                if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
                    d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
                if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
                {
                    mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
                    mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
                    d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
                    d->m_hash[hash] = (mz_uint16)(ins_pos);
                }
            }
        }
        d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
        if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
            break;

        /* Simple lazy/greedy parsing state machine. */
        len_to_move = 1;
        cur_match_dist = 0;
        cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
        cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
        if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
        {
            if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
            {
                mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
                cur_match_len = 0;
                while (cur_match_len < d->m_lookahead_size)
                {
                    if (d->m_dict[cur_pos + cur_match_len] != c)
                        break;
                    cur_match_len++;
                }
                if (cur_match_len < TDEFL_MIN_MATCH_LEN)
                    cur_match_len = 0;
                else
                    cur_match_dist = 1;
            }
        }
        else
        {
            tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
        }
        if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
        {
            cur_match_dist = cur_match_len = 0;
        }
        if (d->m_saved_match_len)
        {
            if (cur_match_len > d->m_saved_match_len)
            {
                tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
                if (cur_match_len >= 128)
                {
                    tdefl_record_match(d, cur_match_len, cur_match_dist);
                    d->m_saved_match_len = 0;
                    len_to_move = cur_match_len;
                }
                else
                {
                    d->m_saved_lit = d->m_dict[cur_pos];
                    d->m_saved_match_dist = cur_match_dist;
                    d->m_saved_match_len = cur_match_len;
                }
            }
            else
            {
                tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
                len_to_move = d->m_saved_match_len - 1;
                d->m_saved_match_len = 0;
            }
        }
        else if (!cur_match_dist)
            tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
        else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
        {
            tdefl_record_match(d, cur_match_len, cur_match_dist);
            len_to_move = cur_match_len;
        }
        else
        {
            d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)];
            d->m_saved_match_dist = cur_match_dist;
            d->m_saved_match_len = cur_match_len;
        }
        /* Move the lookahead forward by len_to_move bytes. */
        d->m_lookahead_pos += len_to_move;
        MZ_ASSERT(d->m_lookahead_size >= len_to_move);
        d->m_lookahead_size -= len_to_move;
        d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
        /* Check if it's time to flush the current LZ codes to the internal output buffer. */
        if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
            ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))))
        {
            int n;
            d->m_pSrc = pSrc;
            d->m_src_buf_left = src_buf_left;
            if ((n = tdefl_flush_block(d, 0)) != 0)
                return (n < 0) ? MZ_FALSE : MZ_TRUE;
        }
    }

    d->m_pSrc = pSrc;
    d->m_src_buf_left = src_buf_left;
    return MZ_TRUE;
}

static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
{
    if (d->m_pIn_buf_size)
    {
        *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
    }

    if (d->m_pOut_buf_size)
    {
        size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
        memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
        d->m_output_flush_ofs += (mz_uint)n;
        d->m_output_flush_remaining -= (mz_uint)n;
        d->m_out_buf_ofs += n;

        *d->m_pOut_buf_size = d->m_out_buf_ofs;
    }

    return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
}

tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush)
{
    if (!d)
    {
        if (pIn_buf_size)
            *pIn_buf_size = 0;
        if (pOut_buf_size)
            *pOut_buf_size = 0;
        return TDEFL_STATUS_BAD_PARAM;
    }

    d->m_pIn_buf = pIn_buf;
    d->m_pIn_buf_size = pIn_buf_size;
    d->m_pOut_buf = pOut_buf;
    d->m_pOut_buf_size = pOut_buf_size;
    d->m_pSrc = (const mz_uint8 *)(pIn_buf);
    d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
    d->m_out_buf_ofs = 0;
    d->m_flush = flush;

    if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
        (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
    {
        if (pIn_buf_size)
            *pIn_buf_size = 0;
        if (pOut_buf_size)
            *pOut_buf_size = 0;
        return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
    }
    d->m_wants_to_finish |= (flush == TDEFL_FINISH);

    if ((d->m_output_flush_remaining) || (d->m_finished))
        return (d->m_prev_return_status = tdefl_flush_output_buffer(d));

#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
    if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
        ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
        ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
    {
        if (!tdefl_compress_fast(d))
            return d->m_prev_return_status;
    }
    else
#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
    {
        if (!tdefl_compress_normal(d))
            return d->m_prev_return_status;
    }

    if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
        d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);

    if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
    {
        if (tdefl_flush_block(d, flush) < 0)
            return d->m_prev_return_status;
        d->m_finished = (flush == TDEFL_FINISH);
        if (flush == TDEFL_FULL_FLUSH)
        {
            MZ_CLEAR_OBJ(d->m_hash);
            MZ_CLEAR_OBJ(d->m_next);
            d->m_dict_size = 0;
        }
    }

    return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
}

tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
{
    MZ_ASSERT(d->m_pPut_buf_func);
    return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
}

tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
    d->m_pPut_buf_func = pPut_buf_func;
    d->m_pPut_buf_user = pPut_buf_user;
    d->m_flags = (mz_uint)(flags);
    d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
    d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
    d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
    if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
        MZ_CLEAR_OBJ(d->m_hash);
    d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
    d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
    d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
    d->m_pLZ_flags = d->m_lz_code_buf;
    d->m_num_flags_left = 8;
    d->m_pOutput_buf = d->m_output_buf;
    d->m_pOutput_buf_end = d->m_output_buf;
    d->m_prev_return_status = TDEFL_STATUS_OKAY;
    d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
    d->m_adler32 = 1;
    d->m_pIn_buf = NULL;
    d->m_pOut_buf = NULL;
    d->m_pIn_buf_size = NULL;
    d->m_pOut_buf_size = NULL;
    d->m_flush = TDEFL_NO_FLUSH;
    d->m_pSrc = NULL;
    d->m_src_buf_left = 0;
    d->m_out_buf_ofs = 0;
    if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
        MZ_CLEAR_OBJ(d->m_dict);
    memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
    memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
    return TDEFL_STATUS_OKAY;
}

tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
{
    return d->m_prev_return_status;
}

mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
{
    return d->m_adler32;
}

mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
    tdefl_compressor *pComp;
    mz_bool succeeded;
    if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
        return MZ_FALSE;
    pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
    if (!pComp)
        return MZ_FALSE;
    succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
    succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
    MZ_FREE(pComp);
    return succeeded;
}

typedef struct
{
    size_t m_size, m_capacity;
    mz_uint8 *m_pBuf;
    mz_bool m_expandable;
} tdefl_output_buffer;

static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
{
    tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
    size_t new_size = p->m_size + len;
    if (new_size > p->m_capacity)
    {
        size_t new_capacity = p->m_capacity;
        mz_uint8 *pNew_buf;
        if (!p->m_expandable)
            return MZ_FALSE;
        do
        {
            new_capacity = MZ_MAX(128U, new_capacity << 1U);
        } while (new_size > new_capacity);
        pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
        if (!pNew_buf)
            return MZ_FALSE;
        p->m_pBuf = pNew_buf;
        p->m_capacity = new_capacity;
    }
    memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
    p->m_size = new_size;
    return MZ_TRUE;
}

void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
{
    tdefl_output_buffer out_buf;
    MZ_CLEAR_OBJ(out_buf);
    if (!pOut_len)
        return MZ_FALSE;
    else
        *pOut_len = 0;
    out_buf.m_expandable = MZ_TRUE;
    if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
        return NULL;
    *pOut_len = out_buf.m_size;
    return out_buf.m_pBuf;
}

size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
{
    tdefl_output_buffer out_buf;
    MZ_CLEAR_OBJ(out_buf);
    if (!pOut_buf)
        return 0;
    out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
    out_buf.m_capacity = out_buf_len;
    if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
        return 0;
    return out_buf.m_size;
}

static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };

/* level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). */
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
{
    mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
    if (window_bits > 0)
        comp_flags |= TDEFL_WRITE_ZLIB_HEADER;

    if (!level)
        comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
    else if (strategy == MZ_FILTERED)
        comp_flags |= TDEFL_FILTER_MATCHES;
    else if (strategy == MZ_HUFFMAN_ONLY)
        comp_flags &= ~TDEFL_MAX_PROBES_MASK;
    else if (strategy == MZ_FIXED)
        comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
    else if (strategy == MZ_RLE)
        comp_flags |= TDEFL_RLE_MATCHES;

    return comp_flags;
}

#ifdef _MSC_VER
//#pragma warning(push)
//#pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */
#endif

/* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
 http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
 This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
{
    /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */
    static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
    tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
    tdefl_output_buffer out_buf;
    int i, bpl = w * num_chans, y, z;
    mz_uint32 c;
    *pLen_out = 0;
    if (!pComp)
        return NULL;
    MZ_CLEAR_OBJ(out_buf);
    out_buf.m_expandable = MZ_TRUE;
    out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
    if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity)))
    {
        MZ_FREE(pComp);
        return NULL;
    }
    /* write dummy header */
    for (z = 41; z; --z)
        tdefl_output_buffer_putter(&z, 1, &out_buf);
    /* compress image data */
    tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
    for (y = 0; y < h; ++y)
    {
        tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
        tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
    }
    if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE)
    {
        MZ_FREE(pComp);
        MZ_FREE(out_buf.m_pBuf);
        return NULL;
    }
    /* write real header */
    *pLen_out = out_buf.m_size - 41;
    {
        static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
        mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d,
                                0x0a, 0x1a, 0x0a, 0x00, 0x00,
                                0x00, 0x0d, 0x49, 0x48, 0x44,
                                0x52, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x08,
                                0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x49, 0x44, 0x41,
                                0x54 };
        pnghdr[18] = (mz_uint8)(w >> 8);
        pnghdr[19] = (mz_uint8)w;
        pnghdr[22] = (mz_uint8)(h >> 8);
        pnghdr[23] = (mz_uint8)h;
        pnghdr[25] = chans[num_chans];
        pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
        pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
        pnghdr[35] = (mz_uint8)(*pLen_out >> 8);
        pnghdr[36] = (mz_uint8)*pLen_out;
        c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
        for (i = 0; i < 4; ++i, c <<= 8)
            ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
        memcpy(out_buf.m_pBuf, pnghdr, 41);
    }
    /* write footer (IDAT CRC-32, followed by IEND chunk) */
    if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf))
    {
        *pLen_out = 0;
        MZ_FREE(pComp);
        MZ_FREE(out_buf.m_pBuf);
        return NULL;
    }
    c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4);
    for (i = 0; i < 4; ++i, c <<= 8)
        (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
    /* compute final size of file, grab compressed data buffer and return */
    *pLen_out += 57;
    MZ_FREE(pComp);
    return out_buf.m_pBuf;
}
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
{
    /* Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) */
    return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
}

/* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */
/* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */
/* structure size and allocation mechanism. */
tdefl_compressor *tdefl_compressor_alloc()
{
    return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
}

void tdefl_compressor_free(tdefl_compressor *pComp)
{
    MZ_FREE(pComp);
}

#ifdef _MSC_VER
//#pragma warning(pop)
#endif

#ifdef __cplusplus
}
#endif
/**************************************************************************
 *
 * Copyright 2013-2014 RAD Game Tools and Valve Software
 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/



#ifdef __cplusplus
extern "C" {
#endif

/* ------------------- Low-level Decompression (completely independent from all compression API's) */

#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
#define TINFL_MEMSET(p, c, l) memset(p, c, l)

#define TINFL_CR_BEGIN  \
    switch (r->m_state) \
    {                   \
        case 0:
#define TINFL_CR_RETURN(state_index, result) \
    do                                       \
    {                                        \
        status = result;                     \
        r->m_state = state_index;            \
        goto common_exit;                    \
        case state_index:;                   \
    }                                        \
    MZ_MACRO_END
#define TINFL_CR_RETURN_FOREVER(state_index, result) \
    do                                               \
    {                                                \
        for (;;)                                     \
        {                                            \
            TINFL_CR_RETURN(state_index, result);    \
        }                                            \
    }                                                \
    MZ_MACRO_END
#define TINFL_CR_FINISH }

#define TINFL_GET_BYTE(state_index, c)                                                                                                                           \
    do                                                                                                                                                           \
    {                                                                                                                                                            \
        while (pIn_buf_cur >= pIn_buf_end)                                                                                                                       \
        {                                                                                                                                                        \
            TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
        }                                                                                                                                                        \
        c = *pIn_buf_cur++;                                                                                                                                      \
    }                                                                                                                                                            \
    MZ_MACRO_END

#define TINFL_NEED_BITS(state_index, n)                \
    do                                                 \
    {                                                  \
        mz_uint c;                                     \
        TINFL_GET_BYTE(state_index, c);                \
        bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
        num_bits += 8;                                 \
    } while (num_bits < (mz_uint)(n))
#define TINFL_SKIP_BITS(state_index, n)      \
    do                                       \
    {                                        \
        if (num_bits < (mz_uint)(n))         \
        {                                    \
            TINFL_NEED_BITS(state_index, n); \
        }                                    \
        bit_buf >>= (n);                     \
        num_bits -= (n);                     \
    }                                        \
    MZ_MACRO_END
#define TINFL_GET_BITS(state_index, b, n)    \
    do                                       \
    {                                        \
        if (num_bits < (mz_uint)(n))         \
        {                                    \
            TINFL_NEED_BITS(state_index, n); \
        }                                    \
        b = bit_buf & ((1 << (n)) - 1);      \
        bit_buf >>= (n);                     \
        num_bits -= (n);                     \
    }                                        \
    MZ_MACRO_END

/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff)                             \
    do                                                                         \
    {                                                                          \
        temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)];     \
        if (temp >= 0)                                                         \
        {                                                                      \
            code_len = temp >> 9;                                              \
            if ((code_len) && (num_bits >= code_len))                          \
                break;                                                         \
        }                                                                      \
        else if (num_bits > TINFL_FAST_LOOKUP_BITS)                            \
        {                                                                      \
            code_len = TINFL_FAST_LOOKUP_BITS;                                 \
            do                                                                 \
            {                                                                  \
                temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
            } while ((temp < 0) && (num_bits >= (code_len + 1)));              \
            if (temp >= 0)                                                     \
                break;                                                         \
        }                                                                      \
        TINFL_GET_BYTE(state_index, c);                                        \
        bit_buf |= (((tinfl_bit_buf_t)c) << num_bits);                         \
        num_bits += 8;                                                         \
    } while (num_bits < 15);

/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */
/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */
/* The slow path is only executed at the very end of the input buffer. */
/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */
/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
#define TINFL_HUFF_DECODE(state_index, sym, pHuff)                                                                                  \
    do                                                                                                                              \
    {                                                                                                                               \
        int temp;                                                                                                                   \
        mz_uint code_len, c;                                                                                                        \
        if (num_bits < 15)                                                                                                          \
        {                                                                                                                           \
            if ((pIn_buf_end - pIn_buf_cur) < 2)                                                                                    \
            {                                                                                                                       \
                TINFL_HUFF_BITBUF_FILL(state_index, pHuff);                                                                         \
            }                                                                                                                       \
            else                                                                                                                    \
            {                                                                                                                       \
                bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
                pIn_buf_cur += 2;                                                                                                   \
                num_bits += 16;                                                                                                     \
            }                                                                                                                       \
        }                                                                                                                           \
        if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)                                               \
            code_len = temp >> 9, temp &= 511;                                                                                      \
        else                                                                                                                        \
        {                                                                                                                           \
            code_len = TINFL_FAST_LOOKUP_BITS;                                                                                      \
            do                                                                                                                      \
            {                                                                                                                       \
                temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)];                                                      \
            } while (temp < 0);                                                                                                     \
        }                                                                                                                           \
        sym = temp;                                                                                                                 \
        bit_buf >>= code_len;                                                                                                       \
        num_bits -= code_len;                                                                                                       \
    }                                                                                                                               \
    MZ_MACRO_END

tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
{
    static const int s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
    static const int s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
    static const int s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
    static const int s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
    static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
    static const int s_min_table_sizes[3] = { 257, 1, 4 };

    tinfl_status status = TINFL_STATUS_FAILED;
    mz_uint32 num_bits, dist, counter, num_extra;
    tinfl_bit_buf_t bit_buf;
    const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
    mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
    size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;

    /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */
    if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
    {
        *pIn_buf_size = *pOut_buf_size = 0;
        return TINFL_STATUS_BAD_PARAM;
    }

    num_bits = r->m_num_bits;
    bit_buf = r->m_bit_buf;
    dist = r->m_dist;
    counter = r->m_counter;
    num_extra = r->m_num_extra;
    dist_from_out_buf_start = r->m_dist_from_out_buf_start;
    TINFL_CR_BEGIN

    bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
    r->m_z_adler32 = r->m_check_adler32 = 1;
    if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
    {
        TINFL_GET_BYTE(1, r->m_zhdr0);
        TINFL_GET_BYTE(2, r->m_zhdr1);
        counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
        if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
            counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
        if (counter)
        {
            TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
        }
    }

    do
    {
        TINFL_GET_BITS(3, r->m_final, 3);
        r->m_type = r->m_final >> 1;
        if (r->m_type == 0)
        {
            TINFL_SKIP_BITS(5, num_bits & 7);
            for (counter = 0; counter < 4; ++counter)
            {
                if (num_bits)
                    TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
                else
                    TINFL_GET_BYTE(7, r->m_raw_header[counter]);
            }
            if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8))))
            {
                TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
            }
            while ((counter) && (num_bits))
            {
                TINFL_GET_BITS(51, dist, 8);
                while (pOut_buf_cur >= pOut_buf_end)
                {
                    TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
                }
                *pOut_buf_cur++ = (mz_uint8)dist;
                counter--;
            }
            while (counter)
            {
                size_t n;
                while (pOut_buf_cur >= pOut_buf_end)
                {
                    TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
                }
                while (pIn_buf_cur >= pIn_buf_end)
                {
                    TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
                }
                n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
                TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
                pIn_buf_cur += n;
                pOut_buf_cur += n;
                counter -= (mz_uint)n;
            }
        }
        else if (r->m_type == 3)
        {
            TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
        }
        else
        {
            if (r->m_type == 1)
            {
                mz_uint8 *p = r->m_tables[0].m_code_size;
                mz_uint i;
                r->m_table_sizes[0] = 288;
                r->m_table_sizes[1] = 32;
                TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
                for (i = 0; i <= 143; ++i)
                    *p++ = 8;
                for (; i <= 255; ++i)
                    *p++ = 9;
                for (; i <= 279; ++i)
                    *p++ = 7;
                for (; i <= 287; ++i)
                    *p++ = 8;
            }
            else
            {
                for (counter = 0; counter < 3; counter++)
                {
                    TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
                    r->m_table_sizes[counter] += s_min_table_sizes[counter];
                }
                MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
                for (counter = 0; counter < r->m_table_sizes[2]; counter++)
                {
                    mz_uint s;
                    TINFL_GET_BITS(14, s, 3);
                    r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
                }
                r->m_table_sizes[2] = 19;
            }
            for (; (int)r->m_type >= 0; r->m_type--)
            {
                int tree_next, tree_cur;
                tinfl_huff_table *pTable;
                mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
                pTable = &r->m_tables[r->m_type];
                MZ_CLEAR_OBJ(total_syms);
                MZ_CLEAR_OBJ(pTable->m_look_up);
                MZ_CLEAR_OBJ(pTable->m_tree);
                for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
                    total_syms[pTable->m_code_size[i]]++;
                used_syms = 0, total = 0;
                next_code[0] = next_code[1] = 0;
                for (i = 1; i <= 15; ++i)
                {
                    used_syms += total_syms[i];
                    next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
                }
                if ((65536 != total) && (used_syms > 1))
                {
                    TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
                }
                for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
                {
                    mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
                    if (!code_size)
                        continue;
                    cur_code = next_code[code_size]++;
                    for (l = code_size; l > 0; l--, cur_code >>= 1)
                        rev_code = (rev_code << 1) | (cur_code & 1);
                    if (code_size <= TINFL_FAST_LOOKUP_BITS)
                    {
                        mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
                        while (rev_code < TINFL_FAST_LOOKUP_SIZE)
                        {
                            pTable->m_look_up[rev_code] = k;
                            rev_code += (1 << code_size);
                        }
                        continue;
                    }
                    if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
                    {
                        pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
                        tree_cur = tree_next;
                        tree_next -= 2;
                    }
                    rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
                    for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
                    {
                        tree_cur -= ((rev_code >>= 1) & 1);
                        if (!pTable->m_tree[-tree_cur - 1])
                        {
                            pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
                            tree_cur = tree_next;
                            tree_next -= 2;
                        }
                        else
                            tree_cur = pTable->m_tree[-tree_cur - 1];
                    }
                    tree_cur -= ((rev_code >>= 1) & 1);
                    pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
                }
                if (r->m_type == 2)
                {
                    for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
                    {
                        mz_uint s;
                        TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
                        if (dist < 16)
                        {
                            r->m_len_codes[counter++] = (mz_uint8)dist;
                            continue;
                        }
                        if ((dist == 16) && (!counter))
                        {
                            TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
                        }
                        num_extra = "\02\03\07"[dist - 16];
                        TINFL_GET_BITS(18, s, num_extra);
                        s += "\03\03\013"[dist - 16];
                        TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
                        counter += s;
                    }
                    if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
                    {
                        TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
                    }
                    TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]);
                    TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
                }
            }
            for (;;)
            {
                mz_uint8 *pSrc;
                for (;;)
                {
                    if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
                    {
                        TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
                        if (counter >= 256)
                            break;
                        while (pOut_buf_cur >= pOut_buf_end)
                        {
                            TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
                        }
                        *pOut_buf_cur++ = (mz_uint8)counter;
                    }
                    else
                    {
                        int sym2;
                        mz_uint code_len;
#if TINFL_USE_64BIT_BITBUF
                        if (num_bits < 30)
                        {
                            bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
                            pIn_buf_cur += 4;
                            num_bits += 32;
                        }
#else
                        if (num_bits < 15)
                        {
                            bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
                            pIn_buf_cur += 2;
                            num_bits += 16;
                        }
#endif
                        if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
                            code_len = sym2 >> 9;
                        else
                        {
                            code_len = TINFL_FAST_LOOKUP_BITS;
                            do
                            {
                                sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
                            } while (sym2 < 0);
                        }
                        counter = sym2;
                        bit_buf >>= code_len;
                        num_bits -= code_len;
                        if (counter & 256)
                            break;

#if !TINFL_USE_64BIT_BITBUF
                        if (num_bits < 15)
                        {
                            bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
                            pIn_buf_cur += 2;
                            num_bits += 16;
                        }
#endif
                        if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
                            code_len = sym2 >> 9;
                        else
                        {
                            code_len = TINFL_FAST_LOOKUP_BITS;
                            do
                            {
                                sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
                            } while (sym2 < 0);
                        }
                        bit_buf >>= code_len;
                        num_bits -= code_len;

                        pOut_buf_cur[0] = (mz_uint8)counter;
                        if (sym2 & 256)
                        {
                            pOut_buf_cur++;
                            counter = sym2;
                            break;
                        }
                        pOut_buf_cur[1] = (mz_uint8)sym2;
                        pOut_buf_cur += 2;
                    }
                }
                if ((counter &= 511) == 256)
                    break;

                num_extra = s_length_extra[counter - 257];
                counter = s_length_base[counter - 257];
                if (num_extra)
                {
                    mz_uint extra_bits;
                    TINFL_GET_BITS(25, extra_bits, num_extra);
                    counter += extra_bits;
                }

                TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
                num_extra = s_dist_extra[dist];
                dist = s_dist_base[dist];
                if (num_extra)
                {
                    mz_uint extra_bits;
                    TINFL_GET_BITS(27, extra_bits, num_extra);
                    dist += extra_bits;
                }

                dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
                if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
                {
                    TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
                }

                pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);

                if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
                {
                    while (counter--)
                    {
                        while (pOut_buf_cur >= pOut_buf_end)
                        {
                            TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
                        }
                        *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
                    }
                    continue;
                }
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
                else if ((counter >= 9) && (counter <= dist))
                {
                    const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
                    do
                    {
                        ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
                        ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
                        pOut_buf_cur += 8;
                    } while ((pSrc += 8) < pSrc_end);
                    if ((counter &= 7) < 3)
                    {
                        if (counter)
                        {
                            pOut_buf_cur[0] = pSrc[0];
                            if (counter > 1)
                                pOut_buf_cur[1] = pSrc[1];
                            pOut_buf_cur += counter;
                        }
                        continue;
                    }
                }
#endif
                while(counter>2)
                {
                    pOut_buf_cur[0] = pSrc[0];
                    pOut_buf_cur[1] = pSrc[1];
                    pOut_buf_cur[2] = pSrc[2];
                    pOut_buf_cur += 3;
                    pSrc += 3;
					counter -= 3;
                }
                if (counter > 0)
                {
                    pOut_buf_cur[0] = pSrc[0];
                    if (counter > 1)
                        pOut_buf_cur[1] = pSrc[1];
                    pOut_buf_cur += counter;
                }
            }
        }
    } while (!(r->m_final & 1));

    /* Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */
    /* I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now. */
    TINFL_SKIP_BITS(32, num_bits & 7);
    while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
    {
        --pIn_buf_cur;
        num_bits -= 8;
    }
    bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
    MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */

    if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
    {
        for (counter = 0; counter < 4; ++counter)
        {
            mz_uint s;
            if (num_bits)
                TINFL_GET_BITS(41, s, 8);
            else
                TINFL_GET_BYTE(42, s);
            r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
        }
    }
    TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);

    TINFL_CR_FINISH

common_exit:
    /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
    /* Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */
    /* We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop. */
    if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
    {
        while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
        {
            --pIn_buf_cur;
            num_bits -= 8;
        }
    }
    r->m_num_bits = num_bits;
    r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
    r->m_dist = dist;
    r->m_counter = counter;
    r->m_num_extra = num_extra;
    r->m_dist_from_out_buf_start = dist_from_out_buf_start;
    *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
    *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
    if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
    {
        const mz_uint8 *ptr = pOut_buf_next;
        size_t buf_len = *pOut_buf_size;
        mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
        size_t block_len = buf_len % 5552;
        while (buf_len)
        {
            for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
            {
                s1 += ptr[0], s2 += s1;
                s1 += ptr[1], s2 += s1;
                s1 += ptr[2], s2 += s1;
                s1 += ptr[3], s2 += s1;
                s1 += ptr[4], s2 += s1;
                s1 += ptr[5], s2 += s1;
                s1 += ptr[6], s2 += s1;
                s1 += ptr[7], s2 += s1;
            }
            for (; i < block_len; ++i)
                s1 += *ptr++, s2 += s1;
            s1 %= 65521U, s2 %= 65521U;
            buf_len -= block_len;
            block_len = 5552;
        }
        r->m_check_adler32 = (s2 << 16) + s1;
        if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
            status = TINFL_STATUS_ADLER32_MISMATCH;
    }
    return status;
}

/* Higher level helper functions. */
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
{
    tinfl_decompressor decomp;
    void *pBuf = NULL, *pNew_buf;
    size_t src_buf_ofs = 0, out_buf_capacity = 0;
    *pOut_len = 0;
    tinfl_init(&decomp);
    for (;;)
    {
        size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
        tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, &dst_buf_size,
                                               (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
        if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
        {
            MZ_FREE(pBuf);
            *pOut_len = 0;
            return NULL;
        }
        src_buf_ofs += src_buf_size;
        *pOut_len += dst_buf_size;
        if (status == TINFL_STATUS_DONE)
            break;
        new_out_buf_capacity = out_buf_capacity * 2;
        if (new_out_buf_capacity < 128)
            new_out_buf_capacity = 128;
        pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
        if (!pNew_buf)
        {
            MZ_FREE(pBuf);
            *pOut_len = 0;
            return NULL;
        }
        pBuf = pNew_buf;
        out_buf_capacity = new_out_buf_capacity;
    }
    return pBuf;
}

size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
{
    tinfl_decompressor decomp;
    tinfl_status status;
    tinfl_init(&decomp);
    status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
    return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
}

int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
    int result = 0;
    tinfl_decompressor decomp;
    mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
    size_t in_buf_ofs = 0, dict_ofs = 0;
    if (!pDict)
        return TINFL_STATUS_FAILED;
    tinfl_init(&decomp);
    for (;;)
    {
        size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
        tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
                                               (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
        in_buf_ofs += in_buf_size;
        if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
            break;
        if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
        {
            result = (status == TINFL_STATUS_DONE);
            break;
        }
        dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
    }
    MZ_FREE(pDict);
    *pIn_buf_size = in_buf_ofs;
    return result;
}

tinfl_decompressor *tinfl_decompressor_alloc()
{
    tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
    if (pDecomp)
        tinfl_init(pDecomp);
    return pDecomp;
}

void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
{
    MZ_FREE(pDecomp);
}

#ifdef __cplusplus
}
#endif
/**************************************************************************
 *
 * Copyright 2013-2014 RAD Game Tools and Valve Software
 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
 * Copyright 2016 Martin Raiber
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/


#ifndef MINIZ_NO_ARCHIVE_APIS

#ifdef __cplusplus
extern "C" {
#endif

/* ------------------- .ZIP archive reading */

#ifdef MINIZ_NO_STDIO
#define MZ_FILE void *
#else
#include <sys/stat.h>

#if defined(_MSC_VER) || defined(__MINGW64__)
static FILE *mz_fopen(const char *pFilename, const char *pMode)
{
    FILE *pFile = NULL;
    fopen_s(&pFile, pFilename, pMode);
    return pFile;
}
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
{
    FILE *pFile = NULL;
    if (freopen_s(&pFile, pPath, pMode, pStream))
        return NULL;
    return pFile;
}
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
#define MZ_FOPEN mz_fopen
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 _ftelli64
#define MZ_FSEEK64 _fseeki64
#define MZ_FILE_STAT_STRUCT _stat
#define MZ_FILE_STAT _stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN mz_freopen
#define MZ_DELETE_FILE remove
#elif defined(__MINGW32__)
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftello64
#define MZ_FSEEK64 fseeko64
#define MZ_FILE_STAT_STRUCT _stat
#define MZ_FILE_STAT _stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
#define MZ_DELETE_FILE remove
#elif defined(__TINYC__)
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftell
#define MZ_FSEEK64 fseek
#define MZ_FILE_STAT_STRUCT stat
#define MZ_FILE_STAT stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
#define MZ_DELETE_FILE remove
#elif defined(__GNUC__) && _LARGEFILE64_SOURCE
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
#define MZ_FOPEN(f, m) fopen64(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftello64
#define MZ_FSEEK64 fseeko64
#define MZ_FILE_STAT_STRUCT stat64
#define MZ_FILE_STAT stat64
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
#define MZ_DELETE_FILE remove
#elif defined(__APPLE__)
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftello
#define MZ_FSEEK64 fseeko
#define MZ_FILE_STAT_STRUCT stat
#define MZ_FILE_STAT stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(p, m, s) freopen(p, m, s)
#define MZ_DELETE_FILE remove

#else
//#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#ifdef __STRICT_ANSI__
#define MZ_FTELL64 ftell
#define MZ_FSEEK64 fseek
#else
#define MZ_FTELL64 ftello
#define MZ_FSEEK64 fseeko
#endif
#define MZ_FILE_STAT_STRUCT stat
#define MZ_FILE_STAT stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
#define MZ_DELETE_FILE remove
#endif /* #ifdef _MSC_VER */
#endif /* #ifdef MINIZ_NO_STDIO */

#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))

/* Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. */
enum
{
    /* ZIP archive identifiers and record sizes */
    MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50,
    MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50,
    MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
    MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30,
    MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46,
    MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,

    /* ZIP64 archive identifier and record sizes */
    MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50,
    MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50,
    MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56,
    MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20,
    MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001,
    MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50,
    MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24,
    MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16,

    /* Central directory header record offsets */
    MZ_ZIP_CDH_SIG_OFS = 0,
    MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4,
    MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6,
    MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
    MZ_ZIP_CDH_METHOD_OFS = 10,
    MZ_ZIP_CDH_FILE_TIME_OFS = 12,
    MZ_ZIP_CDH_FILE_DATE_OFS = 14,
    MZ_ZIP_CDH_CRC32_OFS = 16,
    MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20,
    MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24,
    MZ_ZIP_CDH_FILENAME_LEN_OFS = 28,
    MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
    MZ_ZIP_CDH_COMMENT_LEN_OFS = 32,
    MZ_ZIP_CDH_DISK_START_OFS = 34,
    MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36,
    MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38,
    MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,

    /* Local directory header offsets */
    MZ_ZIP_LDH_SIG_OFS = 0,
    MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4,
    MZ_ZIP_LDH_BIT_FLAG_OFS = 6,
    MZ_ZIP_LDH_METHOD_OFS = 8,
    MZ_ZIP_LDH_FILE_TIME_OFS = 10,
    MZ_ZIP_LDH_FILE_DATE_OFS = 12,
    MZ_ZIP_LDH_CRC32_OFS = 14,
    MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18,
    MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
    MZ_ZIP_LDH_FILENAME_LEN_OFS = 26,
    MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
    MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3,

    /* End of central directory offsets */
    MZ_ZIP_ECDH_SIG_OFS = 0,
    MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4,
    MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6,
    MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
    MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10,
    MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12,
    MZ_ZIP_ECDH_CDIR_OFS_OFS = 16,
    MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,

    /* ZIP64 End of central directory locator offsets */
    MZ_ZIP64_ECDL_SIG_OFS = 0,                    /* 4 bytes */
    MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4,          /* 4 bytes */
    MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8,  /* 8 bytes */
    MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16, /* 4 bytes */

    /* ZIP64 End of central directory header offsets */
    MZ_ZIP64_ECDH_SIG_OFS = 0,                       /* 4 bytes */
    MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4,            /* 8 bytes */
    MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12,          /* 2 bytes */
    MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14,           /* 2 bytes */
    MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16,            /* 4 bytes */
    MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20,            /* 4 bytes */
    MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24, /* 8 bytes */
    MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32,       /* 8 bytes */
    MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40,                /* 8 bytes */
    MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48,                 /* 8 bytes */
    MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0,
    MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10,
    MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1,
    MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32,
    MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64,
    MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192,
    MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11
};

typedef struct
{
    void *m_p;
    size_t m_size, m_capacity;
    mz_uint m_element_size;
} mz_zip_array;

struct mz_zip_internal_state_tag
{
    mz_zip_array m_central_dir;
    mz_zip_array m_central_dir_offsets;
    mz_zip_array m_sorted_central_dir_offsets;

    /* The flags passed in when the archive is initially opened. */
    uint32_t m_init_flags;

    /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */
    mz_bool m_zip64;

    /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 will also be slammed to true too, even if we didn't find a zip64 end of central dir header, etc.) */
    mz_bool m_zip64_has_extended_info_fields;

    /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */
    MZ_FILE *m_pFile;
    mz_uint64 m_file_archive_start_ofs;

    void *m_pMem;
    size_t m_mem_size;
    size_t m_mem_capacity;
};

#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size

#if defined(DEBUG) || defined(_DEBUG) || defined(NDEBUG)
static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index)
{
    MZ_ASSERT(index < pArray->m_size);
    return index;
}
#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
#else
#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
#endif

static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
{
    memset(pArray, 0, sizeof(mz_zip_array));
    pArray->m_element_size = element_size;
}

static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
{
    pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
    memset(pArray, 0, sizeof(mz_zip_array));
}

static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
{
    void *pNew_p;
    size_t new_capacity = min_new_capacity;
    MZ_ASSERT(pArray->m_element_size);
    if (pArray->m_capacity >= min_new_capacity)
        return MZ_TRUE;
    if (growing)
    {
        new_capacity = MZ_MAX(1, pArray->m_capacity);
        while (new_capacity < min_new_capacity)
            new_capacity *= 2;
    }
    if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity)))
        return MZ_FALSE;
    pArray->m_p = pNew_p;
    pArray->m_capacity = new_capacity;
    return MZ_TRUE;
}

static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
{
    if (new_capacity > pArray->m_capacity)
    {
        if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
            return MZ_FALSE;
    }
    return MZ_TRUE;
}

static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
{
    if (new_size > pArray->m_capacity)
    {
        if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
            return MZ_FALSE;
    }
    pArray->m_size = new_size;
    return MZ_TRUE;
}

static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
{
    return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
}

static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
{
    size_t orig_size = pArray->m_size;
    if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
        return MZ_FALSE;
    memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
    return MZ_TRUE;
}

#ifndef MINIZ_NO_TIME
static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date)
{
    struct tm tm;
    memset(&tm, 0, sizeof(tm));
    tm.tm_isdst = -1;
    tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
    tm.tm_mon = ((dos_date >> 5) & 15) - 1;
    tm.tm_mday = dos_date & 31;
    tm.tm_hour = (dos_time >> 11) & 31;
    tm.tm_min = (dos_time >> 5) & 63;
    tm.tm_sec = (dos_time << 1) & 62;
    return mktime(&tm);
}

#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
{
#ifdef _MSC_VER
    struct tm tm_struct;
    struct tm *tm = &tm_struct;
    errno_t err = localtime_s(tm, &time);
    if (err)
    {
        *pDOS_date = 0;
        *pDOS_time = 0;
        return;
    }
#else
    struct tm *tm = localtime(&time);
#endif /* #ifdef _MSC_VER */

    *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
    *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
}
#endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */

#ifndef MINIZ_NO_STDIO
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
static mz_bool mz_zip_get_file_modified_time(const char *pFilename, MZ_TIME_T *pTime)
{
    struct MZ_FILE_STAT_STRUCT file_stat;

    /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */
    if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
        return MZ_FALSE;

    *pTime = file_stat.st_mtime;

    return MZ_TRUE;
}
#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/

static mz_bool mz_zip_set_file_times(const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time)
{
    struct utimbuf t;

    memset(&t, 0, sizeof(t));
    t.actime = access_time;
    t.modtime = modified_time;

    return !utime(pFilename, &t);
}
#endif /* #ifndef MINIZ_NO_STDIO */
#endif /* #ifndef MINIZ_NO_TIME */

static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num)
{
    if (pZip)
        pZip->m_last_error = err_num;
    return MZ_FALSE;
}

static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags)
{
    (void)flags;
    if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!pZip->m_pAlloc)
        pZip->m_pAlloc = miniz_def_alloc_func;
    if (!pZip->m_pFree)
        pZip->m_pFree = miniz_def_free_func;
    if (!pZip->m_pRealloc)
        pZip->m_pRealloc = miniz_def_realloc_func;

    pZip->m_archive_size = 0;
    pZip->m_central_directory_file_ofs = 0;
    pZip->m_total_files = 0;
    pZip->m_last_error = MZ_ZIP_NO_ERROR;

    if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
    MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
    MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
    MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
    pZip->m_pState->m_init_flags = flags;
    pZip->m_pState->m_zip64 = MZ_FALSE;
    pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE;

    pZip->m_zip_mode = MZ_ZIP_MODE_READING;

    return MZ_TRUE;
}

static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
{
    const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
    const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
    mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
    mz_uint8 l = 0, r = 0;
    pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
    pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
    pE = pL + MZ_MIN(l_len, r_len);
    while (pL < pE)
    {
        if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
            break;
        pL++;
        pR++;
    }
    return (pL == pE) ? (l_len < r_len) : (l < r);
}

#define MZ_SWAP_UINT32(a, b) \
    do                       \
    {                        \
        mz_uint32 t = a;     \
        a = b;               \
        b = t;               \
    }                        \
    MZ_MACRO_END

/* Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) */
static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
{
    mz_zip_internal_state *pState = pZip->m_pState;
    const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
    const mz_zip_array *pCentral_dir = &pState->m_central_dir;
    mz_uint32 *pIndices;
    mz_uint32 start, end;
    const mz_uint32 size = pZip->m_total_files;

    if (size <= 1U)
        return;

    pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);

    start = (size - 2U) >> 1U;
    for (;;)
    {
        mz_uint64 child, root = start;
        for (;;)
        {
            if ((child = (root << 1U) + 1U) >= size)
                break;
            child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])));
            if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
                break;
            MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
            root = child;
        }
        if (!start)
            break;
        start--;
    }

    end = size - 1;
    while (end > 0)
    {
        mz_uint64 child, root = 0;
        MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
        for (;;)
        {
            if ((child = (root << 1U) + 1U) >= end)
                break;
            child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]));
            if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
                break;
            MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
            root = child;
        }
        end--;
    }
}

static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs)
{
    mz_int64 cur_file_ofs;
    mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
    mz_uint8 *pBuf = (mz_uint8 *)buf_u32;

    /* Basic sanity checks - reject files which are too small */
    if (pZip->m_archive_size < record_size)
        return MZ_FALSE;

    /* Find the record by scanning the file from the end towards the beginning. */
    cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
    for (;;)
    {
        int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);

        if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
            return MZ_FALSE;

        for (i = n - 4; i >= 0; --i)
        {
            mz_uint s = MZ_READ_LE32(pBuf + i);
            if (s == record_sig)
            {
                if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
                    break;
            }
        }

        if (i >= 0)
        {
            cur_file_ofs += i;
            break;
        }

        /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
        if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size)))
            return MZ_FALSE;

        cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
    }

    *pOfs = cur_file_ofs;
    return MZ_TRUE;
}

static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
{
    mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
    mz_uint64 cdir_ofs = 0;
    mz_int64 cur_file_ofs = 0;
    const mz_uint8 *p;

    mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
    mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
    mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
    mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;

    mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32;

    mz_uint64 zip64_end_of_central_dir_ofs = 0;

    /* Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. */
    if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);

    if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
        return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);

    /* Read and verify the end of central directory record. */
    if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);

    if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
    {
        if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
        {
            if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG)
            {
                zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
                if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
                    return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);

                if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
                {
                    if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
                    {
                        pZip->m_pState->m_zip64 = MZ_TRUE;
                    }
                }
            }
        }
    }

    pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS);
    cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
    num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
    cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
    cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
    cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);

    if (pZip->m_pState->m_zip64)
    {
        mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
        mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
        mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
        mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS);
        mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);

        if (zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

        if (zip64_total_num_of_disks != 1U)
            return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);

        /* Check for miniz's practical limits */
        if (zip64_cdir_total_entries > MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);

        pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;

        if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);

        cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk;

        /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */
        if (zip64_size_of_central_directory > MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);

        cdir_size = (mz_uint32)zip64_size_of_central_directory;

        num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);

        cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);

        cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
    }

    if (pZip->m_total_files != cdir_entries_on_this_disk)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);

    if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);

    if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    pZip->m_central_directory_file_ofs = cdir_ofs;

    if (pZip->m_total_files)
    {
        mz_uint i, n;
        /* Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and possibly another to hold the sorted indices. */
        if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
            (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

        if (sort_central_dir)
        {
            if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
                return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

        /* Now create an index into the central directory file records, do some basic sanity checking on each record */
        p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
        for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
        {
            mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size;
            mz_uint64 comp_size, decomp_size, local_header_ofs;

            if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);

            if (sort_central_dir)
                MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;

            comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
            decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
            local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
            filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
            ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);

            if ((!pZip->m_pState->m_zip64_has_extended_info_fields) &&
                (ext_data_size) &&
                (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX))
            {
                /* Attempt to find zip64 extended information field in the entry's extra data */
                mz_uint32 extra_size_remaining = ext_data_size;

                if (extra_size_remaining)
                {
                    const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;

                    do
                    {
                        mz_uint32 field_id;
                        mz_uint32 field_data_size;

                        if (extra_size_remaining < (sizeof(mz_uint16) * 2))
                            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                        field_id = MZ_READ_LE16(pExtra_data);
                        field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));

                        if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
                            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                        if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
                        {
                            /* Ok, the archive didn't have any zip64 headers but it uses a zip64 extended information field so mark it as zip64 anyway (this can occur with infozip's zip util when it reads compresses files from stdin). */
                            pZip->m_pState->m_zip64 = MZ_TRUE;
                            pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE;
                            break;
                        }

                        pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
                        extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
                    } while (extra_size_remaining);
                }
            }

            /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */
            if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX))
            {
                if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size))
                    return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
            }

            disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
            if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
                return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);

            if (comp_size != MZ_UINT32_MAX)
            {
                if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
                    return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
            }

            bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
            if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED)
                return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);

            if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n)
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            n -= total_header_size;
            p += total_header_size;
        }
    }

    if (sort_central_dir)
        mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);

    return MZ_TRUE;
}

void mz_zip_zero_struct(mz_zip_archive *pZip)
{
    if (pZip)
        MZ_CLEAR_OBJ(*pZip);
}

static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
{
    mz_bool status = MZ_TRUE;

    if (!pZip)
        return MZ_FALSE;

    if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
    {
        if (set_last_error)
            pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER;

        return MZ_FALSE;
    }

    if (pZip->m_pState)
    {
        mz_zip_internal_state *pState = pZip->m_pState;
        pZip->m_pState = NULL;

        mz_zip_array_clear(pZip, &pState->m_central_dir);
        mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
        mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);

#ifndef MINIZ_NO_STDIO
        if (pState->m_pFile)
        {
            if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
            {
                if (MZ_FCLOSE(pState->m_pFile) == EOF)
                {
                    if (set_last_error)
                        pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED;
                    status = MZ_FALSE;
                }
            }
            pState->m_pFile = NULL;
        }
#endif /* #ifndef MINIZ_NO_STDIO */

        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
    }
    pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;

    return status;
}

mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
{
    return mz_zip_reader_end_internal(pZip, MZ_TRUE);
}
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags)
{
    if ((!pZip) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!mz_zip_reader_init_internal(pZip, flags))
        return MZ_FALSE;

    pZip->m_zip_type = MZ_ZIP_TYPE_USER;
    pZip->m_archive_size = size;

    if (!mz_zip_reader_read_central_dir(pZip, flags))
    {
        mz_zip_reader_end_internal(pZip, MZ_FALSE);
        return MZ_FALSE;
    }

    return MZ_TRUE;
}

static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
{
    mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
    size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
    memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
    return s;
}

mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
{
    if (!pMem)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);

    if (!mz_zip_reader_init_internal(pZip, flags))
        return MZ_FALSE;

    pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY;
    pZip->m_archive_size = size;
    pZip->m_pRead = mz_zip_mem_read_func;
    pZip->m_pIO_opaque = pZip;
    pZip->m_pNeeds_keepalive = NULL;

#ifdef __cplusplus
    pZip->m_pState->m_pMem = const_cast<void *>(pMem);
#else
    pZip->m_pState->m_pMem = (void *)pMem;
#endif

    pZip->m_pState->m_mem_size = size;

    if (!mz_zip_reader_read_central_dir(pZip, flags))
    {
        mz_zip_reader_end_internal(pZip, MZ_FALSE);
        return MZ_FALSE;
    }

    return MZ_TRUE;
}

#ifndef MINIZ_NO_STDIO
static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
{
    mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
    mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);

    file_ofs += pZip->m_pState->m_file_archive_start_ofs;

    if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
        return 0;

    return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
}

mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
{
    return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
}

mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size)
{
    mz_uint64 file_size;
    MZ_FILE *pFile;

    if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pFile = MZ_FOPEN(pFilename, "rb");
    if (!pFile)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);

    file_size = archive_size;
    if (!file_size)
    {
        if (MZ_FSEEK64(pFile, 0, SEEK_END))
        {
            MZ_FCLOSE(pFile);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
        }

        file_size = MZ_FTELL64(pFile);
    }

    /* TODO: Better sanity check archive_size and the # of actual remaining bytes */

    if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
    {
	MZ_FCLOSE(pFile);
        return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
    }

    if (!mz_zip_reader_init_internal(pZip, flags))
    {
        MZ_FCLOSE(pFile);
        return MZ_FALSE;
    }

    pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
    pZip->m_pRead = mz_zip_file_read_func;
    pZip->m_pIO_opaque = pZip;
    pZip->m_pState->m_pFile = pFile;
    pZip->m_archive_size = file_size;
    pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;

    if (!mz_zip_reader_read_central_dir(pZip, flags))
    {
        mz_zip_reader_end_internal(pZip, MZ_FALSE);
        return MZ_FALSE;
    }

    return MZ_TRUE;
}

mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags)
{
    mz_uint64 cur_file_ofs;

    if ((!pZip) || (!pFile))
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);

    cur_file_ofs = MZ_FTELL64(pFile);

    if (!archive_size)
    {
        if (MZ_FSEEK64(pFile, 0, SEEK_END))
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);

        archive_size = MZ_FTELL64(pFile) - cur_file_ofs;

        if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
            return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
    }

    if (!mz_zip_reader_init_internal(pZip, flags))
        return MZ_FALSE;

    pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
    pZip->m_pRead = mz_zip_file_read_func;

    pZip->m_pIO_opaque = pZip;
    pZip->m_pState->m_pFile = pFile;
    pZip->m_archive_size = archive_size;
    pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;

    if (!mz_zip_reader_read_central_dir(pZip, flags))
    {
        mz_zip_reader_end_internal(pZip, MZ_FALSE);
        return MZ_FALSE;
    }

    return MZ_TRUE;
}

#endif /* #ifndef MINIZ_NO_STDIO */

static MZ_FORCEINLINE const mz_uint8 *mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
{
    if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
        return NULL;
    return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
}

mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
{
    mz_uint m_bit_flag;
    const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
    if (!p)
    {
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
        return MZ_FALSE;
    }

    m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
    return (m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0;
}

mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index)
{
    mz_uint bit_flag;
    mz_uint method;

    const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
    if (!p)
    {
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
        return MZ_FALSE;
    }

    method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
    bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);

    if ((method != 0) && (method != MZ_DEFLATED))
    {
        mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
        return MZ_FALSE;
    }

    if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION))
    {
        mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
        return MZ_FALSE;
    }

    if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)
    {
        mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
        return MZ_FALSE;
    }

    return MZ_TRUE;
}

mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
{
    mz_uint filename_len, attribute_mapping_id, external_attr;
    const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
    if (!p)
    {
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
        return MZ_FALSE;
    }

    filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
    if (filename_len)
    {
        if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
            return MZ_TRUE;
    }

    /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */
    /* Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. */
    /* FIXME: Remove this check? Is it necessary - we already check the filename. */
    attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8;
    (void)attribute_mapping_id;

    external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
    if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0)
    {
        return MZ_TRUE;
    }

    return MZ_FALSE;
}

static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, mz_uint file_index, const mz_uint8 *pCentral_dir_header, mz_zip_archive_file_stat *pStat, mz_bool *pFound_zip64_extra_data)
{
    mz_uint n;
    const mz_uint8 *p = pCentral_dir_header;

    if (pFound_zip64_extra_data)
        *pFound_zip64_extra_data = MZ_FALSE;

    if ((!p) || (!pStat))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    /* Extract fields from the central directory record. */
    pStat->m_file_index = file_index;
    pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
    pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
    pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
    pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
    pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
#ifndef MINIZ_NO_TIME
    pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
#endif
    pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
    pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
    pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
    pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
    pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
    pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);

    /* Copy as much of the filename and comment as possible. */
    n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
    n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
    memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
    pStat->m_filename[n] = '\0';

    n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
    n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
    pStat->m_comment_size = n;
    memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n);
    pStat->m_comment[n] = '\0';

    /* Set some flags for convienance */
    pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
    pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
    pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);

    /* See if we need to read any zip64 extended information fields. */
    /* Confusingly, these zip64 fields can be present even on non-zip64 archives (Debian zip on a huge files from stdin piped to stdout creates them). */
    if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
    {
        /* Attempt to find zip64 extended information field in the entry's extra data */
        mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);

        if (extra_size_remaining)
        {
            const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);

            do
            {
                mz_uint32 field_id;
                mz_uint32 field_data_size;

                if (extra_size_remaining < (sizeof(mz_uint16) * 2))
                    return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                field_id = MZ_READ_LE16(pExtra_data);
                field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));

                if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
                    return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
                {
                    const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2;
                    mz_uint32 field_data_remaining = field_data_size;

                    if (pFound_zip64_extra_data)
                        *pFound_zip64_extra_data = MZ_TRUE;

                    if (pStat->m_uncomp_size == MZ_UINT32_MAX)
                    {
                        if (field_data_remaining < sizeof(mz_uint64))
                            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                        pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
                        pField_data += sizeof(mz_uint64);
                        field_data_remaining -= sizeof(mz_uint64);
                    }

                    if (pStat->m_comp_size == MZ_UINT32_MAX)
                    {
                        if (field_data_remaining < sizeof(mz_uint64))
                            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                        pStat->m_comp_size = MZ_READ_LE64(pField_data);
                        pField_data += sizeof(mz_uint64);
                        field_data_remaining -= sizeof(mz_uint64);
                    }

                    if (pStat->m_local_header_ofs == MZ_UINT32_MAX)
                    {
                        if (field_data_remaining < sizeof(mz_uint64))
                            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

                        pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
                        pField_data += sizeof(mz_uint64);
                        field_data_remaining -= sizeof(mz_uint64);
                    }

                    break;
                }

                pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
                extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
            } while (extra_size_remaining);
        }
    }

    return MZ_TRUE;
}

static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
{
    mz_uint i;
    if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
        return 0 == memcmp(pA, pB, len);
    for (i = 0; i < len; ++i)
        if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
            return MZ_FALSE;
    return MZ_TRUE;
}

static MZ_FORCEINLINE int mz_zip_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len)
{
    const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
    mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
    mz_uint8 l = 0, r = 0;
    pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
    pE = pL + MZ_MIN(l_len, r_len);
    while (pL < pE)
    {
        if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
            break;
        pL++;
        pR++;
    }
    return (pL == pE) ? (int)(l_len - r_len) : (l - r);
}

static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
{
    mz_zip_internal_state *pState = pZip->m_pState;
    const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
    const mz_zip_array *pCentral_dir = &pState->m_central_dir;
    mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
    const uint32_t size = pZip->m_total_files;
    const mz_uint filename_len = (mz_uint)strlen(pFilename);

    if (pIndex)
        *pIndex = 0;

    if (size)
    {
        /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */
        /* honestly the major expense here on 32-bit CPU's will still be the filename compare */
        mz_int64 l = 0, h = (mz_int64)size - 1;

        while (l <= h)
        {
            mz_int64 m = l + ((h - l) >> 1);
            uint32_t file_index = pIndices[(uint32_t)m];

            int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
            if (!comp)
            {
                if (pIndex)
                    *pIndex = file_index;
                return MZ_TRUE;
            }
            else if (comp < 0)
                l = m + 1;
            else
                h = m - 1;
        }
    }

    return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
}

int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
{
    mz_uint32 index;
    if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
        return -1;
    else
        return (int)index;
}

mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex)
{
    mz_uint file_index;
    size_t name_len, comment_len;

    if (pIndex)
        *pIndex = 0;

    if ((!pZip) || (!pZip->m_pState) || (!pName))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    /* See if we can use a binary search */
    if (((pZip->m_pState->m_init_flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) &&
        (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
        ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
    {
        return mz_zip_locate_file_binary_search(pZip, pName, pIndex);
    }

    /* Locate the entry by scanning the entire central directory */
    name_len = strlen(pName);
    if (name_len > MZ_UINT16_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    comment_len = pComment ? strlen(pComment) : 0;
    if (comment_len > MZ_UINT16_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    for (file_index = 0; file_index < pZip->m_total_files; file_index++)
    {
        const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
        mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
        const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
        if (filename_len < name_len)
            continue;
        if (comment_len)
        {
            mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
            const char *pFile_comment = pFilename + filename_len + file_extra_len;
            if ((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags)))
                continue;
        }
        if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
        {
            int ofs = filename_len - 1;
            do
            {
                if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
                    break;
            } while (--ofs >= 0);
            ofs++;
            pFilename += ofs;
            filename_len -= ofs;
        }
        if ((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags)))
        {
            if (pIndex)
                *pIndex = file_index;
            return MZ_TRUE;
        }
    }

    return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
}

mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
{
    int status = TINFL_STATUS_DONE;
    mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
    mz_zip_archive_file_stat file_stat;
    void *pRead_buf;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
    tinfl_decompressor inflator;

    if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
        return MZ_FALSE;

    /* A directory or zero length file */
    if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
        return MZ_TRUE;

    /* Encryption and patch files are not supported. */
    if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);

    /* This function only supports decompressing stored and deflate. */
    if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);

    /* Ensure supplied output buffer is large enough. */
    needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
    if (buf_size < needed_size)
        return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL);

    /* Read and parse the local directory entry. */
    cur_file_ofs = file_stat.m_local_header_ofs;
    if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
    {
        /* The file is stored or the caller has requested the compressed data. */
        if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
        if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
        {
            if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
                return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
        }
#endif

        return MZ_TRUE;
    }

    /* Decompress the file either directly from memory or from a file input buffer. */
    tinfl_init(&inflator);

    if (pZip->m_pState->m_pMem)
    {
        /* Read directly from the archive in memory. */
        pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
        read_buf_size = read_buf_avail = file_stat.m_comp_size;
        comp_remaining = 0;
    }
    else if (pUser_read_buf)
    {
        /* Use a user provided read buffer. */
        if (!user_read_buf_size)
            return MZ_FALSE;
        pRead_buf = (mz_uint8 *)pUser_read_buf;
        read_buf_size = user_read_buf_size;
        read_buf_avail = 0;
        comp_remaining = file_stat.m_comp_size;
    }
    else
    {
        /* Temporarily allocate a read buffer. */
        read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
        if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
            return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

        if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

        read_buf_avail = 0;
        comp_remaining = file_stat.m_comp_size;
    }

    do
    {
        /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */
        size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
        if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
        {
            read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
            if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
            {
                status = TINFL_STATUS_FAILED;
                mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
                break;
            }
            cur_file_ofs += read_buf_avail;
            comp_remaining -= read_buf_avail;
            read_buf_ofs = 0;
        }
        in_buf_size = (size_t)read_buf_avail;
        status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
        read_buf_avail -= in_buf_size;
        read_buf_ofs += in_buf_size;
        out_buf_ofs += out_buf_size;
    } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);

    if (status == TINFL_STATUS_DONE)
    {
        /* Make sure the entire file was decompressed, and check its CRC. */
        if (out_buf_ofs != file_stat.m_uncomp_size)
        {
            mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
            status = TINFL_STATUS_FAILED;
        }
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
        else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
        {
            mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
            status = TINFL_STATUS_FAILED;
        }
#endif
    }

    if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
        pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);

    return status == TINFL_STATUS_DONE;
}

mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
{
    mz_uint32 file_index;
    if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
        return MZ_FALSE;
    return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
}

mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
{
    return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
}

mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
{
    return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
}

void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
{
    mz_uint64 comp_size, uncomp_size, alloc_size;
    const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
    void *pBuf;

    if (pSize)
        *pSize = 0;

    if (!p)
    {
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
        return NULL;
    }

    comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
    uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);

    alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
    if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
    {
        mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
        return NULL;
    }

    if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
    {
        mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        return NULL;
    }

    if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
    {
        pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
        return NULL;
    }

    if (pSize)
        *pSize = (size_t)alloc_size;
    return pBuf;
}

void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
{
    mz_uint32 file_index;
    if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
    {
        if (pSize)
            *pSize = 0;
        return MZ_FALSE;
    }
    return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
}

mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
{
    int status = TINFL_STATUS_DONE;
    mz_uint file_crc32 = MZ_CRC32_INIT;
    mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
    mz_zip_archive_file_stat file_stat;
    void *pRead_buf = NULL;
    void *pWrite_buf = NULL;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;

    if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
        return MZ_FALSE;

    /* A directory or zero length file */
    if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
        return MZ_TRUE;

    /* Encryption and patch files are not supported. */
    if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);

    /* This function only supports decompressing stored and deflate. */
    if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);

    /* Read and do some minimal validation of the local directory entry (this doesn't crack the zip64 stuff, which we already have from the central dir) */
    cur_file_ofs = file_stat.m_local_header_ofs;
    if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    /* Decompress the file either directly from memory or from a file input buffer. */
    if (pZip->m_pState->m_pMem)
    {
        pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
        read_buf_size = read_buf_avail = file_stat.m_comp_size;
        comp_remaining = 0;
    }
    else
    {
        read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
        if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

        read_buf_avail = 0;
        comp_remaining = file_stat.m_comp_size;
    }

    if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
    {
        /* The file is stored or the caller has requested the compressed data. */
        if (pZip->m_pState->m_pMem)
        {
            if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
                return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

            if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
            {
                mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
                status = TINFL_STATUS_FAILED;
            }
            else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
            {
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
                file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
#endif
            }

            cur_file_ofs += file_stat.m_comp_size;
            out_buf_ofs += file_stat.m_comp_size;
            comp_remaining = 0;
        }
        else
        {
            while (comp_remaining)
            {
                read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
                if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
                    status = TINFL_STATUS_FAILED;
                    break;
                }

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
                if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
                {
                    file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
                }
#endif

                if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
                    status = TINFL_STATUS_FAILED;
                    break;
                }

                cur_file_ofs += read_buf_avail;
                out_buf_ofs += read_buf_avail;
                comp_remaining -= read_buf_avail;
            }
        }
    }
    else
    {
        tinfl_decompressor inflator;
        tinfl_init(&inflator);

        if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
        {
            mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
            status = TINFL_STATUS_FAILED;
        }
        else
        {
            do
            {
                mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
                size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
                if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
                {
                    read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
                    if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
                    {
                        mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
                        status = TINFL_STATUS_FAILED;
                        break;
                    }
                    cur_file_ofs += read_buf_avail;
                    comp_remaining -= read_buf_avail;
                    read_buf_ofs = 0;
                }

                in_buf_size = (size_t)read_buf_avail;
                status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
                read_buf_avail -= in_buf_size;
                read_buf_ofs += in_buf_size;

                if (out_buf_size)
                {
                    if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
                    {
                        mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
                        status = TINFL_STATUS_FAILED;
                        break;
                    }

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
                    file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
#endif
                    if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
                    {
                        mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
                        status = TINFL_STATUS_FAILED;
                        break;
                    }
                }
            } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
        }
    }

    if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
    {
        /* Make sure the entire file was decompressed, and check its CRC. */
        if (out_buf_ofs != file_stat.m_uncomp_size)
        {
            mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
            status = TINFL_STATUS_FAILED;
        }
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
        else if (file_crc32 != file_stat.m_crc32)
        {
            mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
            status = TINFL_STATUS_FAILED;
        }
#endif
    }

    if (!pZip->m_pState->m_pMem)
        pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);

    if (pWrite_buf)
        pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);

    return status == TINFL_STATUS_DONE;
}

mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
{
    mz_uint32 file_index;
    if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
        return MZ_FALSE;

    return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
}

mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
{
    mz_zip_reader_extract_iter_state *pState;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;

    /* Argument sanity check */
    if ((!pZip) || (!pZip->m_pState))
        return NULL;

    /* Allocate an iterator status structure */
    pState = (mz_zip_reader_extract_iter_state*)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_reader_extract_iter_state));
    if (!pState)
    {
        mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        return NULL;
    }

    /* Fetch file details */
    if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat))
    {
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
        return NULL;
    }

    /* Encryption and patch files are not supported. */
    if (pState->file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
    {
        mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
        return NULL;
    }

    /* This function only supports decompressing stored and deflate. */
    if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (pState->file_stat.m_method != 0) && (pState->file_stat.m_method != MZ_DEFLATED))
    {
        mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
        return NULL;
    }

    /* Init state - save args */
    pState->pZip = pZip;
    pState->flags = flags;

    /* Init state - reset variables to defaults */
    pState->status = TINFL_STATUS_DONE;
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
    pState->file_crc32 = MZ_CRC32_INIT;
#endif
    pState->read_buf_ofs = 0;
    pState->out_buf_ofs = 0;
    pState->pRead_buf = NULL;
    pState->pWrite_buf = NULL;
    pState->out_blk_remain = 0;

    /* Read and parse the local directory entry. */
    pState->cur_file_ofs = pState->file_stat.m_local_header_ofs;
    if (pZip->m_pRead(pZip->m_pIO_opaque, pState->cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
    {
        mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
        return NULL;
    }

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
    {
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
        return NULL;
    }

    pState->cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
    {
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
        return NULL;
    }

    /* Decompress the file either directly from memory or from a file input buffer. */
    if (pZip->m_pState->m_pMem)
    {
        pState->pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs;
        pState->read_buf_size = pState->read_buf_avail = pState->file_stat.m_comp_size;
        pState->comp_remaining = pState->file_stat.m_comp_size;
    }
    else
    {
        if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
        {
            /* Decompression required, therefore intermediate read buffer required */
            pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
            if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)pState->read_buf_size)))
            {
                mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
                pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
                return NULL;
            }
        }
        else
        {
            /* Decompression not required - we will be reading directly into user buffer, no temp buf required */
            pState->read_buf_size = 0;
        }
        pState->read_buf_avail = 0;
        pState->comp_remaining = pState->file_stat.m_comp_size;
    }

    if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
    {
        /* Decompression required, init decompressor */
        tinfl_init( &pState->inflator );

        /* Allocate write buffer */
        if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
        {
            mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
            if (pState->pRead_buf)
                pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf);
            pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
            return NULL;
        }
    }

    return pState;
}

mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
{
    mz_uint32 file_index;

    /* Locate file index by name */
    if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
        return NULL;

    /* Construct iterator */
    return mz_zip_reader_extract_iter_new(pZip, file_index, flags);
}

size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size)
{
    size_t copied_to_caller = 0;

    /* Argument sanity check */
    if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
        return 0;

    if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))
    {
        /* The file is stored or the caller has requested the compressed data, calc amount to return. */
        copied_to_caller = MZ_MIN( buf_size, pState->comp_remaining );

        /* Zip is in memory....or requires reading from a file? */
        if (pState->pZip->m_pState->m_pMem)
        {
            /* Copy data to caller's buffer */
            memcpy( pvBuf, pState->pRead_buf, copied_to_caller );
            pState->pRead_buf = ((mz_uint8*)pState->pRead_buf) + copied_to_caller;
        }
        else
        {
            /* Read directly into caller's buffer */
            if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller)
            {
                /* Failed to read all that was asked for, flag failure and alert user */
                mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
                pState->status = TINFL_STATUS_FAILED;
                copied_to_caller = 0;
            }
        }

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
        /* Compute CRC if not returning compressed data only */
        if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
            pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, (const mz_uint8 *)pvBuf, copied_to_caller);
#endif

        /* Advance offsets, dec counters */
        pState->cur_file_ofs += copied_to_caller;
        pState->out_buf_ofs += copied_to_caller;
        pState->comp_remaining -= copied_to_caller;
    }
    else
    {
        do
        {
            /* Calc ptr to write buffer - given current output pos and block size */
            mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));

            /* Calc max output size - given current output pos and block size */
            size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));

            if (!pState->out_blk_remain)
            {
                /* Read more data from file if none available (and reading from file) */
                if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem))
                {
                    /* Calc read size */
                    pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining);
                    if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (size_t)pState->read_buf_avail) != pState->read_buf_avail)
                    {
                        mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
                        pState->status = TINFL_STATUS_FAILED;
                        break;
                    }

                    /* Advance offsets, dec counters */
                    pState->cur_file_ofs += pState->read_buf_avail;
                    pState->comp_remaining -= pState->read_buf_avail;
                    pState->read_buf_ofs = 0;
                }

                /* Perform decompression */
                in_buf_size = (size_t)pState->read_buf_avail;
                pState->status = tinfl_decompress(&pState->inflator, (const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
                pState->read_buf_avail -= in_buf_size;
                pState->read_buf_ofs += in_buf_size;

                /* Update current output block size remaining */
                pState->out_blk_remain = out_buf_size;
            }

            if (pState->out_blk_remain)
            {
                /* Calc amount to return. */
                size_t to_copy = MZ_MIN( (buf_size - copied_to_caller), pState->out_blk_remain );

                /* Copy data to caller's buffer */
                memcpy( (uint8_t*)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy );

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
                /* Perform CRC */
                pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
#endif

                /* Decrement data consumed from block */
                pState->out_blk_remain -= to_copy;

                /* Inc output offset, while performing sanity check */
                if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size)
                {
                    mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
                    pState->status = TINFL_STATUS_FAILED;
                    break;
                }

                /* Increment counter of data copied to caller */
                copied_to_caller += to_copy;
            }
        } while ( (copied_to_caller < buf_size) && ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)) );
    }

    /* Return how many bytes were copied into user buffer */
    return copied_to_caller;
}

mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState)
{
    int status;

    /* Argument sanity check */
    if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState))
        return MZ_FALSE;

    /* Was decompression completed and requested? */
    if ((pState->status == TINFL_STATUS_DONE) && (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
    {
        /* Make sure the entire file was decompressed, and check its CRC. */
        if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size)
        {
            mz_zip_set_error(pState->pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
            pState->status = TINFL_STATUS_FAILED;
        }
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
        else if (pState->file_crc32 != pState->file_stat.m_crc32)
        {
            mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
            pState->status = TINFL_STATUS_FAILED;
        }
#endif
    }

    /* Free buffers */
    if (!pState->pZip->m_pState->m_pMem)
        pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf);
    if (pState->pWrite_buf)
        pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf);

    /* Save status */
    status = pState->status;

    /* Free context */
    pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState);

    return status == TINFL_STATUS_DONE;
}

#ifndef MINIZ_NO_STDIO
static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
{
    (void)ofs;

    return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
}

mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
{
    mz_bool status;
    mz_zip_archive_file_stat file_stat;
    MZ_FILE *pFile;

    if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
        return MZ_FALSE;

    if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);

    pFile = MZ_FOPEN(pDst_filename, "wb");
    if (!pFile)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);

    status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);

    if (MZ_FCLOSE(pFile) == EOF)
    {
        if (status)
            mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);

        status = MZ_FALSE;
    }

#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
    if (status)
        mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
#endif

    return status;
}

mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
{
    mz_uint32 file_index;
    if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
        return MZ_FALSE;

    return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
}

mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *pFile, mz_uint flags)
{
    mz_zip_archive_file_stat file_stat;

    if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
        return MZ_FALSE;

    if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);

    return mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
}

mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags)
{
    mz_uint32 file_index;
    if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
        return MZ_FALSE;

    return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags);
}
#endif /* #ifndef MINIZ_NO_STDIO */

static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
{
    mz_uint32 *p = (mz_uint32 *)pOpaque;
    (void)file_ofs;
    *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n);
    return n;
}

mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
{
    mz_zip_archive_file_stat file_stat;
    mz_zip_internal_state *pState;
    const mz_uint8 *pCentral_dir_header;
    mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
    mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
    mz_uint64 local_header_ofs = 0;
    mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
    mz_uint64 local_header_comp_size, local_header_uncomp_size;
    mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
    mz_bool has_data_descriptor;
    mz_uint32 local_header_bit_flags;

    mz_zip_array file_data_array;
    mz_zip_array_init(&file_data_array, 1);

    if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (file_index > pZip->m_total_files)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);

    if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir))
        return MZ_FALSE;

    /* A directory or zero length file */
    if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
        return MZ_TRUE;

    /* Encryption and patch files are not supported. */
    if (file_stat.m_is_encrypted)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);

    /* This function only supports stored and deflate. */
    if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);

    if (!file_stat.m_is_supported)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);

    /* Read and parse the local directory entry. */
    local_header_ofs = file_stat.m_local_header_ofs;
    if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
    local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
    local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
    local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
    local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
    has_data_descriptor = (local_header_bit_flags & 8) != 0;

    if (local_header_filename_len != strlen(file_stat.m_filename))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    if (local_header_filename_len)
    {
        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len)
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */
        if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0)
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }

    if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
    {
        mz_uint32 extra_size_remaining = local_header_extra_len;
        const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;

        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        do
        {
            mz_uint32 field_id, field_data_size, field_total_size;

            if (extra_size_remaining < (sizeof(mz_uint16) * 2))
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            field_id = MZ_READ_LE16(pExtra_data);
            field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
            field_total_size = field_data_size + sizeof(mz_uint16) * 2;

            if (field_total_size > extra_size_remaining)
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
            {
                const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);

                if (field_data_size < sizeof(mz_uint64) * 2)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
                    goto handle_failure;
                }

                local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
                local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64));

                found_zip64_ext_data_in_ldir = MZ_TRUE;
                break;
            }

            pExtra_data += field_total_size;
            extra_size_remaining -= field_total_size;
        } while (extra_size_remaining);
    }

    /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */
    /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */
    if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
    {
        mz_uint8 descriptor_buf[32];
        mz_bool has_id;
        const mz_uint8 *pSrc;
        mz_uint32 file_crc32;
        mz_uint64 comp_size = 0, uncomp_size = 0;

        mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;

        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s))
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
        pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf;

        file_crc32 = MZ_READ_LE32(pSrc);

        if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
        {
            comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32));
            uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64));
        }
        else
        {
            comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32));
            uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32));
        }

        if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }
    else
    {
        if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size))
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }

    mz_zip_array_clear(pZip, &file_data_array);

    if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
    {
        if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
            return MZ_FALSE;

        /* 1 more check to be sure, although the extract checks too. */
        if (uncomp_crc32 != file_stat.m_crc32)
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            return MZ_FALSE;
        }
    }

    return MZ_TRUE;

handle_failure:
    mz_zip_array_clear(pZip, &file_data_array);
    return MZ_FALSE;
}

mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
{
    mz_zip_internal_state *pState;
    uint32_t i;

    if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    /* Basic sanity checks */
    if (!pState->m_zip64)
    {
        if (pZip->m_total_files > MZ_UINT16_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);

        if (pZip->m_archive_size > MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
    }
    else
    {
        if (pZip->m_total_files >= MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);

        if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
    }

    for (i = 0; i < pZip->m_total_files; i++)
    {
        if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags)
        {
            mz_uint32 found_index;
            mz_zip_archive_file_stat stat;

            if (!mz_zip_reader_file_stat(pZip, i, &stat))
                return MZ_FALSE;

            if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index))
                return MZ_FALSE;

            /* This check can fail if there are duplicate filenames in the archive (which we don't check for when writing - that's up to the user) */
            if (found_index != i)
                return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
        }

        if (!mz_zip_validate_file(pZip, i, flags))
            return MZ_FALSE;
    }

    return MZ_TRUE;
}

mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr)
{
    mz_bool success = MZ_TRUE;
    mz_zip_archive zip;
    mz_zip_error actual_err = MZ_ZIP_NO_ERROR;

    if ((!pMem) || (!size))
    {
        if (pErr)
            *pErr = MZ_ZIP_INVALID_PARAMETER;
        return MZ_FALSE;
    }

    mz_zip_zero_struct(&zip);

    if (!mz_zip_reader_init_mem(&zip, pMem, size, flags))
    {
        if (pErr)
            *pErr = zip.m_last_error;
        return MZ_FALSE;
    }

    if (!mz_zip_validate_archive(&zip, flags))
    {
        actual_err = zip.m_last_error;
        success = MZ_FALSE;
    }

    if (!mz_zip_reader_end_internal(&zip, success))
    {
        if (!actual_err)
            actual_err = zip.m_last_error;
        success = MZ_FALSE;
    }

    if (pErr)
        *pErr = actual_err;

    return success;
}

#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr)
{
    mz_bool success = MZ_TRUE;
    mz_zip_archive zip;
    mz_zip_error actual_err = MZ_ZIP_NO_ERROR;

    if (!pFilename)
    {
        if (pErr)
            *pErr = MZ_ZIP_INVALID_PARAMETER;
        return MZ_FALSE;
    }

    mz_zip_zero_struct(&zip);

    if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0))
    {
        if (pErr)
            *pErr = zip.m_last_error;
        return MZ_FALSE;
    }

    if (!mz_zip_validate_archive(&zip, flags))
    {
        actual_err = zip.m_last_error;
        success = MZ_FALSE;
    }

    if (!mz_zip_reader_end_internal(&zip, success))
    {
        if (!actual_err)
            actual_err = zip.m_last_error;
        success = MZ_FALSE;
    }

    if (pErr)
        *pErr = actual_err;

    return success;
}
#endif /* #ifndef MINIZ_NO_STDIO */

/* ------------------- .ZIP archive writing */

#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS

static MZ_FORCEINLINE void mz_write_le16(mz_uint8 *p, mz_uint16 v)
{
    p[0] = (mz_uint8)v;
    p[1] = (mz_uint8)(v >> 8);
}
static MZ_FORCEINLINE void mz_write_le32(mz_uint8 *p, mz_uint32 v)
{
    p[0] = (mz_uint8)v;
    p[1] = (mz_uint8)(v >> 8);
    p[2] = (mz_uint8)(v >> 16);
    p[3] = (mz_uint8)(v >> 24);
}
static MZ_FORCEINLINE void mz_write_le64(mz_uint8 *p, mz_uint64 v)
{
    mz_write_le32(p, (mz_uint32)v);
    mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32));
}

#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))

static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
{
    mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
    mz_zip_internal_state *pState = pZip->m_pState;
    mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);

    if (!n)
        return 0;

    /* An allocation this big is likely to just fail on 32-bit systems, so don't even go there. */
    if ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))
    {
        mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
        return 0;
    }

    if (new_size > pState->m_mem_capacity)
    {
        void *pNew_block;
        size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);

        while (new_capacity < new_size)
            new_capacity *= 2;

        if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
        {
            mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
            return 0;
        }

        pState->m_pMem = pNew_block;
        pState->m_mem_capacity = new_capacity;
    }
    memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
    pState->m_mem_size = (size_t)new_size;
    return n;
}

static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
{
    mz_zip_internal_state *pState;
    mz_bool status = MZ_TRUE;

    if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
    {
        if (set_last_error)
            mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
        return MZ_FALSE;
    }

    pState = pZip->m_pState;
    pZip->m_pState = NULL;
    mz_zip_array_clear(pZip, &pState->m_central_dir);
    mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
    mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);

#ifndef MINIZ_NO_STDIO
    if (pState->m_pFile)
    {
        if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
        {
            if (MZ_FCLOSE(pState->m_pFile) == EOF)
            {
                if (set_last_error)
                    mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
                status = MZ_FALSE;
            }
        }

        pState->m_pFile = NULL;
    }
#endif /* #ifndef MINIZ_NO_STDIO */

    if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
    {
        pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
        pState->m_pMem = NULL;
    }

    pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
    pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
    return status;
}

mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags)
{
    mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;

    if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
    {
        if (!pZip->m_pRead)
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
    }

    if (pZip->m_file_offset_alignment)
    {
        /* Ensure user specified file offset alignment is a power of 2. */
        if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
    }

    if (!pZip->m_pAlloc)
        pZip->m_pAlloc = miniz_def_alloc_func;
    if (!pZip->m_pFree)
        pZip->m_pFree = miniz_def_free_func;
    if (!pZip->m_pRealloc)
        pZip->m_pRealloc = miniz_def_realloc_func;

    pZip->m_archive_size = existing_size;
    pZip->m_central_directory_file_ofs = 0;
    pZip->m_total_files = 0;

    if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));

    MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
    MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
    MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));

    pZip->m_pState->m_zip64 = zip64;
    pZip->m_pState->m_zip64_has_extended_info_fields = zip64;

    pZip->m_zip_type = MZ_ZIP_TYPE_USER;
    pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;

    return MZ_TRUE;
}

mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
{
    return mz_zip_writer_init_v2(pZip, existing_size, 0);
}

mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags)
{
    pZip->m_pWrite = mz_zip_heap_write_func;
    pZip->m_pNeeds_keepalive = NULL;

    if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
        pZip->m_pRead = mz_zip_mem_read_func;

    pZip->m_pIO_opaque = pZip;

    if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
        return MZ_FALSE;

    pZip->m_zip_type = MZ_ZIP_TYPE_HEAP;

    if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
    {
        if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
        {
            mz_zip_writer_end_internal(pZip, MZ_FALSE);
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }
        pZip->m_pState->m_mem_capacity = initial_allocation_size;
    }

    return MZ_TRUE;
}

mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
{
    return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0);
}

#ifndef MINIZ_NO_STDIO
static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
{
    mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
    mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);

    file_ofs += pZip->m_pState->m_file_archive_start_ofs;

    if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
    {
        mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
        return 0;
    }

    return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
}

mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
{
    return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0);
}

mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags)
{
    MZ_FILE *pFile;

    pZip->m_pWrite = mz_zip_file_write_func;
    pZip->m_pNeeds_keepalive = NULL;

    if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
        pZip->m_pRead = mz_zip_file_read_func;

    pZip->m_pIO_opaque = pZip;

    if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
        return MZ_FALSE;

    if (NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb")))
    {
        mz_zip_writer_end(pZip);
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
    }

    pZip->m_pState->m_pFile = pFile;
    pZip->m_zip_type = MZ_ZIP_TYPE_FILE;

    if (size_to_reserve_at_beginning)
    {
        mz_uint64 cur_ofs = 0;
        char buf[4096];

        MZ_CLEAR_OBJ(buf);

        do
        {
            size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
            if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
            {
                mz_zip_writer_end(pZip);
                return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
            }
            cur_ofs += n;
            size_to_reserve_at_beginning -= n;
        } while (size_to_reserve_at_beginning);
    }

    return MZ_TRUE;
}

mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags)
{
    pZip->m_pWrite = mz_zip_file_write_func;
    pZip->m_pNeeds_keepalive = NULL;

    if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
        pZip->m_pRead = mz_zip_file_read_func;

    pZip->m_pIO_opaque = pZip;

    if (!mz_zip_writer_init_v2(pZip, 0, flags))
        return MZ_FALSE;

    pZip->m_pState->m_pFile = pFile;
    pZip->m_pState->m_file_archive_start_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
    pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;

    return MZ_TRUE;
}
#endif /* #ifndef MINIZ_NO_STDIO */

mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
{
    mz_zip_internal_state *pState;

    if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (flags & MZ_ZIP_FLAG_WRITE_ZIP64)
    {
        /* We don't support converting a non-zip64 file to zip64 - this seems like more trouble than it's worth. (What about the existing 32-bit data descriptors that could follow the compressed data?) */
        if (!pZip->m_pState->m_zip64)
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
    }

    /* No sense in trying to write to an archive that's already at the support max size */
    if (pZip->m_pState->m_zip64)
    {
        if (pZip->m_total_files == MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }
    else
    {
        if (pZip->m_total_files == MZ_UINT16_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);

        if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
    }

    pState = pZip->m_pState;

    if (pState->m_pFile)
    {
#ifdef MINIZ_NO_STDIO
        (void)pFilename;
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
#else
        if (pZip->m_pIO_opaque != pZip)
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

        if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
        {
            if (!pFilename)
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

            /* Archive is being read from stdio and was originally opened only for reading. Try to reopen as writable. */
            if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
            {
                /* The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. */
                mz_zip_reader_end_internal(pZip, MZ_FALSE);
                return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
            }
        }

        pZip->m_pWrite = mz_zip_file_write_func;
        pZip->m_pNeeds_keepalive = NULL;
#endif /* #ifdef MINIZ_NO_STDIO */
    }
    else if (pState->m_pMem)
    {
        /* Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. */
        if (pZip->m_pIO_opaque != pZip)
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

        pState->m_mem_capacity = pState->m_mem_size;
        pZip->m_pWrite = mz_zip_heap_write_func;
        pZip->m_pNeeds_keepalive = NULL;
    }
    /* Archive is being read via a user provided read function - make sure the user has specified a write function too. */
    else if (!pZip->m_pWrite)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    /* Start writing new files at the archive's current central directory location. */
    /* TODO: We could add a flag that lets the user start writing immediately AFTER the existing central dir - this would be safer. */
    pZip->m_archive_size = pZip->m_central_directory_file_ofs;
    pZip->m_central_directory_file_ofs = 0;

    /* Clear the sorted central dir offsets, they aren't useful or maintained now. */
    /* Even though we're now in write mode, files can still be extracted and verified, but file locates will be slow. */
    /* TODO: We could easily maintain the sorted central directory offsets. */
    mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets);

    pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;

    return MZ_TRUE;
}

mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename)
{
    return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0);
}

/* TODO: pArchive_name is a terrible name here! */
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
{
    return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
}

typedef struct
{
    mz_zip_archive *m_pZip;
    mz_uint64 m_cur_archive_file_ofs;
    mz_uint64 m_comp_size;
} mz_zip_writer_add_state;

static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser)
{
    mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
    if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
        return MZ_FALSE;

    pState->m_cur_archive_file_ofs += len;
    pState->m_comp_size += len;
    return MZ_TRUE;
}

#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, mz_uint64 *pComp_size, mz_uint64 *pLocal_header_ofs)
{
    mz_uint8 *pDst = pBuf;
    mz_uint32 field_size = 0;

    MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
    MZ_WRITE_LE16(pDst + 2, 0);
    pDst += sizeof(mz_uint16) * 2;

    if (pUncomp_size)
    {
        MZ_WRITE_LE64(pDst, *pUncomp_size);
        pDst += sizeof(mz_uint64);
        field_size += sizeof(mz_uint64);
    }

    if (pComp_size)
    {
        MZ_WRITE_LE64(pDst, *pComp_size);
        pDst += sizeof(mz_uint64);
        field_size += sizeof(mz_uint64);
    }

    if (pLocal_header_ofs)
    {
        MZ_WRITE_LE64(pDst, *pLocal_header_ofs);
        pDst += sizeof(mz_uint64);
        field_size += sizeof(mz_uint64);
    }

    MZ_WRITE_LE16(pBuf + 2, field_size);

    return (mz_uint32)(pDst - pBuf);
}

static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
{
    (void)pZip;
    memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
    MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
    MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
    MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX));
    MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX));
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
    MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
    return MZ_TRUE;
}

static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst,
                                                       mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size,
                                                       mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
                                                       mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
                                                       mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
{
    (void)pZip;
    memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
    MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
    MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
    MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX));
    MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX));
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
    MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
    MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
    MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_MIN(local_header_ofs, MZ_UINT32_MAX));
    return MZ_TRUE;
}

static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size,
                                                const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size,
                                                mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
                                                mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
                                                mz_uint64 local_header_ofs, mz_uint32 ext_attributes,
                                                const char *user_extra_data, mz_uint user_extra_data_len)
{
    mz_zip_internal_state *pState = pZip->m_pState;
    mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
    size_t orig_central_dir_size = pState->m_central_dir.m_size;
    mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];

    if (!pZip->m_pState->m_zip64)
    {
        if (local_header_ofs > 0xFFFFFFFF)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
    }

    /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
    if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);

    if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size + user_extra_data_len, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
        return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

    if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
        (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
        (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
        (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) ||
        (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
        (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
    {
        /* Try to resize the central directory array back into its original state. */
        mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
    }

    return MZ_TRUE;
}

static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
{
    /* Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. */
    if (*pArchive_name == '/')
        return MZ_FALSE;

    while (*pArchive_name)
    {
        if ((*pArchive_name == '\\') || (*pArchive_name == ':'))
            return MZ_FALSE;

        pArchive_name++;
    }

    return MZ_TRUE;
}

static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
{
    mz_uint32 n;
    if (!pZip->m_file_offset_alignment)
        return 0;
    n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
    return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1));
}

static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
{
    char buf[4096];
    memset(buf, 0, MZ_MIN(sizeof(buf), n));
    while (n)
    {
        mz_uint32 s = MZ_MIN(sizeof(buf), n);
        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_file_ofs += s;
        n -= s;
    }
    return MZ_TRUE;
}

mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
                                 mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
{
    return mz_zip_writer_add_mem_ex_v2(pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0);
}

mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size,
                                    mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified,
                                    const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
{
    mz_uint16 method = 0, dos_time = 0, dos_date = 0;
    mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
    mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
    size_t archive_name_size;
    mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
    tdefl_compressor *pComp = NULL;
    mz_bool store_data_uncompressed;
    mz_zip_internal_state *pState;
    mz_uint8 *pExtra_data = NULL;
    mz_uint32 extra_size = 0;
    mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
    mz_uint16 bit_flags = 0;

    if ((int)level_and_flags < 0)
        level_and_flags = MZ_DEFAULT_LEVEL;

    if (uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
        bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;

    if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
        bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;

    level = level_and_flags & 0xF;
    store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));

    if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    if (pState->m_zip64)
    {
        if (pZip->m_total_files == MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }
    else
    {
        if (pZip->m_total_files == MZ_UINT16_MAX)
        {
            pState->m_zip64 = MZ_TRUE;
            /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
        }
        if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
        {
            pState->m_zip64 = MZ_TRUE;
            /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
        }
    }

    if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!mz_zip_writer_validate_archive_name(pArchive_name))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);

#ifndef MINIZ_NO_TIME
    if (last_modified != NULL)
    {
        mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date);
    }
    else
    {
        MZ_TIME_T cur_time;
        time(&cur_time);
        mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
    }
#endif /* #ifndef MINIZ_NO_TIME */

	if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
	{
		uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
		uncomp_size = buf_size;
		if (uncomp_size <= 3)
		{
			level = 0;
			store_data_uncompressed = MZ_TRUE;
		}
	}

    archive_name_size = strlen(pArchive_name);
    if (archive_name_size > MZ_UINT16_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);

    num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);

    /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
    if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);

    if (!pState->m_zip64)
    {
        /* Bail early if the archive would obviously become too large */
        if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size
			+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
			pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len
			+ MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
        {
            pState->m_zip64 = MZ_TRUE;
            /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
        }
    }

    if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
    {
        /* Set DOS Subdirectory attribute bit. */
        ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;

        /* Subdirectories cannot contain data. */
        if ((buf_size) || (uncomp_size))
            return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
    }

    /* Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) */
    if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    if ((!store_data_uncompressed) && (buf_size))
    {
        if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
    }

    if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
    {
        pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
        return MZ_FALSE;
    }

    local_dir_header_ofs += num_alignment_padding_bytes;
    if (pZip->m_file_offset_alignment)
    {
        MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
    }
    cur_archive_file_ofs += num_alignment_padding_bytes;

    MZ_CLEAR_OBJ(local_dir_header);

    if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
    {
        method = MZ_DEFLATED;
    }

    if (pState->m_zip64)
    {
        if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
        {
            pExtra_data = extra_data;
            extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
                                                               (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
        }

        if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date))
            return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_archive_file_ofs += sizeof(local_dir_header);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }
        cur_archive_file_ofs += archive_name_size;

        if (pExtra_data != NULL)
        {
            if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
                return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

            cur_archive_file_ofs += extra_size;
        }
    }
    else
    {
        if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
        if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date))
            return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_archive_file_ofs += sizeof(local_dir_header);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }
        cur_archive_file_ofs += archive_name_size;
    }

	if (user_extra_data_len > 0)
	{
		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

		cur_archive_file_ofs += user_extra_data_len;
	}

    if (store_data_uncompressed)
    {
        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }

        cur_archive_file_ofs += buf_size;
        comp_size = buf_size;
    }
    else if (buf_size)
    {
        mz_zip_writer_add_state state;

        state.m_pZip = pZip;
        state.m_cur_archive_file_ofs = cur_archive_file_ofs;
        state.m_comp_size = 0;

        if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) ||
            (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
            return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
        }

        comp_size = state.m_comp_size;
        cur_archive_file_ofs = state.m_cur_archive_file_ofs;
    }

    pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
    pComp = NULL;

    if (uncomp_size)
    {
        mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
        mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;

        MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR);

        MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
        MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
        if (pExtra_data == NULL)
        {
            if (comp_size > MZ_UINT32_MAX)
                return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);

            MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
            MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
        }
        else
        {
            MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
            MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
            local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
        }

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
            return MZ_FALSE;

        cur_archive_file_ofs += local_dir_footer_size;
    }

    if (pExtra_data != NULL)
    {
        extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
                                                           (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
    }

    if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment,
                                          comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
                                          user_extra_data_central, user_extra_data_central_len))
        return MZ_FALSE;

    pZip->m_total_files++;
    pZip->m_archive_size = cur_archive_file_ofs;

    return MZ_TRUE;
}

#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
                                const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
{
    mz_uint16 gen_flags = MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
    mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
    mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
    mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = size_to_add, comp_size = 0;
    size_t archive_name_size;
    mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
    mz_uint8 *pExtra_data = NULL;
    mz_uint32 extra_size = 0;
    mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
    mz_zip_internal_state *pState;

    if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
        gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;

    if ((int)level_and_flags < 0)
        level_and_flags = MZ_DEFAULT_LEVEL;
    level = level_and_flags & 0xF;

    /* Sanity checks */
    if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    if ((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX))
    {
        /* Source file is too large for non-zip64 */
        /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
        pState->m_zip64 = MZ_TRUE;
    }

    /* We could support this, but why? */
    if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!mz_zip_writer_validate_archive_name(pArchive_name))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);

    if (pState->m_zip64)
    {
        if (pZip->m_total_files == MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }
    else
    {
        if (pZip->m_total_files == MZ_UINT16_MAX)
        {
            pState->m_zip64 = MZ_TRUE;
            /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
        }
    }

    archive_name_size = strlen(pArchive_name);
    if (archive_name_size > MZ_UINT16_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);

    num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);

    /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
    if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);

    if (!pState->m_zip64)
    {
        /* Bail early if the archive would obviously become too large */
        if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
			+ archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024
			+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
        {
            pState->m_zip64 = MZ_TRUE;
            /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
        }
    }

#ifndef MINIZ_NO_TIME
    if (pFile_time)
    {
        mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
    }
#endif

    if (uncomp_size <= 3)
        level = 0;

    if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
    {
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
    }

    cur_archive_file_ofs += num_alignment_padding_bytes;
    local_dir_header_ofs = cur_archive_file_ofs;

    if (pZip->m_file_offset_alignment)
    {
        MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
    }

    if (uncomp_size && level)
    {
        method = MZ_DEFLATED;
    }

    MZ_CLEAR_OBJ(local_dir_header);
    if (pState->m_zip64)
    {
        if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
        {
            pExtra_data = extra_data;
            extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
                                                               (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
        }

        if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date))
            return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_archive_file_ofs += sizeof(local_dir_header);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
        {
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }

        cur_archive_file_ofs += archive_name_size;

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_archive_file_ofs += extra_size;
    }
    else
    {
        if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
        if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date))
            return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_archive_file_ofs += sizeof(local_dir_header);

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
        {
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }

        cur_archive_file_ofs += archive_name_size;
    }

    if (user_extra_data_len > 0)
    {
        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        cur_archive_file_ofs += user_extra_data_len;
    }

    if (uncomp_size)
    {
        mz_uint64 uncomp_remaining = uncomp_size;
        void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
        if (!pRead_buf)
        {
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        if (!level)
        {
            while (uncomp_remaining)
            {
                mz_uint n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
                if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
                {
                    pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
                    return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
                }
                uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
                uncomp_remaining -= n;
                cur_archive_file_ofs += n;
            }
            comp_size = uncomp_size;
        }
        else
        {
            mz_bool result = MZ_FALSE;
            mz_zip_writer_add_state state;
            tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
            if (!pComp)
            {
                pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
                return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
            }

            state.m_pZip = pZip;
            state.m_cur_archive_file_ofs = cur_archive_file_ofs;
            state.m_comp_size = 0;

            if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY)
            {
                pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
                pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
                return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
            }

            for (;;)
            {
                size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
                tdefl_status status;
                tdefl_flush flush = TDEFL_NO_FLUSH;

                if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
                    break;
                }

                uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
                uncomp_remaining -= in_buf_size;

                if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
                    flush = TDEFL_FULL_FLUSH;

                status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? flush : TDEFL_FINISH);
                if (status == TDEFL_STATUS_DONE)
                {
                    result = MZ_TRUE;
                    break;
                }
                else if (status != TDEFL_STATUS_OKAY)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
                    break;
                }
            }

            pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);

            if (!result)
            {
                pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
                return MZ_FALSE;
            }

            comp_size = state.m_comp_size;
            cur_archive_file_ofs = state.m_cur_archive_file_ofs;
        }

        pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
    }

    {
        mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
        mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;

        MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
        MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
        if (pExtra_data == NULL)
        {
            if (comp_size > MZ_UINT32_MAX)
                return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);

            MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
            MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
        }
        else
        {
            MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
            MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
            local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
        }

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
            return MZ_FALSE;

        cur_archive_file_ofs += local_dir_footer_size;
    }

    if (pExtra_data != NULL)
    {
        extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
                                                           (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
    }

    if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, comment_size,
                                          uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
                                          user_extra_data_central, user_extra_data_central_len))
        return MZ_FALSE;

    pZip->m_total_files++;
    pZip->m_archive_size = cur_archive_file_ofs;

    return MZ_TRUE;
}

mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
{
    MZ_FILE *pSrc_file = NULL;
    mz_uint64 uncomp_size = 0;
    MZ_TIME_T file_modified_time;
    MZ_TIME_T *pFile_time = NULL;
    mz_bool status;

    memset(&file_modified_time, 0, sizeof(file_modified_time));

#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
    pFile_time = &file_modified_time;
    if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED);
#endif

    pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
    if (!pSrc_file)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);

    MZ_FSEEK64(pSrc_file, 0, SEEK_END);
    uncomp_size = MZ_FTELL64(pSrc_file);
    MZ_FSEEK64(pSrc_file, 0, SEEK_SET);

    status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0);

    MZ_FCLOSE(pSrc_file);

    return status;
}
#endif /* #ifndef MINIZ_NO_STDIO */

static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
{
    /* + 64 should be enough for any new zip64 data */
    if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE);

    if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start))
    {
        mz_uint8 new_ext_block[64];
        mz_uint8 *pDst = new_ext_block;
        mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
        mz_write_le16(pDst + sizeof(mz_uint16), 0);
        pDst += sizeof(mz_uint16) * 2;

        if (pUncomp_size)
        {
            mz_write_le64(pDst, *pUncomp_size);
            pDst += sizeof(mz_uint64);
        }

        if (pComp_size)
        {
            mz_write_le64(pDst, *pComp_size);
            pDst += sizeof(mz_uint64);
        }

        if (pLocal_header_ofs)
        {
            mz_write_le64(pDst, *pLocal_header_ofs);
            pDst += sizeof(mz_uint64);
        }

        if (pDisk_start)
        {
            mz_write_le32(pDst, *pDisk_start);
            pDst += sizeof(mz_uint32);
        }

        mz_write_le16(new_ext_block + sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) - sizeof(mz_uint16) * 2));

        if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block))
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
    }

    if ((pExt) && (ext_len))
    {
        mz_uint32 extra_size_remaining = ext_len;
        const mz_uint8 *pExtra_data = pExt;

        do
        {
            mz_uint32 field_id, field_data_size, field_total_size;

            if (extra_size_remaining < (sizeof(mz_uint16) * 2))
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            field_id = MZ_READ_LE16(pExtra_data);
            field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
            field_total_size = field_data_size + sizeof(mz_uint16) * 2;

            if (field_total_size > extra_size_remaining)
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
            {
                if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size))
                    return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
            }

            pExtra_data += field_total_size;
            extra_size_remaining -= field_total_size;
        } while (extra_size_remaining);
    }

    return MZ_TRUE;
}

/* TODO: This func is now pretty freakin complex due to zip64, split it up? */
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index)
{
    mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size;
    mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs;
    mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
    mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
    size_t orig_central_dir_size;
    mz_zip_internal_state *pState;
    void *pBuf;
    const mz_uint8 *pSrc_central_header;
    mz_zip_archive_file_stat src_file_stat;
    mz_uint32 src_filename_len, src_comment_len, src_ext_len;
    mz_uint32 local_header_filename_size, local_header_extra_len;
    mz_uint64 local_header_comp_size, local_header_uncomp_size;
    mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;

    /* Sanity checks */
    if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    /* Don't support copying files from zip64 archives to non-zip64, even though in some cases this is possible */
    if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    /* Get pointer to the source central dir header and crack it */
    if (NULL == (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index)))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    src_filename_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS);
    src_comment_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
    src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS);
    src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len;

    /* TODO: We don't support central dir's >= MZ_UINT32_MAX bytes right now (+32 fudge factor in case we need to add more extra data) */
    if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);

    num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);

    if (!pState->m_zip64)
    {
        if (pZip->m_total_files == MZ_UINT16_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }
    else
    {
        /* TODO: Our zip64 support still has some 32-bit limits that may not be worth fixing. */
        if (pZip->m_total_files == MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }

    if (!mz_zip_file_stat_internal(pSource_zip, src_file_index, pSrc_central_header, &src_file_stat, NULL))
        return MZ_FALSE;

    cur_src_file_ofs = src_file_stat.m_local_header_ofs;
    cur_dst_file_ofs = pZip->m_archive_size;

    /* Read the source archive's local dir header */
    if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;

    /* Compute the total size we need to copy (filename+extra data+compressed data) */
    local_header_filename_size = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
    local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
    local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
    src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size;

    /* Try to find a zip64 extended information field */
    if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
    {
        mz_zip_array file_data_array;
        const mz_uint8 *pExtra_data;
        mz_uint32 extra_size_remaining = local_header_extra_len;

        mz_zip_array_init(&file_data_array, 1);
        if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, MZ_FALSE))
        {
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, src_file_stat.m_local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_size, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
        {
            mz_zip_array_clear(pZip, &file_data_array);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
        }

        pExtra_data = (const mz_uint8 *)file_data_array.m_p;

        do
        {
            mz_uint32 field_id, field_data_size, field_total_size;

            if (extra_size_remaining < (sizeof(mz_uint16) * 2))
            {
                mz_zip_array_clear(pZip, &file_data_array);
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
            }

            field_id = MZ_READ_LE16(pExtra_data);
            field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
            field_total_size = field_data_size + sizeof(mz_uint16) * 2;

            if (field_total_size > extra_size_remaining)
            {
                mz_zip_array_clear(pZip, &file_data_array);
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
            }

            if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
            {
                const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);

                if (field_data_size < sizeof(mz_uint64) * 2)
                {
                    mz_zip_array_clear(pZip, &file_data_array);
                    return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
                }

                local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
                local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); /* may be 0 if there's a descriptor */

                found_zip64_ext_data_in_ldir = MZ_TRUE;
                break;
            }

            pExtra_data += field_total_size;
            extra_size_remaining -= field_total_size;
        } while (extra_size_remaining);

        mz_zip_array_clear(pZip, &file_data_array);
    }

    if (!pState->m_zip64)
    {
        /* Try to detect if the new archive will most likely wind up too big and bail early (+(sizeof(mz_uint32) * 4) is for the optional descriptor which could be present, +64 is a fudge factor). */
        /* We also check when the archive is finalized so this doesn't need to be perfect. */
        mz_uint64 approx_new_archive_size = cur_dst_file_ofs + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + (sizeof(mz_uint32) * 4) +
                                            pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64;

        if (approx_new_archive_size >= MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
    }

    /* Write dest archive padding */
    if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
        return MZ_FALSE;

    cur_dst_file_ofs += num_alignment_padding_bytes;

    local_dir_header_ofs = cur_dst_file_ofs;
    if (pZip->m_file_offset_alignment)
    {
        MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
    }

    /* The original zip's local header+ext block doesn't change, even with zip64, so we can just copy it over to the dest zip */
    if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

    cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;

    /* Copy over the source archive bytes to the dest archive, also ensure we have enough buf space to handle optional data descriptor */
    if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining)))))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    while (src_archive_bytes_remaining)
    {
        n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining);
        if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
        }
        cur_src_file_ofs += n;

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }
        cur_dst_file_ofs += n;

        src_archive_bytes_remaining -= n;
    }

    /* Now deal with the optional data descriptor */
    bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
    if (bit_flags & 8)
    {
        /* Copy data descriptor */
        if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir))
        {
            /* src is zip64, dest must be zip64 */

            /* name			uint32_t's */
            /* id				1 (optional in zip64?) */
            /* crc			1 */
            /* comp_size	2 */
            /* uncomp_size 2 */
            if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6))
            {
                pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
                return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            }

            n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5);
        }
        else
        {
            /* src is NOT zip64 */
            mz_bool has_id;

            if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
            {
                pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
                return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            }

            has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID);

            if (pZip->m_pState->m_zip64)
            {
                /* dest is zip64, so upgrade the data descriptor */
                const mz_uint32 *pSrc_descriptor = (const mz_uint32 *)((const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0));
                const mz_uint32 src_crc32 = pSrc_descriptor[0];
                const mz_uint64 src_comp_size = pSrc_descriptor[1];
                const mz_uint64 src_uncomp_size = pSrc_descriptor[2];

                mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID);
                mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32);
                mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 2, src_comp_size);
                mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 4, src_uncomp_size);

                n = sizeof(mz_uint32) * 6;
            }
            else
            {
                /* dest is NOT zip64, just copy it as-is */
                n = sizeof(mz_uint32) * (has_id ? 4 : 3);
            }
        }

        if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
        {
            pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
        }

        cur_src_file_ofs += n;
        cur_dst_file_ofs += n;
    }
    pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);

    /* Finally, add the new central dir header */
    orig_central_dir_size = pState->m_central_dir.m_size;

    memcpy(new_central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);

    if (pState->m_zip64)
    {
        /* This is the painful part: We need to write a new central dir header + ext block with updated zip64 fields, and ensure the old fields (if any) are not included. */
        const mz_uint8 *pSrc_ext = pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len;
        mz_zip_array new_ext_block;

        mz_zip_array_init(&new_ext_block, sizeof(mz_uint8));

        MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_UINT32_MAX);
        MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_UINT32_MAX);
        MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_UINT32_MAX);

        if (!mz_zip_writer_update_zip64_extension_block(&new_ext_block, pZip, pSrc_ext, src_ext_len, &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, &local_dir_header_ofs, NULL))
        {
            mz_zip_array_clear(pZip, &new_ext_block);
            return MZ_FALSE;
        }

        MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, new_ext_block.m_size);

        if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
        {
            mz_zip_array_clear(pZip, &new_ext_block);
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_filename_len))
        {
            mz_zip_array_clear(pZip, &new_ext_block);
            mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size))
        {
            mz_zip_array_clear(pZip, &new_ext_block);
            mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len + src_ext_len, src_comment_len))
        {
            mz_zip_array_clear(pZip, &new_ext_block);
            mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }

        mz_zip_array_clear(pZip, &new_ext_block);
    }
    else
    {
        /* sanity checks */
        if (cur_dst_file_ofs > MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);

        if (local_dir_header_ofs >= MZ_UINT32_MAX)
            return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);

        MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);

        if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

        if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_central_dir_following_data_size))
        {
            mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
            return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
        }
    }

    /* This shouldn't trigger unless we screwed up during the initial sanity checks */
    if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
    {
        /* TODO: Support central dirs >= 32-bits in size */
        mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
    }

    n = (mz_uint32)orig_central_dir_size;
    if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
    {
        mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
    }

    pZip->m_total_files++;
    pZip->m_archive_size = cur_dst_file_ofs;

    return MZ_TRUE;
}

mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
{
    mz_zip_internal_state *pState;
    mz_uint64 central_dir_ofs, central_dir_size;
    mz_uint8 hdr[256];

    if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    if (pState->m_zip64)
    {
        if ((pZip->m_total_files > MZ_UINT32_MAX) || (pState->m_central_dir.m_size >= MZ_UINT32_MAX))
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }
    else
    {
        if ((pZip->m_total_files > MZ_UINT16_MAX) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX))
            return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
    }

    central_dir_ofs = 0;
    central_dir_size = 0;
    if (pZip->m_total_files)
    {
        /* Write central directory */
        central_dir_ofs = pZip->m_archive_size;
        central_dir_size = pState->m_central_dir.m_size;
        pZip->m_central_directory_file_ofs = central_dir_ofs;
        if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        pZip->m_archive_size += central_dir_size;
    }

    if (pState->m_zip64)
    {
        /* Write zip64 end of central directory header */
        mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;

        MZ_CLEAR_OBJ(hdr);
        MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG);
        MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - sizeof(mz_uint64));
        MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */
        MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D);
        MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files);
        MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
        MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size);
        MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs);
        if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;

        /* Write zip64 end of central directory locator */
        MZ_CLEAR_OBJ(hdr);
        MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG);
        MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr);
        MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1);
        if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
            return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

        pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
    }

    /* Write end of central directory record */
    MZ_CLEAR_OBJ(hdr);
    MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
    MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
    MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
    MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_size));
    MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_ofs));

    if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);

#ifndef MINIZ_NO_STDIO
    if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
#endif /* #ifndef MINIZ_NO_STDIO */

    pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE;

    pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
    return MZ_TRUE;
}

mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize)
{
    if ((!ppBuf) || (!pSize))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    *ppBuf = NULL;
    *pSize = 0;

    if ((!pZip) || (!pZip->m_pState))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (pZip->m_pWrite != mz_zip_heap_write_func)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (!mz_zip_writer_finalize_archive(pZip))
        return MZ_FALSE;

    *ppBuf = pZip->m_pState->m_pMem;
    *pSize = pZip->m_pState->m_mem_size;
    pZip->m_pState->m_pMem = NULL;
    pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;

    return MZ_TRUE;
}

mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
{
    return mz_zip_writer_end_internal(pZip, MZ_TRUE);
}

#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
{
    return mz_zip_add_mem_to_archive_file_in_place_v2(pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, NULL);
}

mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr)
{
    mz_bool status, created_new_archive = MZ_FALSE;
    mz_zip_archive zip_archive;
    struct MZ_FILE_STAT_STRUCT file_stat;
    mz_zip_error actual_err = MZ_ZIP_NO_ERROR;

    mz_zip_zero_struct(&zip_archive);
    if ((int)level_and_flags < 0)
        level_and_flags = MZ_DEFAULT_LEVEL;

    if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
    {
        if (pErr)
            *pErr = MZ_ZIP_INVALID_PARAMETER;
        return MZ_FALSE;
    }

    if (!mz_zip_writer_validate_archive_name(pArchive_name))
    {
        if (pErr)
            *pErr = MZ_ZIP_INVALID_FILENAME;
        return MZ_FALSE;
    }

    /* Important: The regular non-64 bit version of stat() can fail here if the file is very large, which could cause the archive to be overwritten. */
    /* So be sure to compile with _LARGEFILE64_SOURCE 1 */
    if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
    {
        /* Create a new archive. */
        if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags))
        {
            if (pErr)
                *pErr = zip_archive.m_last_error;
            return MZ_FALSE;
        }

        created_new_archive = MZ_TRUE;
    }
    else
    {
        /* Append to an existing archive. */
        if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
        {
            if (pErr)
                *pErr = zip_archive.m_last_error;
            return MZ_FALSE;
        }

        if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags))
        {
            if (pErr)
                *pErr = zip_archive.m_last_error;

            mz_zip_reader_end_internal(&zip_archive, MZ_FALSE);

            return MZ_FALSE;
        }
    }

    status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
    actual_err = zip_archive.m_last_error;

    /* Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) */
    if (!mz_zip_writer_finalize_archive(&zip_archive))
    {
        if (!actual_err)
            actual_err = zip_archive.m_last_error;

        status = MZ_FALSE;
    }

    if (!mz_zip_writer_end_internal(&zip_archive, status))
    {
        if (!actual_err)
            actual_err = zip_archive.m_last_error;

        status = MZ_FALSE;
    }

    if ((!status) && (created_new_archive))
    {
        /* It's a new archive and something went wrong, so just delete it. */
        int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
        (void)ignoredStatus;
    }

    if (pErr)
        *pErr = actual_err;

    return status;
}

void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr)
{
    mz_uint32 file_index;
    mz_zip_archive zip_archive;
    void *p = NULL;

    if (pSize)
        *pSize = 0;

    if ((!pZip_filename) || (!pArchive_name))
    {
        if (pErr)
            *pErr = MZ_ZIP_INVALID_PARAMETER;

        return NULL;
    }

    mz_zip_zero_struct(&zip_archive);
    if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
    {
        if (pErr)
            *pErr = zip_archive.m_last_error;

        return NULL;
    }

    if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, &file_index))
    {
        p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
    }

    mz_zip_reader_end_internal(&zip_archive, p != NULL);

    if (pErr)
        *pErr = zip_archive.m_last_error;

    return p;
}

void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
{
    return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL);
}

#endif /* #ifndef MINIZ_NO_STDIO */

#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */

/* ------------------- Misc utils */

mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip)
{
    return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
}

mz_zip_type mz_zip_get_type(mz_zip_archive *pZip)
{
    return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
}

mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num)
{
    mz_zip_error prev_err;

    if (!pZip)
        return MZ_ZIP_INVALID_PARAMETER;

    prev_err = pZip->m_last_error;

    pZip->m_last_error = err_num;
    return prev_err;
}

mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip)
{
    if (!pZip)
        return MZ_ZIP_INVALID_PARAMETER;

    return pZip->m_last_error;
}

mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip)
{
    return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR);
}

mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip)
{
    mz_zip_error prev_err;

    if (!pZip)
        return MZ_ZIP_INVALID_PARAMETER;

    prev_err = pZip->m_last_error;

    pZip->m_last_error = MZ_ZIP_NO_ERROR;
    return prev_err;
}

const char *mz_zip_get_error_string(mz_zip_error mz_err)
{
    switch (mz_err)
    {
        case MZ_ZIP_NO_ERROR:
            return "no error";
        case MZ_ZIP_UNDEFINED_ERROR:
            return "undefined error";
        case MZ_ZIP_TOO_MANY_FILES:
            return "too many files";
        case MZ_ZIP_FILE_TOO_LARGE:
            return "file too large";
        case MZ_ZIP_UNSUPPORTED_METHOD:
            return "unsupported method";
        case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
            return "unsupported encryption";
        case MZ_ZIP_UNSUPPORTED_FEATURE:
            return "unsupported feature";
        case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
            return "failed finding central directory";
        case MZ_ZIP_NOT_AN_ARCHIVE:
            return "not a ZIP archive";
        case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
            return "invalid header or archive is corrupted";
        case MZ_ZIP_UNSUPPORTED_MULTIDISK:
            return "unsupported multidisk archive";
        case MZ_ZIP_DECOMPRESSION_FAILED:
            return "decompression failed or archive is corrupted";
        case MZ_ZIP_COMPRESSION_FAILED:
            return "compression failed";
        case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
            return "unexpected decompressed size";
        case MZ_ZIP_CRC_CHECK_FAILED:
            return "CRC-32 check failed";
        case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
            return "unsupported central directory size";
        case MZ_ZIP_ALLOC_FAILED:
            return "allocation failed";
        case MZ_ZIP_FILE_OPEN_FAILED:
            return "file open failed";
        case MZ_ZIP_FILE_CREATE_FAILED:
            return "file create failed";
        case MZ_ZIP_FILE_WRITE_FAILED:
            return "file write failed";
        case MZ_ZIP_FILE_READ_FAILED:
            return "file read failed";
        case MZ_ZIP_FILE_CLOSE_FAILED:
            return "file close failed";
        case MZ_ZIP_FILE_SEEK_FAILED:
            return "file seek failed";
        case MZ_ZIP_FILE_STAT_FAILED:
            return "file stat failed";
        case MZ_ZIP_INVALID_PARAMETER:
            return "invalid parameter";
        case MZ_ZIP_INVALID_FILENAME:
            return "invalid filename";
        case MZ_ZIP_BUF_TOO_SMALL:
            return "buffer too small";
        case MZ_ZIP_INTERNAL_ERROR:
            return "internal error";
        case MZ_ZIP_FILE_NOT_FOUND:
            return "file not found";
        case MZ_ZIP_ARCHIVE_TOO_LARGE:
            return "archive is too large";
        case MZ_ZIP_VALIDATION_FAILED:
            return "validation failed";
        case MZ_ZIP_WRITE_CALLBACK_FAILED:
            return "write calledback failed";
        default:
            break;
    }

    return "unknown error";
}

/* Note: Just because the archive is not zip64 doesn't necessarily mean it doesn't have Zip64 extended information extra field, argh. */
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip)
{
    if ((!pZip) || (!pZip->m_pState))
        return MZ_FALSE;

    return pZip->m_pState->m_zip64;
}

size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip)
{
    if ((!pZip) || (!pZip->m_pState))
        return 0;

    return pZip->m_pState->m_central_dir.m_size;
}

mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
{
    return pZip ? pZip->m_total_files : 0;
}

mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip)
{
    if (!pZip)
        return 0;
    return pZip->m_archive_size;
}

mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip)
{
    if ((!pZip) || (!pZip->m_pState))
        return 0;
    return pZip->m_pState->m_file_archive_start_ofs;
}

MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip)
{
    if ((!pZip) || (!pZip->m_pState))
        return 0;
    return pZip->m_pState->m_pFile;
}

size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n)
{
    if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
}

mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
{
    mz_uint n;
    const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
    if (!p)
    {
        if (filename_buf_size)
            pFilename[0] = '\0';
        mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
        return 0;
    }
    n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
    if (filename_buf_size)
    {
        n = MZ_MIN(n, filename_buf_size - 1);
        memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
        pFilename[n] = '\0';
    }
    return n + 1;
}

mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
{
    return mz_zip_file_stat_internal(pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL);
}

mz_bool mz_zip_end(mz_zip_archive *pZip)
{
    if (!pZip)
        return MZ_FALSE;

    if (pZip->m_zip_mode == MZ_ZIP_MODE_READING)
        return mz_zip_reader_end(pZip);
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
    else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))
        return mz_zip_writer_end(pZip);
#endif

    return MZ_FALSE;
}

#ifdef __cplusplus
}
#endif

#endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/
// Copyright 2008 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Tested by search_test.cc, exhaustive_test.cc, tester.cc

// Prog::SearchBitState is a regular expression search with submatch
// tracking for small regular expressions and texts.  Similarly to
// testing/backtrack.cc, it allocates a bitmap with (count of
// lists) * (length of prog) bits to make sure it never explores the
// same (instruction list, character position) multiple times.  This
// limits the search to run in time linear in the length of the text.
//
// Unlike testing/backtrack.cc, SearchBitState is not recursive
// on the text.
//
// SearchBitState is a fast replacement for the NFA code on small
// regexps and texts when SearchOnePass cannot be used.

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <limits>
#include <utility>

// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_LOGGING_H_
#define UTIL_LOGGING_H_

// Simplified version of Google's logging.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <ostream>
#include <sstream>

// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_UTIL_H_
#define UTIL_UTIL_H_

#define arraysize(array) (int)(sizeof(array)/sizeof((array)[0]))

#ifndef ATTRIBUTE_NORETURN
#if defined(__GNUC__)
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define ATTRIBUTE_NORETURN __declspec(noreturn)
#else
#define ATTRIBUTE_NORETURN
#endif
#endif

#ifndef FALLTHROUGH_INTENDED
#if defined(__clang__)
#define FALLTHROUGH_INTENDED [[clang::fallthrough]]
#elif defined(__GNUC__) && __GNUC__ >= 7
#define FALLTHROUGH_INTENDED [[gnu::fallthrough]]
#else
#define FALLTHROUGH_INTENDED do {} while (0)
#endif
#endif

#ifndef NO_THREAD_SAFETY_ANALYSIS
#define NO_THREAD_SAFETY_ANALYSIS
#endif

#endif  // UTIL_UTIL_H_


// Debug-only checking.
#define DCHECK(condition) assert(condition)
#define DCHECK_EQ(val1, val2) assert((val1) == (val2))
#define DCHECK_NE(val1, val2) assert((val1) != (val2))
#define DCHECK_LE(val1, val2) assert((val1) <= (val2))
#define DCHECK_LT(val1, val2) assert((val1) < (val2))
#define DCHECK_GE(val1, val2) assert((val1) >= (val2))
#define DCHECK_GT(val1, val2) assert((val1) > (val2))

// Always-on checking
#define CHECK(x)	if(x){}else LogMessageFatal(__FILE__, __LINE__).stream() << "Check failed: " #x
#define CHECK_LT(x, y)	CHECK((x) < (y))
#define CHECK_GT(x, y)	CHECK((x) > (y))
#define CHECK_LE(x, y)	CHECK((x) <= (y))
#define CHECK_GE(x, y)	CHECK((x) >= (y))
#define CHECK_EQ(x, y)	CHECK((x) == (y))
#define CHECK_NE(x, y)	CHECK((x) != (y))

#define LOG_INFO LogMessage(__FILE__, __LINE__)
#define LOG_WARNING LogMessage(__FILE__, __LINE__)
#define LOG_ERROR LogMessage(__FILE__, __LINE__)
#define LOG_FATAL LogMessageFatal(__FILE__, __LINE__)
#define LOG_QFATAL LOG_FATAL

// It seems that one of the Windows header files defines ERROR as 0.
#ifdef _WIN32
#define LOG_0 LOG_INFO
#endif

#ifdef NDEBUG
#define LOG_DFATAL LOG_ERROR
#else
#define LOG_DFATAL LOG_FATAL
#endif

#define LOG(severity) LOG_ ## severity.stream()

#define VLOG(x) if((x)>0){}else LOG_INFO.stream()

class LogMessage {
 public:
  LogMessage(const char* file, int line)
      : flushed_(false) {
    stream() << file << ":" << line << ": ";
  }
  void Flush() {
    stream() << "\n";
    std::string s = str_.str();
    size_t n = s.size();
    if (fwrite(s.data(), 1, n, stderr) < n) {}  // shut up gcc
    flushed_ = true;
  }
  ~LogMessage() {
    if (!flushed_) {
      Flush();
    }
  }
  std::ostream& stream() { return str_; }

 private:
  bool flushed_;
  std::ostringstream str_;

  LogMessage(const LogMessage&) = delete;
  LogMessage& operator=(const LogMessage&) = delete;
};

// Silence "destructor never returns" warning for ~LogMessageFatal().
// Since this is a header file, push and then pop to limit the scope.
#ifdef _MSC_VER
//#pragma warning(push)
//#pragma warning(disable: 4722)
#endif

class LogMessageFatal : public LogMessage {
 public:
  LogMessageFatal(const char* file, int line)
      : LogMessage(file, line) {}
  ATTRIBUTE_NORETURN ~LogMessageFatal() {
    Flush();
    abort();
  }
 private:
  LogMessageFatal(const LogMessageFatal&) = delete;
  LogMessageFatal& operator=(const LogMessageFatal&) = delete;
};

#ifdef _MSC_VER
//#pragma warning(pop)
#endif

#endif  // UTIL_LOGGING_H_

// Copyright 2018 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_POD_ARRAY_H_
#define UTIL_POD_ARRAY_H_

#include <memory>
#include <type_traits>

namespace re2 {

template <typename T>
class PODArray {
 public:
  static_assert(std::is_pod<T>::value,
                "T must be POD");

  PODArray()
      : ptr_() {}
  explicit PODArray(int len)
      : ptr_(std::allocator<T>().allocate(len), Deleter(len)) {}

  T* data() const {
    return ptr_.get();
  }

  int size() const {
    return ptr_.get_deleter().len_;
  }

  T& operator[](int pos) const {
    return ptr_[pos];
  }

 private:
  struct Deleter {
    Deleter()
        : len_(0) {}
    explicit Deleter(int len)
        : len_(len) {}

    void operator()(T* ptr) const {
      std::allocator<T>().deallocate(ptr, len_);
    }

    int len_;
  };

  std::unique_ptr<T[], Deleter> ptr_;
};

}  // namespace re2

#endif  // UTIL_POD_ARRAY_H_

// Copyright 2007 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_PROG_H_
#define RE2_PROG_H_

// Compiled representation of regular expressions.
// See regexp.h for the Regexp class, which represents a regular
// expression symbolically.

#include <stdint.h>
#include <functional>
#include <mutex>
#include <string>
#include <vector>
#include <type_traits>




// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_SPARSE_ARRAY_H_
#define UTIL_SPARSE_ARRAY_H_

// DESCRIPTION
//
// SparseArray<T>(m) is a map from integers in [0, m) to T values.
// It requires (sizeof(T)+sizeof(int))*m memory, but it provides
// fast iteration through the elements in the array and fast clearing
// of the array.  The array has a concept of certain elements being
// uninitialized (having no value).
//
// Insertion and deletion are constant time operations.
//
// Allocating the array is a constant time operation
// when memory allocation is a constant time operation.
//
// Clearing the array is a constant time operation (unusual!).
//
// Iterating through the array is an O(n) operation, where n
// is the number of items in the array (not O(m)).
//
// The array iterator visits entries in the order they were first
// inserted into the array.  It is safe to add items to the array while
// using an iterator: the iterator will visit indices added to the array
// during the iteration, but will not re-visit indices whose values
// change after visiting.  Thus SparseArray can be a convenient
// implementation of a work queue.
//
// The SparseArray implementation is NOT thread-safe.  It is up to the
// caller to make sure only one thread is accessing the array.  (Typically
// these arrays are temporary values and used in situations where speed is
// important.)
//
// The SparseArray interface does not present all the usual STL bells and
// whistles.
//
// Implemented with reference to Briggs & Torczon, An Efficient
// Representation for Sparse Sets, ACM Letters on Programming Languages
// and Systems, Volume 2, Issue 1-4 (March-Dec.  1993), pp.  59-69.
//
// Briggs & Torczon popularized this technique, but it had been known
// long before their paper.  They point out that Aho, Hopcroft, and
// Ullman's 1974 Design and Analysis of Computer Algorithms and Bentley's
// 1986 Programming Pearls both hint at the technique in exercises to the
// reader (in Aho & Hopcroft, exercise 2.12; in Bentley, column 1
// exercise 8).
//
// Briggs & Torczon describe a sparse set implementation.  I have
// trivially generalized it to create a sparse array (actually the original
// target of the AHU and Bentley exercises).

// IMPLEMENTATION
//
// SparseArray is an array dense_ and an array sparse_ of identical size.
// At any point, the number of elements in the sparse array is size_.
//
// The array dense_ contains the size_ elements in the sparse array (with
// their indices),
// in the order that the elements were first inserted.  This array is dense:
// the size_ pairs are dense_[0] through dense_[size_-1].
//
// The array sparse_ maps from indices in [0,m) to indices in [0,size_).
// For indices present in the array, dense_[sparse_[i]].index_ == i.
// For indices not present in the array, sparse_ can contain any value at all,
// perhaps outside the range [0, size_) but perhaps not.
//
// The lax requirement on sparse_ values makes clearing the array very easy:
// set size_ to 0.  Lookups are slightly more complicated.
// An index i has a value in the array if and only if:
//   sparse_[i] is in [0, size_) AND
//   dense_[sparse_[i]].index_ == i.
// If both these properties hold, only then it is safe to refer to
//   dense_[sparse_[i]].value_
// as the value associated with index i.
//
// To insert a new entry, set sparse_[i] to size_,
// initialize dense_[size_], and then increment size_.
//
// To make the sparse array as efficient as possible for non-primitive types,
// elements may or may not be destroyed when they are deleted from the sparse
// array through a call to resize(). They immediately become inaccessible, but
// they are only guaranteed to be destroyed when the SparseArray destructor is
// called.
//
// A moved-from SparseArray will be empty.

// Doing this simplifies the logic below.
#ifndef __has_feature
#define __has_feature(x) 0
#endif

#include <assert.h>
#include <stdint.h>
#if __has_feature(memory_sanitizer)
#include <sanitizer/msan_interface.h>
#endif
#include <algorithm>
#include <memory>
#include <utility>



namespace re2 {

template<typename Value>
class SparseArray {
 public:
  SparseArray();
  explicit SparseArray(int max_size);
  ~SparseArray();

  // IndexValue pairs: exposed in SparseArray::iterator.
  class IndexValue;

  typedef IndexValue* iterator;
  typedef const IndexValue* const_iterator;

  SparseArray(const SparseArray& src);
  SparseArray(SparseArray&& src);

  SparseArray& operator=(const SparseArray& src);
  SparseArray& operator=(SparseArray&& src);

  // Return the number of entries in the array.
  int size() const {
    return size_;
  }

  // Indicate whether the array is empty.
  int empty() const {
    return size_ == 0;
  }

  // Iterate over the array.
  iterator begin() {
    return dense_.data();
  }
  iterator end() {
    return dense_.data() + size_;
  }

  const_iterator begin() const {
    return dense_.data();
  }
  const_iterator end() const {
    return dense_.data() + size_;
  }

  // Change the maximum size of the array.
  // Invalidates all iterators.
  void resize(int new_max_size);

  // Return the maximum size of the array.
  // Indices can be in the range [0, max_size).
  int max_size() const {
    if (dense_.data() != NULL)
      return dense_.size();
    else
      return 0;
  }

  // Clear the array.
  void clear() {
    size_ = 0;
  }

  // Check whether index i is in the array.
  bool has_index(int i) const;

  // Comparison function for sorting.
  // Can sort the sparse array so that future iterations
  // will visit indices in increasing order using
  // std::sort(arr.begin(), arr.end(), arr.less);
  static bool less(const IndexValue& a, const IndexValue& b);

 public:
  // Set the value at index i to v.
  iterator set(int i, const Value& v) {
    return SetInternal(true, i, v);
  }

  // Set the value at new index i to v.
  // Fast but unsafe: only use if has_index(i) is false.
  iterator set_new(int i, const Value& v) {
    return SetInternal(false, i, v);
  }

  // Set the value at index i to v.
  // Fast but unsafe: only use if has_index(i) is true.
  iterator set_existing(int i, const Value& v) {
    return SetExistingInternal(i, v);
  }

  // Get the value at index i.
  // Fast but unsafe: only use if has_index(i) is true.
  Value& get_existing(int i) {
    assert(has_index(i));
    return dense_[sparse_[i]].value_;
  }
  const Value& get_existing(int i) const {
    assert(has_index(i));
    return dense_[sparse_[i]].value_;
  }

 private:
  iterator SetInternal(bool allow_existing, int i, const Value& v) {
    DebugCheckInvariants();
    if (static_cast<uint32_t>(i) >= static_cast<uint32_t>(max_size())) {
      assert(false && "illegal index");
      // Semantically, end() would be better here, but we already know
      // the user did something stupid, so begin() insulates them from
      // dereferencing an invalid pointer.
      return begin();
    }
    if (!allow_existing) {
      assert(!has_index(i));
      create_index(i);
    } else {
      if (!has_index(i))
        create_index(i);
    }
    return SetExistingInternal(i, v);
  }

  iterator SetExistingInternal(int i, const Value& v) {
    DebugCheckInvariants();
    assert(has_index(i));
    dense_[sparse_[i]].value_ = v;
    DebugCheckInvariants();
    return dense_.data() + sparse_[i];
  }

  // Add the index i to the array.
  // Only use if has_index(i) is known to be false.
  // Since it doesn't set the value associated with i,
  // this function is private, only intended as a helper
  // for other methods.
  void create_index(int i);

  // In debug mode, verify that some invariant properties of the class
  // are being maintained. This is called at the end of the constructor
  // and at the beginning and end of all public non-const member functions.
  void DebugCheckInvariants() const;

  // Initializes memory for elements [min, max).
  void MaybeInitializeMemory(int min, int max) {
#if __has_feature(memory_sanitizer)
    __msan_unpoison(sparse_.data() + min, (max - min) * sizeof sparse_[0]);
#elif defined(RE2_ON_VALGRIND)
    for (int i = min; i < max; i++) {
      sparse_[i] = 0xababababU;
    }
#endif
  }

  int size_ = 0;
  PODArray<int> sparse_;
  PODArray<IndexValue> dense_;
};

template<typename Value>
SparseArray<Value>::SparseArray() = default;

template<typename Value>
SparseArray<Value>::SparseArray(const SparseArray& src)
    : size_(src.size_),
      sparse_(src.max_size()),
      dense_(src.max_size()) {
  std::copy_n(src.sparse_.data(), src.max_size(), sparse_.data());
  std::copy_n(src.dense_.data(), src.max_size(), dense_.data());
}

template<typename Value>
SparseArray<Value>::SparseArray(SparseArray&& src)
    : size_(src.size_),
      sparse_(std::move(src.sparse_)),
      dense_(std::move(src.dense_)) {
  src.size_ = 0;
}

template<typename Value>
SparseArray<Value>& SparseArray<Value>::operator=(const SparseArray& src) {
  // Construct these first for exception safety.
  PODArray<int> a(src.max_size());
  PODArray<IndexValue> b(src.max_size());

  size_ = src.size_;
  sparse_ = std::move(a);
  dense_ = std::move(b);
  std::copy_n(src.sparse_.data(), src.max_size(), sparse_.data());
  std::copy_n(src.dense_.data(), src.max_size(), dense_.data());
  return *this;
}

template<typename Value>
SparseArray<Value>& SparseArray<Value>::operator=(SparseArray&& src) {
  size_ = src.size_;
  sparse_ = std::move(src.sparse_);
  dense_ = std::move(src.dense_);
  src.size_ = 0;
  return *this;
}

// IndexValue pairs: exposed in SparseArray::iterator.
template<typename Value>
class SparseArray<Value>::IndexValue {
 public:
  int index() const { return index_; }
  Value& value() { return value_; }
  const Value& value() const { return value_; }

 private:
  friend class SparseArray;
  int index_;
  Value value_;
};

// Change the maximum size of the array.
// Invalidates all iterators.
template<typename Value>
void SparseArray<Value>::resize(int new_max_size) {
  DebugCheckInvariants();
  if (new_max_size > max_size()) {
    const int old_max_size = max_size();

    // Construct these first for exception safety.
    PODArray<int> a(new_max_size);
    PODArray<IndexValue> b(new_max_size);

    std::copy_n(sparse_.data(), old_max_size, a.data());
    std::copy_n(dense_.data(), old_max_size, b.data());

    sparse_ = std::move(a);
    dense_ = std::move(b);

    MaybeInitializeMemory(old_max_size, new_max_size);
  }
  if (size_ > new_max_size)
    size_ = new_max_size;
  DebugCheckInvariants();
}

// Check whether index i is in the array.
template<typename Value>
bool SparseArray<Value>::has_index(int i) const {
  assert(i >= 0);
  assert(i < max_size());
  if (static_cast<uint32_t>(i) >= static_cast<uint32_t>(max_size())) {
    return false;
  }
  // Unsigned comparison avoids checking sparse_[i] < 0.
  return (uint32_t)sparse_[i] < (uint32_t)size_ &&
         dense_[sparse_[i]].index_ == i;
}

template<typename Value>
void SparseArray<Value>::create_index(int i) {
  assert(!has_index(i));
  assert(size_ < max_size());
  sparse_[i] = size_;
  dense_[size_].index_ = i;
  size_++;
}

template<typename Value> SparseArray<Value>::SparseArray(int max_size) :
    sparse_(max_size), dense_(max_size) {
  MaybeInitializeMemory(size_, max_size);
  DebugCheckInvariants();
}

template<typename Value> SparseArray<Value>::~SparseArray() {
  DebugCheckInvariants();
}

template<typename Value> void SparseArray<Value>::DebugCheckInvariants() const {
  assert(0 <= size_);
  assert(size_ <= max_size());
}

// Comparison function for sorting.
template<typename Value> bool SparseArray<Value>::less(const IndexValue& a,
                                                       const IndexValue& b) {
  return a.index_ < b.index_;
}

}  // namespace re2

#endif  // UTIL_SPARSE_ARRAY_H_

// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_SPARSE_SET_H_
#define UTIL_SPARSE_SET_H_

// DESCRIPTION
//
// SparseSet(m) is a set of integers in [0, m).
// It requires sizeof(int)*m memory, but it provides
// fast iteration through the elements in the set and fast clearing
// of the set.
//
// Insertion and deletion are constant time operations.
//
// Allocating the set is a constant time operation
// when memory allocation is a constant time operation.
//
// Clearing the set is a constant time operation (unusual!).
//
// Iterating through the set is an O(n) operation, where n
// is the number of items in the set (not O(m)).
//
// The set iterator visits entries in the order they were first
// inserted into the set.  It is safe to add items to the set while
// using an iterator: the iterator will visit indices added to the set
// during the iteration, but will not re-visit indices whose values
// change after visiting.  Thus SparseSet can be a convenient
// implementation of a work queue.
//
// The SparseSet implementation is NOT thread-safe.  It is up to the
// caller to make sure only one thread is accessing the set.  (Typically
// these sets are temporary values and used in situations where speed is
// important.)
//
// The SparseSet interface does not present all the usual STL bells and
// whistles.
//
// Implemented with reference to Briggs & Torczon, An Efficient
// Representation for Sparse Sets, ACM Letters on Programming Languages
// and Systems, Volume 2, Issue 1-4 (March-Dec.  1993), pp.  59-69.
//
// This is a specialization of sparse array; see sparse_array.h.

// IMPLEMENTATION
//
// See sparse_array.h for implementation details.

// Doing this simplifies the logic below.
#ifndef __has_feature
#define __has_feature(x) 0
#endif

#include <assert.h>
#include <stdint.h>
#if __has_feature(memory_sanitizer)
#include <sanitizer/msan_interface.h>
#endif
#include <algorithm>
#include <memory>
#include <utility>



namespace re2 {

template<typename Value>
class SparseSetT {
 public:
  SparseSetT();
  explicit SparseSetT(int max_size);
  ~SparseSetT();

  typedef int* iterator;
  typedef const int* const_iterator;

  // Return the number of entries in the set.
  int size() const {
    return size_;
  }

  // Indicate whether the set is empty.
  int empty() const {
    return size_ == 0;
  }

  // Iterate over the set.
  iterator begin() {
    return dense_.data();
  }
  iterator end() {
    return dense_.data() + size_;
  }

  const_iterator begin() const {
    return dense_.data();
  }
  const_iterator end() const {
    return dense_.data() + size_;
  }

  // Change the maximum size of the set.
  // Invalidates all iterators.
  void resize(int new_max_size);

  // Return the maximum size of the set.
  // Indices can be in the range [0, max_size).
  int max_size() const {
    if (dense_.data() != NULL)
      return dense_.size();
    else
      return 0;
  }

  // Clear the set.
  void clear() {
    size_ = 0;
  }

  // Check whether index i is in the set.
  bool contains(int i) const;

  // Comparison function for sorting.
  // Can sort the sparse set so that future iterations
  // will visit indices in increasing order using
  // std::sort(arr.begin(), arr.end(), arr.less);
  static bool less(int a, int b);

 public:
  // Insert index i into the set.
  iterator insert(int i) {
    return InsertInternal(true, i);
  }

  // Insert index i into the set.
  // Fast but unsafe: only use if contains(i) is false.
  iterator insert_new(int i) {
    return InsertInternal(false, i);
  }

 private:
  iterator InsertInternal(bool allow_existing, int i) {
    DebugCheckInvariants();
    if (static_cast<uint32_t>(i) >= static_cast<uint32_t>(max_size())) {
      assert(false && "illegal index");
      // Semantically, end() would be better here, but we already know
      // the user did something stupid, so begin() insulates them from
      // dereferencing an invalid pointer.
      return begin();
    }
    if (!allow_existing) {
      assert(!contains(i));
      create_index(i);
    } else {
      if (!contains(i))
        create_index(i);
    }
    DebugCheckInvariants();
    return dense_.data() + sparse_[i];
  }

  // Add the index i to the set.
  // Only use if contains(i) is known to be false.
  // This function is private, only intended as a helper
  // for other methods.
  void create_index(int i);

  // In debug mode, verify that some invariant properties of the class
  // are being maintained. This is called at the end of the constructor
  // and at the beginning and end of all public non-const member functions.
  void DebugCheckInvariants() const;

  // Initializes memory for elements [min, max).
  void MaybeInitializeMemory(int min, int max) {
#if __has_feature(memory_sanitizer)
    __msan_unpoison(sparse_.data() + min, (max - min) * sizeof sparse_[0]);
#elif defined(RE2_ON_VALGRIND)
    for (int i = min; i < max; i++) {
      sparse_[i] = 0xababababU;
    }
#endif
  }

  int size_ = 0;
  PODArray<int> sparse_;
  PODArray<int> dense_;
};

template<typename Value>
SparseSetT<Value>::SparseSetT() = default;

// Change the maximum size of the set.
// Invalidates all iterators.
template<typename Value>
void SparseSetT<Value>::resize(int new_max_size) {
  DebugCheckInvariants();
  if (new_max_size > max_size()) {
    const int old_max_size = max_size();

    // Construct these first for exception safety.
    PODArray<int> a(new_max_size);
    PODArray<int> b(new_max_size);

    std::copy_n(sparse_.data(), old_max_size, a.data());
    std::copy_n(dense_.data(), old_max_size, b.data());

    sparse_ = std::move(a);
    dense_ = std::move(b);

    MaybeInitializeMemory(old_max_size, new_max_size);
  }
  if (size_ > new_max_size)
    size_ = new_max_size;
  DebugCheckInvariants();
}

// Check whether index i is in the set.
template<typename Value>
bool SparseSetT<Value>::contains(int i) const {
  assert(i >= 0);
  assert(i < max_size());
  if (static_cast<uint32_t>(i) >= static_cast<uint32_t>(max_size())) {
    return false;
  }
  // Unsigned comparison avoids checking sparse_[i] < 0.
  return (uint32_t)sparse_[i] < (uint32_t)size_ &&
         dense_[sparse_[i]] == i;
}

template<typename Value>
void SparseSetT<Value>::create_index(int i) {
  assert(!contains(i));
  assert(size_ < max_size());
  sparse_[i] = size_;
  dense_[size_] = i;
  size_++;
}

template<typename Value> SparseSetT<Value>::SparseSetT(int max_size) :
    sparse_(max_size), dense_(max_size) {
  MaybeInitializeMemory(size_, max_size);
  DebugCheckInvariants();
}

template<typename Value> SparseSetT<Value>::~SparseSetT() {
  DebugCheckInvariants();
}

template<typename Value> void SparseSetT<Value>::DebugCheckInvariants() const {
  assert(0 <= size_);
  assert(size_ <= max_size());
}

// Comparison function for sorting.
template<typename Value> bool SparseSetT<Value>::less(int a, int b) {
  return a < b;
}

typedef SparseSetT<void> SparseSet;

}  // namespace re2

#endif  // UTIL_SPARSE_SET_H_



namespace re2 {

// Opcodes for Inst
enum InstOp {
  kInstAlt = 0,      // choose between out_ and out1_
  kInstAltMatch,     // Alt: out_ is [00-FF] and back, out1_ is match; or vice versa.
  kInstByteRange,    // next (possible case-folded) byte must be in [lo_, hi_]
  kInstCapture,      // capturing parenthesis number cap_
  kInstEmptyWidth,   // empty-width special (^ $ ...); bit(s) set in empty_
  kInstMatch,        // found a match!
  kInstNop,          // no-op; occasionally unavoidable
  kInstFail,         // never match; occasionally unavoidable
  kNumInst,
};

// Bit flags for empty-width specials
enum EmptyOp {
  kEmptyBeginLine        = 1<<0,      // ^ - beginning of line
  kEmptyEndLine          = 1<<1,      // $ - end of line
  kEmptyBeginText        = 1<<2,      // \A - beginning of text
  kEmptyEndText          = 1<<3,      // \z - end of text
  kEmptyWordBoundary     = 1<<4,      // \b - word boundary
  kEmptyNonWordBoundary  = 1<<5,      // \B - not \b
  kEmptyAllFlags         = (1<<6)-1,
};

class DFA;
class Regexp;

// Compiled form of regexp program.
class Prog {
 public:
  Prog();
  ~Prog();

  // Single instruction in regexp program.
  class Inst {
   public:
    // See the assertion below for why this is so.
    Inst() = default;

    // Copyable.
    Inst(const Inst&) = default;
    Inst& operator=(const Inst&) = default;

    // Constructors per opcode
    void InitAlt(uint32_t out, uint32_t out1);
    void InitByteRange(int lo, int hi, int foldcase, uint32_t out);
    void InitCapture(int cap, uint32_t out);
    void InitEmptyWidth(EmptyOp empty, uint32_t out);
    void InitMatch(int id);
    void InitNop(uint32_t out);
    void InitFail();

    // Getters
    int id(Prog* p) { return static_cast<int>(this - p->inst_.data()); }
    InstOp opcode() { return static_cast<InstOp>(out_opcode_&7); }
    int last()      { return (out_opcode_>>3)&1; }
    int out()       { return out_opcode_>>4; }
    int out1()      { DCHECK(opcode() == kInstAlt || opcode() == kInstAltMatch); return out1_; }
    int cap()       { DCHECK_EQ(opcode(), kInstCapture); return cap_; }
    int lo()        { DCHECK_EQ(opcode(), kInstByteRange); return lo_; }
    int hi()        { DCHECK_EQ(opcode(), kInstByteRange); return hi_; }
    int foldcase()  { DCHECK_EQ(opcode(), kInstByteRange); return hint_foldcase_&1; }
    int hint()      { DCHECK_EQ(opcode(), kInstByteRange); return hint_foldcase_>>1; }
    int match_id()  { DCHECK_EQ(opcode(), kInstMatch); return match_id_; }
    EmptyOp empty() { DCHECK_EQ(opcode(), kInstEmptyWidth); return empty_; }

    bool greedy(Prog* p) {
      DCHECK_EQ(opcode(), kInstAltMatch);
      return p->inst(out())->opcode() == kInstByteRange ||
             (p->inst(out())->opcode() == kInstNop &&
              p->inst(p->inst(out())->out())->opcode() == kInstByteRange);
    }

    // Does this inst (an kInstByteRange) match c?
    inline bool Matches(int c) {
      DCHECK_EQ(opcode(), kInstByteRange);
      if (foldcase() && 'A' <= c && c <= 'Z')
        c += 'a' - 'A';
      return lo_ <= c && c <= hi_;
    }

    // Returns string representation for debugging.
    std::string Dump();

    // Maximum instruction id.
    // (Must fit in out_opcode_. PatchList/last steal another bit.)
    static const int kMaxInst = (1<<28) - 1;

   private:
    void set_opcode(InstOp opcode) {
      out_opcode_ = (out()<<4) | (last()<<3) | opcode;
    }

    void set_last() {
      out_opcode_ = (out()<<4) | (1<<3) | opcode();
    }

    void set_out(int out) {
      out_opcode_ = (out<<4) | (last()<<3) | opcode();
    }

    void set_out_opcode(int out, InstOp opcode) {
      out_opcode_ = (out<<4) | (last()<<3) | opcode;
    }

    uint32_t out_opcode_;  // 28 bits: out, 1 bit: last, 3 (low) bits: opcode
    union {                // additional instruction arguments:
      uint32_t out1_;      // opcode == kInstAlt
                           //   alternate next instruction

      int32_t cap_;        // opcode == kInstCapture
                           //   Index of capture register (holds text
                           //   position recorded by capturing parentheses).
                           //   For \n (the submatch for the nth parentheses),
                           //   the left parenthesis captures into register 2*n
                           //   and the right one captures into register 2*n+1.

      int32_t match_id_;   // opcode == kInstMatch
                           //   Match ID to identify this match (for re2::Set).

      struct {             // opcode == kInstByteRange
        uint8_t lo_;       //   byte range is lo_-hi_ inclusive
        uint8_t hi_;       //
        uint16_t hint_foldcase_;  // 15 bits: hint, 1 (low) bit: foldcase
                           //   hint to execution engines: the delta to the
                           //   next instruction (in the current list) worth
                           //   exploring iff this instruction matched; 0
                           //   means there are no remaining possibilities,
                           //   which is most likely for character classes.
                           //   foldcase: A-Z -> a-z before checking range.
      };

      EmptyOp empty_;       // opcode == kInstEmptyWidth
                            //   empty_ is bitwise OR of kEmpty* flags above.
    };

    friend class Compiler;
    friend struct PatchList;
    friend class Prog;
  };

  // Inst must be trivial so that we can freely clear it with memset(3).
  // Arrays of Inst are initialised by copying the initial elements with
  // memmove(3) and then clearing any remaining elements with memset(3).
  static_assert(std::is_trivial<Inst>::value, "Inst must be trivial");

  // Whether to anchor the search.
  enum Anchor {
    kUnanchored,  // match anywhere
    kAnchored,    // match only starting at beginning of text
  };

  // Kind of match to look for (for anchor != kFullMatch)
  //
  // kLongestMatch mode finds the overall longest
  // match but still makes its submatch choices the way
  // Perl would, not in the way prescribed by POSIX.
  // The POSIX rules are much more expensive to implement,
  // and no one has needed them.
  //
  // kFullMatch is not strictly necessary -- we could use
  // kLongestMatch and then check the length of the match -- but
  // the matching code can run faster if it knows to consider only
  // full matches.
  enum MatchKind {
    kFirstMatch,     // like Perl, PCRE
    kLongestMatch,   // like egrep or POSIX
    kFullMatch,      // match only entire text; implies anchor==kAnchored
    kManyMatch       // for SearchDFA, records set of matches
  };

  Inst *inst(int id) { return &inst_[id]; }
  int start() { return start_; }
  int start_unanchored() { return start_unanchored_; }
  void set_start(int start) { start_ = start; }
  void set_start_unanchored(int start) { start_unanchored_ = start; }
  int size() { return size_; }
  bool reversed() { return reversed_; }
  void set_reversed(bool reversed) { reversed_ = reversed; }
  int list_count() { return list_count_; }
  int inst_count(InstOp op) { return inst_count_[op]; }
  uint16_t* list_heads() { return list_heads_.data(); }
  void set_dfa_mem(int64_t dfa_mem) { dfa_mem_ = dfa_mem; }
  int64_t dfa_mem() { return dfa_mem_; }
  int flags() { return flags_; }
  void set_flags(int flags) { flags_ = flags; }
  bool anchor_start() { return anchor_start_; }
  void set_anchor_start(bool b) { anchor_start_ = b; }
  bool anchor_end() { return anchor_end_; }
  void set_anchor_end(bool b) { anchor_end_ = b; }
  int bytemap_range() { return bytemap_range_; }
  const uint8_t* bytemap() { return bytemap_; }

  // Lazily computed.
  int first_byte();

  // Returns string representation of program for debugging.
  std::string Dump();
  std::string DumpUnanchored();
  std::string DumpByteMap();

  // Returns the set of kEmpty flags that are in effect at
  // position p within context.
  static uint32_t EmptyFlags(const StringPiece& context, const char* p);

  // Returns whether byte c is a word character: ASCII only.
  // Used by the implementation of \b and \B.
  // This is not right for Unicode, but:
  //   - it's hard to get right in a byte-at-a-time matching world
  //     (the DFA has only one-byte lookahead).
  //   - even if the lookahead were possible, the Progs would be huge.
  // This crude approximation is the same one PCRE uses.
  static bool IsWordChar(uint8_t c) {
    return ('A' <= c && c <= 'Z') ||
           ('a' <= c && c <= 'z') ||
           ('0' <= c && c <= '9') ||
           c == '_';
  }

  // Execution engines.  They all search for the regexp (run the prog)
  // in text, which is in the larger context (used for ^ $ \b etc).
  // Anchor and kind control the kind of search.
  // Returns true if match found, false if not.
  // If match found, fills match[0..nmatch-1] with submatch info.
  // match[0] is overall match, match[1] is first set of parens, etc.
  // If a particular submatch is not matched during the regexp match,
  // it is set to NULL.
  //
  // Matching text == StringPiece(NULL, 0) is treated as any other empty
  // string, but note that on return, it will not be possible to distinguish
  // submatches that matched that empty string from submatches that didn't
  // match anything.  Either way, match[i] == NULL.

  // Search using NFA: can find submatches but kind of slow.
  bool SearchNFA(const StringPiece& text, const StringPiece& context,
                 Anchor anchor, MatchKind kind,
                 StringPiece* match, int nmatch);

  // Search using DFA: much faster than NFA but only finds
  // end of match and can use a lot more memory.
  // Returns whether a match was found.
  // If the DFA runs out of memory, sets *failed to true and returns false.
  // If matches != NULL and kind == kManyMatch and there is a match,
  // SearchDFA fills matches with the match IDs of the final matching state.
  bool SearchDFA(const StringPiece& text, const StringPiece& context,
                 Anchor anchor, MatchKind kind, StringPiece* match0,
                 bool* failed, SparseSet* matches);

  // The callback issued after building each DFA state with BuildEntireDFA().
  // If next is null, then the memory budget has been exhausted and building
  // will halt. Otherwise, the state has been built and next points to an array
  // of bytemap_range()+1 slots holding the next states as per the bytemap and
  // kByteEndText. The number of the state is implied by the callback sequence:
  // the first callback is for state 0, the second callback is for state 1, ...
  // match indicates whether the state is a matching state.
  using DFAStateCallback = std::function<void(const int* next, bool match)>;

  // Build the entire DFA for the given match kind.
  // Usually the DFA is built out incrementally, as needed, which
  // avoids lots of unnecessary work.
  // If cb is not empty, it receives one callback per state built.
  // Returns the number of states built.
  // FOR TESTING OR EXPERIMENTAL PURPOSES ONLY.
  int BuildEntireDFA(MatchKind kind, const DFAStateCallback& cb);

  // Controls whether the DFA should bail out early if the NFA would be faster.
  // FOR TESTING ONLY.
  static void TEST_dfa_should_bail_when_slow(bool b);

  // Compute bytemap.
  void ComputeByteMap();

  // Computes whether all matches must begin with the same first
  // byte, and if so, returns that byte.  If not, returns -1.
  int ComputeFirstByte();

  // Run peep-hole optimizer on program.
  void Optimize();

  // One-pass NFA: only correct if IsOnePass() is true,
  // but much faster than NFA (competitive with PCRE)
  // for those expressions.
  bool IsOnePass();
  bool SearchOnePass(const StringPiece& text, const StringPiece& context,
                     Anchor anchor, MatchKind kind,
                     StringPiece* match, int nmatch);

  // Bit-state backtracking.  Fast on small cases but uses memory
  // proportional to the product of the list count and the text size.
  bool CanBitState() { return list_heads_.data() != NULL; }
  bool SearchBitState(const StringPiece& text, const StringPiece& context,
                      Anchor anchor, MatchKind kind,
                      StringPiece* match, int nmatch);

  static const int kMaxOnePassCapture = 5;  // $0 through $4

  // Backtracking search: the gold standard against which the other
  // implementations are checked.  FOR TESTING ONLY.
  // It allocates a ton of memory to avoid running forever.
  // It is also recursive, so can't use in production (will overflow stacks).
  // The name "Unsafe" here is supposed to be a flag that
  // you should not be using this function.
  bool UnsafeSearchBacktrack(const StringPiece& text,
                             const StringPiece& context,
                             Anchor anchor, MatchKind kind,
                             StringPiece* match, int nmatch);

  // Computes range for any strings matching regexp. The min and max can in
  // some cases be arbitrarily precise, so the caller gets to specify the
  // maximum desired length of string returned.
  //
  // Assuming PossibleMatchRange(&min, &max, N) returns successfully, any
  // string s that is an anchored match for this regexp satisfies
  //   min <= s && s <= max.
  //
  // Note that PossibleMatchRange() will only consider the first copy of an
  // infinitely repeated element (i.e., any regexp element followed by a '*' or
  // '+' operator). Regexps with "{N}" constructions are not affected, as those
  // do not compile down to infinite repetitions.
  //
  // Returns true on success, false on error.
  bool PossibleMatchRange(std::string* min, std::string* max, int maxlen);

  // EXPERIMENTAL! SUBJECT TO CHANGE!
  // Outputs the program fanout into the given sparse array.
  void Fanout(SparseArray<int>* fanout);

  // Compiles a collection of regexps to Prog.  Each regexp will have
  // its own Match instruction recording the index in the output vector.
  static Prog* CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max_mem);

  // Flattens the Prog from "tree" form to "list" form. This is an in-place
  // operation in the sense that the old instructions are lost.
  void Flatten();

  // Walks the Prog; the "successor roots" or predecessors of the reachable
  // instructions are marked in rootmap or predmap/predvec, respectively.
  // reachable and stk are preallocated scratch structures.
  void MarkSuccessors(SparseArray<int>* rootmap,
                      SparseArray<int>* predmap,
                      std::vector<std::vector<int>>* predvec,
                      SparseSet* reachable, std::vector<int>* stk);

  // Walks the Prog from the given "root" instruction; the "dominator root"
  // of the reachable instructions (if such exists) is marked in rootmap.
  // reachable and stk are preallocated scratch structures.
  void MarkDominator(int root, SparseArray<int>* rootmap,
                     SparseArray<int>* predmap,
                     std::vector<std::vector<int>>* predvec,
                     SparseSet* reachable, std::vector<int>* stk);

  // Walks the Prog from the given "root" instruction; the reachable
  // instructions are emitted in "list" form and appended to flat.
  // reachable and stk are preallocated scratch structures.
  void EmitList(int root, SparseArray<int>* rootmap,
                std::vector<Inst>* flat,
                SparseSet* reachable, std::vector<int>* stk);

  // Computes hints for ByteRange instructions in [begin, end).
  void ComputeHints(std::vector<Inst>* flat, int begin, int end);

 private:
  friend class Compiler;

  DFA* GetDFA(MatchKind kind);
  void DeleteDFA(DFA* dfa);

  bool anchor_start_;       // regexp has explicit start anchor
  bool anchor_end_;         // regexp has explicit end anchor
  bool reversed_;           // whether program runs backward over input
  bool did_flatten_;        // has Flatten been called?
  bool did_onepass_;        // has IsOnePass been called?

  int start_;               // entry point for program
  int start_unanchored_;    // unanchored entry point for program
  int size_;                // number of instructions
  int bytemap_range_;       // bytemap_[x] < bytemap_range_
  int first_byte_;          // required first byte for match, or -1 if none
  int flags_;               // regexp parse flags

  int list_count_;                 // count of lists (see above)
  int inst_count_[kNumInst];       // count of instructions by opcode
  PODArray<uint16_t> list_heads_;  // sparse array enumerating list heads
                                   // not populated if size_ is overly large

  PODArray<Inst> inst_;              // pointer to instruction array
  PODArray<uint8_t> onepass_nodes_;  // data for OnePass nodes

  int64_t dfa_mem_;         // Maximum memory for DFAs.
  DFA* dfa_first_;          // DFA cached for kFirstMatch/kManyMatch
  DFA* dfa_longest_;        // DFA cached for kLongestMatch/kFullMatch

  uint8_t bytemap_[256];    // map from input bytes to byte classes

  std::once_flag first_byte_once_;
  std::once_flag dfa_first_once_;
  std::once_flag dfa_longest_once_;

  Prog(const Prog&) = delete;
  Prog& operator=(const Prog&) = delete;
};

}  // namespace re2

#endif  // RE2_PROG_H_

// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_REGEXP_H_
#define RE2_REGEXP_H_

// --- SPONSORED LINK --------------------------------------------------
// If you want to use this library for regular expression matching,
// you should use re2/re2.h, which provides a class RE2 that
// mimics the PCRE interface provided by PCRE's C++ wrappers.
// This header describes the low-level interface used to implement RE2
// and may change in backwards-incompatible ways from time to time.
// In contrast, RE2's interface will not.
// ---------------------------------------------------------------------

// Regular expression library: parsing, execution, and manipulation
// of regular expressions.
//
// Any operation that traverses the Regexp structures should be written
// using Regexp::Walker (see walker-inl.h), not recursively, because deeply nested
// regular expressions such as x++++++++++++++++++++... might cause recursive
// traversals to overflow the stack.
//
// It is the caller's responsibility to provide appropriate mutual exclusion
// around manipulation of the regexps.  RE2 does this.
//
// PARSING
//
// Regexp::Parse parses regular expressions encoded in UTF-8.
// The default syntax is POSIX extended regular expressions,
// with the following changes:
//
//   1.  Backreferences (optional in POSIX EREs) are not supported.
//         (Supporting them precludes the use of DFA-based
//          matching engines.)
//
//   2.  Collating elements and collation classes are not supported.
//         (No one has needed or wanted them.)
//
// The exact syntax accepted can be modified by passing flags to
// Regexp::Parse.  In particular, many of the basic Perl additions
// are available.  The flags are documented below (search for LikePerl).
//
// If parsed with the flag Regexp::Latin1, both the regular expression
// and the input to the matching routines are assumed to be encoded in
// Latin-1, not UTF-8.
//
// EXECUTION
//
// Once Regexp has parsed a regular expression, it provides methods
// to search text using that regular expression.  These methods are
// implemented via calling out to other regular expression libraries.
// (Let's call them the sublibraries.)
//
// To call a sublibrary, Regexp does not simply prepare a
// string version of the regular expression and hand it to the
// sublibrary.  Instead, Regexp prepares, from its own parsed form, the
// corresponding internal representation used by the sublibrary.
// This has the drawback of needing to know the internal representation
// used by the sublibrary, but it has two important benefits:
//
//   1. The syntax and meaning of regular expressions is guaranteed
//      to be that used by Regexp's parser, not the syntax expected
//      by the sublibrary.  Regexp might accept a restricted or
//      expanded syntax for regular expressions as compared with
//      the sublibrary.  As long as Regexp can translate from its
//      internal form into the sublibrary's, clients need not know
//      exactly which sublibrary they are using.
//
//   2. The sublibrary parsers are bypassed.  For whatever reason,
//      sublibrary regular expression parsers often have security
//      problems.  For example, plan9grep's regular expression parser
//      has a buffer overflow in its handling of large character
//      classes, and PCRE's parser has had buffer overflow problems
//      in the past.  Security-team requires sandboxing of sublibrary
//      regular expression parsers.  Avoiding the sublibrary parsers
//      avoids the sandbox.
//
// The execution methods we use now are provided by the compiled form,
// Prog, described in prog.h
//
// MANIPULATION
//
// Unlike other regular expression libraries, Regexp makes its parsed
// form accessible to clients, so that client code can analyze the
// parsed regular expressions.

#include <stdint.h>
#include <map>
#include <set>
#include <string>



/*
 * The authors of this software are Rob Pike and Ken Thompson.
 *              Copyright (c) 2002 by Lucent Technologies.
 * Permission to use, copy, modify, and distribute this software for any
 * purpose without fee is hereby granted, provided that this entire notice
 * is included in all copies of any software which is or includes a copy
 * or modification of this software and in all copies of the supporting
 * documentation for such software.
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 *
 * This file and rune.cc have been converted to compile as C++ code
 * in name space re2.
 */

#ifndef UTIL_UTF_H_
#define UTIL_UTF_H_

#include <stdint.h>

namespace re2 {

typedef signed int Rune;	/* Code-point values in Unicode 4.0 are 21 bits wide.*/

enum
{
  UTFmax	= 4,		/* maximum bytes per rune */
  Runesync	= 0x80,		/* cannot represent part of a UTF sequence (<) */
  Runeself	= 0x80,		/* rune and UTF sequences are the same (<) */
  Runeerror	= 0xFFFD,	/* decoding error in UTF */
  Runemax	= 0x10FFFF,	/* maximum rune value */
};

int runetochar(char* s, const Rune* r);
int chartorune(Rune* r, const char* s);
int fullrune(const char* s, int n);
int utflen(const char* s);
char* utfrune(const char*, Rune);

}  // namespace re2

#endif  // UTIL_UTF_H_



namespace re2 {

// Keep in sync with string list kOpcodeNames[] in testing/dump.cc
enum RegexpOp {
  // Matches no strings.
  kRegexpNoMatch = 1,

  // Matches empty string.
  kRegexpEmptyMatch,

  // Matches rune_.
  kRegexpLiteral,

  // Matches runes_.
  kRegexpLiteralString,

  // Matches concatenation of sub_[0..nsub-1].
  kRegexpConcat,
  // Matches union of sub_[0..nsub-1].
  kRegexpAlternate,

  // Matches sub_[0] zero or more times.
  kRegexpStar,
  // Matches sub_[0] one or more times.
  kRegexpPlus,
  // Matches sub_[0] zero or one times.
  kRegexpQuest,

  // Matches sub_[0] at least min_ times, at most max_ times.
  // max_ == -1 means no upper limit.
  kRegexpRepeat,

  // Parenthesized (capturing) subexpression.  Index is cap_.
  // Optionally, capturing name is name_.
  kRegexpCapture,

  // Matches any character.
  kRegexpAnyChar,

  // Matches any byte [sic].
  kRegexpAnyByte,

  // Matches empty string at beginning of line.
  kRegexpBeginLine,
  // Matches empty string at end of line.
  kRegexpEndLine,

  // Matches word boundary "\b".
  kRegexpWordBoundary,
  // Matches not-a-word boundary "\B".
  kRegexpNoWordBoundary,

  // Matches empty string at beginning of text.
  kRegexpBeginText,
  // Matches empty string at end of text.
  kRegexpEndText,

  // Matches character class given by cc_.
  kRegexpCharClass,

  // Forces match of entire expression right now,
  // with match ID match_id_ (used by RE2::Set).
  kRegexpHaveMatch,

  kMaxRegexpOp = kRegexpHaveMatch,
};

// Keep in sync with string list in regexp.cc
enum RegexpStatusCode {
  // No error
  kRegexpSuccess = 0,

  // Unexpected error
  kRegexpInternalError,

  // Parse errors
  kRegexpBadEscape,          // bad escape sequence
  kRegexpBadCharClass,       // bad character class
  kRegexpBadCharRange,       // bad character class range
  kRegexpMissingBracket,     // missing closing ]
  kRegexpMissingParen,       // missing closing )
  kRegexpTrailingBackslash,  // at end of regexp
  kRegexpRepeatArgument,     // repeat argument missing, e.g. "*"
  kRegexpRepeatSize,         // bad repetition argument
  kRegexpRepeatOp,           // bad repetition operator
  kRegexpBadPerlOp,          // bad perl operator
  kRegexpBadUTF8,            // invalid UTF-8 in regexp
  kRegexpBadNamedCapture,    // bad named capture
};

// Error status for certain operations.
class RegexpStatus {
 public:
  RegexpStatus() : code_(kRegexpSuccess), tmp_(NULL) {}
  ~RegexpStatus() { delete tmp_; }

  void set_code(RegexpStatusCode code) { code_ = code; }
  void set_error_arg(const StringPiece& error_arg) { error_arg_ = error_arg; }
  void set_tmp(std::string* tmp) { delete tmp_; tmp_ = tmp; }
  RegexpStatusCode code() const { return code_; }
  const StringPiece& error_arg() const { return error_arg_; }
  bool ok() const { return code() == kRegexpSuccess; }

  // Copies state from status.
  void Copy(const RegexpStatus& status);

  // Returns text equivalent of code, e.g.:
  //   "Bad character class"
  static std::string CodeText(RegexpStatusCode code);

  // Returns text describing error, e.g.:
  //   "Bad character class: [z-a]"
  std::string Text() const;

 private:
  RegexpStatusCode code_;  // Kind of error
  StringPiece error_arg_;  // Piece of regexp containing syntax error.
  std::string* tmp_;       // Temporary storage, possibly where error_arg_ is.

  RegexpStatus(const RegexpStatus&) = delete;
  RegexpStatus& operator=(const RegexpStatus&) = delete;
};

// Compiled form; see prog.h
class Prog;

struct RuneRange {
  RuneRange() : lo(0), hi(0) { }
  RuneRange(int l, int h) : lo(l), hi(h) { }
  Rune lo;
  Rune hi;
};

// Less-than on RuneRanges treats a == b if they overlap at all.
// This lets us look in a set to find the range covering a particular Rune.
struct RuneRangeLess {
  bool operator()(const RuneRange& a, const RuneRange& b) const {
    return a.hi < b.lo;
  }
};

class CharClassBuilder;

class CharClass {
 public:
  void Delete();

  typedef RuneRange* iterator;
  iterator begin() { return ranges_; }
  iterator end() { return ranges_ + nranges_; }

  int size() { return nrunes_; }
  bool empty() { return nrunes_ == 0; }
  bool full() { return nrunes_ == Runemax+1; }
  bool FoldsASCII() { return folds_ascii_; }

  bool Contains(Rune r);
  CharClass* Negate();

 private:
  CharClass();  // not implemented
  ~CharClass();  // not implemented
  static CharClass* New(int maxranges);

  friend class CharClassBuilder;

  bool folds_ascii_;
  int nrunes_;
  RuneRange *ranges_;
  int nranges_;

  CharClass(const CharClass&) = delete;
  CharClass& operator=(const CharClass&) = delete;
};

class Regexp {
 public:

  // Flags for parsing.  Can be ORed together.
  enum ParseFlags {
    NoParseFlags  = 0,
    FoldCase      = 1<<0,   // Fold case during matching (case-insensitive).
    Literal       = 1<<1,   // Treat s as literal string instead of a regexp.
    ClassNL       = 1<<2,   // Allow char classes like [^a-z] and \D and \s
                            // and [[:space:]] to match newline.
    DotNL         = 1<<3,   // Allow . to match newline.
    MatchNL       = ClassNL | DotNL,
    OneLine       = 1<<4,   // Treat ^ and $ as only matching at beginning and
                            // end of text, not around embedded newlines.
                            // (Perl's default)
    Latin1        = 1<<5,   // Regexp and text are in Latin1, not UTF-8.
    NonGreedy     = 1<<6,   // Repetition operators are non-greedy by default.
    PerlClasses   = 1<<7,   // Allow Perl character classes like \d.
    PerlB         = 1<<8,   // Allow Perl's \b and \B.
    PerlX         = 1<<9,   // Perl extensions:
                            //   non-capturing parens - (?: )
                            //   non-greedy operators - *? +? ?? {}?
                            //   flag edits - (?i) (?-i) (?i: )
                            //     i - FoldCase
                            //     m - !OneLine
                            //     s - DotNL
                            //     U - NonGreedy
                            //   line ends: \A \z
                            //   \Q and \E to disable/enable metacharacters
                            //   (?P<name>expr) for named captures
                            //   \C to match any single byte
    UnicodeGroups = 1<<10,  // Allow \p{Han} for Unicode Han group
                            //   and \P{Han} for its negation.
    NeverNL       = 1<<11,  // Never match NL, even if the regexp mentions
                            //   it explicitly.
    NeverCapture  = 1<<12,  // Parse all parens as non-capturing.

    // As close to Perl as we can get.
    LikePerl      = ClassNL | OneLine | PerlClasses | PerlB | PerlX |
                    UnicodeGroups,

    // Internal use only.
    WasDollar     = 1<<13,  // on kRegexpEndText: was $ in regexp text
    AllParseFlags = (1<<14)-1,
  };

  // Get.  No set, Regexps are logically immutable once created.
  RegexpOp op() { return static_cast<RegexpOp>(op_); }
  int nsub() { return nsub_; }
  bool simple() { return simple_ != 0; }
  ParseFlags parse_flags() { return static_cast<ParseFlags>(parse_flags_); }
  int Ref();  // For testing.

  Regexp** sub() {
    if(nsub_ <= 1)
      return &subone_;
    else
      return submany_;
  }

  int min() { DCHECK_EQ(op_, kRegexpRepeat); return min_; }
  int max() { DCHECK_EQ(op_, kRegexpRepeat); return max_; }
  Rune rune() { DCHECK_EQ(op_, kRegexpLiteral); return rune_; }
  CharClass* cc() { DCHECK_EQ(op_, kRegexpCharClass); return cc_; }
  int cap() { DCHECK_EQ(op_, kRegexpCapture); return cap_; }
  const std::string* name() { DCHECK_EQ(op_, kRegexpCapture); return name_; }
  Rune* runes() { DCHECK_EQ(op_, kRegexpLiteralString); return runes_; }
  int nrunes() { DCHECK_EQ(op_, kRegexpLiteralString); return nrunes_; }
  int match_id() { DCHECK_EQ(op_, kRegexpHaveMatch); return match_id_; }

  // Increments reference count, returns object as convenience.
  Regexp* Incref();

  // Decrements reference count and deletes this object if count reaches 0.
  void Decref();

  // Parses string s to produce regular expression, returned.
  // Caller must release return value with re->Decref().
  // On failure, sets *status (if status != NULL) and returns NULL.
  static Regexp* Parse(const StringPiece& s, ParseFlags flags,
                       RegexpStatus* status);

  // Returns a _new_ simplified version of the current regexp.
  // Does not edit the current regexp.
  // Caller must release return value with re->Decref().
  // Simplified means that counted repetition has been rewritten
  // into simpler terms and all Perl/POSIX features have been
  // removed.  The result will capture exactly the same
  // subexpressions the original did, unless formatted with ToString.
  Regexp* Simplify();
  friend class CoalesceWalker;
  friend class SimplifyWalker;

  // Parses the regexp src and then simplifies it and sets *dst to the
  // string representation of the simplified form.  Returns true on success.
  // Returns false and sets *status (if status != NULL) on parse error.
  static bool SimplifyRegexp(const StringPiece& src, ParseFlags flags,
                             std::string* dst, RegexpStatus* status);

  // Returns the number of capturing groups in the regexp.
  int NumCaptures();
  friend class NumCapturesWalker;

  // Returns a map from names to capturing group indices,
  // or NULL if the regexp contains no named capture groups.
  // The caller is responsible for deleting the map.
  std::map<std::string, int>* NamedCaptures();

  // Returns a map from capturing group indices to capturing group
  // names or NULL if the regexp contains no named capture groups. The
  // caller is responsible for deleting the map.
  std::map<int, std::string>* CaptureNames();

  // Returns a string representation of the current regexp,
  // using as few parentheses as possible.
  std::string ToString();

  // Convenience functions.  They consume the passed reference,
  // so in many cases you should use, e.g., Plus(re->Incref(), flags).
  // They do not consume allocated arrays like subs or runes.
  static Regexp* Plus(Regexp* sub, ParseFlags flags);
  static Regexp* Star(Regexp* sub, ParseFlags flags);
  static Regexp* Quest(Regexp* sub, ParseFlags flags);
  static Regexp* Concat(Regexp** subs, int nsubs, ParseFlags flags);
  static Regexp* Alternate(Regexp** subs, int nsubs, ParseFlags flags);
  static Regexp* Capture(Regexp* sub, ParseFlags flags, int cap);
  static Regexp* Repeat(Regexp* sub, ParseFlags flags, int min, int max);
  static Regexp* NewLiteral(Rune rune, ParseFlags flags);
  static Regexp* NewCharClass(CharClass* cc, ParseFlags flags);
  static Regexp* LiteralString(Rune* runes, int nrunes, ParseFlags flags);
  static Regexp* HaveMatch(int match_id, ParseFlags flags);

  // Like Alternate but does not factor out common prefixes.
  static Regexp* AlternateNoFactor(Regexp** subs, int nsubs, ParseFlags flags);

  // Debugging function.  Returns string format for regexp
  // that makes structure clear.  Does NOT use regexp syntax.
  std::string Dump();

  // Helper traversal class, defined fully in walker-inl.h.
  template<typename T> class Walker;

  // Compile to Prog.  See prog.h
  // Reverse prog expects to be run over text backward.
  // Construction and execution of prog will
  // stay within approximately max_mem bytes of memory.
  // If max_mem <= 0, a reasonable default is used.
  Prog* CompileToProg(int64_t max_mem);
  Prog* CompileToReverseProg(int64_t max_mem);

  // Whether to expect this library to find exactly the same answer as PCRE
  // when running this regexp.  Most regexps do mimic PCRE exactly, but a few
  // obscure cases behave differently.  Technically this is more a property
  // of the Prog than the Regexp, but the computation is much easier to do
  // on the Regexp.  See mimics_pcre.cc for the exact conditions.
  bool MimicsPCRE();

  // Benchmarking function.
  void NullWalk();

  // Whether every match of this regexp must be anchored and
  // begin with a non-empty fixed string (perhaps after ASCII
  // case-folding).  If so, returns the prefix and the sub-regexp that
  // follows it.
  // Callers should expect *prefix, *foldcase and *suffix to be "zeroed"
  // regardless of the return value.
  bool RequiredPrefix(std::string* prefix, bool* foldcase,
                      Regexp** suffix);

 private:
  // Constructor allocates vectors as appropriate for operator.
  explicit Regexp(RegexpOp op, ParseFlags parse_flags);

  // Use Decref() instead of delete to release Regexps.
  // This is private to catch deletes at compile time.
  ~Regexp();
  void Destroy();
  bool QuickDestroy();

  // Helpers for Parse.  Listed here so they can edit Regexps.
  class ParseState;

  friend class ParseState;
  friend bool ParseCharClass(StringPiece* s, Regexp** out_re,
                             RegexpStatus* status);

  // Helper for testing [sic].
  friend bool RegexpEqualTestingOnly(Regexp*, Regexp*);

  // Computes whether Regexp is already simple.
  bool ComputeSimple();

  // Constructor that generates a Star, Plus or Quest,
  // squashing the pair if sub is also a Star, Plus or Quest.
  static Regexp* StarPlusOrQuest(RegexpOp op, Regexp* sub, ParseFlags flags);

  // Constructor that generates a concatenation or alternation,
  // enforcing the limit on the number of subexpressions for
  // a particular Regexp.
  static Regexp* ConcatOrAlternate(RegexpOp op, Regexp** subs, int nsubs,
                                   ParseFlags flags, bool can_factor);

  // Returns the leading string that re starts with.
  // The returned Rune* points into a piece of re,
  // so it must not be used after the caller calls re->Decref().
  static Rune* LeadingString(Regexp* re, int* nrune, ParseFlags* flags);

  // Removes the first n leading runes from the beginning of re.
  // Edits re in place.
  static void RemoveLeadingString(Regexp* re, int n);

  // Returns the leading regexp in re's top-level concatenation.
  // The returned Regexp* points at re or a sub-expression of re,
  // so it must not be used after the caller calls re->Decref().
  static Regexp* LeadingRegexp(Regexp* re);

  // Removes LeadingRegexp(re) from re and returns the remainder.
  // Might edit re in place.
  static Regexp* RemoveLeadingRegexp(Regexp* re);

  // Simplifies an alternation of literal strings by factoring out
  // common prefixes.
  static int FactorAlternation(Regexp** sub, int nsub, ParseFlags flags);
  friend class FactorAlternationImpl;

  // Is a == b?  Only efficient on regexps that have not been through
  // Simplify yet - the expansion of a kRegexpRepeat will make this
  // take a long time.  Do not call on such regexps, hence private.
  static bool Equal(Regexp* a, Regexp* b);

  // Allocate space for n sub-regexps.
  void AllocSub(int n) {
    DCHECK(n >= 0 && static_cast<uint16_t>(n) == n);
    if (n > 1)
      submany_ = new Regexp*[n];
    nsub_ = static_cast<uint16_t>(n);
  }

  // Add Rune to LiteralString
  void AddRuneToString(Rune r);

  // Swaps this with that, in place.
  void Swap(Regexp *that);

  // Operator.  See description of operators above.
  // uint8_t instead of RegexpOp to control space usage.
  uint8_t op_;

  // Is this regexp structure already simple
  // (has it been returned by Simplify)?
  // uint8_t instead of bool to control space usage.
  uint8_t simple_;

  // Flags saved from parsing and used during execution.
  // (Only FoldCase is used.)
  // uint16_t instead of ParseFlags to control space usage.
  uint16_t parse_flags_;

  // Reference count.  Exists so that SimplifyRegexp can build
  // regexp structures that are dags rather than trees to avoid
  // exponential blowup in space requirements.
  // uint16_t to control space usage.
  // The standard regexp routines will never generate a
  // ref greater than the maximum repeat count (kMaxRepeat),
  // but even so, Incref and Decref consult an overflow map
  // when ref_ reaches kMaxRef.
  uint16_t ref_;
  static const uint16_t kMaxRef = 0xffff;

  // Subexpressions.
  // uint16_t to control space usage.
  // Concat and Alternate handle larger numbers of subexpressions
  // by building concatenation or alternation trees.
  // Other routines should call Concat or Alternate instead of
  // filling in sub() by hand.
  uint16_t nsub_;
  static const uint16_t kMaxNsub = 0xffff;
  union {
    Regexp** submany_;  // if nsub_ > 1
    Regexp* subone_;  // if nsub_ == 1
  };

  // Extra space for parse and teardown stacks.
  Regexp* down_;

  // Arguments to operator.  See description of operators above.
  union {
    struct {  // Repeat
      int max_;
      int min_;
    };
    struct {  // Capture
      int cap_;
      std::string* name_;
    };
    struct {  // LiteralString
      int nrunes_;
      Rune* runes_;
    };
    struct {  // CharClass
      // These two could be in separate union members,
      // but it wouldn't save any space (there are other two-word structs)
      // and keeping them separate avoids confusion during parsing.
      CharClass* cc_;
      CharClassBuilder* ccb_;
    };
    Rune rune_;  // Literal
    int match_id_;  // HaveMatch
    void *the_union_[2];  // as big as any other element, for memset
  };

  Regexp(const Regexp&) = delete;
  Regexp& operator=(const Regexp&) = delete;
};

// Character class set: contains non-overlapping, non-abutting RuneRanges.
typedef std::set<RuneRange, RuneRangeLess> RuneRangeSet;

class CharClassBuilder {
 public:
  CharClassBuilder();

  typedef RuneRangeSet::iterator iterator;
  iterator begin() { return ranges_.begin(); }
  iterator end() { return ranges_.end(); }

  int size() { return nrunes_; }
  bool empty() { return nrunes_ == 0; }
  bool full() { return nrunes_ == Runemax+1; }

  bool Contains(Rune r);
  bool FoldsASCII();
  bool AddRange(Rune lo, Rune hi);  // returns whether class changed
  CharClassBuilder* Copy();
  void AddCharClass(CharClassBuilder* cc);
  void Negate();
  void RemoveAbove(Rune r);
  CharClass* GetCharClass();
  void AddRangeFlags(Rune lo, Rune hi, Regexp::ParseFlags parse_flags);

 private:
  static const uint32_t AlphaMask = (1<<26) - 1;
  uint32_t upper_;  // bitmap of A-Z
  uint32_t lower_;  // bitmap of a-z
  int nrunes_;
  RuneRangeSet ranges_;

  CharClassBuilder(const CharClassBuilder&) = delete;
  CharClassBuilder& operator=(const CharClassBuilder&) = delete;
};

// Bitwise ops on ParseFlags produce ParseFlags.
inline Regexp::ParseFlags operator|(Regexp::ParseFlags a,
                                    Regexp::ParseFlags b) {
  return static_cast<Regexp::ParseFlags>(
      static_cast<int>(a) | static_cast<int>(b));
}

inline Regexp::ParseFlags operator^(Regexp::ParseFlags a,
                                    Regexp::ParseFlags b) {
  return static_cast<Regexp::ParseFlags>(
      static_cast<int>(a) ^ static_cast<int>(b));
}

inline Regexp::ParseFlags operator&(Regexp::ParseFlags a,
                                    Regexp::ParseFlags b) {
  return static_cast<Regexp::ParseFlags>(
      static_cast<int>(a) & static_cast<int>(b));
}

inline Regexp::ParseFlags operator~(Regexp::ParseFlags a) {
  // Attempting to produce a value out of enum's range has undefined behaviour.
  return static_cast<Regexp::ParseFlags>(
      ~static_cast<int>(a) & static_cast<int>(Regexp::AllParseFlags));
}

}  // namespace re2

#endif  // RE2_REGEXP_H_


namespace re2 {

struct Job {
  int id;
  int rle;  // run length encoding
  const char* p;
};

class BitState {
 public:
  explicit BitState(Prog* prog);

  // The usual Search prototype.
  // Can only call Search once per BitState.
  bool Search(const StringPiece& text, const StringPiece& context,
              bool anchored, bool longest,
              StringPiece* submatch, int nsubmatch);

 private:
  inline bool ShouldVisit(int id, const char* p);
  void Push(int id, const char* p);
  void GrowStack();
  bool TrySearch(int id, const char* p);

  // Search parameters
  Prog* prog_;              // program being run
  StringPiece text_;        // text being searched
  StringPiece context_;     // greater context of text being searched
  bool anchored_;           // whether search is anchored at text.begin()
  bool longest_;            // whether search wants leftmost-longest match
  bool endmatch_;           // whether match must end at text.end()
  StringPiece* submatch_;   // submatches to fill in
  int nsubmatch_;           //   # of submatches to fill in

  // Search state
  static const int VisitedBits = 32;
  PODArray<uint32_t> visited_;  // bitmap: (list ID, char*) pairs visited
  PODArray<const char*> cap_;   // capture registers
  PODArray<Job> job_;           // stack of text positions to explore
  int njob_;                    // stack size
};

BitState::BitState(Prog* prog)
  : prog_(prog),
    anchored_(false),
    longest_(false),
    endmatch_(false),
    submatch_(NULL),
    nsubmatch_(0),
    njob_(0) {
}

// Given id, which *must* be a list head, we can look up its list ID.
// Then the question is: Should the search visit the (list ID, p) pair?
// If so, remember that it was visited so that the next time,
// we don't repeat the visit.
bool BitState::ShouldVisit(int id, const char* p) {
  int n = prog_->list_heads()[id] * static_cast<int>(text_.size()+1) +
          static_cast<int>(p-text_.begin());
  if (visited_[n/VisitedBits] & (1 << (n & (VisitedBits-1))))
    return false;
  visited_[n/VisitedBits] |= 1 << (n & (VisitedBits-1));
  return true;
}

// Grow the stack.
void BitState::GrowStack() {
  PODArray<Job> tmp(2*job_.size());
  memmove(tmp.data(), job_.data(), njob_*sizeof job_[0]);
  job_ = std::move(tmp);
}

// Push (id, p) onto the stack, growing it if necessary.
void BitState::Push(int id, const char* p) {
  if (njob_ >= job_.size()) {
    GrowStack();
    if (njob_ >= job_.size()) {
      LOG(DFATAL) << "GrowStack() failed: "
                  << "njob_ = " << njob_ << ", "
                  << "job_.size() = " << job_.size();
      return;
    }
  }

  // If id < 0, it's undoing a Capture,
  // so we mustn't interfere with that.
  if (id >= 0 && njob_ > 0) {
    Job* top = &job_[njob_-1];
    if (id == top->id &&
        p == top->p + top->rle + 1 &&
        top->rle < std::numeric_limits<int>::max()) {
      ++top->rle;
      return;
    }
  }

  Job* top = &job_[njob_++];
  top->id = id;
  top->rle = 0;
  top->p = p;
}

// Try a search from instruction id0 in state p0.
// Return whether it succeeded.
bool BitState::TrySearch(int id0, const char* p0) {
  bool matched = false;
  const char* end = text_.end();
  njob_ = 0;
  // Push() no longer checks ShouldVisit(),
  // so we must perform the check ourselves.
  if (ShouldVisit(id0, p0))
    Push(id0, p0);
  while (njob_ > 0) {
    // Pop job off stack.
    --njob_;
    int id = job_[njob_].id;
    int& rle = job_[njob_].rle;
    const char* p = job_[njob_].p;

    if (id < 0) {
      // Undo the Capture.
      cap_[prog_->inst(-id)->cap()] = p;
      continue;
    }

    if (rle > 0) {
      p += rle;
      // Revivify job on stack.
      --rle;
      ++njob_;
    }

  Loop:
    // Visit id, p.
    Prog::Inst* ip = prog_->inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "Unexpected opcode: " << ip->opcode();
        return false;

      case kInstFail:
        break;

      case kInstAltMatch:
        if (ip->greedy(prog_)) {
          // out1 is the Match instruction.
          id = ip->out1();
          p = end;
          goto Loop;
        }
        if (longest_) {
          // ip must be non-greedy...
          // out is the Match instruction.
          id = ip->out();
          p = end;
          goto Loop;
        }
        goto Next;

      case kInstByteRange: {
        int c = -1;
        if (p < end)
          c = *p & 0xFF;
        if (!ip->Matches(c))
          goto Next;

        if (ip->hint() != 0)
          Push(id+ip->hint(), p);  // try the next when we're done
        id = ip->out();
        p++;
        goto CheckAndLoop;
      }

      case kInstCapture:
        if (!ip->last())
          Push(id+1, p);  // try the next when we're done

        if (0 <= ip->cap() && ip->cap() < cap_.size()) {
          // Capture p to register, but save old value first.
          Push(-id, cap_[ip->cap()]);  // undo when we're done
          cap_[ip->cap()] = p;
        }

        id = ip->out();
        goto CheckAndLoop;

      case kInstEmptyWidth:
        if (ip->empty() & ~Prog::EmptyFlags(context_, p))
          goto Next;

        if (!ip->last())
          Push(id+1, p);  // try the next when we're done
        id = ip->out();
        goto CheckAndLoop;

      case kInstNop:
        if (!ip->last())
          Push(id+1, p);  // try the next when we're done
        id = ip->out();

      CheckAndLoop:
        // Sanity check: id is the head of its list, which must
        // be the case if id-1 is the last of *its* list. :)
        DCHECK(id == 0 || prog_->inst(id-1)->last());
        if (ShouldVisit(id, p))
          goto Loop;
        break;

      case kInstMatch: {
        if (endmatch_ && p != end)
          goto Next;

        // We found a match.  If the caller doesn't care
        // where the match is, no point going further.
        if (nsubmatch_ == 0)
          return true;

        // Record best match so far.
        // Only need to check end point, because this entire
        // call is only considering one start position.
        matched = true;
        cap_[1] = p;
        if (submatch_[0].data() == NULL ||
            (longest_ && p > submatch_[0].end())) {
          for (int i = 0; i < nsubmatch_; i++)
            submatch_[i] =
                StringPiece(cap_[2 * i],
                            static_cast<size_t>(cap_[2 * i + 1] - cap_[2 * i]));
        }

        // If going for first match, we're done.
        if (!longest_)
          return true;

        // If we used the entire text, no longer match is possible.
        if (p == end)
          return true;

        // Otherwise, continue on in hope of a longer match.
        // Note the absence of the ShouldVisit() check here
        // due to execution remaining in the same list.
      Next:
        if (!ip->last()) {
          id++;
          goto Loop;
        }
        break;
      }
    }
  }
  return matched;
}

// Search text (within context) for prog_.
bool BitState::Search(const StringPiece& text, const StringPiece& context,
                      bool anchored, bool longest,
                      StringPiece* submatch, int nsubmatch) {
  // Search parameters.
  text_ = text;
  context_ = context;
  if (context_.begin() == NULL)
    context_ = text;
  if (prog_->anchor_start() && context_.begin() != text.begin())
    return false;
  if (prog_->anchor_end() && context_.end() != text.end())
    return false;
  anchored_ = anchored || prog_->anchor_start();
  longest_ = longest || prog_->anchor_end();
  endmatch_ = prog_->anchor_end();
  submatch_ = submatch;
  nsubmatch_ = nsubmatch;
  for (int i = 0; i < nsubmatch_; i++)
    submatch_[i] = StringPiece();

  // Allocate scratch space.
  int nvisited = prog_->list_count() * static_cast<int>(text.size()+1);
  nvisited = (nvisited + VisitedBits-1) / VisitedBits;
  visited_ = PODArray<uint32_t>(nvisited);
  memset(visited_.data(), 0, nvisited*sizeof visited_[0]);

  int ncap = 2*nsubmatch;
  if (ncap < 2)
    ncap = 2;
  cap_ = PODArray<const char*>(ncap);
  memset(cap_.data(), 0, ncap*sizeof cap_[0]);

  // When sizeof(Job) == 16, we start with a nice round 1KiB. :)
  job_ = PODArray<Job>(64);

  // Anchored search must start at text.begin().
  if (anchored_) {
    cap_[0] = text.begin();
    return TrySearch(prog_->start(), text.begin());
  }

  // Unanchored search, starting from each possible text position.
  // Notice that we have to try the empty string at the end of
  // the text, so the loop condition is p <= text.end(), not p < text.end().
  // This looks like it's quadratic in the size of the text,
  // but we are not clearing visited_ between calls to TrySearch,
  // so no work is duplicated and it ends up still being linear.
  for (const char* p = text.begin(); p <= text.end(); p++) {
    // Try to use memchr to find the first byte quickly.
    int fb = prog_->first_byte();
    if (fb >= 0 && p < text.end() && (p[0] & 0xFF) != fb) {
      p = reinterpret_cast<const char*>(memchr(p, fb, text.end() - p));
      if (p == NULL)
        p = text.end();
    }

    cap_[0] = p;
    if (TrySearch(prog_->start(), p))  // Match must be leftmost; done.
      return true;
  }
  return false;
}

// Bit-state search.
bool Prog::SearchBitState(const StringPiece& text,
                          const StringPiece& context,
                          Anchor anchor,
                          MatchKind kind,
                          StringPiece* match,
                          int nmatch) {
  // If full match, we ask for an anchored longest match
  // and then check that match[0] == text.
  // So make sure match[0] exists.
  StringPiece sp0;
  if (kind == kFullMatch) {
    anchor = kAnchored;
    if (nmatch < 1) {
      match = &sp0;
      nmatch = 1;
    }
  }

  // Run the search.
  BitState b(this);
  bool anchored = anchor == kAnchored;
  bool longest = kind != kFirstMatch;
  if (!b.Search(text, context, anchored, longest, match, nmatch))
    return false;
  if (kind == kFullMatch && match[0].end() != text.end())
    return false;
  return true;
}

}  // namespace re2
// Copyright 2007 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Compile regular expression to Prog.
//
// Prog and Inst are defined in prog.h.
// This file's external interface is just Regexp::CompileToProg.
// The Compiler class defined in this file is private.

#include <stdint.h>
#include <string.h>
#include <unordered_map>
#include <utility>







// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_WALKER_INL_H_
#define RE2_WALKER_INL_H_

// Helper class for traversing Regexps without recursion.
// Clients should declare their own subclasses that override
// the PreVisit and PostVisit methods, which are called before
// and after visiting the subexpressions.

// Not quite the Visitor pattern, because (among other things)
// the Visitor pattern is recursive.

#include <stack>




namespace re2 {

template<typename T> struct WalkState;

template<typename T> class Regexp::Walker {
 public:
  Walker();
  virtual ~Walker();

  // Virtual method called before visiting re's children.
  // PreVisit passes ownership of its return value to its caller.
  // The Arg* that PreVisit returns will be passed to PostVisit as pre_arg
  // and passed to the child PreVisits and PostVisits as parent_arg.
  // At the top-most Regexp, parent_arg is arg passed to walk.
  // If PreVisit sets *stop to true, the walk does not recurse
  // into the children.  Instead it behaves as though the return
  // value from PreVisit is the return value from PostVisit.
  // The default PreVisit returns parent_arg.
  virtual T PreVisit(Regexp* re, T parent_arg, bool* stop);

  // Virtual method called after visiting re's children.
  // The pre_arg is the T that PreVisit returned.
  // The child_args is a vector of the T that the child PostVisits returned.
  // PostVisit takes ownership of pre_arg.
  // PostVisit takes ownership of the Ts
  // in *child_args, but not the vector itself.
  // PostVisit passes ownership of its return value
  // to its caller.
  // The default PostVisit simply returns pre_arg.
  virtual T PostVisit(Regexp* re, T parent_arg, T pre_arg,
                      T* child_args, int nchild_args);

  // Virtual method called to copy a T,
  // when Walk notices that more than one child is the same re.
  virtual T Copy(T arg);

  // Virtual method called to do a "quick visit" of the re,
  // but not its children.  Only called once the visit budget
  // has been used up and we're trying to abort the walk
  // as quickly as possible.  Should return a value that
  // makes sense for the parent PostVisits still to be run.
  // This function is (hopefully) only called by
  // WalkExponential, but must be implemented by all clients,
  // just in case.
  virtual T ShortVisit(Regexp* re, T parent_arg) = 0;

  // Walks over a regular expression.
  // Top_arg is passed as parent_arg to PreVisit and PostVisit of re.
  // Returns the T returned by PostVisit on re.
  T Walk(Regexp* re, T top_arg);

  // Like Walk, but doesn't use Copy.  This can lead to
  // exponential runtimes on cross-linked Regexps like the
  // ones generated by Simplify.  To help limit this,
  // at most max_visits nodes will be visited and then
  // the walk will be cut off early.
  // If the walk *is* cut off early, ShortVisit(re)
  // will be called on regexps that cannot be fully
  // visited rather than calling PreVisit/PostVisit.
  T WalkExponential(Regexp* re, T top_arg, int max_visits);

  // Clears the stack.  Should never be necessary, since
  // Walk always enters and exits with an empty stack.
  // Logs DFATAL if stack is not already clear.
  void Reset();

  // Returns whether walk was cut off.
  bool stopped_early() { return stopped_early_; }

 private:
  // Walk state for the entire traversal.
  std::stack<WalkState<T> >* stack_;
  bool stopped_early_;
  int max_visits_;

  T WalkInternal(Regexp* re, T top_arg, bool use_copy);

  Walker(const Walker&) = delete;
  Walker& operator=(const Walker&) = delete;
};

template<typename T> T Regexp::Walker<T>::PreVisit(Regexp* re,
                                                   T parent_arg,
                                                   bool* stop) {
  return parent_arg;
}

template<typename T> T Regexp::Walker<T>::PostVisit(Regexp* re,
                                                    T parent_arg,
                                                    T pre_arg,
                                                    T* child_args,
                                                    int nchild_args) {
  return pre_arg;
}

template<typename T> T Regexp::Walker<T>::Copy(T arg) {
  return arg;
}

// State about a single level in the traversal.
template<typename T> struct WalkState {
  WalkState<T>(Regexp* re, T parent)
    : re(re),
      n(-1),
      parent_arg(parent),
      child_args(NULL) { }

  Regexp* re;  // The regexp
  int n;  // The index of the next child to process; -1 means need to PreVisit
  T parent_arg;  // Accumulated arguments.
  T pre_arg;
  T child_arg;  // One-element buffer for child_args.
  T* child_args;
};

template<typename T> Regexp::Walker<T>::Walker() {
  stack_ = new std::stack<WalkState<T> >;
  stopped_early_ = false;
}

template<typename T> Regexp::Walker<T>::~Walker() {
  Reset();
  delete stack_;
}

// Clears the stack.  Should never be necessary, since
// Walk always enters and exits with an empty stack.
// Logs DFATAL if stack is not already clear.
template<typename T> void Regexp::Walker<T>::Reset() {
  if (stack_ && stack_->size() > 0) {
    LOG(DFATAL) << "Stack not empty.";
    while (stack_->size() > 0) {
      delete stack_->top().child_args;
      stack_->pop();
    }
  }
}

template<typename T> T Regexp::Walker<T>::WalkInternal(Regexp* re, T top_arg,
                                                       bool use_copy) {
  Reset();

  if (re == NULL) {
    LOG(DFATAL) << "Walk NULL";
    return top_arg;
  }

  stack_->push(WalkState<T>(re, top_arg));

  WalkState<T>* s;
  for (;;) {
    T t;
    s = &stack_->top();
    Regexp* re = s->re;
    switch (s->n) {
      case -1: {
        if (--max_visits_ < 0) {
          stopped_early_ = true;
          t = ShortVisit(re, s->parent_arg);
          break;
        }
        bool stop = false;
        s->pre_arg = PreVisit(re, s->parent_arg, &stop);
        if (stop) {
          t = s->pre_arg;
          break;
        }
        s->n = 0;
        s->child_args = NULL;
        if (re->nsub_ == 1)
          s->child_args = &s->child_arg;
        else if (re->nsub_ > 1)
          s->child_args = new T[re->nsub_];
        FALLTHROUGH_INTENDED;
      }
      default: {
        if (re->nsub_ > 0) {
          Regexp** sub = re->sub();
          if (s->n < re->nsub_) {
            if (use_copy && s->n > 0 && sub[s->n - 1] == sub[s->n]) {
              s->child_args[s->n] = Copy(s->child_args[s->n - 1]);
              s->n++;
            } else {
              stack_->push(WalkState<T>(sub[s->n], s->pre_arg));
            }
            continue;
          }
        }

        t = PostVisit(re, s->parent_arg, s->pre_arg, s->child_args, s->n);
        if (re->nsub_ > 1)
          delete[] s->child_args;
        break;
      }
    }

    // We've finished stack_->top().
    // Update next guy down.
    stack_->pop();
    if (stack_->size() == 0)
      return t;
    s = &stack_->top();
    if (s->child_args != NULL)
      s->child_args[s->n] = t;
    else
      s->child_arg = t;
    s->n++;
  }
}

template<typename T> T Regexp::Walker<T>::Walk(Regexp* re, T top_arg) {
  // Without the exponential walking behavior,
  // this budget should be more than enough for any
  // regexp, and yet not enough to get us in trouble
  // as far as CPU time.
  max_visits_ = 1000000;
  return WalkInternal(re, top_arg, true);
}

template<typename T> T Regexp::Walker<T>::WalkExponential(Regexp* re, T top_arg,
                                                          int max_visits) {
  max_visits_ = max_visits;
  return WalkInternal(re, top_arg, false);
}

}  // namespace re2

#endif  // RE2_WALKER_INL_H_


namespace re2 {

// List of pointers to Inst* that need to be filled in (patched).
// Because the Inst* haven't been filled in yet,
// we can use the Inst* word to hold the list's "next" pointer.
// It's kind of sleazy, but it works well in practice.
// See http://swtch.com/~rsc/regexp/regexp1.html for inspiration.
//
// Because the out and out1 fields in Inst are no longer pointers,
// we can't use pointers directly here either.  Instead, p refers
// to inst_[p>>1].out (p&1 == 0) or inst_[p>>1].out1 (p&1 == 1).
// p == 0 represents the NULL list.  This is okay because instruction #0
// is always the fail instruction, which never appears on a list.

struct PatchList {
  uint32_t p;

  // Returns patch list containing just p.
  static PatchList Mk(uint32_t p);

  // Patches all the entries on l to have value v.
  // Caller must not ever use patch list again.
  static void Patch(Prog::Inst *inst0, PatchList l, uint32_t v);

  // Deref returns the next pointer pointed at by p.
  static PatchList Deref(Prog::Inst *inst0, PatchList l);

  // Appends two patch lists and returns result.
  static PatchList Append(Prog::Inst *inst0, PatchList l1, PatchList l2);
};

static PatchList nullPatchList = { 0 };

// Returns patch list containing just p.
PatchList PatchList::Mk(uint32_t p) {
  PatchList l;
  l.p = p;
  return l;
}

// Returns the next pointer pointed at by l.
PatchList PatchList::Deref(Prog::Inst* inst0, PatchList l) {
  Prog::Inst* ip = &inst0[l.p>>1];
  if (l.p&1)
    l.p = ip->out1();
  else
    l.p = ip->out();
  return l;
}

// Patches all the entries on l to have value v.
void PatchList::Patch(Prog::Inst *inst0, PatchList l, uint32_t val) {
  while (l.p != 0) {
    Prog::Inst* ip = &inst0[l.p>>1];
    if (l.p&1) {
      l.p = ip->out1();
      ip->out1_ = val;
    } else {
      l.p = ip->out();
      ip->set_out(val);
    }
  }
}

// Appends two patch lists and returns result.
PatchList PatchList::Append(Prog::Inst* inst0, PatchList l1, PatchList l2) {
  if (l1.p == 0)
    return l2;
  if (l2.p == 0)
    return l1;

  PatchList l = l1;
  for (;;) {
    PatchList next = PatchList::Deref(inst0, l);
    if (next.p == 0)
      break;
    l = next;
  }

  Prog::Inst* ip = &inst0[l.p>>1];
  if (l.p&1)
    ip->out1_ = l2.p;
  else
    ip->set_out(l2.p);

  return l1;
}

// Compiled program fragment.
struct Frag {
  uint32_t begin;
  PatchList end;

  Frag() : begin(0) { end.p = 0; }  // needed so Frag can go in vector
  Frag(uint32_t begin, PatchList end) : begin(begin), end(end) {}
};

// Input encodings.
enum Encoding {
  kEncodingUTF8 = 1,  // UTF-8 (0-10FFFF)
  kEncodingLatin1,    // Latin-1 (0-FF)
};

class Compiler : public Regexp::Walker<Frag> {
 public:
  explicit Compiler();
  ~Compiler();

  // Compiles Regexp to a new Prog.
  // Caller is responsible for deleting Prog when finished with it.
  // If reversed is true, compiles for walking over the input
  // string backward (reverses all concatenations).
  static Prog *Compile(Regexp* re, bool reversed, int64_t max_mem);

  // Compiles alternation of all the re to a new Prog.
  // Each re has a match with an id equal to its index in the vector.
  static Prog* CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max_mem);

  // Interface for Regexp::Walker, which helps traverse the Regexp.
  // The walk is purely post-recursive: given the machines for the
  // children, PostVisit combines them to create the machine for
  // the current node.  The child_args are Frags.
  // The Compiler traverses the Regexp parse tree, visiting
  // each node in depth-first order.  It invokes PreVisit before
  // visiting the node's children and PostVisit after visiting
  // the children.
  Frag PreVisit(Regexp* re, Frag parent_arg, bool* stop);
  Frag PostVisit(Regexp* re, Frag parent_arg, Frag pre_arg, Frag* child_args,
                 int nchild_args);
  Frag ShortVisit(Regexp* re, Frag parent_arg);
  Frag Copy(Frag arg);

  // Given fragment a, returns a+ or a+?; a* or a*?; a? or a??
  Frag Plus(Frag a, bool nongreedy);
  Frag Star(Frag a, bool nongreedy);
  Frag Quest(Frag a, bool nongreedy);

  // Given fragment a, returns (a) capturing as \n.
  Frag Capture(Frag a, int n);

  // Given fragments a and b, returns ab; a|b
  Frag Cat(Frag a, Frag b);
  Frag Alt(Frag a, Frag b);

  // Returns a fragment that can't match anything.
  Frag NoMatch();

  // Returns a fragment that matches the empty string.
  Frag Match(int32_t id);

  // Returns a no-op fragment.
  Frag Nop();

  // Returns a fragment matching the byte range lo-hi.
  Frag ByteRange(int lo, int hi, bool foldcase);

  // Returns a fragment matching an empty-width special op.
  Frag EmptyWidth(EmptyOp op);

  // Adds n instructions to the program.
  // Returns the index of the first one.
  // Returns -1 if no more instructions are available.
  int AllocInst(int n);

  // Rune range compiler.

  // Begins a new alternation.
  void BeginRange();

  // Adds a fragment matching the rune range lo-hi.
  void AddRuneRange(Rune lo, Rune hi, bool foldcase);
  void AddRuneRangeLatin1(Rune lo, Rune hi, bool foldcase);
  void AddRuneRangeUTF8(Rune lo, Rune hi, bool foldcase);
  void Add_80_10ffff();

  // New suffix that matches the byte range lo-hi, then goes to next.
  int UncachedRuneByteSuffix(uint8_t lo, uint8_t hi, bool foldcase, int next);
  int CachedRuneByteSuffix(uint8_t lo, uint8_t hi, bool foldcase, int next);

  // Returns true iff the suffix is cached.
  bool IsCachedRuneByteSuffix(int id);

  // Adds a suffix to alternation.
  void AddSuffix(int id);

  // Adds a suffix to the trie starting from the given root node.
  // Returns zero iff allocating an instruction fails. Otherwise, returns
  // the current root node, which might be different from what was given.
  int AddSuffixRecursive(int root, int id);

  // Finds the trie node for the given suffix. Returns a Frag in order to
  // distinguish between pointing at the root node directly (end.p == 0)
  // and pointing at an Alt's out1 or out (end.p&1 == 1 or 0, respectively).
  Frag FindByteRange(int root, int id);

  // Compares two ByteRanges and returns true iff they are equal.
  bool ByteRangeEqual(int id1, int id2);

  // Returns the alternation of all the added suffixes.
  Frag EndRange();

  // Single rune.
  Frag Literal(Rune r, bool foldcase);

  void Setup(Regexp::ParseFlags, int64_t, RE2::Anchor);
  Prog* Finish();

  // Returns .* where dot = any byte
  Frag DotStar();

 private:
  Prog* prog_;         // Program being built.
  bool failed_;        // Did we give up compiling?
  Encoding encoding_;  // Input encoding
  bool reversed_;      // Should program run backward over text?

  PODArray<Prog::Inst> inst_;
  int ninst_;          // Number of instructions used.
  int max_ninst_;      // Maximum number of instructions.

  int64_t max_mem_;    // Total memory budget.

  std::unordered_map<uint64_t, int> rune_cache_;
  Frag rune_range_;

  RE2::Anchor anchor_;  // anchor mode for RE2::Set

  Compiler(const Compiler&) = delete;
  Compiler& operator=(const Compiler&) = delete;
};

Compiler::Compiler() {
  prog_ = new Prog();
  failed_ = false;
  encoding_ = kEncodingUTF8;
  reversed_ = false;
  ninst_ = 0;
  max_ninst_ = 1;  // make AllocInst for fail instruction okay
  max_mem_ = 0;
  int fail = AllocInst(1);
  inst_[fail].InitFail();
  max_ninst_ = 0;  // Caller must change
}

Compiler::~Compiler() {
  delete prog_;
}

int Compiler::AllocInst(int n) {
  if (failed_ || ninst_ + n > max_ninst_) {
    failed_ = true;
    return -1;
  }

  if (ninst_ + n > inst_.size()) {
    int cap = inst_.size();
    if (cap == 0)
      cap = 8;
    while (ninst_ + n > cap)
      cap *= 2;
    PODArray<Prog::Inst> inst(cap);
    if (inst_.data() != NULL)
      memmove(inst.data(), inst_.data(), ninst_*sizeof inst_[0]);
    memset(inst.data() + ninst_, 0, (cap - ninst_)*sizeof inst_[0]);
    inst_ = std::move(inst);
  }
  int id = ninst_;
  ninst_ += n;
  return id;
}

// These routines are somewhat hard to visualize in text --
// see http://swtch.com/~rsc/regexp/regexp1.html for
// pictures explaining what is going on here.

// Returns an unmatchable fragment.
Frag Compiler::NoMatch() {
  return Frag(0, nullPatchList);
}

// Is a an unmatchable fragment?
static bool IsNoMatch(Frag a) {
  return a.begin == 0;
}

// Given fragments a and b, returns fragment for ab.
Frag Compiler::Cat(Frag a, Frag b) {
  if (IsNoMatch(a) || IsNoMatch(b))
    return NoMatch();

  // Elide no-op.
  Prog::Inst* begin = &inst_[a.begin];
  if (begin->opcode() == kInstNop &&
      a.end.p == (a.begin << 1) &&
      begin->out() == 0) {
    // in case refs to a somewhere
    PatchList::Patch(inst_.data(), a.end, b.begin);
    return b;
  }

  // To run backward over string, reverse all concatenations.
  if (reversed_) {
    PatchList::Patch(inst_.data(), b.end, a.begin);
    return Frag(b.begin, a.end);
  }

  PatchList::Patch(inst_.data(), a.end, b.begin);
  return Frag(a.begin, b.end);
}

// Given fragments for a and b, returns fragment for a|b.
Frag Compiler::Alt(Frag a, Frag b) {
  // Special case for convenience in loops.
  if (IsNoMatch(a))
    return b;
  if (IsNoMatch(b))
    return a;

  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();

  inst_[id].InitAlt(a.begin, b.begin);
  return Frag(id, PatchList::Append(inst_.data(), a.end, b.end));
}

// When capturing submatches in like-Perl mode, a kOpAlt Inst
// treats out_ as the first choice, out1_ as the second.
//
// For *, +, and ?, if out_ causes another repetition,
// then the operator is greedy.  If out1_ is the repetition
// (and out_ moves forward), then the operator is non-greedy.

// Given a fragment a, returns a fragment for a* or a*? (if nongreedy)
Frag Compiler::Star(Frag a, bool nongreedy) {
  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();
  inst_[id].InitAlt(0, 0);
  PatchList::Patch(inst_.data(), a.end, id);
  if (nongreedy) {
    inst_[id].out1_ = a.begin;
    return Frag(id, PatchList::Mk(id << 1));
  } else {
    inst_[id].set_out(a.begin);
    return Frag(id, PatchList::Mk((id << 1) | 1));
  }
}

// Given a fragment for a, returns a fragment for a+ or a+? (if nongreedy)
Frag Compiler::Plus(Frag a, bool nongreedy) {
  // a+ is just a* with a different entry point.
  Frag f = Star(a, nongreedy);
  return Frag(a.begin, f.end);
}

// Given a fragment for a, returns a fragment for a? or a?? (if nongreedy)
Frag Compiler::Quest(Frag a, bool nongreedy) {
  if (IsNoMatch(a))
    return Nop();
  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();
  PatchList pl;
  if (nongreedy) {
    inst_[id].InitAlt(0, a.begin);
    pl = PatchList::Mk(id << 1);
  } else {
    inst_[id].InitAlt(a.begin, 0);
    pl = PatchList::Mk((id << 1) | 1);
  }
  return Frag(id, PatchList::Append(inst_.data(), pl, a.end));
}

// Returns a fragment for the byte range lo-hi.
Frag Compiler::ByteRange(int lo, int hi, bool foldcase) {
  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();
  inst_[id].InitByteRange(lo, hi, foldcase, 0);
  return Frag(id, PatchList::Mk(id << 1));
}

// Returns a no-op fragment.  Sometimes unavoidable.
Frag Compiler::Nop() {
  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();
  inst_[id].InitNop(0);
  return Frag(id, PatchList::Mk(id << 1));
}

// Returns a fragment that signals a match.
Frag Compiler::Match(int32_t match_id) {
  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();
  inst_[id].InitMatch(match_id);
  return Frag(id, nullPatchList);
}

// Returns a fragment matching a particular empty-width op (like ^ or $)
Frag Compiler::EmptyWidth(EmptyOp empty) {
  int id = AllocInst(1);
  if (id < 0)
    return NoMatch();
  inst_[id].InitEmptyWidth(empty, 0);
  return Frag(id, PatchList::Mk(id << 1));
}

// Given a fragment a, returns a fragment with capturing parens around a.
Frag Compiler::Capture(Frag a, int n) {
  if (IsNoMatch(a))
    return NoMatch();
  int id = AllocInst(2);
  if (id < 0)
    return NoMatch();
  inst_[id].InitCapture(2*n, a.begin);
  inst_[id+1].InitCapture(2*n+1, 0);
  PatchList::Patch(inst_.data(), a.end, id+1);

  return Frag(id, PatchList::Mk((id+1) << 1));
}

// A Rune is a name for a Unicode code point.
// Returns maximum rune encoded by UTF-8 sequence of length len.
static int MaxRune(int len) {
  int b;  // number of Rune bits in len-byte UTF-8 sequence (len < UTFmax)
  if (len == 1)
    b = 7;
  else
    b = 8-(len+1) + 6*(len-1);
  return (1<<b) - 1;   // maximum Rune for b bits.
}

// The rune range compiler caches common suffix fragments,
// which are very common in UTF-8 (e.g., [80-bf]).
// The fragment suffixes are identified by their start
// instructions.  NULL denotes the eventual end match.
// The Frag accumulates in rune_range_.  Caching common
// suffixes reduces the UTF-8 "." from 32 to 24 instructions,
// and it reduces the corresponding one-pass NFA from 16 nodes to 8.

void Compiler::BeginRange() {
  rune_cache_.clear();
  rune_range_.begin = 0;
  rune_range_.end = nullPatchList;
}

int Compiler::UncachedRuneByteSuffix(uint8_t lo, uint8_t hi, bool foldcase,
                                     int next) {
  Frag f = ByteRange(lo, hi, foldcase);
  if (next != 0) {
    PatchList::Patch(inst_.data(), f.end, next);
  } else {
    rune_range_.end = PatchList::Append(inst_.data(), rune_range_.end, f.end);
  }
  return f.begin;
}

static uint64_t MakeRuneCacheKey(uint8_t lo, uint8_t hi, bool foldcase,
                                 int next) {
  return (uint64_t)next << 17 |
         (uint64_t)lo   <<  9 |
         (uint64_t)hi   <<  1 |
         (uint64_t)foldcase;
}

int Compiler::CachedRuneByteSuffix(uint8_t lo, uint8_t hi, bool foldcase,
                                   int next) {
  uint64_t key = MakeRuneCacheKey(lo, hi, foldcase, next);
  std::unordered_map<uint64_t, int>::const_iterator it = rune_cache_.find(key);
  if (it != rune_cache_.end())
    return it->second;
  int id = UncachedRuneByteSuffix(lo, hi, foldcase, next);
  rune_cache_[key] = id;
  return id;
}

bool Compiler::IsCachedRuneByteSuffix(int id) {
  uint8_t lo = inst_[id].lo_;
  uint8_t hi = inst_[id].hi_;
  bool foldcase = inst_[id].foldcase() != 0;
  int next = inst_[id].out();

  uint64_t key = MakeRuneCacheKey(lo, hi, foldcase, next);
  return rune_cache_.find(key) != rune_cache_.end();
}

void Compiler::AddSuffix(int id) {
  if (failed_)
    return;

  if (rune_range_.begin == 0) {
    rune_range_.begin = id;
    return;
  }

  if (encoding_ == kEncodingUTF8) {
    // Build a trie in order to reduce fanout.
    rune_range_.begin = AddSuffixRecursive(rune_range_.begin, id);
    return;
  }

  int alt = AllocInst(1);
  if (alt < 0) {
    rune_range_.begin = 0;
    return;
  }
  inst_[alt].InitAlt(rune_range_.begin, id);
  rune_range_.begin = alt;
}

int Compiler::AddSuffixRecursive(int root, int id) {
  DCHECK(inst_[root].opcode() == kInstAlt ||
         inst_[root].opcode() == kInstByteRange);

  Frag f = FindByteRange(root, id);
  if (IsNoMatch(f)) {
    int alt = AllocInst(1);
    if (alt < 0)
      return 0;
    inst_[alt].InitAlt(root, id);
    return alt;
  }

  int br;
  if (f.end.p == 0)
    br = root;
  else if (f.end.p&1)
    br = inst_[f.begin].out1();
  else
    br = inst_[f.begin].out();

  if (IsCachedRuneByteSuffix(br)) {
    // We can't fiddle with cached suffixes, so make a clone of the head.
    int byterange = AllocInst(1);
    if (byterange < 0)
      return 0;
    inst_[byterange].InitByteRange(inst_[br].lo(), inst_[br].hi(),
                                   inst_[br].foldcase(), inst_[br].out());

    // Ensure that the parent points to the clone, not to the original.
    // Note that this could leave the head unreachable except via the cache.
    br = byterange;
    if (f.end.p == 0)
      root = br;
    else if (f.end.p&1)
      inst_[f.begin].out1_ = br;
    else
      inst_[f.begin].set_out(br);
  }

  int out = inst_[id].out();
  if (!IsCachedRuneByteSuffix(id)) {
    // The head should be the instruction most recently allocated, so free it
    // instead of leaving it unreachable.
    DCHECK_EQ(id, ninst_-1);
    inst_[id].out_opcode_ = 0;
    inst_[id].out1_ = 0;
    ninst_--;
  }

  out = AddSuffixRecursive(inst_[br].out(), out);
  if (out == 0)
    return 0;

  inst_[br].set_out(out);
  return root;
}

bool Compiler::ByteRangeEqual(int id1, int id2) {
  return inst_[id1].lo() == inst_[id2].lo() &&
         inst_[id1].hi() == inst_[id2].hi() &&
         inst_[id1].foldcase() == inst_[id2].foldcase();
}

Frag Compiler::FindByteRange(int root, int id) {
  if (inst_[root].opcode() == kInstByteRange) {
    if (ByteRangeEqual(root, id))
      return Frag(root, nullPatchList);
    else
      return NoMatch();
  }

  while (inst_[root].opcode() == kInstAlt) {
    int out1 = inst_[root].out1();
    if (ByteRangeEqual(out1, id))
      return Frag(root, PatchList::Mk((root << 1) | 1));

    // CharClass is a sorted list of ranges, so if out1 of the root Alt wasn't
    // what we're looking for, then we can stop immediately. Unfortunately, we
    // can't short-circuit the search in reverse mode.
    if (!reversed_)
      return NoMatch();

    int out = inst_[root].out();
    if (inst_[out].opcode() == kInstAlt)
      root = out;
    else if (ByteRangeEqual(out, id))
      return Frag(root, PatchList::Mk(root << 1));
    else
      return NoMatch();
  }

  LOG(DFATAL) << "should never happen";
  return NoMatch();
}

Frag Compiler::EndRange() {
  return rune_range_;
}

// Converts rune range lo-hi into a fragment that recognizes
// the bytes that would make up those runes in the current
// encoding (Latin 1 or UTF-8).
// This lets the machine work byte-by-byte even when
// using multibyte encodings.

void Compiler::AddRuneRange(Rune lo, Rune hi, bool foldcase) {
  switch (encoding_) {
    default:
    case kEncodingUTF8:
      AddRuneRangeUTF8(lo, hi, foldcase);
      break;
    case kEncodingLatin1:
      AddRuneRangeLatin1(lo, hi, foldcase);
      break;
  }
}

void Compiler::AddRuneRangeLatin1(Rune lo, Rune hi, bool foldcase) {
  // Latin-1 is easy: runes *are* bytes.
  if (lo > hi || lo > 0xFF)
    return;
  if (hi > 0xFF)
    hi = 0xFF;
  AddSuffix(UncachedRuneByteSuffix(static_cast<uint8_t>(lo),
                                   static_cast<uint8_t>(hi), foldcase, 0));
}

// Table describing how to make a UTF-8 matching machine
// for the rune range 80-10FFFF (Runeself-Runemax).
// This range happens frequently enough (for example /./ and /[^a-z]/)
// and the rune_cache_ map is slow enough that this is worth
// special handling.  Makes compilation of a small expression
// with a dot in it about 10% faster.
// The * in the comments below mark whole sequences.
static struct ByteRangeProg {
  int next;
  int lo;
  int hi;
} prog_80_10ffff[] = {
  // Two-byte
  { -1, 0x80, 0xBF, },  // 0:  80-BF
  {  0, 0xC2, 0xDF, },  // 1:  C2-DF 80-BF*

  // Three-byte
  {  0, 0xA0, 0xBF, },  // 2:  A0-BF 80-BF
  {  2, 0xE0, 0xE0, },  // 3:  E0 A0-BF 80-BF*
  {  0, 0x80, 0xBF, },  // 4:  80-BF 80-BF
  {  4, 0xE1, 0xEF, },  // 5:  E1-EF 80-BF 80-BF*

  // Four-byte
  {  4, 0x90, 0xBF, },  // 6:  90-BF 80-BF 80-BF
  {  6, 0xF0, 0xF0, },  // 7:  F0 90-BF 80-BF 80-BF*
  {  4, 0x80, 0xBF, },  // 8:  80-BF 80-BF 80-BF
  {  8, 0xF1, 0xF3, },  // 9: F1-F3 80-BF 80-BF 80-BF*
  {  4, 0x80, 0x8F, },  // 10: 80-8F 80-BF 80-BF
  { 10, 0xF4, 0xF4, },  // 11: F4 80-8F 80-BF 80-BF*
};

void Compiler::Add_80_10ffff() {
  int inst[arraysize(prog_80_10ffff)] = { 0 }; // does not need to be initialized; silences gcc warning
  for (int i = 0; i < arraysize(prog_80_10ffff); i++) {
    const ByteRangeProg& p = prog_80_10ffff[i];
    int next = 0;
    if (p.next >= 0)
      next = inst[p.next];
    inst[i] = UncachedRuneByteSuffix(static_cast<uint8_t>(p.lo),
                                     static_cast<uint8_t>(p.hi), false, next);
    if ((p.lo & 0xC0) != 0x80)
      AddSuffix(inst[i]);
  }
}

void Compiler::AddRuneRangeUTF8(Rune lo, Rune hi, bool foldcase) {
  if (lo > hi)
    return;

  // Pick off 80-10FFFF as a common special case
  // that can bypass the slow rune_cache_.
  if (lo == 0x80 && hi == 0x10ffff && !reversed_) {
    Add_80_10ffff();
    return;
  }

  // Split range into same-length sized ranges.
  for (int i = 1; i < UTFmax; i++) {
    Rune max = MaxRune(i);
    if (lo <= max && max < hi) {
      AddRuneRangeUTF8(lo, max, foldcase);
      AddRuneRangeUTF8(max+1, hi, foldcase);
      return;
    }
  }

  // ASCII range is always a special case.
  if (hi < Runeself) {
    AddSuffix(UncachedRuneByteSuffix(static_cast<uint8_t>(lo),
                                     static_cast<uint8_t>(hi), foldcase, 0));
    return;
  }

  // Split range into sections that agree on leading bytes.
  for (int i = 1; i < UTFmax; i++) {
    uint32_t m = (1<<(6*i)) - 1;  // last i bytes of a UTF-8 sequence
    if ((lo & ~m) != (hi & ~m)) {
      if ((lo & m) != 0) {
        AddRuneRangeUTF8(lo, lo|m, foldcase);
        AddRuneRangeUTF8((lo|m)+1, hi, foldcase);
        return;
      }
      if ((hi & m) != m) {
        AddRuneRangeUTF8(lo, (hi&~m)-1, foldcase);
        AddRuneRangeUTF8(hi&~m, hi, foldcase);
        return;
      }
    }
  }

  // Finally.  Generate byte matching equivalent for lo-hi.
  uint8_t ulo[UTFmax], uhi[UTFmax];
  int n = runetochar(reinterpret_cast<char*>(ulo), &lo);
  int m = runetochar(reinterpret_cast<char*>(uhi), &hi);
  (void)m;  // USED(m)
  DCHECK_EQ(n, m);

  // The logic below encodes this thinking:
  //
  // 1. When we have built the whole suffix, we know that it cannot
  // possibly be a suffix of anything longer: in forward mode, nothing
  // else can occur before the leading byte; in reverse mode, nothing
  // else can occur after the last continuation byte or else the leading
  // byte would have to change. Thus, there is no benefit to caching
  // the first byte of the suffix whereas there is a cost involved in
  // cloning it if it begins a common prefix, which is fairly likely.
  //
  // 2. Conversely, the last byte of the suffix cannot possibly be a
  // prefix of anything because next == 0, so we will never want to
  // clone it, but it is fairly likely to be a common suffix. Perhaps
  // more so in reverse mode than in forward mode because the former is
  // "converging" towards lower entropy, but caching is still worthwhile
  // for the latter in cases such as 80-BF.
  //
  // 3. Handling the bytes between the first and the last is less
  // straightforward and, again, the approach depends on whether we are
  // "converging" towards lower entropy: in forward mode, a single byte
  // is unlikely to be part of a common suffix whereas a byte range
  // is more likely so; in reverse mode, a byte range is unlikely to
  // be part of a common suffix whereas a single byte is more likely
  // so. The same benefit versus cost argument applies here.
  int id = 0;
  if (reversed_) {
    for (int i = 0; i < n; i++) {
      // In reverse UTF-8 mode: cache the leading byte; don't cache the last
      // continuation byte; cache anything else iff it's a single byte (XX-XX).
      if (i == 0 || (ulo[i] == uhi[i] && i != n-1))
        id = CachedRuneByteSuffix(ulo[i], uhi[i], false, id);
      else
        id = UncachedRuneByteSuffix(ulo[i], uhi[i], false, id);
    }
  } else {
    for (int i = n-1; i >= 0; i--) {
      // In forward UTF-8 mode: don't cache the leading byte; cache the last
      // continuation byte; cache anything else iff it's a byte range (XX-YY).
      if (i == n-1 || (ulo[i] < uhi[i] && i != 0))
        id = CachedRuneByteSuffix(ulo[i], uhi[i], false, id);
      else
        id = UncachedRuneByteSuffix(ulo[i], uhi[i], false, id);
    }
  }
  AddSuffix(id);
}

// Should not be called.
Frag Compiler::Copy(Frag arg) {
  // We're using WalkExponential; there should be no copying.
  LOG(DFATAL) << "Compiler::Copy called!";
  failed_ = true;
  return NoMatch();
}

// Visits a node quickly; called once WalkExponential has
// decided to cut this walk short.
Frag Compiler::ShortVisit(Regexp* re, Frag) {
  failed_ = true;
  return NoMatch();
}

// Called before traversing a node's children during the walk.
Frag Compiler::PreVisit(Regexp* re, Frag, bool* stop) {
  // Cut off walk if we've already failed.
  if (failed_)
    *stop = true;

  return Frag();  // not used by caller
}

Frag Compiler::Literal(Rune r, bool foldcase) {
  switch (encoding_) {
    default:
      return Frag();

    case kEncodingLatin1:
      return ByteRange(r, r, foldcase);

    case kEncodingUTF8: {
      if (r < Runeself)  // Make common case fast.
        return ByteRange(r, r, foldcase);
      uint8_t buf[UTFmax];
      int n = runetochar(reinterpret_cast<char*>(buf), &r);
      Frag f = ByteRange((uint8_t)buf[0], buf[0], false);
      for (int i = 1; i < n; i++)
        f = Cat(f, ByteRange((uint8_t)buf[i], buf[i], false));
      return f;
    }
  }
}

// Called after traversing the node's children during the walk.
// Given their frags, build and return the frag for this re.
Frag Compiler::PostVisit(Regexp* re, Frag, Frag, Frag* child_frags,
                         int nchild_frags) {
  // If a child failed, don't bother going forward, especially
  // since the child_frags might contain Frags with NULLs in them.
  if (failed_)
    return NoMatch();

  // Given the child fragments, return the fragment for this node.
  switch (re->op()) {
    case kRegexpRepeat:
      // Should not see; code at bottom of function will print error
      break;

    case kRegexpNoMatch:
      return NoMatch();

    case kRegexpEmptyMatch:
      return Nop();

    case kRegexpHaveMatch: {
      Frag f = Match(re->match_id());
      if (anchor_ == RE2::ANCHOR_BOTH) {
        // Append \z or else the subexpression will effectively be unanchored.
        // Complemented by the UNANCHORED case in CompileSet().
        f = Cat(EmptyWidth(kEmptyEndText), f);
      }
      return f;
    }

    case kRegexpConcat: {
      Frag f = child_frags[0];
      for (int i = 1; i < nchild_frags; i++)
        f = Cat(f, child_frags[i]);
      return f;
    }

    case kRegexpAlternate: {
      Frag f = child_frags[0];
      for (int i = 1; i < nchild_frags; i++)
        f = Alt(f, child_frags[i]);
      return f;
    }

    case kRegexpStar:
      return Star(child_frags[0], (re->parse_flags()&Regexp::NonGreedy) != 0);

    case kRegexpPlus:
      return Plus(child_frags[0], (re->parse_flags()&Regexp::NonGreedy) != 0);

    case kRegexpQuest:
      return Quest(child_frags[0], (re->parse_flags()&Regexp::NonGreedy) != 0);

    case kRegexpLiteral:
      return Literal(re->rune(), (re->parse_flags()&Regexp::FoldCase) != 0);

    case kRegexpLiteralString: {
      // Concatenation of literals.
      if (re->nrunes() == 0)
        return Nop();
      Frag f;
      for (int i = 0; i < re->nrunes(); i++) {
        Frag f1 = Literal(re->runes()[i],
                          (re->parse_flags()&Regexp::FoldCase) != 0);
        if (i == 0)
          f = f1;
        else
          f = Cat(f, f1);
      }
      return f;
    }

    case kRegexpAnyChar:
      BeginRange();
      AddRuneRange(0, Runemax, false);
      return EndRange();

    case kRegexpAnyByte:
      return ByteRange(0x00, 0xFF, false);

    case kRegexpCharClass: {
      CharClass* cc = re->cc();
      if (cc->empty()) {
        // This can't happen.
        LOG(DFATAL) << "No ranges in char class";
        failed_ = true;
        return NoMatch();
      }

      // ASCII case-folding optimization: if the char class
      // behaves the same on A-Z as it does on a-z,
      // discard any ranges wholly contained in A-Z
      // and mark the other ranges as foldascii.
      // This reduces the size of a program for
      // (?i)abc from 3 insts per letter to 1 per letter.
      bool foldascii = cc->FoldsASCII();

      // Character class is just a big OR of the different
      // character ranges in the class.
      BeginRange();
      for (CharClass::iterator i = cc->begin(); i != cc->end(); ++i) {
        // ASCII case-folding optimization (see above).
        if (foldascii && 'A' <= i->lo && i->hi <= 'Z')
          continue;

        // If this range contains all of A-Za-z or none of it,
        // the fold flag is unnecessary; don't bother.
        bool fold = foldascii;
        if ((i->lo <= 'A' && 'z' <= i->hi) || i->hi < 'A' || 'z' < i->lo ||
            ('Z' < i->lo && i->hi < 'a'))
          fold = false;

        AddRuneRange(i->lo, i->hi, fold);
      }
      return EndRange();
    }

    case kRegexpCapture:
      // If this is a non-capturing parenthesis -- (?:foo) --
      // just use the inner expression.
      if (re->cap() < 0)
        return child_frags[0];
      return Capture(child_frags[0], re->cap());

    case kRegexpBeginLine:
      return EmptyWidth(reversed_ ? kEmptyEndLine : kEmptyBeginLine);

    case kRegexpEndLine:
      return EmptyWidth(reversed_ ? kEmptyBeginLine : kEmptyEndLine);

    case kRegexpBeginText:
      return EmptyWidth(reversed_ ? kEmptyEndText : kEmptyBeginText);

    case kRegexpEndText:
      return EmptyWidth(reversed_ ? kEmptyBeginText : kEmptyEndText);

    case kRegexpWordBoundary:
      return EmptyWidth(kEmptyWordBoundary);

    case kRegexpNoWordBoundary:
      return EmptyWidth(kEmptyNonWordBoundary);
  }
  LOG(DFATAL) << "Missing case in Compiler: " << re->op();
  failed_ = true;
  return NoMatch();
}

// Is this regexp required to start at the beginning of the text?
// Only approximate; can return false for complicated regexps like (\Aa|\Ab),
// but handles (\A(a|b)).  Could use the Walker to write a more exact one.
static bool IsAnchorStart(Regexp** pre, int depth) {
  Regexp* re = *pre;
  Regexp* sub;
  // The depth limit makes sure that we don't overflow
  // the stack on a deeply nested regexp.  As the comment
  // above says, IsAnchorStart is conservative, so returning
  // a false negative is okay.  The exact limit is somewhat arbitrary.
  if (re == NULL || depth >= 4)
    return false;
  switch (re->op()) {
    default:
      break;
    case kRegexpConcat:
      if (re->nsub() > 0) {
        sub = re->sub()[0]->Incref();
        if (IsAnchorStart(&sub, depth+1)) {
          PODArray<Regexp*> subcopy(re->nsub());
          subcopy[0] = sub;  // already have reference
          for (int i = 1; i < re->nsub(); i++)
            subcopy[i] = re->sub()[i]->Incref();
          *pre = Regexp::Concat(subcopy.data(), re->nsub(), re->parse_flags());
          re->Decref();
          return true;
        }
        sub->Decref();
      }
      break;
    case kRegexpCapture:
      sub = re->sub()[0]->Incref();
      if (IsAnchorStart(&sub, depth+1)) {
        *pre = Regexp::Capture(sub, re->parse_flags(), re->cap());
        re->Decref();
        return true;
      }
      sub->Decref();
      break;
    case kRegexpBeginText:
      *pre = Regexp::LiteralString(NULL, 0, re->parse_flags());
      re->Decref();
      return true;
  }
  return false;
}

// Is this regexp required to start at the end of the text?
// Only approximate; can return false for complicated regexps like (a\z|b\z),
// but handles ((a|b)\z).  Could use the Walker to write a more exact one.
static bool IsAnchorEnd(Regexp** pre, int depth) {
  Regexp* re = *pre;
  Regexp* sub;
  // The depth limit makes sure that we don't overflow
  // the stack on a deeply nested regexp.  As the comment
  // above says, IsAnchorEnd is conservative, so returning
  // a false negative is okay.  The exact limit is somewhat arbitrary.
  if (re == NULL || depth >= 4)
    return false;
  switch (re->op()) {
    default:
      break;
    case kRegexpConcat:
      if (re->nsub() > 0) {
        sub = re->sub()[re->nsub() - 1]->Incref();
        if (IsAnchorEnd(&sub, depth+1)) {
          PODArray<Regexp*> subcopy(re->nsub());
          subcopy[re->nsub() - 1] = sub;  // already have reference
          for (int i = 0; i < re->nsub() - 1; i++)
            subcopy[i] = re->sub()[i]->Incref();
          *pre = Regexp::Concat(subcopy.data(), re->nsub(), re->parse_flags());
          re->Decref();
          return true;
        }
        sub->Decref();
      }
      break;
    case kRegexpCapture:
      sub = re->sub()[0]->Incref();
      if (IsAnchorEnd(&sub, depth+1)) {
        *pre = Regexp::Capture(sub, re->parse_flags(), re->cap());
        re->Decref();
        return true;
      }
      sub->Decref();
      break;
    case kRegexpEndText:
      *pre = Regexp::LiteralString(NULL, 0, re->parse_flags());
      re->Decref();
      return true;
  }
  return false;
}

void Compiler::Setup(Regexp::ParseFlags flags, int64_t max_mem,
                     RE2::Anchor anchor) {
  prog_->set_flags(flags);

  if (flags & Regexp::Latin1)
    encoding_ = kEncodingLatin1;
  max_mem_ = max_mem;
  if (max_mem <= 0) {
    max_ninst_ = 100000;  // more than enough
  } else if (static_cast<size_t>(max_mem) <= sizeof(Prog)) {
    // No room for anything.
    max_ninst_ = 0;
  } else {
    int64_t m = (max_mem - sizeof(Prog)) / sizeof(Prog::Inst);
    // Limit instruction count so that inst->id() fits nicely in an int.
    // SparseArray also assumes that the indices (inst->id()) are ints.
    // The call to WalkExponential uses 2*max_ninst_ below,
    // and other places in the code use 2 or 3 * prog->size().
    // Limiting to 2^24 should avoid overflow in those places.
    // (The point of allowing more than 32 bits of memory is to
    // have plenty of room for the DFA states, not to use it up
    // on the program.)
    if (m >= 1<<24)
      m = 1<<24;

    // Inst imposes its own limit (currently bigger than 2^24 but be safe).
    if (m > Prog::Inst::kMaxInst)
      m = Prog::Inst::kMaxInst;

    max_ninst_ = static_cast<int>(m);
  }

  anchor_ = anchor;
}

// Compiles re, returning program.
// Caller is responsible for deleting prog_.
// If reversed is true, compiles a program that expects
// to run over the input string backward (reverses all concatenations).
// The reversed flag is also recorded in the returned program.
Prog* Compiler::Compile(Regexp* re, bool reversed, int64_t max_mem) {
  Compiler c;
  c.Setup(re->parse_flags(), max_mem, RE2::UNANCHORED /* unused */);
  c.reversed_ = reversed;

  // Simplify to remove things like counted repetitions
  // and character classes like \d.
  Regexp* sre = re->Simplify();
  if (sre == NULL)
    return NULL;

  // Record whether prog is anchored, removing the anchors.
  // (They get in the way of other optimizations.)
  bool is_anchor_start = IsAnchorStart(&sre, 0);
  bool is_anchor_end = IsAnchorEnd(&sre, 0);

  // Generate fragment for entire regexp.
  Frag all = c.WalkExponential(sre, Frag(), 2*c.max_ninst_);
  sre->Decref();
  if (c.failed_)
    return NULL;

  // Success!  Finish by putting Match node at end, and record start.
  // Turn off c.reversed_ (if it is set) to force the remaining concatenations
  // to behave normally.
  c.reversed_ = false;
  all = c.Cat(all, c.Match(0));

  c.prog_->set_reversed(reversed);
  if (c.prog_->reversed()) {
    c.prog_->set_anchor_start(is_anchor_end);
    c.prog_->set_anchor_end(is_anchor_start);
  } else {
    c.prog_->set_anchor_start(is_anchor_start);
    c.prog_->set_anchor_end(is_anchor_end);
  }

  c.prog_->set_start(all.begin);
  if (!c.prog_->anchor_start()) {
    // Also create unanchored version, which starts with a .*? loop.
    all = c.Cat(c.DotStar(), all);
  }
  c.prog_->set_start_unanchored(all.begin);

  // Hand ownership of prog_ to caller.
  return c.Finish();
}

Prog* Compiler::Finish() {
  if (failed_)
    return NULL;

  if (prog_->start() == 0 && prog_->start_unanchored() == 0) {
    // No possible matches; keep Fail instruction only.
    ninst_ = 1;
  }

  // Hand off the array to Prog.
  prog_->inst_ = std::move(inst_);
  prog_->size_ = ninst_;

  prog_->Optimize();
  prog_->Flatten();
  prog_->ComputeByteMap();

  // Record remaining memory for DFA.
  if (max_mem_ <= 0) {
    prog_->set_dfa_mem(1<<20);
  } else {
    int64_t m = max_mem_ - sizeof(Prog);
    m -= prog_->size_*sizeof(Prog::Inst);  // account for inst_
    if (prog_->CanBitState())
      m -= prog_->size_*sizeof(uint16_t);  // account for list_heads_
    if (m < 0)
      m = 0;
    prog_->set_dfa_mem(m);
  }

  Prog* p = prog_;
  prog_ = NULL;
  return p;
}

// Converts Regexp to Prog.
Prog* Regexp::CompileToProg(int64_t max_mem) {
  return Compiler::Compile(this, false, max_mem);
}

Prog* Regexp::CompileToReverseProg(int64_t max_mem) {
  return Compiler::Compile(this, true, max_mem);
}

Frag Compiler::DotStar() {
  return Star(ByteRange(0x00, 0xff, false), true);
}

// Compiles RE set to Prog.
Prog* Compiler::CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max_mem) {
  Compiler c;
  c.Setup(re->parse_flags(), max_mem, anchor);

  Regexp* sre = re->Simplify();
  if (sre == NULL)
    return NULL;

  Frag all = c.WalkExponential(sre, Frag(), 2*c.max_ninst_);
  sre->Decref();
  if (c.failed_)
    return NULL;

  c.prog_->set_anchor_start(true);
  c.prog_->set_anchor_end(true);

  if (anchor == RE2::UNANCHORED) {
    // Prepend .* or else the expression will effectively be anchored.
    // Complemented by the ANCHOR_BOTH case in PostVisit().
    all = c.Cat(c.DotStar(), all);
  }
  c.prog_->set_start(all.begin);
  c.prog_->set_start_unanchored(all.begin);

  Prog* prog = c.Finish();
  if (prog == NULL)
    return NULL;

  // Make sure DFA has enough memory to operate,
  // since we're not going to fall back to the NFA.
  bool dfa_failed = false;
  StringPiece sp = "hello, world";
  prog->SearchDFA(sp, sp, Prog::kAnchored, Prog::kManyMatch,
                  NULL, &dfa_failed, NULL);
  if (dfa_failed) {
    delete prog;
    return NULL;
  }

  return prog;
}

Prog* Prog::CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max_mem) {
  return Compiler::CompileSet(re, anchor, max_mem);
}

}  // namespace re2
// Copyright 2008 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// A DFA (deterministic finite automaton)-based regular expression search.
//
// The DFA search has two main parts: the construction of the automaton,
// which is represented by a graph of State structures, and the execution
// of the automaton over a given input string.
//
// The basic idea is that the State graph is constructed so that the
// execution can simply start with a state s, and then for each byte c in
// the input string, execute "s = s->next[c]", checking at each point whether
// the current s represents a matching state.
//
// The simple explanation just given does convey the essence of this code,
// but it omits the details of how the State graph gets constructed as well
// as some performance-driven optimizations to the execution of the automaton.
// All these details are explained in the comments for the code following
// the definition of class DFA.
//
// See http://swtch.com/~rsc/regexp/ for a very bare-bones equivalent.

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <atomic>
#include <deque>
#include <mutex>
#include <new>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>


// Copyright 2016 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_MIX_H_
#define UTIL_MIX_H_

#include <stddef.h>
#include <limits>

namespace re2 {

// Silence "truncation of constant value" warning for kMul in 32-bit mode.
// Since this is a header file, push and then pop to limit the scope.
#ifdef _MSC_VER
//#pragma warning(push)
//#pragma warning(disable: 4309)
#endif

class HashMix {
 public:
  HashMix() : hash_(1) {}
  explicit HashMix(size_t val) : hash_(val + 83) {}
  void Mix(size_t val) {
    static const size_t kMul = static_cast<size_t>(0xdc3eb94af8ab4c93ULL);
    hash_ *= kMul;
    hash_ = ((hash_ << 19) |
             (hash_ >> (std::numeric_limits<size_t>::digits - 19))) + val;
  }
  size_t get() const { return hash_; }
 private:
  size_t hash_;
};

#ifdef _MSC_VER
//#pragma warning(pop)
#endif

}  // namespace re2

#endif  // UTIL_MIX_H_

// Copyright 2007 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_MUTEX_H_
#define UTIL_MUTEX_H_

/*
 * A simple mutex wrapper, supporting locks and read-write locks.
 * You should assume the locks are *not* re-entrant.
 */

#if !defined(_WIN32)
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
#include <unistd.h>
//#if defined(_POSIX_READER_WRITER_LOCKS) && _POSIX_READER_WRITER_LOCKS > 0
//#define MUTEX_IS_PTHREAD_RWLOCK
//#endif
#endif

#if defined(MUTEX_IS_PTHREAD_RWLOCK)
#error We really dont want to include pthread
#include <pthread.h>
#include <stdlib.h>
typedef pthread_rwlock_t MutexType;
#else
#include <mutex>
typedef std::mutex MutexType;
#endif

namespace re2 {

class Mutex {
 public:
  inline Mutex();
  inline ~Mutex();
  inline void Lock();    // Block if needed until free then acquire exclusively
  inline void Unlock();  // Release a lock acquired via Lock()
  // Note that on systems that don't support read-write locks, these may
  // be implemented as synonyms to Lock() and Unlock().  So you can use
  // these for efficiency, but don't use them anyplace where being able
  // to do shared reads is necessary to avoid deadlock.
  inline void ReaderLock();   // Block until free or shared then acquire a share
  inline void ReaderUnlock(); // Release a read share of this Mutex
  inline void WriterLock() { Lock(); }     // Acquire an exclusive lock
  inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()

 private:
  MutexType mutex_;

  // Catch the error of writing Mutex when intending MutexLock.
  Mutex(Mutex *ignored);

  Mutex(const Mutex&) = delete;
  Mutex& operator=(const Mutex&) = delete;
};

#if defined(MUTEX_IS_PTHREAD_RWLOCK)

#define SAFE_PTHREAD(fncall)    \
  do {                          \
    if ((fncall) != 0) abort(); \
  } while (0)

Mutex::Mutex()             { SAFE_PTHREAD(pthread_rwlock_init(&mutex_, NULL)); }
Mutex::~Mutex()            { SAFE_PTHREAD(pthread_rwlock_destroy(&mutex_)); }
void Mutex::Lock()         { SAFE_PTHREAD(pthread_rwlock_wrlock(&mutex_)); }
void Mutex::Unlock()       { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
void Mutex::ReaderLock()   { SAFE_PTHREAD(pthread_rwlock_rdlock(&mutex_)); }
void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }

#undef SAFE_PTHREAD

#else

Mutex::Mutex()             { }
Mutex::~Mutex()            { }
void Mutex::Lock()         { mutex_.lock(); }
void Mutex::Unlock()       { mutex_.unlock(); }
void Mutex::ReaderLock()   { Lock(); }  // C++11 doesn't have std::shared_mutex.
void Mutex::ReaderUnlock() { Unlock(); }

#endif

// --------------------------------------------------------------------------
// Some helper classes

// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
class MutexLock {
 public:
  explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
  ~MutexLock() { mu_->Unlock(); }
 private:
  Mutex * const mu_;

  MutexLock(const MutexLock&) = delete;
  MutexLock& operator=(const MutexLock&) = delete;
};

// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
class ReaderMutexLock {
 public:
  explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
  ~ReaderMutexLock() { mu_->ReaderUnlock(); }
 private:
  Mutex * const mu_;

  ReaderMutexLock(const ReaderMutexLock&) = delete;
  ReaderMutexLock& operator=(const ReaderMutexLock&) = delete;
};

class WriterMutexLock {
 public:
  explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
  ~WriterMutexLock() { mu_->WriterUnlock(); }
 private:
  Mutex * const mu_;

  WriterMutexLock(const WriterMutexLock&) = delete;
  WriterMutexLock& operator=(const WriterMutexLock&) = delete;
};

// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
#define MutexLock(x) static_assert(false, "MutexLock declaration missing variable name")
#define ReaderMutexLock(x) static_assert(false, "ReaderMutexLock declaration missing variable name")
#define WriterMutexLock(x) static_assert(false, "WriterMutexLock declaration missing variable name")

}  // namespace re2

#endif  // UTIL_MUTEX_H_



// Copyright 2016 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef UTIL_STRUTIL_H_
#define UTIL_STRUTIL_H_

#include <string>




namespace re2 {

std::string CEscape(const StringPiece& src);
void PrefixSuccessor(std::string* prefix);
std::string StringPrintf(const char* format, ...);
void SStringPrintf(std::string* dst, const char* format, ...);
void StringAppendF(std::string* dst, const char* format, ...);

}  // namespace re2

#endif  // UTIL_STRUTIL_H_




// Silence "zero-sized array in struct/union" warning for DFA::State::next_.
#ifdef _MSC_VER
//#pragma warning(disable: 4200)
#endif

namespace re2 {

#if !defined(__linux__)  /* only Linux seems to have memrchr */
static void* memrchr(const void* s, int c, size_t n) {
  const unsigned char* p = (const unsigned char*)s;
  for (p += n; n > 0; n--)
    if (*--p == c)
      return (void*)p;

  return NULL;
}
#endif

// Controls whether the DFA should bail out early if the NFA would be faster.
static bool dfa_should_bail_when_slow = true;

// A DFA implementation of a regular expression program.
// Since this is entirely a forward declaration mandated by C++,
// some of the comments here are better understood after reading
// the comments in the sections that follow the DFA definition.
class DFA {
 public:
  DFA(Prog* prog, Prog::MatchKind kind, int64_t max_mem);
  ~DFA();
  bool ok() const { return !init_failed_; }
  Prog::MatchKind kind() { return kind_; }

  // Searches for the regular expression in text, which is considered
  // as a subsection of context for the purposes of interpreting flags
  // like ^ and $ and \A and \z.
  // Returns whether a match was found.
  // If a match is found, sets *ep to the end point of the best match in text.
  // If "anchored", the match must begin at the start of text.
  // If "want_earliest_match", the match that ends first is used, not
  //   necessarily the best one.
  // If "run_forward" is true, the DFA runs from text.begin() to text.end().
  //   If it is false, the DFA runs from text.end() to text.begin(),
  //   returning the leftmost end of the match instead of the rightmost one.
  // If the DFA cannot complete the search (for example, if it is out of
  //   memory), it sets *failed and returns false.
  bool Search(const StringPiece& text, const StringPiece& context,
              bool anchored, bool want_earliest_match, bool run_forward,
              bool* failed, const char** ep, SparseSet* matches);

  // Builds out all states for the entire DFA.
  // If cb is not empty, it receives one callback per state built.
  // Returns the number of states built.
  // FOR TESTING OR EXPERIMENTAL PURPOSES ONLY.
  int BuildAllStates(const Prog::DFAStateCallback& cb);

  // Computes min and max for matching strings.  Won't return strings
  // bigger than maxlen.
  bool PossibleMatchRange(std::string* min, std::string* max, int maxlen);

  // These data structures are logically private, but C++ makes it too
  // difficult to mark them as such.
  class RWLocker;
  class StateSaver;
  class Workq;

  // A single DFA state.  The DFA is represented as a graph of these
  // States, linked by the next_ pointers.  If in state s and reading
  // byte c, the next state should be s->next_[c].
  struct State {
    inline bool IsMatch() const { return (flag_ & kFlagMatch) != 0; }
    void SaveMatch(std::vector<int>* v);

    int* inst_;         // Instruction pointers in the state.
    int ninst_;         // # of inst_ pointers.
    uint32_t flag_;     // Empty string bitfield flags in effect on the way
                        // into this state, along with kFlagMatch if this
                        // is a matching state.

// Work around the bug affecting flexible array members in GCC 6.x (for x >= 1).
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70932)
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && __GNUC_MINOR__ >= 1
    std::atomic<State*> next_[0];   // Outgoing arrows from State,
#else
    std::atomic<State*> next_[];    // Outgoing arrows from State,
#endif

                        // one per input byte class
  };

  // Marks separate thread groups of different priority
  // in the work queue when in leftmost-longest matching mode.
  constexpr static int32_t Mark = -1;
  // Separates the match IDs from the instructions in inst_.
  // Used only for "many match" DFA states.
  constexpr static int32_t MatchSep = -2;

  enum {
    kByteEndText = 256,         // imaginary byte at end of text

    kFlagEmptyMask = 0xFF,      // State.flag_: bits holding kEmptyXXX flags
    kFlagMatch = 0x0100,        // State.flag_: this is a matching state
    kFlagLastWord = 0x0200,     // State.flag_: last byte was a word char
    kFlagNeedShift = 16,        // needed kEmpty bits are or'ed in shifted left
  };

  struct StateHash {
    size_t operator()(const State* a) const {
      DCHECK(a != NULL);
      HashMix mix(a->flag_);
      for (int i = 0; i < a->ninst_; i++)
        mix.Mix(a->inst_[i]);
      mix.Mix(0);
      return mix.get();
    }
  };

  struct StateEqual {
    bool operator()(const State* a, const State* b) const {
      DCHECK(a != NULL);
      DCHECK(b != NULL);
      if (a == b)
        return true;
      if (a->flag_ != b->flag_)
        return false;
      if (a->ninst_ != b->ninst_)
        return false;
      for (int i = 0; i < a->ninst_; i++)
        if (a->inst_[i] != b->inst_[i])
          return false;
      return true;
    }
  };

  typedef std::unordered_set<State*, StateHash, StateEqual> StateSet;

 private:
  // Special "first_byte" values for a state.  (Values >= 0 denote actual bytes.)
  enum {
    kFbUnknown = -1,   // No analysis has been performed.
    kFbNone = -2,      // The first-byte trick cannot be used.
  };

  enum {
    // Indices into start_ for unanchored searches.
    // Add kStartAnchored for anchored searches.
    kStartBeginText = 0,          // text at beginning of context
    kStartBeginLine = 2,          // text at beginning of line
    kStartAfterWordChar = 4,      // text follows a word character
    kStartAfterNonWordChar = 6,   // text follows non-word character
    kMaxStart = 8,

    kStartAnchored = 1,
  };

  // Resets the DFA State cache, flushing all saved State* information.
  // Releases and reacquires cache_mutex_ via cache_lock, so any
  // State* existing before the call are not valid after the call.
  // Use a StateSaver to preserve important states across the call.
  // cache_mutex_.r <= L < mutex_
  // After: cache_mutex_.w <= L < mutex_
  void ResetCache(RWLocker* cache_lock);

  // Looks up and returns the State corresponding to a Workq.
  // L >= mutex_
  State* WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag);

  // Looks up and returns a State matching the inst, ninst, and flag.
  // L >= mutex_
  State* CachedState(int* inst, int ninst, uint32_t flag);

  // Clear the cache entirely.
  // Must hold cache_mutex_.w or be in destructor.
  void ClearCache();

  // Converts a State into a Workq: the opposite of WorkqToCachedState.
  // L >= mutex_
  void StateToWorkq(State* s, Workq* q);

  // Runs a State on a given byte, returning the next state.
  State* RunStateOnByteUnlocked(State*, int);  // cache_mutex_.r <= L < mutex_
  State* RunStateOnByte(State*, int);          // L >= mutex_

  // Runs a Workq on a given byte followed by a set of empty-string flags,
  // producing a new Workq in nq.  If a match instruction is encountered,
  // sets *ismatch to true.
  // L >= mutex_
  void RunWorkqOnByte(Workq* q, Workq* nq,
                      int c, uint32_t flag, bool* ismatch);

  // Runs a Workq on a set of empty-string flags, producing a new Workq in nq.
  // L >= mutex_
  void RunWorkqOnEmptyString(Workq* q, Workq* nq, uint32_t flag);

  // Adds the instruction id to the Workq, following empty arrows
  // according to flag.
  // L >= mutex_
  void AddToQueue(Workq* q, int id, uint32_t flag);

  // For debugging, returns a text representation of State.
  static std::string DumpState(State* state);

  // For debugging, returns a text representation of a Workq.
  static std::string DumpWorkq(Workq* q);

  // Search parameters
  struct SearchParams {
    SearchParams(const StringPiece& text, const StringPiece& context,
                 RWLocker* cache_lock)
      : text(text), context(context),
        anchored(false),
        want_earliest_match(false),
        run_forward(false),
        start(NULL),
        first_byte(kFbUnknown),
        cache_lock(cache_lock),
        failed(false),
        ep(NULL),
        matches(NULL) { }

    StringPiece text;
    StringPiece context;
    bool anchored;
    bool want_earliest_match;
    bool run_forward;
    State* start;
    int first_byte;
    RWLocker *cache_lock;
    bool failed;     // "out" parameter: whether search gave up
    const char* ep;  // "out" parameter: end pointer for match
    SparseSet* matches;

   private:
    SearchParams(const SearchParams&) = delete;
    SearchParams& operator=(const SearchParams&) = delete;
  };

  // Before each search, the parameters to Search are analyzed by
  // AnalyzeSearch to determine the state in which to start and the
  // "first_byte" for that state, if any.
  struct StartInfo {
    StartInfo() : start(NULL), first_byte(kFbUnknown) {}
    State* start;
    std::atomic<int> first_byte;
  };

  // Fills in params->start and params->first_byte using
  // the other search parameters.  Returns true on success,
  // false on failure.
  // cache_mutex_.r <= L < mutex_
  bool AnalyzeSearch(SearchParams* params);
  bool AnalyzeSearchHelper(SearchParams* params, StartInfo* info,
                           uint32_t flags);

  // The generic search loop, inlined to create specialized versions.
  // cache_mutex_.r <= L < mutex_
  // Might unlock and relock cache_mutex_ via params->cache_lock.
  inline bool InlinedSearchLoop(SearchParams* params,
                                bool have_first_byte,
                                bool want_earliest_match,
                                bool run_forward);

  // The specialized versions of InlinedSearchLoop.  The three letters
  // at the ends of the name denote the true/false values used as the
  // last three parameters of InlinedSearchLoop.
  // cache_mutex_.r <= L < mutex_
  // Might unlock and relock cache_mutex_ via params->cache_lock.
  bool SearchFFF(SearchParams* params);
  bool SearchFFT(SearchParams* params);
  bool SearchFTF(SearchParams* params);
  bool SearchFTT(SearchParams* params);
  bool SearchTFF(SearchParams* params);
  bool SearchTFT(SearchParams* params);
  bool SearchTTF(SearchParams* params);
  bool SearchTTT(SearchParams* params);

  // The main search loop: calls an appropriate specialized version of
  // InlinedSearchLoop.
  // cache_mutex_.r <= L < mutex_
  // Might unlock and relock cache_mutex_ via params->cache_lock.
  bool FastSearchLoop(SearchParams* params);

  // For debugging, a slow search loop that calls InlinedSearchLoop
  // directly -- because the booleans passed are not constants, the
  // loop is not specialized like the SearchFFF etc. versions, so it
  // runs much more slowly.  Useful only for debugging.
  // cache_mutex_.r <= L < mutex_
  // Might unlock and relock cache_mutex_ via params->cache_lock.
  bool SlowSearchLoop(SearchParams* params);

  // Looks up bytes in bytemap_ but handles case c == kByteEndText too.
  int ByteMap(int c) {
    if (c == kByteEndText)
      return prog_->bytemap_range();
    return prog_->bytemap()[c];
  }

  // Constant after initialization.
  Prog* prog_;              // The regular expression program to run.
  Prog::MatchKind kind_;    // The kind of DFA.
  bool init_failed_;        // initialization failed (out of memory)

  Mutex mutex_;  // mutex_ >= cache_mutex_.r

  // Scratch areas, protected by mutex_.
  Workq* q0_;             // Two pre-allocated work queues.
  Workq* q1_;
  PODArray<int> stack_;   // Pre-allocated stack for AddToQueue

  // State* cache.  Many threads use and add to the cache simultaneously,
  // holding cache_mutex_ for reading and mutex_ (above) when adding.
  // If the cache fills and needs to be discarded, the discarding is done
  // while holding cache_mutex_ for writing, to avoid interrupting other
  // readers.  Any State* pointers are only valid while cache_mutex_
  // is held.
  Mutex cache_mutex_;
  int64_t mem_budget_;     // Total memory budget for all States.
  int64_t state_budget_;   // Amount of memory remaining for new States.
  StateSet state_cache_;   // All States computed so far.
  StartInfo start_[kMaxStart];
};

// Shorthand for casting to uint8_t*.
static inline const uint8_t* BytePtr(const void* v) {
  return reinterpret_cast<const uint8_t*>(v);
}

// Work queues

// Internally, the DFA uses a sparse array of
// program instruction pointers as a work queue.
// In leftmost longest mode, marks separate sections
// of workq that started executing at different
// locations in the string (earlier locations first).
class DFA::Workq : public SparseSet {
 public:
  // Constructor: n is number of normal slots, maxmark number of mark slots.
  Workq(int n, int maxmark) :
    SparseSet(n+maxmark),
    n_(n),
    maxmark_(maxmark),
    nextmark_(n),
    last_was_mark_(true) {
  }

  bool is_mark(int i) { return i >= n_; }

  int maxmark() { return maxmark_; }

  void clear() {
    SparseSet::clear();
    nextmark_ = n_;
  }

  void mark() {
    if (last_was_mark_)
      return;
    last_was_mark_ = false;
    SparseSet::insert_new(nextmark_++);
  }

  int size() {
    return n_ + maxmark_;
  }

  void insert(int id) {
    if (contains(id))
      return;
    insert_new(id);
  }

  void insert_new(int id) {
    last_was_mark_ = false;
    SparseSet::insert_new(id);
  }

 private:
  int n_;                // size excluding marks
  int maxmark_;          // maximum number of marks
  int nextmark_;         // id of next mark
  bool last_was_mark_;   // last inserted was mark

  Workq(const Workq&) = delete;
  Workq& operator=(const Workq&) = delete;
};

DFA::DFA(Prog* prog, Prog::MatchKind kind, int64_t max_mem)
  : prog_(prog),
    kind_(kind),
    init_failed_(false),
    q0_(NULL),
    q1_(NULL),
    mem_budget_(max_mem) {
  int nmark = 0;
  if (kind_ == Prog::kLongestMatch)
    nmark = prog_->size();
  // See DFA::AddToQueue() for why this is so.
  int nstack = prog_->inst_count(kInstCapture) +
               prog_->inst_count(kInstEmptyWidth) +
               prog_->inst_count(kInstNop) +
               nmark + 1;  // + 1 for start inst

  // Account for space needed for DFA, q0, q1, stack.
  mem_budget_ -= sizeof(DFA);
  mem_budget_ -= (prog_->size() + nmark) *
                 (sizeof(int)+sizeof(int)) * 2;  // q0, q1
  mem_budget_ -= nstack * sizeof(int);  // stack
  if (mem_budget_ < 0) {
    init_failed_ = true;
    return;
  }

  state_budget_ = mem_budget_;

  // Make sure there is a reasonable amount of working room left.
  // At minimum, the search requires room for two states in order
  // to limp along, restarting frequently.  We'll get better performance
  // if there is room for a larger number of states, say 20.
  // Note that a state stores list heads only, so we use the program
  // list count for the upper bound, not the program size.
  int nnext = prog_->bytemap_range() + 1;  // + 1 for kByteEndText slot
  int64_t one_state = sizeof(State) + nnext*sizeof(std::atomic<State*>) +
                      (prog_->list_count()+nmark)*sizeof(int);
  if (state_budget_ < 20*one_state) {
    init_failed_ = true;
    return;
  }

  q0_ = new Workq(prog_->size(), nmark);
  q1_ = new Workq(prog_->size(), nmark);
  stack_ = PODArray<int>(nstack);
}

DFA::~DFA() {
  delete q0_;
  delete q1_;
  ClearCache();
}

// In the DFA state graph, s->next[c] == NULL means that the
// state has not yet been computed and needs to be.  We need
// a different special value to signal that s->next[c] is a
// state that can never lead to a match (and thus the search
// can be called off).  Hence DeadState.
#define DeadState reinterpret_cast<State*>(1)

// Signals that the rest of the string matches no matter what it is.
#define FullMatchState reinterpret_cast<State*>(2)

#define SpecialStateMax FullMatchState

// Debugging printouts

// For debugging, returns a string representation of the work queue.
std::string DFA::DumpWorkq(Workq* q) {
  std::string s;
  const char* sep = "";
  for (Workq::iterator it = q->begin(); it != q->end(); ++it) {
    if (q->is_mark(*it)) {
      StringAppendF(&s, "|");
      sep = "";
    } else {
      StringAppendF(&s, "%s%d", sep, *it);
      sep = ",";
    }
  }
  return s;
}

// For debugging, returns a string representation of the state.
std::string DFA::DumpState(State* state) {
  if (state == NULL)
    return "_";
  if (state == DeadState)
    return "X";
  if (state == FullMatchState)
    return "*";
  std::string s;
  const char* sep = "";
  StringAppendF(&s, "(%p)", state);
  for (int i = 0; i < state->ninst_; i++) {
    if (state->inst_[i] == Mark) {
      StringAppendF(&s, "|");
      sep = "";
    } else if (state->inst_[i] == MatchSep) {
      StringAppendF(&s, "||");
      sep = "";
    } else {
      StringAppendF(&s, "%s%d", sep, state->inst_[i]);
      sep = ",";
    }
  }
  StringAppendF(&s, " flag=%#x", state->flag_);
  return s;
}

//////////////////////////////////////////////////////////////////////
//
// DFA state graph construction.
//
// The DFA state graph is a heavily-linked collection of State* structures.
// The state_cache_ is a set of all the State structures ever allocated,
// so that if the same state is reached by two different paths,
// the same State structure can be used.  This reduces allocation
// requirements and also avoids duplication of effort across the two
// identical states.
//
// A State is defined by an ordered list of instruction ids and a flag word.
//
// The choice of an ordered list of instructions differs from a typical
// textbook DFA implementation, which would use an unordered set.
// Textbook descriptions, however, only care about whether
// the DFA matches, not where it matches in the text.  To decide where the
// DFA matches, we need to mimic the behavior of the dominant backtracking
// implementations like PCRE, which try one possible regular expression
// execution, then another, then another, stopping when one of them succeeds.
// The DFA execution tries these many executions in parallel, representing
// each by an instruction id.  These pointers are ordered in the State.inst_
// list in the same order that the executions would happen in a backtracking
// search: if a match is found during execution of inst_[2], inst_[i] for i>=3
// can be discarded.
//
// Textbooks also typically do not consider context-aware empty string operators
// like ^ or $.  These are handled by the flag word, which specifies the set
// of empty-string operators that should be matched when executing at the
// current text position.  These flag bits are defined in prog.h.
// The flag word also contains two DFA-specific bits: kFlagMatch if the state
// is a matching state (one that reached a kInstMatch in the program)
// and kFlagLastWord if the last processed byte was a word character, for the
// implementation of \B and \b.
//
// The flag word also contains, shifted up 16 bits, the bits looked for by
// any kInstEmptyWidth instructions in the state.  These provide a useful
// summary indicating when new flags might be useful.
//
// The permanent representation of a State's instruction ids is just an array,
// but while a state is being analyzed, these instruction ids are represented
// as a Workq, which is an array that allows iteration in insertion order.

// NOTE(rsc): The choice of State construction determines whether the DFA
// mimics backtracking implementations (so-called leftmost first matching) or
// traditional DFA implementations (so-called leftmost longest matching as
// prescribed by POSIX).  This implementation chooses to mimic the
// backtracking implementations, because we want to replace PCRE.  To get
// POSIX behavior, the states would need to be considered not as a simple
// ordered list of instruction ids, but as a list of unordered sets of instruction
// ids.  A match by a state in one set would inhibit the running of sets
// farther down the list but not other instruction ids in the same set.  Each
// set would correspond to matches beginning at a given point in the string.
// This is implemented by separating different sets with Mark pointers.

// Looks in the State cache for a State matching q, flag.
// If one is found, returns it.  If one is not found, allocates one,
// inserts it in the cache, and returns it.
// If mq is not null, MatchSep and the match IDs in mq will be appended
// to the State.
DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
  //mutex_.AssertHeld();

  // Construct array of instruction ids for the new state.
  // Only ByteRange, EmptyWidth, and Match instructions are useful to keep:
  // those are the only operators with any effect in
  // RunWorkqOnEmptyString or RunWorkqOnByte.
  int* inst = new int[q->size()];
  int n = 0;
  uint32_t needflags = 0;  // flags needed by kInstEmptyWidth instructions
  bool sawmatch = false;   // whether queue contains guaranteed kInstMatch
  bool sawmark = false;    // whether queue contains a Mark
  for (Workq::iterator it = q->begin(); it != q->end(); ++it) {
    int id = *it;
    if (sawmatch && (kind_ == Prog::kFirstMatch || q->is_mark(id)))
      break;
    if (q->is_mark(id)) {
      if (n > 0 && inst[n-1] != Mark) {
        sawmark = true;
        inst[n++] = Mark;
      }
      continue;
    }
    Prog::Inst* ip = prog_->inst(id);
    switch (ip->opcode()) {
      case kInstAltMatch:
        // This state will continue to a match no matter what
        // the rest of the input is.  If it is the highest priority match
        // being considered, return the special FullMatchState
        // to indicate that it's all matches from here out.
        if (kind_ != Prog::kManyMatch &&
            (kind_ != Prog::kFirstMatch ||
             (it == q->begin() && ip->greedy(prog_))) &&
            (kind_ != Prog::kLongestMatch || !sawmark) &&
            (flag & kFlagMatch)) {
          delete[] inst;
          return FullMatchState;
        }
        FALLTHROUGH_INTENDED;
      default:
        // Record iff id is the head of its list, which must
        // be the case if id-1 is the last of *its* list. :)
        if (prog_->inst(id-1)->last())
          inst[n++] = *it;
        if (ip->opcode() == kInstEmptyWidth)
          needflags |= ip->empty();
        if (ip->opcode() == kInstMatch && !prog_->anchor_end())
          sawmatch = true;
        break;
    }
  }
  DCHECK_LE(n, q->size());
  if (n > 0 && inst[n-1] == Mark)
    n--;

  // If there are no empty-width instructions waiting to execute,
  // then the extra flag bits will not be used, so there is no
  // point in saving them.  (Discarding them reduces the number
  // of distinct states.)
  if (needflags == 0)
    flag &= kFlagMatch;

  // NOTE(rsc): The code above cannot do flag &= needflags,
  // because if the right flags were present to pass the current
  // kInstEmptyWidth instructions, new kInstEmptyWidth instructions
  // might be reached that in turn need different flags.
  // The only sure thing is that if there are no kInstEmptyWidth
  // instructions at all, no flags will be needed.
  // We could do the extra work to figure out the full set of
  // possibly needed flags by exploring past the kInstEmptyWidth
  // instructions, but the check above -- are any flags needed
  // at all? -- handles the most common case.  More fine-grained
  // analysis can only be justified by measurements showing that
  // too many redundant states are being allocated.

  // If there are no Insts in the list, it's a dead state,
  // which is useful to signal with a special pointer so that
  // the execution loop can stop early.  This is only okay
  // if the state is *not* a matching state.
  if (n == 0 && flag == 0) {
    delete[] inst;
    return DeadState;
  }

  // If we're in longest match mode, the state is a sequence of
  // unordered state sets separated by Marks.  Sort each set
  // to canonicalize, to reduce the number of distinct sets stored.
  if (kind_ == Prog::kLongestMatch) {
    int* ip = inst;
    int* ep = ip + n;
    while (ip < ep) {
      int* markp = ip;
      while (markp < ep && *markp != Mark)
        markp++;
      std::sort(ip, markp);
      if (markp < ep)
        markp++;
      ip = markp;
    }
  }

  // Append MatchSep and the match IDs in mq if necessary.
  if (mq != NULL) {
    inst[n++] = MatchSep;
    for (Workq::iterator i = mq->begin(); i != mq->end(); ++i) {
      int id = *i;
      Prog::Inst* ip = prog_->inst(id);
      if (ip->opcode() == kInstMatch)
        inst[n++] = ip->match_id();
    }
  }

  // Save the needed empty-width flags in the top bits for use later.
  flag |= needflags << kFlagNeedShift;

  State* state = CachedState(inst, n, flag);
  delete[] inst;
  return state;
}

// Looks in the State cache for a State matching inst, ninst, flag.
// If one is found, returns it.  If one is not found, allocates one,
// inserts it in the cache, and returns it.
DFA::State* DFA::CachedState(int* inst, int ninst, uint32_t flag) {
  //mutex_.AssertHeld();

  // Look in the cache for a pre-existing state.
  // We have to initialise the struct like this because otherwise
  // MSVC will complain about the flexible array member. :(
  State state;
  state.inst_ = inst;
  state.ninst_ = ninst;
  state.flag_ = flag;
  StateSet::iterator it = state_cache_.find(&state);
  if (it != state_cache_.end()) {
    return *it;
  }

  // Must have enough memory for new state.
  // In addition to what we're going to allocate,
  // the state cache hash table seems to incur about 40 bytes per
  // State*, empirically.
  const int kStateCacheOverhead = 40;
  int nnext = prog_->bytemap_range() + 1;  // + 1 for kByteEndText slot
  int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>) +
            ninst*sizeof(int);
  if (mem_budget_ < mem + kStateCacheOverhead) {
    mem_budget_ = -1;
    return NULL;
  }
  mem_budget_ -= mem + kStateCacheOverhead;

  // Allocate new state along with room for next_ and inst_.
  char* space = std::allocator<char>().allocate(mem);
  State* s = new (space) State;
  (void) new (s->next_) std::atomic<State*>[nnext];
  // Work around a unfortunate bug in older versions of libstdc++.
  // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64658)
  for (int i = 0; i < nnext; i++)
    (void) new (s->next_ + i) std::atomic<State*>(NULL);
  s->inst_ = new (s->next_ + nnext) int[ninst];
  memmove(s->inst_, inst, ninst*sizeof s->inst_[0]);
  s->ninst_ = ninst;
  s->flag_ = flag;
  // Put state in cache and return it.
  state_cache_.insert(s);
  return s;
}

// Clear the cache.  Must hold cache_mutex_.w or be in destructor.
void DFA::ClearCache() {
  StateSet::iterator begin = state_cache_.begin();
  StateSet::iterator end = state_cache_.end();
  while (begin != end) {
    StateSet::iterator tmp = begin;
    ++begin;
    // Deallocate the blob of memory that we allocated in DFA::CachedState().
    // We recompute mem in order to benefit from sized delete where possible.
    int ninst = (*tmp)->ninst_;
    int nnext = prog_->bytemap_range() + 1;  // + 1 for kByteEndText slot
    int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>) +
              ninst*sizeof(int);
    std::allocator<char>().deallocate(reinterpret_cast<char*>(*tmp), mem);
  }
  state_cache_.clear();
}

// Copies insts in state s to the work queue q.
void DFA::StateToWorkq(State* s, Workq* q) {
  q->clear();
  for (int i = 0; i < s->ninst_; i++) {
    if (s->inst_[i] == Mark) {
      q->mark();
    } else if (s->inst_[i] == MatchSep) {
      // Nothing after this is an instruction!
      break;
    } else {
      // Explore from the head of the list.
      AddToQueue(q, s->inst_[i], s->flag_ & kFlagEmptyMask);
    }
  }
}

// Adds ip to the work queue, following empty arrows according to flag.
void DFA::AddToQueue(Workq* q, int id, uint32_t flag) {

  // Use stack_ to hold our stack of instructions yet to process.
  // It was preallocated as follows:
  //   one entry per Capture;
  //   one entry per EmptyWidth; and
  //   one entry per Nop.
  // This reflects the maximum number of stack pushes that each can
  // perform. (Each instruction can be processed at most once.)
  // When using marks, we also added nmark == prog_->size().
  // (Otherwise, nmark == 0.)
  int* stk = stack_.data();
  int nstk = 0;

  stk[nstk++] = id;
  while (nstk > 0) {
    DCHECK_LE(nstk, stack_.size());
    id = stk[--nstk];

  Loop:
    if (id == Mark) {
      q->mark();
      continue;
    }

    if (id == 0)
      continue;

    // If ip is already on the queue, nothing to do.
    // Otherwise add it.  We don't actually keep all the
    // ones that get added, but adding all of them here
    // increases the likelihood of q->contains(id),
    // reducing the amount of duplicated work.
    if (q->contains(id))
      continue;
    q->insert_new(id);

    // Process instruction.
    Prog::Inst* ip = prog_->inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
        break;

      case kInstByteRange:  // just save these on the queue
      case kInstMatch:
        if (ip->last())
          break;
        id = id+1;
        goto Loop;

      case kInstCapture:    // DFA treats captures as no-ops.
      case kInstNop:
        if (!ip->last())
          stk[nstk++] = id+1;

        // If this instruction is the [00-FF]* loop at the beginning of
        // a leftmost-longest unanchored search, separate with a Mark so
        // that future threads (which will start farther to the right in
        // the input string) are lower priority than current threads.
        if (ip->opcode() == kInstNop && q->maxmark() > 0 &&
            id == prog_->start_unanchored() && id != prog_->start())
          stk[nstk++] = Mark;
        id = ip->out();
        goto Loop;

      case kInstAltMatch:
        DCHECK(!ip->last());
        id = id+1;
        goto Loop;

      case kInstEmptyWidth:
        if (!ip->last())
          stk[nstk++] = id+1;

        // Continue on if we have all the right flag bits.
        if (ip->empty() & ~flag)
          break;
        id = ip->out();
        goto Loop;
    }
  }
}

// Running of work queues.  In the work queue, order matters:
// the queue is sorted in priority order.  If instruction i comes before j,
// then the instructions that i produces during the run must come before
// the ones that j produces.  In order to keep this invariant, all the
// work queue runners have to take an old queue to process and then
// also a new queue to fill in.  It's not acceptable to add to the end of
// an existing queue, because new instructions will not end up in the
// correct position.

// Runs the work queue, processing the empty strings indicated by flag.
// For example, flag == kEmptyBeginLine|kEmptyEndLine means to match
// both ^ and $.  It is important that callers pass all flags at once:
// processing both ^ and $ is not the same as first processing only ^
// and then processing only $.  Doing the two-step sequence won't match
// ^$^$^$ but processing ^ and $ simultaneously will (and is the behavior
// exhibited by existing implementations).
void DFA::RunWorkqOnEmptyString(Workq* oldq, Workq* newq, uint32_t flag) {
  newq->clear();
  for (Workq::iterator i = oldq->begin(); i != oldq->end(); ++i) {
    if (oldq->is_mark(*i))
      AddToQueue(newq, Mark, flag);
    else
      AddToQueue(newq, *i, flag);
  }
}

// Runs the work queue, processing the single byte c followed by any empty
// strings indicated by flag.  For example, c == 'a' and flag == kEmptyEndLine,
// means to match c$.  Sets the bool *ismatch to true if the end of the
// regular expression program has been reached (the regexp has matched).
void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq,
                         int c, uint32_t flag, bool* ismatch) {
  //mutex_.AssertHeld();

  newq->clear();
  for (Workq::iterator i = oldq->begin(); i != oldq->end(); ++i) {
    if (oldq->is_mark(*i)) {
      if (*ismatch)
        return;
      newq->mark();
      continue;
    }
    int id = *i;
    Prog::Inst* ip = prog_->inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
        break;

      case kInstFail:        // never succeeds
      case kInstCapture:     // already followed
      case kInstNop:         // already followed
      case kInstAltMatch:    // already followed
      case kInstEmptyWidth:  // already followed
        break;

      case kInstByteRange:   // can follow if c is in range
        if (ip->Matches(c))
          AddToQueue(newq, ip->out(), flag);
        break;

      case kInstMatch:
        if (prog_->anchor_end() && c != kByteEndText &&
            kind_ != Prog::kManyMatch)
          break;
        *ismatch = true;
        if (kind_ == Prog::kFirstMatch) {
          // Can stop processing work queue since we found a match.
          return;
        }
        break;
    }
  }
}

// Processes input byte c in state, returning new state.
// Caller does not hold mutex.
DFA::State* DFA::RunStateOnByteUnlocked(State* state, int c) {
  // Keep only one RunStateOnByte going
  // even if the DFA is being run by multiple threads.
  MutexLock l(&mutex_);
  return RunStateOnByte(state, c);
}

// Processes input byte c in state, returning new state.
DFA::State* DFA::RunStateOnByte(State* state, int c) {
  //mutex_.AssertHeld();

  if (state <= SpecialStateMax) {
    if (state == FullMatchState) {
      // It is convenient for routines like PossibleMatchRange
      // if we implement RunStateOnByte for FullMatchState:
      // once you get into this state you never get out,
      // so it's pretty easy.
      return FullMatchState;
    }
    if (state == DeadState) {
      LOG(DFATAL) << "DeadState in RunStateOnByte";
      return NULL;
    }
    if (state == NULL) {
      LOG(DFATAL) << "NULL state in RunStateOnByte";
      return NULL;
    }
    LOG(DFATAL) << "Unexpected special state in RunStateOnByte";
    return NULL;
  }

  // If someone else already computed this, return it.
  State* ns = state->next_[ByteMap(c)].load(std::memory_order_relaxed);
  if (ns != NULL)
    return ns;

  // Convert state into Workq.
  StateToWorkq(state, q0_);

  // Flags marking the kinds of empty-width things (^ $ etc)
  // around this byte.  Before the byte we have the flags recorded
  // in the State structure itself.  After the byte we have
  // nothing yet (but that will change: read on).
  uint32_t needflag = state->flag_ >> kFlagNeedShift;
  uint32_t beforeflag = state->flag_ & kFlagEmptyMask;
  uint32_t oldbeforeflag = beforeflag;
  uint32_t afterflag = 0;

  if (c == '\n') {
    // Insert implicit $ and ^ around \n
    beforeflag |= kEmptyEndLine;
    afterflag |= kEmptyBeginLine;
  }

  if (c == kByteEndText) {
    // Insert implicit $ and \z before the fake "end text" byte.
    beforeflag |= kEmptyEndLine | kEmptyEndText;
  }

  // The state flag kFlagLastWord says whether the last
  // byte processed was a word character.  Use that info to
  // insert empty-width (non-)word boundaries.
  bool islastword = (state->flag_ & kFlagLastWord) != 0;
  bool isword = c != kByteEndText && Prog::IsWordChar(static_cast<uint8_t>(c));
  if (isword == islastword)
    beforeflag |= kEmptyNonWordBoundary;
  else
    beforeflag |= kEmptyWordBoundary;

  // Okay, finally ready to run.
  // Only useful to rerun on empty string if there are new, useful flags.
  if (beforeflag & ~oldbeforeflag & needflag) {
    RunWorkqOnEmptyString(q0_, q1_, beforeflag);
    using std::swap;
    swap(q0_, q1_);
  }
  bool ismatch = false;
  RunWorkqOnByte(q0_, q1_, c, afterflag, &ismatch);
  using std::swap;
  swap(q0_, q1_);

  // Save afterflag along with ismatch and isword in new state.
  uint32_t flag = afterflag;
  if (ismatch)
    flag |= kFlagMatch;
  if (isword)
    flag |= kFlagLastWord;

  if (ismatch && kind_ == Prog::kManyMatch)
    ns = WorkqToCachedState(q0_, q1_, flag);
  else
    ns = WorkqToCachedState(q0_, NULL, flag);

  // Flush ns before linking to it.
  // Write barrier before updating state->next_ so that the
  // main search loop can proceed without any locking, for speed.
  // (Otherwise it would need one mutex operation per input byte.)
  state->next_[ByteMap(c)].store(ns, std::memory_order_release);
  return ns;
}


//////////////////////////////////////////////////////////////////////
// DFA cache reset.

// Reader-writer lock helper.
//
// The DFA uses a reader-writer mutex to protect the state graph itself.
// Traversing the state graph requires holding the mutex for reading,
// and discarding the state graph and starting over requires holding the
// lock for writing.  If a search needs to expand the graph but is out
// of memory, it will need to drop its read lock and then acquire the
// write lock.  Since it cannot then atomically downgrade from write lock
// to read lock, it runs the rest of the search holding the write lock.
// (This probably helps avoid repeated contention, but really the decision
// is forced by the Mutex interface.)  It's a bit complicated to keep
// track of whether the lock is held for reading or writing and thread
// that through the search, so instead we encapsulate it in the RWLocker
// and pass that around.

class DFA::RWLocker {
 public:
  explicit RWLocker(Mutex* mu);
  ~RWLocker();

  // If the lock is only held for reading right now,
  // drop the read lock and re-acquire for writing.
  // Subsequent calls to LockForWriting are no-ops.
  // Notice that the lock is *released* temporarily.
  void LockForWriting();

 private:
  Mutex* mu_;
  bool writing_;

  RWLocker(const RWLocker&) = delete;
  RWLocker& operator=(const RWLocker&) = delete;
};

DFA::RWLocker::RWLocker(Mutex* mu) : mu_(mu), writing_(false) {
  mu_->ReaderLock();
}

// This function is marked as NO_THREAD_SAFETY_ANALYSIS because the annotations
// does not support lock upgrade.
void DFA::RWLocker::LockForWriting() NO_THREAD_SAFETY_ANALYSIS {
  if (!writing_) {
    mu_->ReaderUnlock();
    mu_->WriterLock();
    writing_ = true;
  }
}

DFA::RWLocker::~RWLocker() {
  if (!writing_)
    mu_->ReaderUnlock();
  else
    mu_->WriterUnlock();
}


// When the DFA's State cache fills, we discard all the states in the
// cache and start over.  Many threads can be using and adding to the
// cache at the same time, so we synchronize using the cache_mutex_
// to keep from stepping on other threads.  Specifically, all the
// threads using the current cache hold cache_mutex_ for reading.
// When a thread decides to flush the cache, it drops cache_mutex_
// and then re-acquires it for writing.  That ensures there are no
// other threads accessing the cache anymore.  The rest of the search
// runs holding cache_mutex_ for writing, avoiding any contention
// with or cache pollution caused by other threads.

void DFA::ResetCache(RWLocker* cache_lock) {
  // Re-acquire the cache_mutex_ for writing (exclusive use).
  cache_lock->LockForWriting();

  // Clear the cache, reset the memory budget.
  for (int i = 0; i < kMaxStart; i++) {
    start_[i].start = NULL;
    start_[i].first_byte.store(kFbUnknown, std::memory_order_relaxed);
  }
  ClearCache();
  mem_budget_ = state_budget_;
}

// Typically, a couple States do need to be preserved across a cache
// reset, like the State at the current point in the search.
// The StateSaver class helps keep States across cache resets.
// It makes a copy of the state's guts outside the cache (before the reset)
// and then can be asked, after the reset, to recreate the State
// in the new cache.  For example, in a DFA method ("this" is a DFA):
//
//   StateSaver saver(this, s);
//   ResetCache(cache_lock);
//   s = saver.Restore();
//
// The saver should always have room in the cache to re-create the state,
// because resetting the cache locks out all other threads, and the cache
// is known to have room for at least a couple states (otherwise the DFA
// constructor fails).

class DFA::StateSaver {
 public:
  explicit StateSaver(DFA* dfa, State* state);
  ~StateSaver();

  // Recreates and returns a state equivalent to the
  // original state passed to the constructor.
  // Returns NULL if the cache has filled, but
  // since the DFA guarantees to have room in the cache
  // for a couple states, should never return NULL
  // if used right after ResetCache.
  State* Restore();

 private:
  DFA* dfa_;         // the DFA to use
  int* inst_;        // saved info from State
  int ninst_;
  uint32_t flag_;
  bool is_special_;  // whether original state was special
  State* special_;   // if is_special_, the original state

  StateSaver(const StateSaver&) = delete;
  StateSaver& operator=(const StateSaver&) = delete;
};

DFA::StateSaver::StateSaver(DFA* dfa, State* state) {
  dfa_ = dfa;
  if (state <= SpecialStateMax) {
    inst_ = NULL;
    ninst_ = 0;
    flag_ = 0;
    is_special_ = true;
    special_ = state;
    return;
  }
  is_special_ = false;
  special_ = NULL;
  flag_ = state->flag_;
  ninst_ = state->ninst_;
  inst_ = new int[ninst_];
  memmove(inst_, state->inst_, ninst_*sizeof inst_[0]);
}

DFA::StateSaver::~StateSaver() {
  if (!is_special_)
    delete[] inst_;
}

DFA::State* DFA::StateSaver::Restore() {
  if (is_special_)
    return special_;
  MutexLock l(&dfa_->mutex_);
  State* s = dfa_->CachedState(inst_, ninst_, flag_);
  if (s == NULL)
    LOG(DFATAL) << "StateSaver failed to restore state.";
  return s;
}


//////////////////////////////////////////////////////////////////////
//
// DFA execution.
//
// The basic search loop is easy: start in a state s and then for each
// byte c in the input, s = s->next[c].
//
// This simple description omits a few efficiency-driven complications.
//
// First, the State graph is constructed incrementally: it is possible
// that s->next[c] is null, indicating that that state has not been
// fully explored.  In this case, RunStateOnByte must be invoked to
// determine the next state, which is cached in s->next[c] to save
// future effort.  An alternative reason for s->next[c] to be null is
// that the DFA has reached a so-called "dead state", in which any match
// is no longer possible.  In this case RunStateOnByte will return NULL
// and the processing of the string can stop early.
//
// Second, a 256-element pointer array for s->next_ makes each State
// quite large (2kB on 64-bit machines).  Instead, dfa->bytemap_[]
// maps from bytes to "byte classes" and then next_ only needs to have
// as many pointers as there are byte classes.  A byte class is simply a
// range of bytes that the regexp never distinguishes between.
// A regexp looking for a[abc] would have four byte ranges -- 0 to 'a'-1,
// 'a', 'b' to 'c', and 'c' to 0xFF.  The bytemap slows us a little bit
// but in exchange we typically cut the size of a State (and thus our
// memory footprint) by about 5-10x.  The comments still refer to
// s->next[c] for simplicity, but code should refer to s->next_[bytemap_[c]].
//
// Third, it is common for a DFA for an unanchored match to begin in a
// state in which only one particular byte value can take the DFA to a
// different state.  That is, s->next[c] != s for only one c.  In this
// situation, the DFA can do better than executing the simple loop.
// Instead, it can call memchr to search very quickly for the byte c.
// Whether the start state has this property is determined during a
// pre-compilation pass, and if so, the byte b is passed to the search
// loop as the "first_byte" argument, along with a boolean "have_first_byte".
//
// Fourth, the desired behavior is to search for the leftmost-best match
// (approximately, the same one that Perl would find), which is not
// necessarily the match ending earliest in the string.  Each time a
// match is found, it must be noted, but the DFA must continue on in
// hope of finding a higher-priority match.  In some cases, the caller only
// cares whether there is any match at all, not which one is found.
// The "want_earliest_match" flag causes the search to stop at the first
// match found.
//
// Fifth, one algorithm that uses the DFA needs it to run over the
// input string backward, beginning at the end and ending at the beginning.
// Passing false for the "run_forward" flag causes the DFA to run backward.
//
// The checks for these last three cases, which in a naive implementation
// would be performed once per input byte, slow the general loop enough
// to merit specialized versions of the search loop for each of the
// eight possible settings of the three booleans.  Rather than write
// eight different functions, we write one general implementation and then
// inline it to create the specialized ones.
//
// Note that matches are delayed by one byte, to make it easier to
// accomodate match conditions depending on the next input byte (like $ and \b).
// When s->next[c]->IsMatch(), it means that there is a match ending just
// *before* byte c.

// The generic search loop.  Searches text for a match, returning
// the pointer to the end of the chosen match, or NULL if no match.
// The bools are equal to the same-named variables in params, but
// making them function arguments lets the inliner specialize
// this function to each combination (see two paragraphs above).
inline bool DFA::InlinedSearchLoop(SearchParams* params,
                                   bool have_first_byte,
                                   bool want_earliest_match,
                                   bool run_forward) {
  State* start = params->start;
  const uint8_t* bp = BytePtr(params->text.begin());  // start of text
  const uint8_t* p = bp;                              // text scanning point
  const uint8_t* ep = BytePtr(params->text.end());    // end of text
  const uint8_t* resetp = NULL;                       // p at last cache reset
  if (!run_forward) {
    using std::swap;
    swap(p, ep);
  }

  const uint8_t* bytemap = prog_->bytemap();
  const uint8_t* lastmatch = NULL;   // most recent matching position in text
  bool matched = false;

  State* s = start;

  if (s->IsMatch()) {
    matched = true;
    lastmatch = p;
    if (params->matches != NULL && kind_ == Prog::kManyMatch) {
      for (int i = s->ninst_ - 1; i >= 0; i--) {
        int id = s->inst_[i];
        if (id == MatchSep)
          break;
        params->matches->insert(id);
      }
    }
    if (want_earliest_match) {
      params->ep = reinterpret_cast<const char*>(lastmatch);
      return true;
    }
  }

  while (p != ep) {
    if (have_first_byte && s == start) {
      // In start state, only way out is to find first_byte,
      // so use optimized assembly in memchr to skip ahead.
      // If first_byte isn't found, we can skip to the end
      // of the string.
      if (run_forward) {
        if ((p = BytePtr(memchr(p, params->first_byte, ep - p))) == NULL) {
          p = ep;
          break;
        }
      } else {
        if ((p = BytePtr(memrchr(ep, params->first_byte, p - ep))) == NULL) {
          p = ep;
          break;
        }
        p++;
      }
    }

    int c;
    if (run_forward)
      c = *p++;
    else
      c = *--p;

    // Note that multiple threads might be consulting
    // s->next_[bytemap[c]] simultaneously.
    // RunStateOnByte takes care of the appropriate locking,
    // including a memory barrier so that the unlocked access
    // (sometimes known as "double-checked locking") is safe.
    // The alternative would be either one DFA per thread
    // or one mutex operation per input byte.
    //
    // ns == DeadState means the state is known to be dead
    // (no more matches are possible).
    // ns == NULL means the state has not yet been computed
    // (need to call RunStateOnByteUnlocked).
    // RunStateOnByte returns ns == NULL if it is out of memory.
    // ns == FullMatchState means the rest of the string matches.
    //
    // Okay to use bytemap[] not ByteMap() here, because
    // c is known to be an actual byte and not kByteEndText.

    State* ns = s->next_[bytemap[c]].load(std::memory_order_acquire);
    if (ns == NULL) {
      ns = RunStateOnByteUnlocked(s, c);
      if (ns == NULL) {
        // After we reset the cache, we hold cache_mutex exclusively,
        // so if resetp != NULL, it means we filled the DFA state
        // cache with this search alone (without any other threads).
        // Benchmarks show that doing a state computation on every
        // byte runs at about 0.2 MB/s, while the NFA (nfa.cc) can do the
        // same at about 2 MB/s.  Unless we're processing an average
        // of 10 bytes per state computation, fail so that RE2 can
        // fall back to the NFA.
        if (dfa_should_bail_when_slow && resetp != NULL &&
            static_cast<size_t>(p - resetp) < 10*state_cache_.size()) {
          params->failed = true;
          return false;
        }
        resetp = p;

        // Prepare to save start and s across the reset.
        StateSaver save_start(this, start);
        StateSaver save_s(this, s);

        // Discard all the States in the cache.
        ResetCache(params->cache_lock);

        // Restore start and s so we can continue.
        if ((start = save_start.Restore()) == NULL ||
            (s = save_s.Restore()) == NULL) {
          // Restore already did LOG(DFATAL).
          params->failed = true;
          return false;
        }
        ns = RunStateOnByteUnlocked(s, c);
        if (ns == NULL) {
          LOG(DFATAL) << "RunStateOnByteUnlocked failed after ResetCache";
          params->failed = true;
          return false;
        }
      }
    }
    if (ns <= SpecialStateMax) {
      if (ns == DeadState) {
        params->ep = reinterpret_cast<const char*>(lastmatch);
        return matched;
      }
      // FullMatchState
      params->ep = reinterpret_cast<const char*>(ep);
      return true;
    }

    s = ns;
    if (s->IsMatch()) {
      matched = true;
      // The DFA notices the match one byte late,
      // so adjust p before using it in the match.
      if (run_forward)
        lastmatch = p - 1;
      else
        lastmatch = p + 1;
      if (params->matches != NULL && kind_ == Prog::kManyMatch) {
        for (int i = s->ninst_ - 1; i >= 0; i--) {
          int id = s->inst_[i];
          if (id == MatchSep)
            break;
          params->matches->insert(id);
        }
      }
      if (want_earliest_match) {
        params->ep = reinterpret_cast<const char*>(lastmatch);
        return true;
      }
    }
  }

  // Process one more byte to see if it triggers a match.
  // (Remember, matches are delayed one byte.)
  int lastbyte;
  if (run_forward) {
    if (params->text.end() == params->context.end())
      lastbyte = kByteEndText;
    else
      lastbyte = params->text.end()[0] & 0xFF;
  } else {
    if (params->text.begin() == params->context.begin())
      lastbyte = kByteEndText;
    else
      lastbyte = params->text.begin()[-1] & 0xFF;
  }

  State* ns = s->next_[ByteMap(lastbyte)].load(std::memory_order_acquire);
  if (ns == NULL) {
    ns = RunStateOnByteUnlocked(s, lastbyte);
    if (ns == NULL) {
      StateSaver save_s(this, s);
      ResetCache(params->cache_lock);
      if ((s = save_s.Restore()) == NULL) {
        params->failed = true;
        return false;
      }
      ns = RunStateOnByteUnlocked(s, lastbyte);
      if (ns == NULL) {
        LOG(DFATAL) << "RunStateOnByteUnlocked failed after Reset";
        params->failed = true;
        return false;
      }
    }
  }
  if (ns <= SpecialStateMax) {
    if (ns == DeadState) {
      params->ep = reinterpret_cast<const char*>(lastmatch);
      return matched;
    }
    // FullMatchState
    params->ep = reinterpret_cast<const char*>(ep);
    return true;
  }

  s = ns;
  if (s->IsMatch()) {
    matched = true;
    lastmatch = p;
    if (params->matches != NULL && kind_ == Prog::kManyMatch) {
      for (int i = s->ninst_ - 1; i >= 0; i--) {
        int id = s->inst_[i];
        if (id == MatchSep)
          break;
        params->matches->insert(id);
      }
    }
  }

  params->ep = reinterpret_cast<const char*>(lastmatch);
  return matched;
}

// Inline specializations of the general loop.
bool DFA::SearchFFF(SearchParams* params) {
  return InlinedSearchLoop(params, 0, 0, 0);
}
bool DFA::SearchFFT(SearchParams* params) {
  return InlinedSearchLoop(params, 0, 0, 1);
}
bool DFA::SearchFTF(SearchParams* params) {
  return InlinedSearchLoop(params, 0, 1, 0);
}
bool DFA::SearchFTT(SearchParams* params) {
  return InlinedSearchLoop(params, 0, 1, 1);
}
bool DFA::SearchTFF(SearchParams* params) {
  return InlinedSearchLoop(params, 1, 0, 0);
}
bool DFA::SearchTFT(SearchParams* params) {
  return InlinedSearchLoop(params, 1, 0, 1);
}
bool DFA::SearchTTF(SearchParams* params) {
  return InlinedSearchLoop(params, 1, 1, 0);
}
bool DFA::SearchTTT(SearchParams* params) {
  return InlinedSearchLoop(params, 1, 1, 1);
}

// For debugging, calls the general code directly.
bool DFA::SlowSearchLoop(SearchParams* params) {
  return InlinedSearchLoop(params,
                           params->first_byte >= 0,
                           params->want_earliest_match,
                           params->run_forward);
}

// For performance, calls the appropriate specialized version
// of InlinedSearchLoop.
bool DFA::FastSearchLoop(SearchParams* params) {
  // Because the methods are private, the Searches array
  // cannot be declared at top level.
  static bool (DFA::*Searches[])(SearchParams*) = {
    &DFA::SearchFFF,
    &DFA::SearchFFT,
    &DFA::SearchFTF,
    &DFA::SearchFTT,
    &DFA::SearchTFF,
    &DFA::SearchTFT,
    &DFA::SearchTTF,
    &DFA::SearchTTT,
  };

  bool have_first_byte = params->first_byte >= 0;
  int index = 4 * have_first_byte +
              2 * params->want_earliest_match +
              1 * params->run_forward;
  return (this->*Searches[index])(params);
}


// The discussion of DFA execution above ignored the question of how
// to determine the initial state for the search loop.  There are two
// factors that influence the choice of start state.
//
// The first factor is whether the search is anchored or not.
// The regexp program (Prog*) itself has
// two different entry points: one for anchored searches and one for
// unanchored searches.  (The unanchored version starts with a leading ".*?"
// and then jumps to the anchored one.)
//
// The second factor is where text appears in the larger context, which
// determines which empty-string operators can be matched at the beginning
// of execution.  If text is at the very beginning of context, \A and ^ match.
// Otherwise if text is at the beginning of a line, then ^ matches.
// Otherwise it matters whether the character before text is a word character
// or a non-word character.
//
// The two cases (unanchored vs not) and four cases (empty-string flags)
// combine to make the eight cases recorded in the DFA's begin_text_[2],
// begin_line_[2], after_wordchar_[2], and after_nonwordchar_[2] cached
// StartInfos.  The start state for each is filled in the first time it
// is used for an actual search.

// Examines text, context, and anchored to determine the right start
// state for the DFA search loop.  Fills in params and returns true on success.
// Returns false on failure.
bool DFA::AnalyzeSearch(SearchParams* params) {
  const StringPiece& text = params->text;
  const StringPiece& context = params->context;

  // Sanity check: make sure that text lies within context.
  if (text.begin() < context.begin() || text.end() > context.end()) {
    LOG(DFATAL) << "context does not contain text";
    params->start = DeadState;
    return true;
  }

  // Determine correct search type.
  int start;
  uint32_t flags;
  if (params->run_forward) {
    if (text.begin() == context.begin()) {
      start = kStartBeginText;
      flags = kEmptyBeginText|kEmptyBeginLine;
    } else if (text.begin()[-1] == '\n') {
      start = kStartBeginLine;
      flags = kEmptyBeginLine;
    } else if (Prog::IsWordChar(text.begin()[-1] & 0xFF)) {
      start = kStartAfterWordChar;
      flags = kFlagLastWord;
    } else {
      start = kStartAfterNonWordChar;
      flags = 0;
    }
  } else {
    if (text.end() == context.end()) {
      start = kStartBeginText;
      flags = kEmptyBeginText|kEmptyBeginLine;
    } else if (text.end()[0] == '\n') {
      start = kStartBeginLine;
      flags = kEmptyBeginLine;
    } else if (Prog::IsWordChar(text.end()[0] & 0xFF)) {
      start = kStartAfterWordChar;
      flags = kFlagLastWord;
    } else {
      start = kStartAfterNonWordChar;
      flags = 0;
    }
  }
  if (params->anchored)
    start |= kStartAnchored;
  StartInfo* info = &start_[start];

  // Try once without cache_lock for writing.
  // Try again after resetting the cache
  // (ResetCache will relock cache_lock for writing).
  if (!AnalyzeSearchHelper(params, info, flags)) {
    ResetCache(params->cache_lock);
    if (!AnalyzeSearchHelper(params, info, flags)) {
      LOG(DFATAL) << "Failed to analyze start state.";
      params->failed = true;
      return false;
    }
  }

  params->start = info->start;
  params->first_byte = info->first_byte.load(std::memory_order_acquire);

  return true;
}

// Fills in info if needed.  Returns true on success, false on failure.
bool DFA::AnalyzeSearchHelper(SearchParams* params, StartInfo* info,
                              uint32_t flags) {
  // Quick check.
  int fb = info->first_byte.load(std::memory_order_acquire);
  if (fb != kFbUnknown)
    return true;

  MutexLock l(&mutex_);
  fb = info->first_byte.load(std::memory_order_relaxed);
  if (fb != kFbUnknown)
    return true;

  q0_->clear();
  AddToQueue(q0_,
             params->anchored ? prog_->start() : prog_->start_unanchored(),
             flags);
  info->start = WorkqToCachedState(q0_, NULL, flags);
  if (info->start == NULL)
    return false;

  if (info->start == DeadState) {
    // Synchronize with "quick check" above.
    info->first_byte.store(kFbNone, std::memory_order_release);
    return true;
  }

  if (info->start == FullMatchState) {
    // Synchronize with "quick check" above.
    info->first_byte.store(kFbNone, std::memory_order_release);  // will be ignored
    return true;
  }

  // Even if we have a first_byte, we cannot use it when anchored and,
  // less obviously, we cannot use it when we are going to need flags.
  // This trick works only when there is a single byte that leads to a
  // different state!
  int first_byte = prog_->first_byte();
  if (first_byte == -1 ||
      params->anchored ||
      info->start->flag_ >> kFlagNeedShift != 0)
    first_byte = kFbNone;

  // Synchronize with "quick check" above.
  info->first_byte.store(first_byte, std::memory_order_release);
  return true;
}

// The actual DFA search: calls AnalyzeSearch and then FastSearchLoop.
bool DFA::Search(const StringPiece& text,
                 const StringPiece& context,
                 bool anchored,
                 bool want_earliest_match,
                 bool run_forward,
                 bool* failed,
                 const char** epp,
                 SparseSet* matches) {
  *epp = NULL;
  if (!ok()) {
    *failed = true;
    return false;
  }
  *failed = false;

  RWLocker l(&cache_mutex_);
  SearchParams params(text, context, &l);
  params.anchored = anchored;
  params.want_earliest_match = want_earliest_match;
  params.run_forward = run_forward;
  params.matches = matches;

  if (!AnalyzeSearch(&params)) {
    *failed = true;
    return false;
  }
  if (params.start == DeadState)
    return false;
  if (params.start == FullMatchState) {
    if (run_forward == want_earliest_match)
      *epp = text.begin();
    else
      *epp = text.end();
    return true;
  }
  bool ret = FastSearchLoop(&params);
  if (params.failed) {
    *failed = true;
    return false;
  }
  *epp = params.ep;
  return ret;
}

DFA* Prog::GetDFA(MatchKind kind) {
  // For a forward DFA, half the memory goes to each DFA.
  // However, if it is a "many match" DFA, then there is
  // no counterpart with which the memory must be shared.
  //
  // For a reverse DFA, all the memory goes to the
  // "longest match" DFA, because RE2 never does reverse
  // "first match" searches.
  if (kind == kFirstMatch) {
    std::call_once(dfa_first_once_, [](Prog* prog) {
      prog->dfa_first_ = new DFA(prog, kFirstMatch, prog->dfa_mem_ / 2);
    }, this);
    return dfa_first_;
  } else if (kind == kManyMatch) {
    std::call_once(dfa_first_once_, [](Prog* prog) {
      prog->dfa_first_ = new DFA(prog, kManyMatch, prog->dfa_mem_);
    }, this);
    return dfa_first_;
  } else {
    std::call_once(dfa_longest_once_, [](Prog* prog) {
      if (!prog->reversed_)
        prog->dfa_longest_ = new DFA(prog, kLongestMatch, prog->dfa_mem_ / 2);
      else
        prog->dfa_longest_ = new DFA(prog, kLongestMatch, prog->dfa_mem_);
    }, this);
    return dfa_longest_;
  }
}

void Prog::DeleteDFA(DFA* dfa) {
  delete dfa;
}

// Executes the regexp program to search in text,
// which itself is inside the larger context.  (As a convenience,
// passing a NULL context is equivalent to passing text.)
// Returns true if a match is found, false if not.
// If a match is found, fills in match0->end() to point at the end of the match
// and sets match0->begin() to text.begin(), since the DFA can't track
// where the match actually began.
//
// This is the only external interface (class DFA only exists in this file).
//
bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context,
                     Anchor anchor, MatchKind kind, StringPiece* match0,
                     bool* failed, SparseSet* matches) {
  *failed = false;

  StringPiece context = const_context;
  if (context.begin() == NULL)
    context = text;
  bool carat = anchor_start();
  bool dollar = anchor_end();
  if (reversed_) {
    using std::swap;
    swap(carat, dollar);
  }
  if (carat && context.begin() != text.begin())
    return false;
  if (dollar && context.end() != text.end())
    return false;

  // Handle full match by running an anchored longest match
  // and then checking if it covers all of text.
  bool anchored = anchor == kAnchored || anchor_start() || kind == kFullMatch;
  bool endmatch = false;
  if (kind == kManyMatch) {
    // This is split out in order to avoid clobbering kind.
  } else if (kind == kFullMatch || anchor_end()) {
    endmatch = true;
    kind = kLongestMatch;
  }

  // If the caller doesn't care where the match is (just whether one exists),
  // then we can stop at the very first match we find, the so-called
  // "earliest match".
  bool want_earliest_match = false;
  if (kind == kManyMatch) {
    // This is split out in order to avoid clobbering kind.
    if (matches == NULL) {
      want_earliest_match = true;
    }
  } else if (match0 == NULL && !endmatch) {
    want_earliest_match = true;
    kind = kLongestMatch;
  }

  DFA* dfa = GetDFA(kind);
  const char* ep;
  bool matched = dfa->Search(text, context, anchored,
                             want_earliest_match, !reversed_,
                             failed, &ep, matches);
  if (*failed)
    return false;
  if (!matched)
    return false;
  if (endmatch && ep != (reversed_ ? text.begin() : text.end()))
    return false;

  // If caller cares, record the boundary of the match.
  // We only know where it ends, so use the boundary of text
  // as the beginning.
  if (match0) {
    if (reversed_)
      *match0 = StringPiece(ep, static_cast<size_t>(text.end() - ep));
    else
      *match0 =
          StringPiece(text.begin(), static_cast<size_t>(ep - text.begin()));
  }
  return true;
}

// Build out all states in DFA.  Returns number of states.
int DFA::BuildAllStates(const Prog::DFAStateCallback& cb) {
  if (!ok())
    return 0;

  // Pick out start state for unanchored search
  // at beginning of text.
  RWLocker l(&cache_mutex_);
  SearchParams params(StringPiece(), StringPiece(), &l);
  params.anchored = false;
  if (!AnalyzeSearch(&params) ||
      params.start == NULL ||
      params.start == DeadState)
    return 0;

  // Add start state to work queue.
  // Note that any State* that we handle here must point into the cache,
  // so we can simply depend on pointer-as-a-number hashing and equality.
  std::unordered_map<State*, int> m;
  std::deque<State*> q;
  m.emplace(params.start, static_cast<int>(m.size()));
  q.push_back(params.start);

  // Compute the input bytes needed to cover all of the next pointers.
  int nnext = prog_->bytemap_range() + 1;  // + 1 for kByteEndText slot
  std::vector<int> input(nnext);
  for (int c = 0; c < 256; c++) {
    int b = prog_->bytemap()[c];
    while (c < 256-1 && prog_->bytemap()[c+1] == b)
      c++;
    input[b] = c;
  }
  input[prog_->bytemap_range()] = kByteEndText;

  // Scratch space for the output.
  std::vector<int> output(nnext);

  // Flood to expand every state.
  bool oom = false;
  while (!q.empty()) {
    State* s = q.front();
    q.pop_front();
    for (int c : input) {
      State* ns = RunStateOnByteUnlocked(s, c);
      if (ns == NULL) {
        oom = true;
        break;
      }
      if (ns == DeadState) {
        output[ByteMap(c)] = -1;
        continue;
      }
      if (m.find(ns) == m.end()) {
        m.emplace(ns, static_cast<int>(m.size()));
        q.push_back(ns);
      }
      output[ByteMap(c)] = m[ns];
    }
    if (cb)
      cb(oom ? NULL : output.data(),
         s == FullMatchState || s->IsMatch());
    if (oom)
      break;
  }

  return static_cast<int>(m.size());
}

// Build out all states in DFA for kind.  Returns number of states.
int Prog::BuildEntireDFA(MatchKind kind, const DFAStateCallback& cb) {
  return GetDFA(kind)->BuildAllStates(cb);
}

void Prog::TEST_dfa_should_bail_when_slow(bool b) {
  dfa_should_bail_when_slow = b;
}

// Computes min and max for matching string.
// Won't return strings bigger than maxlen.
bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) {
  if (!ok())
    return false;

  // NOTE: if future users of PossibleMatchRange want more precision when
  // presented with infinitely repeated elements, consider making this a
  // parameter to PossibleMatchRange.
  static int kMaxEltRepetitions = 0;

  // Keep track of the number of times we've visited states previously. We only
  // revisit a given state if it's part of a repeated group, so if the value
  // portion of the map tuple exceeds kMaxEltRepetitions we bail out and set
  // |*max| to |PrefixSuccessor(*max)|.
  //
  // Also note that previously_visited_states[UnseenStatePtr] will, in the STL
  // tradition, implicitly insert a '0' value at first use. We take advantage
  // of that property below.
  std::unordered_map<State*, int> previously_visited_states;

  // Pick out start state for anchored search at beginning of text.
  RWLocker l(&cache_mutex_);
  SearchParams params(StringPiece(), StringPiece(), &l);
  params.anchored = true;
  if (!AnalyzeSearch(&params))
    return false;
  if (params.start == DeadState) {  // No matching strings
    *min = "";
    *max = "";
    return true;
  }
  if (params.start == FullMatchState)  // Every string matches: no max
    return false;

  // The DFA is essentially a big graph rooted at params.start,
  // and paths in the graph correspond to accepted strings.
  // Each node in the graph has potentially 256+1 arrows
  // coming out, one for each byte plus the magic end of
  // text character kByteEndText.

  // To find the smallest possible prefix of an accepted
  // string, we just walk the graph preferring to follow
  // arrows with the lowest bytes possible.  To find the
  // largest possible prefix, we follow the largest bytes
  // possible.

  // The test for whether there is an arrow from s on byte j is
  //    ns = RunStateOnByteUnlocked(s, j);
  //    if (ns == NULL)
  //      return false;
  //    if (ns != DeadState && ns->ninst > 0)
  // The RunStateOnByteUnlocked call asks the DFA to build out the graph.
  // It returns NULL only if the DFA has run out of memory,
  // in which case we can't be sure of anything.
  // The second check sees whether there was graph built
  // and whether it is interesting graph.  Nodes might have
  // ns->ninst == 0 if they exist only to represent the fact
  // that a match was found on the previous byte.

  // Build minimum prefix.
  State* s = params.start;
  min->clear();
  MutexLock lock(&mutex_);
  for (int i = 0; i < maxlen; i++) {
    if (previously_visited_states[s] > kMaxEltRepetitions)
      break;
    previously_visited_states[s]++;

    // Stop if min is a match.
    State* ns = RunStateOnByte(s, kByteEndText);
    if (ns == NULL)  // DFA out of memory
      return false;
    if (ns != DeadState && (ns == FullMatchState || ns->IsMatch()))
      break;

    // Try to extend the string with low bytes.
    bool extended = false;
    for (int j = 0; j < 256; j++) {
      ns = RunStateOnByte(s, j);
      if (ns == NULL)  // DFA out of memory
        return false;
      if (ns == FullMatchState ||
          (ns > SpecialStateMax && ns->ninst_ > 0)) {
        extended = true;
        min->append(1, static_cast<char>(j));
        s = ns;
        break;
      }
    }
    if (!extended)
      break;
  }

  // Build maximum prefix.
  previously_visited_states.clear();
  s = params.start;
  max->clear();
  for (int i = 0; i < maxlen; i++) {
    if (previously_visited_states[s] > kMaxEltRepetitions)
      break;
    previously_visited_states[s] += 1;

    // Try to extend the string with high bytes.
    bool extended = false;
    for (int j = 255; j >= 0; j--) {
      State* ns = RunStateOnByte(s, j);
      if (ns == NULL)
        return false;
      if (ns == FullMatchState ||
          (ns > SpecialStateMax && ns->ninst_ > 0)) {
        extended = true;
        max->append(1, static_cast<char>(j));
        s = ns;
        break;
      }
    }
    if (!extended) {
      // Done, no need for PrefixSuccessor.
      return true;
    }
  }

  // Stopped while still adding to *max - round aaaaaaaaaa... to aaaa...b
  PrefixSuccessor(max);

  // If there are no bytes left, we have no way to say "there is no maximum
  // string".  We could make the interface more complicated and be able to
  // return "there is no maximum but here is a minimum", but that seems like
  // overkill -- the most common no-max case is all possible strings, so not
  // telling the caller that the empty string is the minimum match isn't a
  // great loss.
  if (max->empty())
    return false;

  return true;
}

// PossibleMatchRange for a Prog.
bool Prog::PossibleMatchRange(std::string* min, std::string* max, int maxlen) {
  // Have to use dfa_longest_ to get all strings for full matches.
  // For example, (a|aa) never matches aa in first-match mode.
  return GetDFA(kLongestMatch)->PossibleMatchRange(min, max, maxlen);
}

}  // namespace re2
// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_FILTERED_RE2_H_
#define RE2_FILTERED_RE2_H_

// The class FilteredRE2 is used as a wrapper to multiple RE2 regexps.
// It provides a prefilter mechanism that helps in cutting down the
// number of regexps that need to be actually searched.
//
// By design, it does not include a string matching engine. This is to
// allow the user of the class to use their favorite string match
// engine. The overall flow is: Add all the regexps using Add, then
// Compile the FilteredRE2. The compile returns strings that need to
// be matched. Note that all returned strings are lowercase. For
// applying regexps to a search text, the caller does the string
// matching using the strings returned. When doing the string match,
// note that the caller has to do that on lower cased version of the
// search text. Then call FirstMatch or AllMatches with a vector of
// indices of strings that were found in the text to get the actual
// regexp matches.

#include <string>
#include <vector>



namespace re2 {

class PrefilterTree;

class FilteredRE2 {
 public:
  FilteredRE2();
  explicit FilteredRE2(int min_atom_len);
  ~FilteredRE2();

  // Uses RE2 constructor to create a RE2 object (re). Returns
  // re->error_code(). If error_code is other than NoError, then re is
  // deleted and not added to re2_vec_.
  RE2::ErrorCode Add(const StringPiece& pattern,
                     const RE2::Options& options,
                     int *id);

  // Prepares the regexps added by Add for filtering.  Returns a set
  // of strings that the caller should check for in candidate texts.
  // The returned strings are lowercased. When doing string matching,
  // the search text should be lowercased first to find matching
  // strings from the set of strings returned by Compile.  Call after
  // all Add calls are done.
  void Compile(std::vector<std::string>* strings_to_match);

  // Returns the index of the first matching regexp.
  // Returns -1 on no match. Can be called prior to Compile.
  // Does not do any filtering: simply tries to Match the
  // regexps in a loop.
  int SlowFirstMatch(const StringPiece& text) const;

  // Returns the index of the first matching regexp.
  // Returns -1 on no match. Compile has to be called before
  // calling this.
  int FirstMatch(const StringPiece& text,
                 const std::vector<int>& atoms) const;

  // Returns the indices of all matching regexps, after first clearing
  // matched_regexps.
  bool AllMatches(const StringPiece& text,
                  const std::vector<int>& atoms,
                  std::vector<int>* matching_regexps) const;

  // Returns the indices of all potentially matching regexps after first
  // clearing potential_regexps.
  // A regexp is potentially matching if it passes the filter.
  // If a regexp passes the filter it may still not match.
  // A regexp that does not pass the filter is guaranteed to not match.
  void AllPotentials(const std::vector<int>& atoms,
                     std::vector<int>* potential_regexps) const;

  // The number of regexps added.
  int NumRegexps() const { return static_cast<int>(re2_vec_.size()); }

 private:

  // Get the individual RE2 objects. Useful for testing.
  RE2* GetRE2(int regexpid) const { return re2_vec_[regexpid]; }

  // Print prefilter.
  void PrintPrefilter(int regexpid);

  // Useful for testing and debugging.
  void RegexpsGivenStrings(const std::vector<int>& matched_atoms,
                           std::vector<int>* passed_regexps);

  // All the regexps in the FilteredRE2.
  std::vector<RE2*> re2_vec_;

  // Has the FilteredRE2 been compiled using Compile()
  bool compiled_;

  // An AND-OR tree of string atoms used for filtering regexps.
  PrefilterTree* prefilter_tree_;

  FilteredRE2(const FilteredRE2&) = delete;
  FilteredRE2& operator=(const FilteredRE2&) = delete;
};

}  // namespace re2

#endif  // RE2_FILTERED_RE2_H_


#include <stddef.h>
#include <string>



// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_PREFILTER_H_
#define RE2_PREFILTER_H_

// Prefilter is the class used to extract string guards from regexps.
// Rather than using Prefilter class directly, use FilteredRE2.
// See filtered_re2.h

#include <set>
#include <string>
#include <vector>




namespace re2 {

class RE2;

class Regexp;

class Prefilter {
  // Instead of using Prefilter directly, use FilteredRE2; see filtered_re2.h
 public:
  enum Op {
    ALL = 0,  // Everything matches
    NONE,  // Nothing matches
    ATOM,  // The string atom() must match
    AND,   // All in subs() must match
    OR,   // One of subs() must match
  };

  explicit Prefilter(Op op);
  ~Prefilter();

  Op op() { return op_; }
  const std::string& atom() const { return atom_; }
  void set_unique_id(int id) { unique_id_ = id; }
  int unique_id() const { return unique_id_; }

  // The children of the Prefilter node.
  std::vector<Prefilter*>* subs() {
    DCHECK(op_ == AND || op_ == OR);
    return subs_;
  }

  // Set the children vector. Prefilter takes ownership of subs and
  // subs_ will be deleted when Prefilter is deleted.
  void set_subs(std::vector<Prefilter*>* subs) { subs_ = subs; }

  // Given a RE2, return a Prefilter. The caller takes ownership of
  // the Prefilter and should deallocate it. Returns NULL if Prefilter
  // cannot be formed.
  static Prefilter* FromRE2(const RE2* re2);

  // Returns a readable debug string of the prefilter.
  std::string DebugString() const;

 private:
  class Info;

  // Combines two prefilters together to create an AND. The passed
  // Prefilters will be part of the returned Prefilter or deleted.
  static Prefilter* And(Prefilter* a, Prefilter* b);

  // Combines two prefilters together to create an OR. The passed
  // Prefilters will be part of the returned Prefilter or deleted.
  static Prefilter* Or(Prefilter* a, Prefilter* b);

  // Generalized And/Or
  static Prefilter* AndOr(Op op, Prefilter* a, Prefilter* b);

  static Prefilter* FromRegexp(Regexp* a);

  static Prefilter* FromString(const std::string& str);

  static Prefilter* OrStrings(std::set<std::string>* ss);

  static Info* BuildInfo(Regexp* re);

  Prefilter* Simplify();

  // Kind of Prefilter.
  Op op_;

  // Sub-matches for AND or OR Prefilter.
  std::vector<Prefilter*>* subs_;

  // Actual string to match in leaf node.
  std::string atom_;

  // If different prefilters have the same string atom, or if they are
  // structurally the same (e.g., OR of same atom strings) they are
  // considered the same unique nodes. This is the id for each unique
  // node. This field is populated with a unique id for every node,
  // and -1 for duplicate nodes.
  int unique_id_;

  Prefilter(const Prefilter&) = delete;
  Prefilter& operator=(const Prefilter&) = delete;
};

}  // namespace re2

#endif  // RE2_PREFILTER_H_

// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_PREFILTER_TREE_H_
#define RE2_PREFILTER_TREE_H_

// The PrefilterTree class is used to form an AND-OR tree of strings
// that would trigger each regexp. The 'prefilter' of each regexp is
// added tp PrefilterTree, and then PrefilterTree is used to find all
// the unique strings across the prefilters. During search, by using
// matches from a string matching engine, PrefilterTree deduces the
// set of regexps that are to be triggered. The 'string matching
// engine' itself is outside of this class, and the caller can use any
// favorite engine. PrefilterTree provides a set of strings (called
// atoms) that the user of this class should use to do the string
// matching.

#include <map>
#include <string>
#include <vector>





namespace re2 {

class PrefilterTree {
 public:
  PrefilterTree();
  explicit PrefilterTree(int min_atom_len);
  ~PrefilterTree();

  // Adds the prefilter for the next regexp. Note that we assume that
  // Add called sequentially for all regexps. All Add calls
  // must precede Compile.
  void Add(Prefilter* prefilter);

  // The Compile returns a vector of string in atom_vec.
  // Call this after all the prefilters are added through Add.
  // No calls to Add after Compile are allowed.
  // The caller should use the returned set of strings to do string matching.
  // Each time a string matches, the corresponding index then has to be
  // and passed to RegexpsGivenStrings below.
  void Compile(std::vector<std::string>* atom_vec);

  // Given the indices of the atoms that matched, returns the indexes
  // of regexps that should be searched.  The matched_atoms should
  // contain all the ids of string atoms that were found to match the
  // content. The caller can use any string match engine to perform
  // this function. This function is thread safe.
  void RegexpsGivenStrings(const std::vector<int>& matched_atoms,
                           std::vector<int>* regexps) const;

  // Print debug prefilter. Also prints unique ids associated with
  // nodes of the prefilter of the regexp.
  void PrintPrefilter(int regexpid);

 private:
  typedef SparseArray<int> IntMap;
  typedef std::map<int, int> StdIntMap;
  typedef std::map<std::string, Prefilter*> NodeMap;

  // Each unique node has a corresponding Entry that helps in
  // passing the matching trigger information along the tree.
  struct Entry {
   public:
    // How many children should match before this node triggers the
    // parent. For an atom and an OR node, this is 1 and for an AND
    // node, it is the number of unique children.
    int propagate_up_at_count;

    // When this node is ready to trigger the parent, what are the indices
    // of the parent nodes to trigger. The reason there may be more than
    // one is because of sharing. For example (abc | def) and (xyz | def)
    // are two different nodes, but they share the atom 'def'. So when
    // 'def' matches, it triggers two parents, corresponding to the two
    // different OR nodes.
    StdIntMap* parents;

    // When this node is ready to trigger the parent, what are the
    // regexps that are triggered.
    std::vector<int> regexps;
  };

  // Returns true if the prefilter node should be kept.
  bool KeepNode(Prefilter* node) const;

  // This function assigns unique ids to various parts of the
  // prefilter, by looking at if these nodes are already in the
  // PrefilterTree.
  void AssignUniqueIds(NodeMap* nodes, std::vector<std::string>* atom_vec);

  // Given the matching atoms, find the regexps to be triggered.
  void PropagateMatch(const std::vector<int>& atom_ids,
                      IntMap* regexps) const;

  // Returns the prefilter node that has the same NodeString as this
  // node. For the canonical node, returns node.
  Prefilter* CanonicalNode(NodeMap* nodes, Prefilter* node);

  // A string that uniquely identifies the node. Assumes that the
  // children of node has already been assigned unique ids.
  std::string NodeString(Prefilter* node) const;

  // Recursively constructs a readable prefilter string.
  std::string DebugNodeString(Prefilter* node) const;

  // Used for debugging.
  void PrintDebugInfo(NodeMap* nodes);

  // These are all the nodes formed by Compile. Essentially, there is
  // one node for each unique atom and each unique AND/OR node.
  std::vector<Entry> entries_;

  // indices of regexps that always pass through the filter (since we
  // found no required literals in these regexps).
  std::vector<int> unfiltered_;

  // vector of Prefilter for all regexps.
  std::vector<Prefilter*> prefilter_vec_;

  // Atom index in returned strings to entry id mapping.
  std::vector<int> atom_index_to_id_;

  // Has the prefilter tree been compiled.
  bool compiled_;

  // Strings less than this length are not stored as atoms.
  const int min_atom_len_;

  PrefilterTree(const PrefilterTree&) = delete;
  PrefilterTree& operator=(const PrefilterTree&) = delete;
};

}  // namespace

#endif  // RE2_PREFILTER_TREE_H_


namespace re2 {

FilteredRE2::FilteredRE2()
    : compiled_(false),
      prefilter_tree_(new PrefilterTree()) {
}

FilteredRE2::FilteredRE2(int min_atom_len)
    : compiled_(false),
      prefilter_tree_(new PrefilterTree(min_atom_len)) {
}

FilteredRE2::~FilteredRE2() {
  for (size_t i = 0; i < re2_vec_.size(); i++)
    delete re2_vec_[i];
  delete prefilter_tree_;
}

RE2::ErrorCode FilteredRE2::Add(const StringPiece& pattern,
                                const RE2::Options& options, int* id) {
  RE2* re = new RE2(pattern, options);
  RE2::ErrorCode code = re->error_code();

  if (!re->ok()) {
    if (options.log_errors()) {
      LOG(ERROR) << "Couldn't compile regular expression, skipping: "
                 << re << " due to error " << re->error();
    }
    delete re;
  } else {
    *id = static_cast<int>(re2_vec_.size());
    re2_vec_.push_back(re);
  }

  return code;
}

void FilteredRE2::Compile(std::vector<std::string>* atoms) {
  if (compiled_) {
    LOG(ERROR) << "Compile called already.";
    return;
  }

  if (re2_vec_.empty()) {
    LOG(ERROR) << "Compile called before Add.";
    return;
  }

  for (size_t i = 0; i < re2_vec_.size(); i++) {
    Prefilter* prefilter = Prefilter::FromRE2(re2_vec_[i]);
    prefilter_tree_->Add(prefilter);
  }
  atoms->clear();
  prefilter_tree_->Compile(atoms);
  compiled_ = true;
}

int FilteredRE2::SlowFirstMatch(const StringPiece& text) const {
  for (size_t i = 0; i < re2_vec_.size(); i++)
    if (RE2::PartialMatch(text, *re2_vec_[i]))
      return static_cast<int>(i);
  return -1;
}

int FilteredRE2::FirstMatch(const StringPiece& text,
                            const std::vector<int>& atoms) const {
  if (!compiled_) {
    LOG(DFATAL) << "FirstMatch called before Compile.";
    return -1;
  }
  std::vector<int> regexps;
  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
  for (size_t i = 0; i < regexps.size(); i++)
    if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
      return regexps[i];
  return -1;
}

bool FilteredRE2::AllMatches(
    const StringPiece& text,
    const std::vector<int>& atoms,
    std::vector<int>* matching_regexps) const {
  matching_regexps->clear();
  std::vector<int> regexps;
  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
  for (size_t i = 0; i < regexps.size(); i++)
    if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
      matching_regexps->push_back(regexps[i]);
  return !matching_regexps->empty();
}

void FilteredRE2::AllPotentials(
    const std::vector<int>& atoms,
    std::vector<int>* potential_regexps) const {
  prefilter_tree_->RegexpsGivenStrings(atoms, potential_regexps);
}

void FilteredRE2::RegexpsGivenStrings(const std::vector<int>& matched_atoms,
                                      std::vector<int>* passed_regexps) {
  prefilter_tree_->RegexpsGivenStrings(matched_atoms, passed_regexps);
}

void FilteredRE2::PrintPrefilter(int regexpid) {
  prefilter_tree_->PrintPrefilter(regexpid);
}

}  // namespace re2
// Copyright 2008 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Determine whether this library should match PCRE exactly
// for a particular Regexp.  (If so, the testing framework can
// check that it does.)
//
// This library matches PCRE except in these cases:
//   * the regexp contains a repetition of an empty string,
//     like (a*)* or (a*)+.  In this case, PCRE will treat
//     the repetition sequence as ending with an empty string,
//     while this library does not.
//   * Perl and PCRE differ on whether \v matches \n.
//     For historical reasons, this library implements the Perl behavior.
//   * Perl and PCRE allow $ in one-line mode to match either the very
//     end of the text or just before a \n at the end of the text.
//     This library requires it to match only the end of the text.
//   * Similarly, Perl and PCRE do not allow ^ in multi-line mode to
//     match the end of the text if the last character is a \n.
//     This library does allow it.
//
// Regexp::MimicsPCRE checks for any of these conditions.






namespace re2 {

// Returns whether re might match an empty string.
static bool CanBeEmptyString(Regexp *re);

// Walker class to compute whether library handles a regexp
// exactly as PCRE would.  See comment at top for conditions.

class PCREWalker : public Regexp::Walker<bool> {
 public:
  PCREWalker() {}
  bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg, bool* child_args,
                 int nchild_args);

  bool ShortVisit(Regexp* re, bool a) {
    // Should never be called: we use Walk not WalkExponential.
    LOG(DFATAL) << "EmptyStringWalker::ShortVisit called";
    return a;
  }
};

// Called after visiting each of re's children and accumulating
// the return values in child_args.  So child_args contains whether
// this library mimics PCRE for those subexpressions.
bool PCREWalker::PostVisit(Regexp* re, bool parent_arg, bool pre_arg,
                           bool* child_args, int nchild_args) {
  // If children failed, so do we.
  for (int i = 0; i < nchild_args; i++)
    if (!child_args[i])
      return false;

  // Otherwise look for other reasons to fail.
  switch (re->op()) {
    // Look for repeated empty string.
    case kRegexpStar:
    case kRegexpPlus:
    case kRegexpQuest:
      if (CanBeEmptyString(re->sub()[0]))
        return false;
      break;
    case kRegexpRepeat:
      if (re->max() == -1 && CanBeEmptyString(re->sub()[0]))
        return false;
      break;

    // Look for \v
    case kRegexpLiteral:
      if (re->rune() == '\v')
        return false;
      break;

    // Look for $ in single-line mode.
    case kRegexpEndText:
    case kRegexpEmptyMatch:
      if (re->parse_flags() & Regexp::WasDollar)
        return false;
      break;

    // Look for ^ in multi-line mode.
    case kRegexpBeginLine:
      // No condition: in single-line mode ^ becomes kRegexpBeginText.
      return false;

    default:
      break;
  }

  // Not proven guilty.
  return true;
}

// Returns whether this regexp's behavior will mimic PCRE's exactly.
bool Regexp::MimicsPCRE() {
  PCREWalker w;
  return w.Walk(this, true);
}


// Walker class to compute whether a Regexp can match an empty string.
// It is okay to overestimate.  For example, \b\B cannot match an empty
// string, because \b and \B are mutually exclusive, but this isn't
// that smart and will say it can.  Spurious empty strings
// will reduce the number of regexps we sanity check against PCRE,
// but they won't break anything.

class EmptyStringWalker : public Regexp::Walker<bool> {
 public:
  EmptyStringWalker() { }
  bool PostVisit(Regexp* re, bool parent_arg, bool pre_arg,
                 bool* child_args, int nchild_args);

  bool ShortVisit(Regexp* re, bool a) {
    // Should never be called: we use Walk not WalkExponential.
    LOG(DFATAL) << "EmptyStringWalker::ShortVisit called";
    return a;
  }

 private:
  EmptyStringWalker(const EmptyStringWalker&) = delete;
  EmptyStringWalker& operator=(const EmptyStringWalker&) = delete;
};

// Called after visiting re's children.  child_args contains the return
// value from each of the children's PostVisits (i.e., whether each child
// can match an empty string).  Returns whether this clause can match an
// empty string.
bool EmptyStringWalker::PostVisit(Regexp* re, bool parent_arg, bool pre_arg,
                                  bool* child_args, int nchild_args) {
  switch (re->op()) {
    case kRegexpNoMatch:               // never empty
    case kRegexpLiteral:
    case kRegexpAnyChar:
    case kRegexpAnyByte:
    case kRegexpCharClass:
    case kRegexpLiteralString:
      return false;

    case kRegexpEmptyMatch:            // always empty
    case kRegexpBeginLine:             // always empty, when they match
    case kRegexpEndLine:
    case kRegexpNoWordBoundary:
    case kRegexpWordBoundary:
    case kRegexpBeginText:
    case kRegexpEndText:
    case kRegexpStar:                  // can always be empty
    case kRegexpQuest:
    case kRegexpHaveMatch:
      return true;

    case kRegexpConcat:                // can be empty if all children can
      for (int i = 0; i < nchild_args; i++)
        if (!child_args[i])
          return false;
      return true;

    case kRegexpAlternate:             // can be empty if any child can
      for (int i = 0; i < nchild_args; i++)
        if (child_args[i])
          return true;
      return false;

    case kRegexpPlus:                  // can be empty if the child can
    case kRegexpCapture:
      return child_args[0];

    case kRegexpRepeat:                // can be empty if child can or is x{0}
      return child_args[0] || re->min() == 0;
  }
  return false;
}

// Returns whether re can match an empty string.
static bool CanBeEmptyString(Regexp* re) {
  EmptyStringWalker w;
  return w.Walk(re, true);
}

}  // namespace re2
// Copyright 2006-2007 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Tested by search_test.cc.
//
// Prog::SearchNFA, an NFA search.
// This is an actual NFA like the theorists talk about,
// not the pseudo-NFA found in backtracking regexp implementations.
//
// IMPLEMENTATION
//
// This algorithm is a variant of one that appeared in Rob Pike's sam editor,
// which is a variant of the one described in Thompson's 1968 CACM paper.
// See http://swtch.com/~rsc/regexp/ for various history.  The main feature
// over the DFA implementation is that it tracks submatch boundaries.
//
// When the choice of submatch boundaries is ambiguous, this particular
// implementation makes the same choices that traditional backtracking
// implementations (in particular, Perl and PCRE) do.
// Note that unlike in Perl and PCRE, this algorithm *cannot* take exponential
// time in the length of the input.
//
// Like Thompson's original machine and like the DFA implementation, this
// implementation notices a match only once it is one byte past it.

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>









namespace re2 {

class NFA {
 public:
  NFA(Prog* prog);
  ~NFA();

  // Searches for a matching string.
  //   * If anchored is true, only considers matches starting at offset.
  //     Otherwise finds lefmost match at or after offset.
  //   * If longest is true, returns the longest match starting
  //     at the chosen start point.  Otherwise returns the so-called
  //     left-biased match, the one traditional backtracking engines
  //     (like Perl and PCRE) find.
  // Records submatch boundaries in submatch[1..nsubmatch-1].
  // Submatch[0] is the entire match.  When there is a choice in
  // which text matches each subexpression, the submatch boundaries
  // are chosen to match what a backtracking implementation would choose.
  bool Search(const StringPiece& text, const StringPiece& context,
              bool anchored, bool longest,
              StringPiece* submatch, int nsubmatch);

 private:
  struct Thread {
    union {
      int ref;
      Thread* next;  // when on free list
    };
    const char** capture;
  };

  // State for explicit stack in AddToThreadq.
  struct AddState {
    int id;     // Inst to process
    Thread* t;  // if not null, set t0 = t before processing id
  };

  // Threadq is a list of threads.  The list is sorted by the order
  // in which Perl would explore that particular state -- the earlier
  // choices appear earlier in the list.
  typedef SparseArray<Thread*> Threadq;

  inline Thread* AllocThread();
  inline Thread* Incref(Thread* t);
  inline void Decref(Thread* t);

  // Follows all empty arrows from id0 and enqueues all the states reached.
  // Enqueues only the ByteRange instructions that match byte c.
  // context is used (with p) for evaluating empty-width specials.
  // p is the current input position, and t0 is the current thread.
  void AddToThreadq(Threadq* q, int id0, int c, const StringPiece& context,
                    const char* p, Thread* t0);

  // Run runq on byte c, appending new states to nextq.
  // Updates matched_ and match_ as new, better matches are found.
  // context is used (with p) for evaluating empty-width specials.
  // p is the position of byte c in the input string for AddToThreadq;
  // p-1 will be used when processing Match instructions.
  // Frees all the threads on runq.
  // If there is a shortcut to the end, returns that shortcut.
  int Step(Threadq* runq, Threadq* nextq, int c, const StringPiece& context,
           const char* p);

  // Returns text version of capture information, for debugging.
  std::string FormatCapture(const char** capture);

  inline void CopyCapture(const char** dst, const char** src);

  Prog* prog_;                // underlying program
  int start_;                 // start instruction in program
  int ncapture_;              // number of submatches to track
  bool longest_;              // whether searching for longest match
  bool endmatch_;             // whether match must end at text.end()
  const char* btext_;         // beginning of text being matched (for FormatSubmatch)
  const char* etext_;         // end of text being matched (for endmatch_)
  Threadq q0_, q1_;           // pre-allocated for Search.
  PODArray<AddState> stack_;  // pre-allocated for AddToThreadq
  Thread* free_threads_;      // free list
  const char** match_;        // best match so far
  bool matched_;              // any match so far?

  NFA(const NFA&) = delete;
  NFA& operator=(const NFA&) = delete;
};

NFA::NFA(Prog* prog) {
  prog_ = prog;
  start_ = prog_->start();
  ncapture_ = 0;
  longest_ = false;
  endmatch_ = false;
  btext_ = NULL;
  etext_ = NULL;
  q0_.resize(prog_->size());
  q1_.resize(prog_->size());
  // See NFA::AddToThreadq() for why this is so.
  int nstack = 2*prog_->inst_count(kInstCapture) +
               prog_->inst_count(kInstEmptyWidth) +
               prog_->inst_count(kInstNop) + 1;  // + 1 for start inst
  stack_ = PODArray<AddState>(nstack);
  free_threads_ = NULL;
  match_ = NULL;
  matched_ = false;
}

NFA::~NFA() {
  delete[] match_;
  Thread* next;
  for (Thread* t = free_threads_; t; t = next) {
    next = t->next;
    delete[] t->capture;
    delete t;
  }
}

NFA::Thread* NFA::AllocThread() {
  Thread* t = free_threads_;
  if (t == NULL) {
    t = new Thread;
    t->ref = 1;
    t->capture = new const char*[ncapture_];
    return t;
  }
  free_threads_ = t->next;
  t->ref = 1;
  return t;
}

NFA::Thread* NFA::Incref(Thread* t) {
  DCHECK(t != NULL);
  t->ref++;
  return t;
}

void NFA::Decref(Thread* t) {
  if (t == NULL)
    return;
  t->ref--;
  if (t->ref > 0)
    return;
  DCHECK_EQ(t->ref, 0);
  t->next = free_threads_;
  free_threads_ = t;
}

void NFA::CopyCapture(const char** dst, const char** src) {
  for (int i = 0; i < ncapture_; i+=2) {
    dst[i] = src[i];
    dst[i+1] = src[i+1];
  }
}

// Follows all empty arrows from id0 and enqueues all the states reached.
// Enqueues only the ByteRange instructions that match byte c.
// context is used (with p) for evaluating empty-width specials.
// p is the current input position, and t0 is the current thread.
void NFA::AddToThreadq(Threadq* q, int id0, int c, const StringPiece& context,
                       const char* p, Thread* t0) {
  if (id0 == 0)
    return;

  // Use stack_ to hold our stack of instructions yet to process.
  // It was preallocated as follows:
  //   two entries per Capture;
  //   one entry per EmptyWidth; and
  //   one entry per Nop.
  // This reflects the maximum number of stack pushes that each can
  // perform. (Each instruction can be processed at most once.)
  AddState* stk = stack_.data();
  int nstk = 0;

  stk[nstk++] = {id0, NULL};
  while (nstk > 0) {
    DCHECK_LE(nstk, stack_.size());
    AddState a = stk[--nstk];

  Loop:
    if (a.t != NULL) {
      // t0 was a thread that we allocated and copied in order to
      // record the capture, so we must now decref it.
      Decref(t0);
      t0 = a.t;
    }

    int id = a.id;
    if (id == 0)
      continue;
    if (q->has_index(id)) {
      continue;
    }

    // Create entry in q no matter what.  We might fill it in below,
    // or we might not.  Even if not, it is necessary to have it,
    // so that we don't revisit id0 during the recursion.
    q->set_new(id, NULL);
    Thread** tp = &q->get_existing(id);
    int j;
    Thread* t;
    Prog::Inst* ip = prog_->inst(id);
    switch (ip->opcode()) {
    default:
      LOG(DFATAL) << "unhandled " << ip->opcode() << " in AddToThreadq";
      break;

    case kInstFail:
      break;

    case kInstAltMatch:
      // Save state; will pick up at next byte.
      t = Incref(t0);
      *tp = t;

      DCHECK(!ip->last());
      a = {id+1, NULL};
      goto Loop;

    case kInstNop:
      if (!ip->last())
        stk[nstk++] = {id+1, NULL};

      // Continue on.
      a = {ip->out(), NULL};
      goto Loop;

    case kInstCapture:
      if (!ip->last())
        stk[nstk++] = {id+1, NULL};

      if ((j=ip->cap()) < ncapture_) {
        // Push a dummy whose only job is to restore t0
        // once we finish exploring this possibility.
        stk[nstk++] = {0, t0};

        // Record capture.
        t = AllocThread();
        CopyCapture(t->capture, t0->capture);
        t->capture[j] = p;
        t0 = t;
      }
      a = {ip->out(), NULL};
      goto Loop;

    case kInstByteRange:
      if (!ip->Matches(c))
        goto Next;

      // Save state; will pick up at next byte.
      t = Incref(t0);
      *tp = t;
      if (ip->hint() == 0)
        break;
      a = {id+ip->hint(), NULL};
      goto Loop;

    case kInstMatch:
      // Save state; will pick up at next byte.
      t = Incref(t0);
      *tp = t;
    Next:
      if (ip->last())
        break;
      a = {id+1, NULL};
      goto Loop;

    case kInstEmptyWidth:
      if (!ip->last())
        stk[nstk++] = {id+1, NULL};

      // Continue on if we have all the right flag bits.
      if (ip->empty() & ~Prog::EmptyFlags(context, p))
        break;
      a = {ip->out(), NULL};
      goto Loop;
    }
  }
}

// Run runq on byte c, appending new states to nextq.
// Updates matched_ and match_ as new, better matches are found.
// context is used (with p) for evaluating empty-width specials.
// p is the position of byte c in the input string for AddToThreadq;
// p-1 will be used when processing Match instructions.
// Frees all the threads on runq.
// If there is a shortcut to the end, returns that shortcut.
int NFA::Step(Threadq* runq, Threadq* nextq, int c, const StringPiece& context,
              const char* p) {
  nextq->clear();

  for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i) {
    Thread* t = i->value();
    if (t == NULL)
      continue;

    if (longest_) {
      // Can skip any threads started after our current best match.
      if (matched_ && match_[0] < t->capture[0]) {
        Decref(t);
        continue;
      }
    }

    int id = i->index();
    Prog::Inst* ip = prog_->inst(id);

    switch (ip->opcode()) {
      default:
        // Should only see the values handled below.
        LOG(DFATAL) << "Unhandled " << ip->opcode() << " in step";
        break;

      case kInstByteRange:
        AddToThreadq(nextq, ip->out(), c, context, p, t);
        break;

      case kInstAltMatch:
        if (i != runq->begin())
          break;
        // The match is ours if we want it.
        if (ip->greedy(prog_) || longest_) {
          CopyCapture(match_, t->capture);
          matched_ = true;

          Decref(t);
          for (++i; i != runq->end(); ++i)
            Decref(i->value());
          runq->clear();
          if (ip->greedy(prog_))
            return ip->out1();
          return ip->out();
        }
        break;

      case kInstMatch: {
        // Avoid invoking undefined behavior when p happens
        // to be null - and p-1 would be meaningless anyway.
        if (p == NULL)
          break;

        if (endmatch_ && p-1 != etext_)
          break;

        if (longest_) {
          // Leftmost-longest mode: save this match only if
          // it is either farther to the left or at the same
          // point but longer than an existing match.
          if (!matched_ || t->capture[0] < match_[0] ||
              (t->capture[0] == match_[0] && p-1 > match_[1])) {
            CopyCapture(match_, t->capture);
            match_[1] = p-1;
            matched_ = true;
          }
        } else {
          // Leftmost-biased mode: this match is by definition
          // better than what we've already found (see next line).
          CopyCapture(match_, t->capture);
          match_[1] = p-1;
          matched_ = true;

          // Cut off the threads that can only find matches
          // worse than the one we just found: don't run the
          // rest of the current Threadq.
          Decref(t);
          for (++i; i != runq->end(); ++i)
            Decref(i->value());
          runq->clear();
          return 0;
        }
        break;
      }
    }
    Decref(t);
  }
  runq->clear();
  return 0;
}

std::string NFA::FormatCapture(const char** capture) {
  std::string s;
  for (int i = 0; i < ncapture_; i+=2) {
    if (capture[i] == NULL)
      StringAppendF(&s, "(?,?)");
    else if (capture[i+1] == NULL)
      StringAppendF(&s, "(%d,?)", (int)(capture[i] - btext_));
    else
      StringAppendF(&s, "(%d,%d)",
                    (int)(capture[i] - btext_),
                    (int)(capture[i+1] - btext_));
  }
  return s;
}

bool NFA::Search(const StringPiece& text, const StringPiece& const_context,
            bool anchored, bool longest,
            StringPiece* submatch, int nsubmatch) {
  if (start_ == 0)
    return false;

  StringPiece context = const_context;
  if (context.begin() == NULL)
    context = text;

  // Sanity check: make sure that text lies within context.
  if (text.begin() < context.begin() || text.end() > context.end()) {
    LOG(DFATAL) << "context does not contain text";
    return false;
  }

  if (prog_->anchor_start() && context.begin() != text.begin())
    return false;
  if (prog_->anchor_end() && context.end() != text.end())
    return false;
  anchored |= prog_->anchor_start();
  if (prog_->anchor_end()) {
    longest = true;
    endmatch_ = true;
    etext_ = text.end();
  }

  if (nsubmatch < 0) {
    LOG(DFATAL) << "Bad args: nsubmatch=" << nsubmatch;
    return false;
  }

  // Save search parameters.
  ncapture_ = 2*nsubmatch;
  longest_ = longest;

  if (nsubmatch == 0) {
    // We need to maintain match[0], both to distinguish the
    // longest match (if longest is true) and also to tell
    // whether we've seen any matches at all.
    ncapture_ = 2;
  }

  match_ = new const char*[ncapture_];
  matched_ = false;

  // For debugging prints.
  btext_ = context.begin();

  // Set up search.
  Threadq* runq = &q0_;
  Threadq* nextq = &q1_;
  runq->clear();
  nextq->clear();
  memset(&match_[0], 0, ncapture_*sizeof match_[0]);

  // Loop over the text, stepping the machine.
  for (const char* p = text.begin();; p++) {
    // This is a no-op the first time around the loop because runq is empty.
    int id = Step(runq, nextq, p < text.end() ? p[0] & 0xFF : -1, context, p);
    DCHECK_EQ(runq->size(), 0);
    using std::swap;
    swap(nextq, runq);
    nextq->clear();
    if (id != 0) {
      // We're done: full match ahead.
      p = text.end();
      for (;;) {
        Prog::Inst* ip = prog_->inst(id);
        switch (ip->opcode()) {
          default:
            LOG(DFATAL) << "Unexpected opcode in short circuit: " << ip->opcode();
            break;

          case kInstCapture:
            if (ip->cap() < ncapture_)
              match_[ip->cap()] = p;
            id = ip->out();
            continue;

          case kInstNop:
            id = ip->out();
            continue;

          case kInstMatch:
            match_[1] = p;
            matched_ = true;
            break;
        }
        break;
      }
      break;
    }

    if (p > text.end())
      break;

    // Start a new thread if there have not been any matches.
    // (No point in starting a new thread if there have been
    // matches, since it would be to the right of the match
    // we already found.)
    if (!matched_ && (!anchored || p == text.begin())) {
      // If there's a required first byte for an unanchored search
      // and we're not in the middle of any possible matches,
      // use memchr to search for the byte quickly.
      int fb = prog_->first_byte();
      if (!anchored && runq->size() == 0 &&
          fb >= 0 && p < text.end() && (p[0] & 0xFF) != fb) {
        p = reinterpret_cast<const char*>(memchr(p, fb, text.end() - p));
        if (p == NULL) {
          p = text.end();
        }
      }

      Thread* t = AllocThread();
      CopyCapture(t->capture, match_);
      t->capture[0] = p;
      AddToThreadq(runq, start_, p < text.end() ? p[0] & 0xFF : -1, context, p,
                   t);
      Decref(t);
    }

    // If all the threads have died, stop early.
    if (runq->size() == 0) {
      break;
    }
  }

  for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i)
    Decref(i->value());

  if (matched_) {
    for (int i = 0; i < nsubmatch; i++)
      submatch[i] =
          StringPiece(match_[2 * i],
                      static_cast<size_t>(match_[2 * i + 1] - match_[2 * i]));
    return true;
  }
  return false;
}

// Computes whether all successful matches have a common first byte,
// and if so, returns that byte.  If not, returns -1.
int Prog::ComputeFirstByte() {
  int b = -1;
  SparseSet q(size());
  q.insert(start());
  for (SparseSet::iterator it = q.begin(); it != q.end(); ++it) {
    int id = *it;
    Prog::Inst* ip = inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled " << ip->opcode() << " in ComputeFirstByte";
        break;

      case kInstMatch:
        // The empty string matches: no first byte.
        return -1;

      case kInstByteRange:
        if (!ip->last())
          q.insert(id+1);

        // Must match only a single byte
        if (ip->lo() != ip->hi())
          return -1;
        if (ip->foldcase() && 'a' <= ip->lo() && ip->lo() <= 'z')
          return -1;
        // If we haven't seen any bytes yet, record it;
        // otherwise must match the one we saw before.
        if (b == -1)
          b = ip->lo();
        else if (b != ip->lo())
          return -1;
        break;

      case kInstNop:
      case kInstCapture:
      case kInstEmptyWidth:
        if (!ip->last())
          q.insert(id+1);

        // Continue on.
        // Ignore ip->empty() flags for kInstEmptyWidth
        // in order to be as conservative as possible
        // (assume all possible empty-width flags are true).
        if (ip->out())
          q.insert(ip->out());
        break;

      case kInstAltMatch:
        DCHECK(!ip->last());
        q.insert(id+1);
        break;

      case kInstFail:
        break;
    }
  }
  return b;
}

bool
Prog::SearchNFA(const StringPiece& text, const StringPiece& context,
                Anchor anchor, MatchKind kind,
                StringPiece* match, int nmatch) {
  NFA nfa(this);
  StringPiece sp;
  if (kind == kFullMatch) {
    anchor = kAnchored;
    if (nmatch == 0) {
      match = &sp;
      nmatch = 1;
    }
  }
  if (!nfa.Search(text, context, anchor == kAnchored, kind != kFirstMatch, match, nmatch))
    return false;
  if (kind == kFullMatch && match[0].end() != text.end())
    return false;
  return true;
}

// For each instruction i in the program reachable from the start, compute the
// number of instructions reachable from i by following only empty transitions
// and record that count as fanout[i].
//
// fanout holds the results and is also the work queue for the outer iteration.
// reachable holds the reached nodes for the inner iteration.
void Prog::Fanout(SparseArray<int>* fanout) {
  DCHECK_EQ(fanout->max_size(), size());
  SparseSet reachable(size());
  fanout->clear();
  fanout->set_new(start(), 0);
  for (SparseArray<int>::iterator i = fanout->begin(); i != fanout->end(); ++i) {
    int* count = &i->value();
    reachable.clear();
    reachable.insert(i->index());
    for (SparseSet::iterator j = reachable.begin(); j != reachable.end(); ++j) {
      int id = *j;
      Prog::Inst* ip = inst(id);
      switch (ip->opcode()) {
        default:
          LOG(DFATAL) << "unhandled " << ip->opcode() << " in Prog::Fanout()";
          break;

        case kInstByteRange:
          if (!ip->last())
            reachable.insert(id+1);

          (*count)++;
          if (!fanout->has_index(ip->out())) {
            fanout->set_new(ip->out(), 0);
          }
          break;

        case kInstAltMatch:
          DCHECK(!ip->last());
          reachable.insert(id+1);
          break;

        case kInstCapture:
        case kInstEmptyWidth:
        case kInstNop:
          if (!ip->last())
            reachable.insert(id+1);

          reachable.insert(ip->out());
          break;

        case kInstMatch:
          if (!ip->last())
            reachable.insert(id+1);
          break;

        case kInstFail:
          break;
      }
    }
  }
}

}  // namespace re2
// Copyright 2008 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Tested by search_test.cc.
//
// Prog::SearchOnePass is an efficient implementation of
// regular expression search with submatch tracking for
// what I call "one-pass regular expressions".  (An alternate
// name might be "backtracking-free regular expressions".)
//
// One-pass regular expressions have the property that
// at each input byte during an anchored match, there may be
// multiple alternatives but only one can proceed for any
// given input byte.
//
// For example, the regexp /x*yx*/ is one-pass: you read
// x's until a y, then you read the y, then you keep reading x's.
// At no point do you have to guess what to do or back up
// and try a different guess.
//
// On the other hand, /x*x/ is not one-pass: when you're
// looking at an input "x", it's not clear whether you should
// use it to extend the x* or as the final x.
//
// More examples: /([^ ]*) (.*)/ is one-pass; /(.*) (.*)/ is not.
// /(\d+)-(\d+)/ is one-pass; /(\d+).(\d+)/ is not.
//
// A simple intuition for identifying one-pass regular expressions
// is that it's always immediately obvious when a repetition ends.
// It must also be immediately obvious which branch of an | to take:
//
// /x(y|z)/ is one-pass, but /(xy|xz)/ is not.
//
// The NFA-based search in nfa.cc does some bookkeeping to
// avoid the need for backtracking and its associated exponential blowup.
// But if we have a one-pass regular expression, there is no
// possibility of backtracking, so there is no need for the
// extra bookkeeping.  Hence, this code.
//
// On a one-pass regular expression, the NFA code in nfa.cc
// runs at about 1/20 of the backtracking-based PCRE speed.
// In contrast, the code in this file runs at about the same
// speed as PCRE.
//
// One-pass regular expressions get used a lot when RE is
// used for parsing simple strings, so it pays off to
// notice them and handle them efficiently.
//
// See also Anne Brüggemann-Klein and Derick Wood,
// "One-unambiguous regular languages", Information and Computation 142(2).

#include <stdint.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <string>
#include <vector>










// Silence "zero-sized array in struct/union" warning for OneState::action.
#ifdef _MSC_VER
//#pragma warning(disable: 4200)
#endif

namespace re2 {

// The key insight behind this implementation is that the
// non-determinism in an NFA for a one-pass regular expression
// is contained.  To explain what that means, first a
// refresher about what regular expression programs look like
// and how the usual NFA execution runs.
//
// In a regular expression program, only the kInstByteRange
// instruction processes an input byte c and moves on to the
// next byte in the string (it does so if c is in the given range).
// The kInstByteRange instructions correspond to literal characters
// and character classes in the regular expression.
//
// The kInstAlt instructions are used as wiring to connect the
// kInstByteRange instructions together in interesting ways when
// implementing | + and *.
// The kInstAlt instruction forks execution, like a goto that
// jumps to ip->out() and ip->out1() in parallel.  Each of the
// resulting computation paths is called a thread.
//
// The other instructions -- kInstEmptyWidth, kInstMatch, kInstCapture --
// are interesting in their own right but like kInstAlt they don't
// advance the input pointer.  Only kInstByteRange does.
//
// The automaton execution in nfa.cc runs all the possible
// threads of execution in lock-step over the input.  To process
// a particular byte, each thread gets run until it either dies
// or finds a kInstByteRange instruction matching the byte.
// If the latter happens, the thread stops just past the
// kInstByteRange instruction (at ip->out()) and waits for
// the other threads to finish processing the input byte.
// Then, once all the threads have processed that input byte,
// the whole process repeats.  The kInstAlt state instruction
// might create new threads during input processing, but no
// matter what, all the threads stop after a kInstByteRange
// and wait for the other threads to "catch up".
// Running in lock step like this ensures that the NFA reads
// the input string only once.
//
// Each thread maintains its own set of capture registers
// (the string positions at which it executed the kInstCapture
// instructions corresponding to capturing parentheses in the
// regular expression).  Repeated copying of the capture registers
// is the main performance bottleneck in the NFA implementation.
//
// A regular expression program is "one-pass" if, no matter what
// the input string, there is only one thread that makes it
// past a kInstByteRange instruction at each input byte.  This means
// that there is in some sense only one active thread throughout
// the execution.  Other threads might be created during the
// processing of an input byte, but they are ephemeral: only one
// thread is left to start processing the next input byte.
// This is what I meant above when I said the non-determinism
// was "contained".
//
// To execute a one-pass regular expression program, we can build
// a DFA (no non-determinism) that has at most as many states as
// the NFA (compare this to the possibly exponential number of states
// in the general case).  Each state records, for each possible
// input byte, the next state along with the conditions required
// before entering that state -- empty-width flags that must be true
// and capture operations that must be performed.  It also records
// whether a set of conditions required to finish a match at that
// point in the input rather than process the next byte.

// A state in the one-pass NFA - just an array of actions indexed
// by the bytemap_[] of the next input byte.  (The bytemap
// maps next input bytes into equivalence classes, to reduce
// the memory footprint.)
struct OneState {
  uint32_t matchcond;   // conditions to match right now.
  uint32_t action[];
};

// The uint32_t conditions in the action are a combination of
// condition and capture bits and the next state.  The bottom 16 bits
// are the condition and capture bits, and the top 16 are the index of
// the next state.
//
// Bits 0-5 are the empty-width flags from prog.h.
// Bit 6 is kMatchWins, which means the match takes
// priority over moving to next in a first-match search.
// The remaining bits mark capture registers that should
// be set to the current input position.  The capture bits
// start at index 2, since the search loop can take care of
// cap[0], cap[1] (the overall match position).
// That means we can handle up to 5 capturing parens: $1 through $4, plus $0.
// No input position can satisfy both kEmptyWordBoundary
// and kEmptyNonWordBoundary, so we can use that as a sentinel
// instead of needing an extra bit.

static const int    kIndexShift   = 16;  // number of bits below index
static const int    kEmptyShift   = 6;   // number of empty flags in prog.h
static const int    kRealCapShift = kEmptyShift + 1;
static const int    kRealMaxCap   = (kIndexShift - kRealCapShift) / 2 * 2;

// Parameters used to skip over cap[0], cap[1].
static const int    kCapShift     = kRealCapShift - 2;
static const int    kMaxCap       = kRealMaxCap + 2;

static const uint32_t kMatchWins  = 1 << kEmptyShift;
static const uint32_t kCapMask    = ((1 << kRealMaxCap) - 1) << kRealCapShift;

static const uint32_t kImpossible = kEmptyWordBoundary | kEmptyNonWordBoundary;

// Check, at compile time, that prog.h agrees with math above.
// This function is never called.
void OnePass_Checks() {
  static_assert((1<<kEmptyShift)-1 == kEmptyAllFlags,
                "kEmptyShift disagrees with kEmptyAllFlags");
  // kMaxCap counts pointers, kMaxOnePassCapture counts pairs.
  static_assert(kMaxCap == Prog::kMaxOnePassCapture*2,
                "kMaxCap disagrees with kMaxOnePassCapture");
}

static bool Satisfy(uint32_t cond, const StringPiece& context, const char* p) {
  uint32_t satisfied = Prog::EmptyFlags(context, p);
  if (cond & kEmptyAllFlags & ~satisfied)
    return false;
  return true;
}

// Apply the capture bits in cond, saving p to the appropriate
// locations in cap[].
static void ApplyCaptures(uint32_t cond, const char* p,
                          const char** cap, int ncap) {
  for (int i = 2; i < ncap; i++)
    if (cond & (1 << kCapShift << i))
      cap[i] = p;
}

// Computes the OneState* for the given nodeindex.
static inline OneState* IndexToNode(uint8_t* nodes, int statesize,
                                    int nodeindex) {
  return reinterpret_cast<OneState*>(nodes + statesize*nodeindex);
}

bool Prog::SearchOnePass(const StringPiece& text,
                         const StringPiece& const_context,
                         Anchor anchor, MatchKind kind,
                         StringPiece* match, int nmatch) {
  if (anchor != kAnchored && kind != kFullMatch) {
    LOG(DFATAL) << "Cannot use SearchOnePass for unanchored matches.";
    return false;
  }

  // Make sure we have at least cap[1],
  // because we use it to tell if we matched.
  int ncap = 2*nmatch;
  if (ncap < 2)
    ncap = 2;

  const char* cap[kMaxCap];
  for (int i = 0; i < ncap; i++)
    cap[i] = NULL;

  const char* matchcap[kMaxCap];
  for (int i = 0; i < ncap; i++)
    matchcap[i] = NULL;

  StringPiece context = const_context;
  if (context.begin() == NULL)
    context = text;
  if (anchor_start() && context.begin() != text.begin())
    return false;
  if (anchor_end() && context.end() != text.end())
    return false;
  if (anchor_end())
    kind = kFullMatch;

  uint8_t* nodes = onepass_nodes_.data();
  int statesize = sizeof(OneState) + bytemap_range()*sizeof(uint32_t);
  // start() is always mapped to the zeroth OneState.
  OneState* state = IndexToNode(nodes, statesize, 0);
  uint8_t* bytemap = bytemap_;
  const char* bp = text.begin();
  const char* ep = text.end();
  const char* p;
  bool matched = false;
  matchcap[0] = bp;
  cap[0] = bp;
  uint32_t nextmatchcond = state->matchcond;
  for (p = bp; p < ep; p++) {
    int c = bytemap[*p & 0xFF];
    uint32_t matchcond = nextmatchcond;
    uint32_t cond = state->action[c];

    // Determine whether we can reach act->next.
    // If so, advance state and nextmatchcond.
    if ((cond & kEmptyAllFlags) == 0 || Satisfy(cond, context, p)) {
      uint32_t nextindex = cond >> kIndexShift;
      state = IndexToNode(nodes, statesize, nextindex);
      nextmatchcond = state->matchcond;
    } else {
      state = NULL;
      nextmatchcond = kImpossible;
    }

    // This code section is carefully tuned.
    // The goto sequence is about 10% faster than the
    // obvious rewrite as a large if statement in the
    // ASCIIMatchRE2 and DotMatchRE2 benchmarks.

    // Saving the match capture registers is expensive.
    // Is this intermediate match worth thinking about?

    // Not if we want a full match.
    if (kind == kFullMatch)
      goto skipmatch;

    // Not if it's impossible.
    if (matchcond == kImpossible)
      goto skipmatch;

    // Not if the possible match is beaten by the certain
    // match at the next byte.  When this test is useless
    // (e.g., HTTPPartialMatchRE2) it slows the loop by
    // about 10%, but when it avoids work (e.g., DotMatchRE2),
    // it cuts the loop execution by about 45%.
    if ((cond & kMatchWins) == 0 && (nextmatchcond & kEmptyAllFlags) == 0)
      goto skipmatch;

    // Finally, the match conditions must be satisfied.
    if ((matchcond & kEmptyAllFlags) == 0 || Satisfy(matchcond, context, p)) {
      for (int i = 2; i < 2*nmatch; i++)
        matchcap[i] = cap[i];
      if (nmatch > 1 && (matchcond & kCapMask))
        ApplyCaptures(matchcond, p, matchcap, ncap);
      matchcap[1] = p;
      matched = true;

      // If we're in longest match mode, we have to keep
      // going and see if we find a longer match.
      // In first match mode, we can stop if the match
      // takes priority over the next state for this input byte.
      // That bit is per-input byte and thus in cond, not matchcond.
      if (kind == kFirstMatch && (cond & kMatchWins))
        goto done;
    }

  skipmatch:
    if (state == NULL)
      goto done;
    if ((cond & kCapMask) && nmatch > 1)
      ApplyCaptures(cond, p, cap, ncap);
  }

  // Look for match at end of input.
  {
    uint32_t matchcond = state->matchcond;
    if (matchcond != kImpossible &&
        ((matchcond & kEmptyAllFlags) == 0 || Satisfy(matchcond, context, p))) {
      if (nmatch > 1 && (matchcond & kCapMask))
        ApplyCaptures(matchcond, p, cap, ncap);
      for (int i = 2; i < ncap; i++)
        matchcap[i] = cap[i];
      matchcap[1] = p;
      matched = true;
    }
  }

done:
  if (!matched)
    return false;
  for (int i = 0; i < nmatch; i++)
    match[i] =
        StringPiece(matchcap[2 * i],
                    static_cast<size_t>(matchcap[2 * i + 1] - matchcap[2 * i]));
  return true;
}


// Analysis to determine whether a given regexp program is one-pass.

// If ip is not on workq, adds ip to work queue and returns true.
// If ip is already on work queue, does nothing and returns false.
// If ip is NULL, does nothing and returns true (pretends to add it).
typedef SparseSet Instq;
static bool AddQ(Instq *q, int id) {
  if (id == 0)
    return true;
  if (q->contains(id))
    return false;
  q->insert(id);
  return true;
}

struct InstCond {
  int id;
  uint32_t cond;
};

// Returns whether this is a one-pass program; that is,
// returns whether it is safe to use SearchOnePass on this program.
// These conditions must be true for any instruction ip:
//
//   (1) for any other Inst nip, there is at most one input-free
//       path from ip to nip.
//   (2) there is at most one kInstByte instruction reachable from
//       ip that matches any particular byte c.
//   (3) there is at most one input-free path from ip to a kInstMatch
//       instruction.
//
// This is actually just a conservative approximation: it might
// return false when the answer is true, when kInstEmptyWidth
// instructions are involved.
// Constructs and saves corresponding one-pass NFA on success.
bool Prog::IsOnePass() {
  if (did_onepass_)
    return onepass_nodes_.data() != NULL;
  did_onepass_ = true;

  if (start() == 0)  // no match
    return false;

  // Steal memory for the one-pass NFA from the overall DFA budget.
  // Willing to use at most 1/4 of the DFA budget (heuristic).
  // Limit max node count to 65000 as a conservative estimate to
  // avoid overflowing 16-bit node index in encoding.
  int maxnodes = 2 + inst_count(kInstByteRange);
  int statesize = sizeof(OneState) + bytemap_range()*sizeof(uint32_t);
  if (maxnodes >= 65000 || dfa_mem_ / 4 / statesize < maxnodes)
    return false;

  // Flood the graph starting at the start state, and check
  // that in each reachable state, each possible byte leads
  // to a unique next state.
  int stacksize = inst_count(kInstCapture) +
                  inst_count(kInstEmptyWidth) +
                  inst_count(kInstNop) + 1;  // + 1 for start inst
  PODArray<InstCond> stack(stacksize);

  int size = this->size();
  PODArray<int> nodebyid(size);  // indexed by ip
  memset(nodebyid.data(), 0xFF, size*sizeof nodebyid[0]);

  // Originally, nodes was a uint8_t[maxnodes*statesize], but that was
  // unnecessarily optimistic: why allocate a large amount of memory
  // upfront for a large program when it is unlikely to be one-pass?
  std::vector<uint8_t> nodes;

  Instq tovisit(size), workq(size);
  AddQ(&tovisit, start());
  nodebyid[start()] = 0;
  int nalloc = 1;
  nodes.insert(nodes.end(), statesize, 0);
  for (Instq::iterator it = tovisit.begin(); it != tovisit.end(); ++it) {
    int id = *it;
    int nodeindex = nodebyid[id];
    OneState* node = IndexToNode(nodes.data(), statesize, nodeindex);

    // Flood graph using manual stack, filling in actions as found.
    // Default is none.
    for (int b = 0; b < bytemap_range_; b++)
      node->action[b] = kImpossible;
    node->matchcond = kImpossible;

    workq.clear();
    bool matched = false;
    int nstack = 0;
    stack[nstack].id = id;
    stack[nstack++].cond = 0;
    while (nstack > 0) {
      int id = stack[--nstack].id;
      uint32_t cond = stack[nstack].cond;

    Loop:
      Prog::Inst* ip = inst(id);
      switch (ip->opcode()) {
        default:
          LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
          break;

        case kInstAltMatch:
          // TODO(rsc): Ignoring kInstAltMatch optimization.
          // Should implement it in this engine, but it's subtle.
          DCHECK(!ip->last());
          // If already on work queue, (1) is violated: bail out.
          if (!AddQ(&workq, id+1))
            goto fail;
          id = id+1;
          goto Loop;

        case kInstByteRange: {
          int nextindex = nodebyid[ip->out()];
          if (nextindex == -1) {
            if (nalloc >= maxnodes) {
              goto fail;
            }
            nextindex = nalloc;
            AddQ(&tovisit, ip->out());
            nodebyid[ip->out()] = nalloc;
            nalloc++;
            nodes.insert(nodes.end(), statesize, 0);
            // Update node because it might have been invalidated.
            node = IndexToNode(nodes.data(), statesize, nodeindex);
          }
          for (int c = ip->lo(); c <= ip->hi(); c++) {
            int b = bytemap_[c];
            // Skip any bytes immediately after c that are also in b.
            while (c < 256-1 && bytemap_[c+1] == b)
              c++;
            uint32_t act = node->action[b];
            uint32_t newact = (nextindex << kIndexShift) | cond;
            if (matched)
              newact |= kMatchWins;
            if ((act & kImpossible) == kImpossible) {
              node->action[b] = newact;
            } else if (act != newact) {
              goto fail;
            }
          }
          if (ip->foldcase()) {
            Rune lo = std::max<Rune>(ip->lo(), 'a') + 'A' - 'a';
            Rune hi = std::min<Rune>(ip->hi(), 'z') + 'A' - 'a';
            for (int c = lo; c <= hi; c++) {
              int b = bytemap_[c];
              // Skip any bytes immediately after c that are also in b.
              while (c < 256-1 && bytemap_[c+1] == b)
                c++;
              uint32_t act = node->action[b];
              uint32_t newact = (nextindex << kIndexShift) | cond;
              if (matched)
                newact |= kMatchWins;
              if ((act & kImpossible) == kImpossible) {
                node->action[b] = newact;
              } else if (act != newact) {
                goto fail;
              }
            }
          }

          if (ip->last())
            break;
          // If already on work queue, (1) is violated: bail out.
          if (!AddQ(&workq, id+1))
            goto fail;
          id = id+1;
          goto Loop;
        }

        case kInstCapture:
        case kInstEmptyWidth:
        case kInstNop:
          if (!ip->last()) {
            // If already on work queue, (1) is violated: bail out.
            if (!AddQ(&workq, id+1))
              goto fail;
            stack[nstack].id = id+1;
            stack[nstack++].cond = cond;
          }

          if (ip->opcode() == kInstCapture && ip->cap() < kMaxCap)
            cond |= (1 << kCapShift) << ip->cap();
          if (ip->opcode() == kInstEmptyWidth)
            cond |= ip->empty();

          // kInstCapture and kInstNop always proceed to ip->out().
          // kInstEmptyWidth only sometimes proceeds to ip->out(),
          // but as a conservative approximation we assume it always does.
          // We could be a little more precise by looking at what c
          // is, but that seems like overkill.

          // If already on work queue, (1) is violated: bail out.
          if (!AddQ(&workq, ip->out())) {
            goto fail;
          }
          id = ip->out();
          goto Loop;

        case kInstMatch:
          if (matched) {
            // (3) is violated
            goto fail;
          }
          matched = true;
          node->matchcond = cond;

          if (ip->last())
            break;
          // If already on work queue, (1) is violated: bail out.
          if (!AddQ(&workq, id+1))
            goto fail;
          id = id+1;
          goto Loop;

        case kInstFail:
          break;
      }
    }
  }
  dfa_mem_ -= nalloc*statesize;
  onepass_nodes_ = PODArray<uint8_t>(nalloc*statesize);
  memmove(onepass_nodes_.data(), nodes.data(), nalloc*statesize);
  return true;

fail:
  return false;
}

}  // namespace re2
// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Regular expression parser.

// The parser is a simple precedence-based parser with a
// manual stack.  The parsing work is done by the methods
// of the ParseState class.  The Regexp::Parse function is
// essentially just a lexer that calls the ParseState method
// for each token.

// The parser recognizes POSIX extended regular expressions
// excluding backreferences, collating elements, and collating
// classes.  It also allows the empty string as a regular expression
// and recognizes the Perl escape sequences \d, \s, \w, \D, \S, and \W.
// See regexp.h for rationale.

#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <string>
#include <vector>








// Copyright 2008 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_UNICODE_CASEFOLD_H_
#define RE2_UNICODE_CASEFOLD_H_

// Unicode case folding tables.

// The Unicode case folding tables encode the mapping from one Unicode point
// to the next largest Unicode point with equivalent folding.  The largest
// point wraps back to the first.  For example, the tables map:
//
//     'A' -> 'a'
//     'a' -> 'A'
//
//     'K' -> 'k'
//     'k' -> 'K'  (Kelvin symbol)
//     'K' -> 'K'
//
// Like everything Unicode, these tables are big.  If we represent the table
// as a sorted list of uint32_t pairs, it has 2049 entries and is 16 kB.
// Most table entries look like the ones around them:
// 'A' maps to 'A'+32, 'B' maps to 'B'+32, etc.
// Instead of listing all the pairs explicitly, we make a list of ranges
// and deltas, so that the table entries for 'A' through 'Z' can be represented
// as a single entry { 'A', 'Z', +32 }.
//
// In addition to blocks that map to each other (A-Z mapping to a-z)
// there are blocks of pairs that individually map to each other
// (for example, 0100<->0101, 0102<->0103, 0104<->0105, ...).
// For those, the special delta value EvenOdd marks even/odd pairs
// (if even, add 1; if odd, subtract 1), and OddEven marks odd/even pairs.
//
// In this form, the table has 274 entries, about 3kB.  If we were to split
// the table into one for 16-bit codes and an overflow table for larger ones,
// we could get it down to about 1.5kB, but that's not worth the complexity.
//
// The grouped form also allows for efficient fold range calculations
// rather than looping one character at a time.

#include <stdint.h>




namespace re2 {

enum {
  EvenOdd = 1,
  OddEven = -1,
  EvenOddSkip = 1<<30,
  OddEvenSkip,
};

struct CaseFold {
  Rune lo;
  Rune hi;
  int32_t delta;
};

extern const CaseFold unicode_casefold[];
extern const int num_unicode_casefold;

extern const CaseFold unicode_tolower[];
extern const int num_unicode_tolower;

// Returns the CaseFold* in the tables that contains rune.
// If rune is not in the tables, returns the first CaseFold* after rune.
// If rune is larger than any value in the tables, returns NULL.
extern const CaseFold* LookupCaseFold(const CaseFold*, int, Rune rune);

// Returns the result of applying the fold f to the rune r.
extern Rune ApplyFold(const CaseFold *f, Rune r);

}  // namespace re2

#endif  // RE2_UNICODE_CASEFOLD_H_

// Copyright 2008 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_UNICODE_GROUPS_H_
#define RE2_UNICODE_GROUPS_H_

// Unicode character groups.

// The codes get split into ranges of 16-bit codes
// and ranges of 32-bit codes.  It would be simpler
// to use only 32-bit ranges, but these tables are large
// enough to warrant extra care.
//
// Using just 32-bit ranges gives 27 kB of data.
// Adding 16-bit ranges gives 18 kB of data.
// Adding an extra table of 16-bit singletons would reduce
// to 16.5 kB of data but make the data harder to use;
// we don't bother.

#include <stdint.h>




namespace re2 {

struct URange16
{
  uint16_t lo;
  uint16_t hi;
};

struct URange32
{
  Rune lo;
  Rune hi;
};

struct UGroup
{
  const char *name;
  int sign;  // +1 for [abc], -1 for [^abc]
  const URange16 *r16;
  int nr16;
  const URange32 *r32;
  int nr32;
};

// Named by property or script name (e.g., "Nd", "N", "Han").
// Negated groups are not included.
extern const UGroup unicode_groups[];
extern const int num_unicode_groups;

// Named by POSIX name (e.g., "[:alpha:]", "[:^lower:]").
// Negated groups are included.
extern const UGroup posix_groups[];
extern const int num_posix_groups;

// Named by Perl name (e.g., "\\d", "\\D").
// Negated groups are included.
extern const UGroup perl_groups[];
extern const int num_perl_groups;

}  // namespace re2

#endif  // RE2_UNICODE_GROUPS_H_



// #if defined(RE2_USE_ICU)
// #include "unicode/uniset.h"
// #include "unicode/unistr.h"
// #include "unicode/utypes.h"
// #endif

namespace re2 {

// Reduce the maximum repeat count by an order of magnitude when fuzzing.
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
static const int kMaxRepeat = 100;
#else
static const int kMaxRepeat = 1000;
#endif

// Regular expression parse state.
// The list of parsed regexps so far is maintained as a vector of
// Regexp pointers called the stack.  Left parenthesis and vertical
// bar markers are also placed on the stack, as Regexps with
// non-standard opcodes.
// Scanning a left parenthesis causes the parser to push a left parenthesis
// marker on the stack.
// Scanning a vertical bar causes the parser to pop the stack until it finds a
// vertical bar or left parenthesis marker (not popping the marker),
// concatenate all the popped results, and push them back on
// the stack (DoConcatenation).
// Scanning a right parenthesis causes the parser to act as though it
// has seen a vertical bar, which then leaves the top of the stack in the
// form LeftParen regexp VerticalBar regexp VerticalBar ... regexp VerticalBar.
// The parser pops all this off the stack and creates an alternation of the
// regexps (DoAlternation).

class Regexp::ParseState {
 public:
  ParseState(ParseFlags flags, const StringPiece& whole_regexp,
             RegexpStatus* status);
  ~ParseState();

  ParseFlags flags() { return flags_; }
  int rune_max() { return rune_max_; }

  // Parse methods.  All public methods return a bool saying
  // whether parsing should continue.  If a method returns
  // false, it has set fields in *status_, and the parser
  // should return NULL.

  // Pushes the given regular expression onto the stack.
  // Could check for too much memory used here.
  bool PushRegexp(Regexp* re);

  // Pushes the literal rune r onto the stack.
  bool PushLiteral(Rune r);

  // Pushes a regexp with the given op (and no args) onto the stack.
  bool PushSimpleOp(RegexpOp op);

  // Pushes a ^ onto the stack.
  bool PushCarat();

  // Pushes a \b (word == true) or \B (word == false) onto the stack.
  bool PushWordBoundary(bool word);

  // Pushes a $ onto the stack.
  bool PushDollar();

  // Pushes a . onto the stack
  bool PushDot();

  // Pushes a repeat operator regexp onto the stack.
  // A valid argument for the operator must already be on the stack.
  // s is the name of the operator, for use in error messages.
  bool PushRepeatOp(RegexpOp op, const StringPiece& s, bool nongreedy);

  // Pushes a repetition regexp onto the stack.
  // A valid argument for the operator must already be on the stack.
  bool PushRepetition(int min, int max, const StringPiece& s, bool nongreedy);

  // Checks whether a particular regexp op is a marker.
  bool IsMarker(RegexpOp op);

  // Processes a left parenthesis in the input.
  // Pushes a marker onto the stack.
  bool DoLeftParen(const StringPiece& name);
  bool DoLeftParenNoCapture();

  // Processes a vertical bar in the input.
  bool DoVerticalBar();

  // Processes a right parenthesis in the input.
  bool DoRightParen();

  // Processes the end of input, returning the final regexp.
  Regexp* DoFinish();

  // Finishes the regexp if necessary, preparing it for use
  // in a more complicated expression.
  // If it is a CharClassBuilder, converts into a CharClass.
  Regexp* FinishRegexp(Regexp*);

  // These routines don't manipulate the parse stack
  // directly, but they do need to look at flags_.
  // ParseCharClass also manipulates the internals of Regexp
  // while creating *out_re.

  // Parse a character class into *out_re.
  // Removes parsed text from s.
  bool ParseCharClass(StringPiece* s, Regexp** out_re,
                      RegexpStatus* status);

  // Parse a character class character into *rp.
  // Removes parsed text from s.
  bool ParseCCCharacter(StringPiece* s, Rune *rp,
                        const StringPiece& whole_class,
                        RegexpStatus* status);

  // Parse a character class range into rr.
  // Removes parsed text from s.
  bool ParseCCRange(StringPiece* s, RuneRange* rr,
                    const StringPiece& whole_class,
                    RegexpStatus* status);

  // Parse a Perl flag set or non-capturing group from s.
  bool ParsePerlFlags(StringPiece* s);


  // Finishes the current concatenation,
  // collapsing it into a single regexp on the stack.
  void DoConcatenation();

  // Finishes the current alternation,
  // collapsing it to a single regexp on the stack.
  void DoAlternation();

  // Generalized DoAlternation/DoConcatenation.
  void DoCollapse(RegexpOp op);

  // Maybe concatenate Literals into LiteralString.
  bool MaybeConcatString(int r, ParseFlags flags);

private:
  ParseFlags flags_;
  StringPiece whole_regexp_;
  RegexpStatus* status_;
  Regexp* stacktop_;
  int ncap_;  // number of capturing parens seen
  int rune_max_;  // maximum char value for this encoding

  ParseState(const ParseState&) = delete;
  ParseState& operator=(const ParseState&) = delete;
};

// Pseudo-operators - only on parse stack.
const RegexpOp kLeftParen = static_cast<RegexpOp>(kMaxRegexpOp+1);
const RegexpOp kVerticalBar = static_cast<RegexpOp>(kMaxRegexpOp+2);

Regexp::ParseState::ParseState(ParseFlags flags,
                               const StringPiece& whole_regexp,
                               RegexpStatus* status)
  : flags_(flags), whole_regexp_(whole_regexp),
    status_(status), stacktop_(NULL), ncap_(0) {
  if (flags_ & Latin1)
    rune_max_ = 0xFF;
  else
    rune_max_ = Runemax;
}

// Cleans up by freeing all the regexps on the stack.
Regexp::ParseState::~ParseState() {
  Regexp* next;
  for (Regexp* re = stacktop_; re != NULL; re = next) {
    next = re->down_;
    re->down_ = NULL;
    if (re->op() == kLeftParen)
      delete re->name_;
    re->Decref();
  }
}

// Finishes the regexp if necessary, preparing it for use in
// a more complex expression.
// If it is a CharClassBuilder, converts into a CharClass.
Regexp* Regexp::ParseState::FinishRegexp(Regexp* re) {
  if (re == NULL)
    return NULL;
  re->down_ = NULL;

  if (re->op_ == kRegexpCharClass && re->ccb_ != NULL) {
    CharClassBuilder* ccb = re->ccb_;
    re->ccb_ = NULL;
    re->cc_ = ccb->GetCharClass();
    delete ccb;
  }

  return re;
}

// Pushes the given regular expression onto the stack.
// Could check for too much memory used here.
bool Regexp::ParseState::PushRegexp(Regexp* re) {
  MaybeConcatString(-1, NoParseFlags);

  // Special case: a character class of one character is just
  // a literal.  This is a common idiom for escaping
  // single characters (e.g., [.] instead of \.), and some
  // analysis does better with fewer character classes.
  // Similarly, [Aa] can be rewritten as a literal A with ASCII case folding.
  auto ccb = re->ccb_;
  if (re->op_ == kRegexpCharClass && ccb != NULL) {
	  ccb->RemoveAbove(rune_max_);
    if (ccb->size() == 1) {
      Rune r = ccb->begin()->lo;
      re->Decref();
      re = new Regexp(kRegexpLiteral, flags_);
      re->rune_ = r;
    } else if (ccb->size() == 2) {
      Rune r = ccb->begin()->lo;
      if ('A' <= r && r <= 'Z' && ccb->Contains(r + 'a' - 'A')) {
        re->Decref();
        re = new Regexp(kRegexpLiteral, flags_ | FoldCase);
        re->rune_ = r + 'a' - 'A';
      }
    }
  }

  if (!IsMarker(re->op()))
    re->simple_ = re->ComputeSimple();
  re->down_ = stacktop_;
  stacktop_ = re;
  return true;
}

// Searches the case folding tables and returns the CaseFold* that contains r.
// If there isn't one, returns the CaseFold* with smallest f->lo bigger than r.
// If there isn't one, returns NULL.
const CaseFold* LookupCaseFold(const CaseFold *f, int n, Rune r) {
  const CaseFold* ef = f + n;

  // Binary search for entry containing r.
  while (n > 0) {
    int m = n/2;
    if (f[m].lo <= r && r <= f[m].hi)
      return &f[m];
    if (r < f[m].lo) {
      n = m;
    } else {
      f += m+1;
      n -= m+1;
    }
  }

  // There is no entry that contains r, but f points
  // where it would have been.  Unless f points at
  // the end of the array, it points at the next entry
  // after r.
  if (f < ef)
    return f;

  // No entry contains r; no entry contains runes > r.
  return NULL;
}

// Returns the result of applying the fold f to the rune r.
Rune ApplyFold(const CaseFold *f, Rune r) {
  switch (f->delta) {
    default:
      return r + f->delta;

    case EvenOddSkip:  // even <-> odd but only applies to every other
      if ((r - f->lo) % 2)
        return r;
      FALLTHROUGH_INTENDED;
    case EvenOdd:  // even <-> odd
      if (r%2 == 0)
        return r + 1;
      return r - 1;

    case OddEvenSkip:  // odd <-> even but only applies to every other
      if ((r - f->lo) % 2)
        return r;
      FALLTHROUGH_INTENDED;
    case OddEven:  // odd <-> even
      if (r%2 == 1)
        return r + 1;
      return r - 1;
  }
}

// Returns the next Rune in r's folding cycle (see unicode_casefold.h).
// Examples:
//   CycleFoldRune('A') = 'a'
//   CycleFoldRune('a') = 'A'
//
//   CycleFoldRune('K') = 'k'
//   CycleFoldRune('k') = 0x212A (Kelvin)
//   CycleFoldRune(0x212A) = 'K'
//
//   CycleFoldRune('?') = '?'
Rune CycleFoldRune(Rune r) {
  const CaseFold* f = LookupCaseFold(unicode_casefold, num_unicode_casefold, r);
  if (f == NULL || r < f->lo)
    return r;
  return ApplyFold(f, r);
}

// Add lo-hi to the class, along with their fold-equivalent characters.
// If lo-hi is already in the class, assume that the fold-equivalent
// chars are there too, so there's no work to do.
static void AddFoldedRange(CharClassBuilder* cc, Rune lo, Rune hi, int depth) {
  // AddFoldedRange calls itself recursively for each rune in the fold cycle.
  // Most folding cycles are small: there aren't any bigger than four in the
  // current Unicode tables.  make_unicode_casefold.py checks that
  // the cycles are not too long, and we double-check here using depth.
  if (depth > 10) {
    LOG(DFATAL) << "AddFoldedRange recurses too much.";
    return;
  }

  if (!cc->AddRange(lo, hi))  // lo-hi was already there? we're done
    return;

  while (lo <= hi) {
    const CaseFold* f = LookupCaseFold(unicode_casefold, num_unicode_casefold, lo);
    if (f == NULL)  // lo has no fold, nor does anything above lo
      break;
    if (lo < f->lo) {  // lo has no fold; next rune with a fold is f->lo
      lo = f->lo;
      continue;
    }

    // Add in the result of folding the range lo - f->hi
    // and that range's fold, recursively.
    Rune lo1 = lo;
    Rune hi1 = std::min<Rune>(hi, f->hi);
    switch (f->delta) {
      default:
        lo1 += f->delta;
        hi1 += f->delta;
        break;
      case EvenOdd:
        if (lo1%2 == 1)
          lo1--;
        if (hi1%2 == 0)
          hi1++;
        break;
      case OddEven:
        if (lo1%2 == 0)
          lo1--;
        if (hi1%2 == 1)
          hi1++;
        break;
    }
    AddFoldedRange(cc, lo1, hi1, depth+1);

    // Pick up where this fold left off.
    lo = f->hi + 1;
  }
}

// Pushes the literal rune r onto the stack.
bool Regexp::ParseState::PushLiteral(Rune r) {
  // Do case folding if needed.
  if ((flags_ & FoldCase) && CycleFoldRune(r) != r) {
    Regexp* re = new Regexp(kRegexpCharClass, flags_ & ~FoldCase);
    re->ccb_ = new CharClassBuilder;
    Rune r1 = r;
    do {
      if (!(flags_ & NeverNL) || r != '\n') {
        re->ccb_->AddRange(r, r);
      }
      r = CycleFoldRune(r);
    } while (r != r1);
    return PushRegexp(re);
  }

  // Exclude newline if applicable.
  if ((flags_ & NeverNL) && r == '\n')
    return PushRegexp(new Regexp(kRegexpNoMatch, flags_));

  // No fancy stuff worked.  Ordinary literal.
  if (MaybeConcatString(r, flags_))
    return true;

  Regexp* re = new Regexp(kRegexpLiteral, flags_);
  re->rune_ = r;
  return PushRegexp(re);
}

// Pushes a ^ onto the stack.
bool Regexp::ParseState::PushCarat() {
  if (flags_ & OneLine) {
    return PushSimpleOp(kRegexpBeginText);
  }
  return PushSimpleOp(kRegexpBeginLine);
}

// Pushes a \b or \B onto the stack.
bool Regexp::ParseState::PushWordBoundary(bool word) {
  if (word)
    return PushSimpleOp(kRegexpWordBoundary);
  return PushSimpleOp(kRegexpNoWordBoundary);
}

// Pushes a $ onto the stack.
bool Regexp::ParseState::PushDollar() {
  if (flags_ & OneLine) {
    // Clumsy marker so that MimicsPCRE() can tell whether
    // this kRegexpEndText was a $ and not a \z.
    Regexp::ParseFlags oflags = flags_;
    flags_ = flags_ | WasDollar;
    bool ret = PushSimpleOp(kRegexpEndText);
    flags_ = oflags;
    return ret;
  }
  return PushSimpleOp(kRegexpEndLine);
}

// Pushes a . onto the stack.
bool Regexp::ParseState::PushDot() {
  if ((flags_ & DotNL) && !(flags_ & NeverNL))
    return PushSimpleOp(kRegexpAnyChar);
  // Rewrite . into [^\n]
  Regexp* re = new Regexp(kRegexpCharClass, flags_ & ~FoldCase);
  re->ccb_ = new CharClassBuilder;
  re->ccb_->AddRange(0, '\n' - 1);
  re->ccb_->AddRange('\n' + 1, rune_max_);
  return PushRegexp(re);
}

// Pushes a regexp with the given op (and no args) onto the stack.
bool Regexp::ParseState::PushSimpleOp(RegexpOp op) {
  Regexp* re = new Regexp(op, flags_);
  return PushRegexp(re);
}

// Pushes a repeat operator regexp onto the stack.
// A valid argument for the operator must already be on the stack.
// The char c is the name of the operator, for use in error messages.
bool Regexp::ParseState::PushRepeatOp(RegexpOp op, const StringPiece& s,
                                      bool nongreedy) {
  if (stacktop_ == NULL || IsMarker(stacktop_->op())) {
    status_->set_code(kRegexpRepeatArgument);
    status_->set_error_arg(s);
    return false;
  }
  Regexp::ParseFlags fl = flags_;
  if (nongreedy)
    fl = fl ^ NonGreedy;

  // Squash **, ++ and ??. Regexp::Star() et al. handle this too, but
  // they're mostly for use during simplification, not during parsing.
  if (op == stacktop_->op() && fl == stacktop_->parse_flags())
    return true;

  // Squash *+, *?, +*, +?, ?* and ?+. They all squash to *, so because
  // op is a repeat, we just have to check that stacktop_->op() is too,
  // then adjust stacktop_.
  if ((stacktop_->op() == kRegexpStar ||
       stacktop_->op() == kRegexpPlus ||
       stacktop_->op() == kRegexpQuest) &&
      fl == stacktop_->parse_flags()) {
    stacktop_->op_ = kRegexpStar;
    return true;
  }

  Regexp* re = new Regexp(op, fl);
  re->AllocSub(1);
  re->down_ = stacktop_->down_;
  re->sub()[0] = FinishRegexp(stacktop_);
  re->simple_ = re->ComputeSimple();
  stacktop_ = re;
  return true;
}

// RepetitionWalker reports whether the repetition regexp is valid.
// Valid means that the combination of the top-level repetition
// and any inner repetitions does not exceed n copies of the
// innermost thing.
// This rewalks the regexp tree and is called for every repetition,
// so we have to worry about inducing quadratic behavior in the parser.
// We avoid this by only using RepetitionWalker when min or max >= 2.
// In that case the depth of any >= 2 nesting can only get to 9 without
// triggering a parse error, so each subtree can only be rewalked 9 times.
class RepetitionWalker : public Regexp::Walker<int> {
 public:
  RepetitionWalker() {}
  virtual int PreVisit(Regexp* re, int parent_arg, bool* stop);
  virtual int PostVisit(Regexp* re, int parent_arg, int pre_arg,
                        int* child_args, int nchild_args);
  virtual int ShortVisit(Regexp* re, int parent_arg);

 private:
  RepetitionWalker(const RepetitionWalker&) = delete;
  RepetitionWalker& operator=(const RepetitionWalker&) = delete;
};

int RepetitionWalker::PreVisit(Regexp* re, int parent_arg, bool* stop) {
  int arg = parent_arg;
  if (re->op() == kRegexpRepeat) {
    int m = re->max();
    if (m < 0) {
      m = re->min();
    }
    if (m > 0) {
      arg /= m;
    }
  }
  return arg;
}

int RepetitionWalker::PostVisit(Regexp* re, int parent_arg, int pre_arg,
                                int* child_args, int nchild_args) {
  int arg = pre_arg;
  for (int i = 0; i < nchild_args; i++) {
    if (child_args[i] < arg) {
      arg = child_args[i];
    }
  }
  return arg;
}

int RepetitionWalker::ShortVisit(Regexp* re, int parent_arg) {
  // This should never be called, since we use Walk and not
  // WalkExponential.
  LOG(DFATAL) << "RepetitionWalker::ShortVisit called";
  return 0;
}

// Pushes a repetition regexp onto the stack.
// A valid argument for the operator must already be on the stack.
bool Regexp::ParseState::PushRepetition(int min, int max,
                                        const StringPiece& s,
                                        bool nongreedy) {
  if ((max != -1 && max < min) || min > kMaxRepeat || max > kMaxRepeat) {
    status_->set_code(kRegexpRepeatSize);
    status_->set_error_arg(s);
    return false;
  }
  if (stacktop_ == NULL || IsMarker(stacktop_->op())) {
    status_->set_code(kRegexpRepeatArgument);
    status_->set_error_arg(s);
    return false;
  }
  Regexp::ParseFlags fl = flags_;
  if (nongreedy)
    fl = fl ^ NonGreedy;
  Regexp* re = new Regexp(kRegexpRepeat, fl);
  re->min_ = min;
  re->max_ = max;
  re->AllocSub(1);
  re->down_ = stacktop_->down_;
  re->sub()[0] = FinishRegexp(stacktop_);
  re->simple_ = re->ComputeSimple();
  stacktop_ = re;
  if (min >= 2 || max >= 2) {
    RepetitionWalker w;
    if (w.Walk(stacktop_, kMaxRepeat) == 0) {
      status_->set_code(kRegexpRepeatSize);
      status_->set_error_arg(s);
      return false;
    }
  }
  return true;
}

// Checks whether a particular regexp op is a marker.
bool Regexp::ParseState::IsMarker(RegexpOp op) {
  return op >= kLeftParen;
}

// Processes a left parenthesis in the input.
// Pushes a marker onto the stack.
bool Regexp::ParseState::DoLeftParen(const StringPiece& name) {
  Regexp* re = new Regexp(kLeftParen, flags_);
  re->cap_ = ++ncap_;
  if (name.data() != NULL)
    re->name_ = new std::string(name);
  return PushRegexp(re);
}

// Pushes a non-capturing marker onto the stack.
bool Regexp::ParseState::DoLeftParenNoCapture() {
  Regexp* re = new Regexp(kLeftParen, flags_);
  re->cap_ = -1;
  return PushRegexp(re);
}

// Processes a vertical bar in the input.
bool Regexp::ParseState::DoVerticalBar() {
  MaybeConcatString(-1, NoParseFlags);
  DoConcatenation();

  // Below the vertical bar is a list to alternate.
  // Above the vertical bar is a list to concatenate.
  // We just did the concatenation, so either swap
  // the result below the vertical bar or push a new
  // vertical bar on the stack.
  Regexp* r1;
  Regexp* r2;
  if ((r1 = stacktop_) != NULL &&
      (r2 = r1->down_) != NULL &&
      r2->op() == kVerticalBar) {
    Regexp* r3;
    if ((r3 = r2->down_) != NULL &&
        (r1->op() == kRegexpAnyChar || r3->op() == kRegexpAnyChar)) {
      // AnyChar is above or below the vertical bar. Let it subsume
      // the other when the other is Literal, CharClass or AnyChar.
      if (r3->op() == kRegexpAnyChar &&
          (r1->op() == kRegexpLiteral ||
           r1->op() == kRegexpCharClass ||
           r1->op() == kRegexpAnyChar)) {
        // Discard r1.
        stacktop_ = r2;
        r1->Decref();
        return true;
      }
      if (r1->op() == kRegexpAnyChar &&
          (r3->op() == kRegexpLiteral ||
           r3->op() == kRegexpCharClass ||
           r3->op() == kRegexpAnyChar)) {
        // Rearrange the stack and discard r3.
        r1->down_ = r3->down_;
        r2->down_ = r1;
        stacktop_ = r2;
        r3->Decref();
        return true;
      }
    }
    // Swap r1 below vertical bar (r2).
    r1->down_ = r2->down_;
    r2->down_ = r1;
    stacktop_ = r2;
    return true;
  }
  return PushSimpleOp(kVerticalBar);
}

// Processes a right parenthesis in the input.
bool Regexp::ParseState::DoRightParen() {
  // Finish the current concatenation and alternation.
  DoAlternation();

  // The stack should be: LeftParen regexp
  // Remove the LeftParen, leaving the regexp,
  // parenthesized.
  Regexp* r1;
  Regexp* r2;
  if ((r1 = stacktop_) == NULL ||
      (r2 = r1->down_) == NULL ||
      r2->op() != kLeftParen) {
    status_->set_code(kRegexpMissingParen);
    status_->set_error_arg(whole_regexp_);
    return false;
  }

  // Pop off r1, r2.  Will Decref or reuse below.
  stacktop_ = r2->down_;

  // Restore flags from when paren opened.
  Regexp* re = r2;
  flags_ = re->parse_flags();

  // Rewrite LeftParen as capture if needed.
  if (re->cap_ > 0) {
    re->op_ = kRegexpCapture;
    // re->cap_ is already set
    re->AllocSub(1);
    re->sub()[0] = FinishRegexp(r1);
    re->simple_ = re->ComputeSimple();
  } else {
    re->Decref();
    re = r1;
  }
  return PushRegexp(re);
}

// Processes the end of input, returning the final regexp.
Regexp* Regexp::ParseState::DoFinish() {
  DoAlternation();
  Regexp* re = stacktop_;
  if (re != NULL && re->down_ != NULL) {
    status_->set_code(kRegexpMissingParen);
    status_->set_error_arg(whole_regexp_);
    return NULL;
  }
  stacktop_ = NULL;
  return FinishRegexp(re);
}

// Returns the leading regexp that re starts with.
// The returned Regexp* points into a piece of re,
// so it must not be used after the caller calls re->Decref().
Regexp* Regexp::LeadingRegexp(Regexp* re) {
  if (re->op() == kRegexpEmptyMatch)
    return NULL;
  if (re->op() == kRegexpConcat && re->nsub() >= 2) {
    Regexp** sub = re->sub();
    if (sub[0]->op() == kRegexpEmptyMatch)
      return NULL;
    return sub[0];
  }
  return re;
}

// Removes LeadingRegexp(re) from re and returns what's left.
// Consumes the reference to re and may edit it in place.
// If caller wants to hold on to LeadingRegexp(re),
// must have already Incref'ed it.
Regexp* Regexp::RemoveLeadingRegexp(Regexp* re) {
  if (re->op() == kRegexpEmptyMatch)
    return re;
  if (re->op() == kRegexpConcat && re->nsub() >= 2) {
    Regexp** sub = re->sub();
    if (sub[0]->op() == kRegexpEmptyMatch)
      return re;
    sub[0]->Decref();
    sub[0] = NULL;
    if (re->nsub() == 2) {
      // Collapse concatenation to single regexp.
      Regexp* nre = sub[1];
      sub[1] = NULL;
      re->Decref();
      return nre;
    }
    // 3 or more -> 2 or more.
    re->nsub_--;
    memmove(sub, sub + 1, re->nsub_ * sizeof sub[0]);
    return re;
  }
  Regexp::ParseFlags pf = re->parse_flags();
  re->Decref();
  return new Regexp(kRegexpEmptyMatch, pf);
}

// Returns the leading string that re starts with.
// The returned Rune* points into a piece of re,
// so it must not be used after the caller calls re->Decref().
Rune* Regexp::LeadingString(Regexp* re, int *nrune,
                            Regexp::ParseFlags *flags) {
  while (re->op() == kRegexpConcat && re->nsub() > 0)
    re = re->sub()[0];

  *flags = static_cast<Regexp::ParseFlags>(re->parse_flags_ & Regexp::FoldCase);

  if (re->op() == kRegexpLiteral) {
    *nrune = 1;
    return &re->rune_;
  }

  if (re->op() == kRegexpLiteralString) {
    *nrune = re->nrunes_;
    return re->runes_;
  }

  *nrune = 0;
  return NULL;
}

// Removes the first n leading runes from the beginning of re.
// Edits re in place.
void Regexp::RemoveLeadingString(Regexp* re, int n) {
  // Chase down concats to find first string.
  // For regexps generated by parser, nested concats are
  // flattened except when doing so would overflow the 16-bit
  // limit on the size of a concatenation, so we should never
  // see more than two here.
  Regexp* stk[4];
  int d = 0;
  while (re->op() == kRegexpConcat) {
    if (d < arraysize(stk))
      stk[d++] = re;
    re = re->sub()[0];
  }

  // Remove leading string from re.
  if (re->op() == kRegexpLiteral) {
    re->rune_ = 0;
    re->op_ = kRegexpEmptyMatch;
  } else if (re->op() == kRegexpLiteralString) {
    if (n >= re->nrunes_) {
      delete[] re->runes_;
      re->runes_ = NULL;
      re->nrunes_ = 0;
      re->op_ = kRegexpEmptyMatch;
    } else if (n == re->nrunes_ - 1) {
      Rune rune = re->runes_[re->nrunes_ - 1];
      delete[] re->runes_;
      re->runes_ = NULL;
      re->nrunes_ = 0;
      re->rune_ = rune;
      re->op_ = kRegexpLiteral;
    } else {
      re->nrunes_ -= n;
      memmove(re->runes_, re->runes_ + n, re->nrunes_ * sizeof re->runes_[0]);
    }
  }

  // If re is now empty, concatenations might simplify too.
  while (d-- > 0) {
    re = stk[d];
    Regexp** sub = re->sub();
    if (sub[0]->op() == kRegexpEmptyMatch) {
      sub[0]->Decref();
      sub[0] = NULL;
      // Delete first element of concat.
      switch (re->nsub()) {
        case 0:
        case 1:
          // Impossible.
          LOG(DFATAL) << "Concat of " << re->nsub();
          re->submany_ = NULL;
          re->op_ = kRegexpEmptyMatch;
          break;

        case 2: {
          // Replace re with sub[1].
          Regexp* old = sub[1];
          sub[1] = NULL;
          re->Swap(old);
          old->Decref();
          break;
        }

        default:
          // Slide down.
          re->nsub_--;
          memmove(sub, sub + 1, re->nsub_ * sizeof sub[0]);
          break;
      }
    }
  }
}

// In the context of factoring alternations, a Splice is: a factored prefix or
// merged character class computed by one iteration of one round of factoring;
// the span of subexpressions of the alternation to be "spliced" (i.e. removed
// and replaced); and, for a factored prefix, the number of suffixes after any
// factoring that might have subsequently been performed on them. For a merged
// character class, there are no suffixes, of course, so the field is ignored.
struct Splice {
  Splice(Regexp* prefix, Regexp** sub, int nsub)
      : prefix(prefix),
        sub(sub),
        nsub(nsub),
        nsuffix(-1) {}

  Regexp* prefix;
  Regexp** sub;
  int nsub;
  int nsuffix;
};

// Named so because it is used to implement an explicit stack, a Frame is: the
// span of subexpressions of the alternation to be factored; the current round
// of factoring; any Splices computed; and, for a factored prefix, an iterator
// to the next Splice to be factored (i.e. in another Frame) because suffixes.
struct Frame {
  Frame(Regexp** sub, int nsub)
      : sub(sub),
        nsub(nsub),
        round(0) {}

  Regexp** sub;
  int nsub;
  int round;
  std::vector<Splice> splices;
  int spliceidx;
};

// Bundled into a class for friend access to Regexp without needing to declare
// (or define) Splice in regexp.h.
class FactorAlternationImpl {
 public:
  static void Round1(Regexp** sub, int nsub,
                     Regexp::ParseFlags flags,
                     std::vector<Splice>* splices);
  static void Round2(Regexp** sub, int nsub,
                     Regexp::ParseFlags flags,
                     std::vector<Splice>* splices);
  static void Round3(Regexp** sub, int nsub,
                     Regexp::ParseFlags flags,
                     std::vector<Splice>* splices);
};

// Factors common prefixes from alternation.
// For example,
//     ABC|ABD|AEF|BCX|BCY
// simplifies to
//     A(B(C|D)|EF)|BC(X|Y)
// and thence to
//     A(B[CD]|EF)|BC[XY]
//
// Rewrites sub to contain simplified list to alternate and returns
// the new length of sub.  Adjusts reference counts accordingly
// (incoming sub[i] decremented, outgoing sub[i] incremented).
int Regexp::FactorAlternation(Regexp** sub, int nsub, ParseFlags flags) {
  std::vector<Frame> stk;
  stk.emplace_back(sub, nsub);

  for (;;) {
    auto& sub = stk.back().sub;
    auto& nsub = stk.back().nsub;
    auto& round = stk.back().round;
    auto& splices = stk.back().splices;
    auto& spliceidx = stk.back().spliceidx;

    if (splices.empty()) {
      // Advance to the next round of factoring. Note that this covers
      // the initialised state: when splices is empty and round is 0.
      round++;
    } else if (spliceidx < static_cast<int>(splices.size())) {
      // We have at least one more Splice to factor. Recurse logically.
      stk.emplace_back(splices[spliceidx].sub, splices[spliceidx].nsub);
      continue;
    } else {
      // We have no more Splices to factor. Apply them.
      auto iter = splices.begin();
      int out = 0;
      for (int i = 0; i < nsub; ) {
        // Copy until we reach where the next Splice begins.
        while (sub + i < iter->sub)
          sub[out++] = sub[i++];
        switch (round) {
          case 1:
          case 2: {
            // Assemble the Splice prefix and the suffixes.
            Regexp* re[2];
            re[0] = iter->prefix;
            re[1] = Regexp::AlternateNoFactor(iter->sub, iter->nsuffix, flags);
            sub[out++] = Regexp::Concat(re, 2, flags);
            i += iter->nsub;
            break;
          }
          case 3:
            // Just use the Splice prefix.
            sub[out++] = iter->prefix;
            i += iter->nsub;
            break;
          default:
            LOG(DFATAL) << "unknown round: " << round;
            break;
        }
        // If we are done, copy until the end of sub.
        if (++iter == splices.end()) {
          while (i < nsub)
            sub[out++] = sub[i++];
        }
      }
      splices.clear();
      nsub = out;
      // Advance to the next round of factoring.
      round++;
    }

    switch (round) {
      case 1:
        FactorAlternationImpl::Round1(sub, nsub, flags, &splices);
        break;
      case 2:
        FactorAlternationImpl::Round2(sub, nsub, flags, &splices);
        break;
      case 3:
        FactorAlternationImpl::Round3(sub, nsub, flags, &splices);
        break;
      case 4:
        if (stk.size() == 1) {
          // We are at the top of the stack. Just return.
          return nsub;
        } else {
          // Pop the stack and set the number of suffixes.
          // (Note that references will be invalidated!)
          int nsuffix = nsub;
          stk.pop_back();
          stk.back().splices[stk.back().spliceidx].nsuffix = nsuffix;
          ++stk.back().spliceidx;
          continue;
        }
      default:
        LOG(DFATAL) << "unknown round: " << round;
        break;
    }

    // Set spliceidx depending on whether we have Splices to factor.
    if (splices.empty() || round == 3) {
      spliceidx = static_cast<int>(splices.size());
    } else {
      spliceidx = 0;
    }
  }
}

void FactorAlternationImpl::Round1(Regexp** sub, int nsub,
                                   Regexp::ParseFlags flags,
                                   std::vector<Splice>* splices) {
  // Round 1: Factor out common literal prefixes.
  int start = 0;
  Rune* rune = NULL;
  int nrune = 0;
  Regexp::ParseFlags runeflags = Regexp::NoParseFlags;
  for (int i = 0; i <= nsub; i++) {
    // Invariant: sub[start:i] consists of regexps that all
    // begin with rune[0:nrune].
    Rune* rune_i = NULL;
    int nrune_i = 0;
    Regexp::ParseFlags runeflags_i = Regexp::NoParseFlags;
    if (i < nsub) {
      rune_i = Regexp::LeadingString(sub[i], &nrune_i, &runeflags_i);
      if (runeflags_i == runeflags) {
        int same = 0;
        while (same < nrune && same < nrune_i && rune[same] == rune_i[same])
          same++;
        if (same > 0) {
          // Matches at least one rune in current range.  Keep going around.
          nrune = same;
          continue;
        }
      }
    }

    // Found end of a run with common leading literal string:
    // sub[start:i] all begin with rune[0:nrune],
    // but sub[i] does not even begin with rune[0].
    if (i == start) {
      // Nothing to do - first iteration.
    } else if (i == start+1) {
      // Just one: don't bother factoring.
    } else {
      Regexp* prefix = Regexp::LiteralString(rune, nrune, runeflags);
      for (int j = start; j < i; j++)
        Regexp::RemoveLeadingString(sub[j], nrune);
      splices->emplace_back(prefix, sub + start, i - start);
    }

    // Prepare for next iteration (if there is one).
    if (i < nsub) {
      start = i;
      rune = rune_i;
      nrune = nrune_i;
      runeflags = runeflags_i;
    }
  }
}

void FactorAlternationImpl::Round2(Regexp** sub, int nsub,
                                   Regexp::ParseFlags flags,
                                   std::vector<Splice>* splices) {
  // Round 2: Factor out common simple prefixes,
  // just the first piece of each concatenation.
  // This will be good enough a lot of the time.
  //
  // Complex subexpressions (e.g. involving quantifiers)
  // are not safe to factor because that collapses their
  // distinct paths through the automaton, which affects
  // correctness in some cases.
  int start = 0;
  Regexp* first = NULL;
  for (int i = 0; i <= nsub; i++) {
    // Invariant: sub[start:i] consists of regexps that all
    // begin with first.
    Regexp* first_i = NULL;
    if (i < nsub) {
      first_i = Regexp::LeadingRegexp(sub[i]);
      if (first != NULL &&
          // first must be an empty-width op
          // OR a char class, any char or any byte
          // OR a fixed repeat of a literal, char class, any char or any byte.
          (first->op() == kRegexpBeginLine ||
           first->op() == kRegexpEndLine ||
           first->op() == kRegexpWordBoundary ||
           first->op() == kRegexpNoWordBoundary ||
           first->op() == kRegexpBeginText ||
           first->op() == kRegexpEndText ||
           first->op() == kRegexpCharClass ||
           first->op() == kRegexpAnyChar ||
           first->op() == kRegexpAnyByte ||
           (first->op() == kRegexpRepeat &&
            first->min() == first->max() &&
            (first->sub()[0]->op() == kRegexpLiteral ||
             first->sub()[0]->op() == kRegexpCharClass ||
             first->sub()[0]->op() == kRegexpAnyChar ||
             first->sub()[0]->op() == kRegexpAnyByte))) &&
          Regexp::Equal(first, first_i))
        continue;
    }

    // Found end of a run with common leading regexp:
    // sub[start:i] all begin with first,
    // but sub[i] does not.
    if (i == start) {
      // Nothing to do - first iteration.
    } else if (i == start+1) {
      // Just one: don't bother factoring.
    } else {
      Regexp* prefix = first->Incref();
      for (int j = start; j < i; j++)
        sub[j] = Regexp::RemoveLeadingRegexp(sub[j]);
      splices->emplace_back(prefix, sub + start, i - start);
    }

    // Prepare for next iteration (if there is one).
    if (i < nsub) {
      start = i;
      first = first_i;
    }
  }
}

void FactorAlternationImpl::Round3(Regexp** sub, int nsub,
                                   Regexp::ParseFlags flags,
                                   std::vector<Splice>* splices) {
  // Round 3: Merge runs of literals and/or character classes.
  int start = 0;
  Regexp* first = NULL;
  for (int i = 0; i <= nsub; i++) {
    // Invariant: sub[start:i] consists of regexps that all
    // are either literals (i.e. runes) or character classes.
    Regexp* first_i = NULL;
    if (i < nsub) {
      first_i = sub[i];
      if (first != NULL &&
          (first->op() == kRegexpLiteral ||
           first->op() == kRegexpCharClass) &&
          (first_i->op() == kRegexpLiteral ||
           first_i->op() == kRegexpCharClass))
        continue;
    }

    // Found end of a run of Literal/CharClass:
    // sub[start:i] all are either one or the other,
    // but sub[i] is not.
    if (i == start) {
      // Nothing to do - first iteration.
    } else if (i == start+1) {
      // Just one: don't bother factoring.
    } else {
      CharClassBuilder ccb;
      for (int j = start; j < i; j++) {
        Regexp* re = sub[j];
        if (re->op() == kRegexpCharClass) {
          CharClass* cc = re->cc();
          for (CharClass::iterator it = cc->begin(); it != cc->end(); ++it)
            ccb.AddRange(it->lo, it->hi);
        } else if (re->op() == kRegexpLiteral) {
          ccb.AddRangeFlags(re->rune(), re->rune(), re->parse_flags());
        } else {
          LOG(DFATAL) << "RE2: unexpected op: " << re->op() << " "
                      << re->ToString();
        }
        re->Decref();
      }
      Regexp* re = Regexp::NewCharClass(ccb.GetCharClass(), flags);
      splices->emplace_back(re, sub + start, i - start);
    }

    // Prepare for next iteration (if there is one).
    if (i < nsub) {
      start = i;
      first = first_i;
    }
  }
}

// Collapse the regexps on top of the stack, down to the
// first marker, into a new op node (op == kRegexpAlternate
// or op == kRegexpConcat).
void Regexp::ParseState::DoCollapse(RegexpOp op) {
  // Scan backward to marker, counting children of composite.
  int n = 0;
  Regexp* next = NULL;
  Regexp* sub;
  for (sub = stacktop_; sub != NULL && !IsMarker(sub->op()); sub = next) {
    next = sub->down_;
    if (sub->op_ == op)
      n += sub->nsub_;
    else
      n++;
  }

  // If there's just one child, leave it alone.
  // (Concat of one thing is that one thing; alternate of one thing is same.)
  if (stacktop_ != NULL && stacktop_->down_ == next)
    return;

  // Construct op (alternation or concatenation), flattening op of op.
  PODArray<Regexp*> subs(n);
  next = NULL;
  int i = n;
  for (sub = stacktop_; sub != NULL && !IsMarker(sub->op()); sub = next) {
    next = sub->down_;
    if (sub->op_ == op) {
      Regexp** sub_subs = sub->sub();
      for (int k = sub->nsub_ - 1; k >= 0; k--)
        subs[--i] = sub_subs[k]->Incref();
      sub->Decref();
    } else {
      subs[--i] = FinishRegexp(sub);
    }
  }

  Regexp* re = ConcatOrAlternate(op, subs.data(), n, flags_, true);
  re->simple_ = re->ComputeSimple();
  re->down_ = next;
  stacktop_ = re;
}

// Finishes the current concatenation,
// collapsing it into a single regexp on the stack.
void Regexp::ParseState::DoConcatenation() {
  Regexp* r1 = stacktop_;
  if (r1 == NULL || IsMarker(r1->op())) {
    // empty concatenation is special case
    Regexp* re = new Regexp(kRegexpEmptyMatch, flags_);
    PushRegexp(re);
  }
  DoCollapse(kRegexpConcat);
}

// Finishes the current alternation,
// collapsing it to a single regexp on the stack.
void Regexp::ParseState::DoAlternation() {
  DoVerticalBar();
  // Now stack top is kVerticalBar.
  Regexp* r1 = stacktop_;
  stacktop_ = r1->down_;
  r1->Decref();
  DoCollapse(kRegexpAlternate);
}

// Incremental conversion of concatenated literals into strings.
// If top two elements on stack are both literal or string,
// collapse into single string.
// Don't walk down the stack -- the parser calls this frequently
// enough that below the bottom two is known to be collapsed.
// Only called when another regexp is about to be pushed
// on the stack, so that the topmost literal is not being considered.
// (Otherwise ab* would turn into (ab)*.)
// If r >= 0, consider pushing a literal r on the stack.
// Return whether that happened.
bool Regexp::ParseState::MaybeConcatString(int r, ParseFlags flags) {
  Regexp* re1;
  Regexp* re2;
  if ((re1 = stacktop_) == NULL || (re2 = re1->down_) == NULL)
    return false;

  if (re1->op_ != kRegexpLiteral && re1->op_ != kRegexpLiteralString)
    return false;
  if (re2->op_ != kRegexpLiteral && re2->op_ != kRegexpLiteralString)
    return false;
  if ((re1->parse_flags_ & FoldCase) != (re2->parse_flags_ & FoldCase))
    return false;

  if (re2->op_ == kRegexpLiteral) {
    // convert into string
    Rune rune = re2->rune_;
    re2->op_ = kRegexpLiteralString;
    re2->nrunes_ = 0;
    re2->runes_ = NULL;
    re2->AddRuneToString(rune);
  }

  // push re1 into re2.
  if (re1->op_ == kRegexpLiteral) {
    re2->AddRuneToString(re1->rune_);
  } else {
    for (int i = 0; i < re1->nrunes_; i++)
      re2->AddRuneToString(re1->runes_[i]);
    re1->nrunes_ = 0;
    delete[] re1->runes_;
    re1->runes_ = NULL;
  }

  // reuse re1 if possible
  if (r >= 0) {
    re1->op_ = kRegexpLiteral;
    re1->rune_ = r;
    re1->parse_flags_ = static_cast<uint16_t>(flags);
    return true;
  }

  stacktop_ = re2;
  re1->Decref();
  return false;
}

// Lexing routines.

// Parses a decimal integer, storing it in *np.
// Sets *s to span the remainder of the string.
static bool ParseInteger(StringPiece* s, int* np) {
  if (s->size() == 0 || !isdigit((*s)[0] & 0xFF))
    return false;
  // Disallow leading zeros.
  if (s->size() >= 2 && (*s)[0] == '0' && isdigit((*s)[1] & 0xFF))
    return false;
  int n = 0;
  int c;
  while (s->size() > 0 && isdigit(c = (*s)[0] & 0xFF)) {
    // Avoid overflow.
    if (n >= 100000000)
      return false;
    n = n*10 + c - '0';
    s->remove_prefix(1);  // digit
  }
  *np = n;
  return true;
}

// Parses a repetition suffix like {1,2} or {2} or {2,}.
// Sets *s to span the remainder of the string on success.
// Sets *lo and *hi to the given range.
// In the case of {2,}, the high number is unbounded;
// sets *hi to -1 to signify this.
// {,2} is NOT a valid suffix.
// The Maybe in the name signifies that the regexp parse
// doesn't fail even if ParseRepetition does, so the StringPiece
// s must NOT be edited unless MaybeParseRepetition returns true.
static bool MaybeParseRepetition(StringPiece* sp, int* lo, int* hi) {
  StringPiece s = *sp;
  if (s.size() == 0 || s[0] != '{')
    return false;
  s.remove_prefix(1);  // '{'
  if (!ParseInteger(&s, lo))
    return false;
  if (s.size() == 0)
    return false;
  if (s[0] == ',') {
    s.remove_prefix(1);  // ','
    if (s.size() == 0)
      return false;
    if (s[0] == '}') {
      // {2,} means at least 2
      *hi = -1;
    } else {
      // {2,4} means 2, 3, or 4.
      if (!ParseInteger(&s, hi))
        return false;
    }
  } else {
    // {2} means exactly two
    *hi = *lo;
  }
  if (s.size() == 0 || s[0] != '}')
    return false;
  s.remove_prefix(1);  // '}'
  *sp = s;
  return true;
}

// Removes the next Rune from the StringPiece and stores it in *r.
// Returns number of bytes removed from sp.
// Behaves as though there is a terminating NUL at the end of sp.
// Argument order is backwards from usual Google style
// but consistent with chartorune.
static int StringPieceToRune(Rune *r, StringPiece *sp, RegexpStatus* status) {
  // fullrune() takes int, not size_t. However, it just looks
  // at the leading byte and treats any length >= 4 the same.
  if (fullrune(sp->data(), static_cast<int>(std::min(size_t{4}, sp->size())))) {
    int n = chartorune(r, sp->data());
    // Some copies of chartorune have a bug that accepts
    // encodings of values in (10FFFF, 1FFFFF] as valid.
    // Those values break the character class algorithm,
    // which assumes Runemax is the largest rune.
    if (*r > Runemax) {
      n = 1;
      *r = Runeerror;
    }
    if (!(n == 1 && *r == Runeerror)) {  // no decoding error
      sp->remove_prefix(n);
      return n;
    }
  }

  status->set_code(kRegexpBadUTF8);
  status->set_error_arg(StringPiece());
  return -1;
}

// Return whether name is valid UTF-8.
// If not, set status to kRegexpBadUTF8.
static bool IsValidUTF8(const StringPiece& s, RegexpStatus* status) {
  StringPiece t = s;
  Rune r;
  while (t.size() > 0) {
    if (StringPieceToRune(&r, &t, status) < 0)
      return false;
  }
  return true;
}

// Is c a hex digit?
static int IsHex(int c) {
  return ('0' <= c && c <= '9') ||
         ('A' <= c && c <= 'F') ||
         ('a' <= c && c <= 'f');
}

// Convert hex digit to value.
static int UnHex(int c) {
  if ('0' <= c && c <= '9')
    return c - '0';
  if ('A' <= c && c <= 'F')
    return c - 'A' + 10;
  if ('a' <= c && c <= 'f')
    return c - 'a' + 10;
  LOG(DFATAL) << "Bad hex digit " << c;
  return 0;
}

// Parse an escape sequence (e.g., \n, \{).
// Sets *s to span the remainder of the string.
// Sets *rp to the named character.
static bool ParseEscape(StringPiece* s, Rune* rp,
                        RegexpStatus* status, int rune_max) {
  const char* begin = s->begin();
  if (s->size() < 1 || (*s)[0] != '\\') {
    // Should not happen - caller always checks.
    status->set_code(kRegexpInternalError);
    status->set_error_arg(StringPiece());
    return false;
  }
  if (s->size() < 2) {
    status->set_code(kRegexpTrailingBackslash);
    status->set_error_arg(StringPiece());
    return false;
  }
  Rune c, c1;
  s->remove_prefix(1);  // backslash
  if (StringPieceToRune(&c, s, status) < 0)
    return false;
  int code;
  switch (c) {
    default:
      if (c < Runeself && !isalpha(c) && !isdigit(c)) {
        // Escaped non-word characters are always themselves.
        // PCRE is not quite so rigorous: it accepts things like
        // \q, but we don't.  We once rejected \_, but too many
        // programs and people insist on using it, so allow \_.
        *rp = c;
        return true;
      }
      goto BadEscape;

    // Octal escapes.
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      // Single non-zero octal digit is a backreference; not supported.
      if (s->size() == 0 || (*s)[0] < '0' || (*s)[0] > '7')
        goto BadEscape;
      FALLTHROUGH_INTENDED;
    case '0':
      // consume up to three octal digits; already have one.
      code = c - '0';
      if (s->size() > 0 && '0' <= (c = (*s)[0]) && c <= '7') {
        code = code * 8 + c - '0';
        s->remove_prefix(1);  // digit
        if (s->size() > 0) {
          c = (*s)[0];
          if ('0' <= c && c <= '7') {
            code = code * 8 + c - '0';
            s->remove_prefix(1);  // digit
          }
        }
      }
      if (code > rune_max)
        goto BadEscape;
      *rp = code;
      return true;

    // Hexadecimal escapes
    case 'x':
      if (s->size() == 0)
        goto BadEscape;
      if (StringPieceToRune(&c, s, status) < 0)
        return false;
      if (c == '{') {
        // Any number of digits in braces.
        // Update n as we consume the string, so that
        // the whole thing gets shown in the error message.
        // Perl accepts any text at all; it ignores all text
        // after the first non-hex digit.  We require only hex digits,
        // and at least one.
        if (StringPieceToRune(&c, s, status) < 0)
          return false;
        int nhex = 0;
        code = 0;
        while (IsHex(c)) {
          nhex++;
          code = code * 16 + UnHex(c);
          if (code > rune_max)
            goto BadEscape;
          if (s->size() == 0)
            goto BadEscape;
          if (StringPieceToRune(&c, s, status) < 0)
            return false;
        }
        if (c != '}' || nhex == 0)
          goto BadEscape;
        *rp = code;
        return true;
      }
      // Easy case: two hex digits.
      if (s->size() == 0)
        goto BadEscape;
      if (StringPieceToRune(&c1, s, status) < 0)
        return false;
      if (!IsHex(c) || !IsHex(c1))
        goto BadEscape;
      *rp = UnHex(c) * 16 + UnHex(c1);
      return true;

    // C escapes.
    case 'n':
      *rp = '\n';
      return true;
    case 'r':
      *rp = '\r';
      return true;
    case 't':
      *rp = '\t';
      return true;

    // Less common C escapes.
    case 'a':
      *rp = '\a';
      return true;
    case 'f':
      *rp = '\f';
      return true;
    case 'v':
      *rp = '\v';
      return true;

    // This code is disabled to avoid misparsing
    // the Perl word-boundary \b as a backspace
    // when in POSIX regexp mode.  Surprisingly,
    // in Perl, \b means word-boundary but [\b]
    // means backspace.  We don't support that:
    // if you want a backspace embed a literal
    // backspace character or use \x08.
    //
    // case 'b':
    //   *rp = '\b';
    //   return true;
  }

  LOG(DFATAL) << "Not reached in ParseEscape.";

BadEscape:
  // Unrecognized escape sequence.
  status->set_code(kRegexpBadEscape);
  status->set_error_arg(
      StringPiece(begin, static_cast<size_t>(s->begin() - begin)));
  return false;
}

// Add a range to the character class, but exclude newline if asked.
// Also handle case folding.
void CharClassBuilder::AddRangeFlags(
    Rune lo, Rune hi, Regexp::ParseFlags parse_flags) {

  // Take out \n if the flags say so.
  bool cutnl = !(parse_flags & Regexp::ClassNL) ||
               (parse_flags & Regexp::NeverNL);
  if (cutnl && lo <= '\n' && '\n' <= hi) {
    if (lo < '\n')
      AddRangeFlags(lo, '\n' - 1, parse_flags);
    if (hi > '\n')
      AddRangeFlags('\n' + 1, hi, parse_flags);
    return;
  }

  // If folding case, add fold-equivalent characters too.
  if (parse_flags & Regexp::FoldCase)
    AddFoldedRange(this, lo, hi, 0);
  else
    AddRange(lo, hi);
}

// Look for a group with the given name.
static const UGroup* LookupGroup(const StringPiece& name,
                                 const UGroup *groups, int ngroups) {
  // Simple name lookup.
  for (int i = 0; i < ngroups; i++)
    if (StringPiece(groups[i].name) == name)
      return &groups[i];
  return NULL;
}

// Look for a POSIX group with the given name (e.g., "[:^alpha:]")
static const UGroup* LookupPosixGroup(const StringPiece& name) {
  return LookupGroup(name, posix_groups, num_posix_groups);
}

static const UGroup* LookupPerlGroup(const StringPiece& name) {
  return LookupGroup(name, perl_groups, num_perl_groups);
}

#if !defined(RE2_USE_ICU)
// Fake UGroup containing all Runes
static URange16 any16[] = { { 0, 65535 } };
static URange32 any32[] = { { 65536, Runemax } };
static UGroup anygroup = { "Any", +1, any16, 1, any32, 1 };

// Look for a Unicode group with the given name (e.g., "Han")
static const UGroup* LookupUnicodeGroup(const StringPiece& name) {
  // Special case: "Any" means any.
  if (name == StringPiece("Any"))
    return &anygroup;
  return LookupGroup(name, unicode_groups, num_unicode_groups);
}
#endif

// Add a UGroup or its negation to the character class.
static void AddUGroup(CharClassBuilder *cc, const UGroup *g, int sign,
                      Regexp::ParseFlags parse_flags) {
  if (sign == +1) {
    for (int i = 0; i < g->nr16; i++) {
      cc->AddRangeFlags(g->r16[i].lo, g->r16[i].hi, parse_flags);
    }
    for (int i = 0; i < g->nr32; i++) {
      cc->AddRangeFlags(g->r32[i].lo, g->r32[i].hi, parse_flags);
    }
  } else {
    if (parse_flags & Regexp::FoldCase) {
      // Normally adding a case-folded group means
      // adding all the extra fold-equivalent runes too.
      // But if we're adding the negation of the group,
      // we have to exclude all the runes that are fold-equivalent
      // to what's already missing.  Too hard, so do in two steps.
      CharClassBuilder ccb1;
      AddUGroup(&ccb1, g, +1, parse_flags);
      // If the flags say to take out \n, put it in, so that negating will take it out.
      // Normally AddRangeFlags does this, but we're bypassing AddRangeFlags.
      bool cutnl = !(parse_flags & Regexp::ClassNL) ||
                   (parse_flags & Regexp::NeverNL);
      if (cutnl) {
        ccb1.AddRange('\n', '\n');
      }
      ccb1.Negate();
      cc->AddCharClass(&ccb1);
      return;
    }
    int next = 0;
    for (int i = 0; i < g->nr16; i++) {
      if (next < g->r16[i].lo)
        cc->AddRangeFlags(next, g->r16[i].lo - 1, parse_flags);
      next = g->r16[i].hi + 1;
    }
    for (int i = 0; i < g->nr32; i++) {
      if (next < g->r32[i].lo)
        cc->AddRangeFlags(next, g->r32[i].lo - 1, parse_flags);
      next = g->r32[i].hi + 1;
    }
    if (next <= Runemax)
      cc->AddRangeFlags(next, Runemax, parse_flags);
  }
}

// Maybe parse a Perl character class escape sequence.
// Only recognizes the Perl character classes (\d \s \w \D \S \W),
// not the Perl empty-string classes (\b \B \A \Z \z).
// On success, sets *s to span the remainder of the string
// and returns the corresponding UGroup.
// The StringPiece must *NOT* be edited unless the call succeeds.
const UGroup* MaybeParsePerlCCEscape(StringPiece* s, Regexp::ParseFlags parse_flags) {
  if (!(parse_flags & Regexp::PerlClasses))
    return NULL;
  if (s->size() < 2 || (*s)[0] != '\\')
    return NULL;
  // Could use StringPieceToRune, but there aren't
  // any non-ASCII Perl group names.
  StringPiece name(s->begin(), 2);
  const UGroup *g = LookupPerlGroup(name);
  if (g == NULL)
    return NULL;
  s->remove_prefix(name.size());
  return g;
}

enum ParseStatus {
  kParseOk,  // Did some parsing.
  kParseError,  // Found an error.
  kParseNothing,  // Decided not to parse.
};

// Maybe parses a Unicode character group like \p{Han} or \P{Han}
// (the latter is a negated group).
ParseStatus ParseUnicodeGroup(StringPiece* s, Regexp::ParseFlags parse_flags,
                              CharClassBuilder *cc,
                              RegexpStatus* status) {
  // Decide whether to parse.
  if (!(parse_flags & Regexp::UnicodeGroups))
    return kParseNothing;
  if (s->size() < 2 || (*s)[0] != '\\')
    return kParseNothing;
  Rune c = (*s)[1];
  if (c != 'p' && c != 'P')
    return kParseNothing;

  // Committed to parse.  Results:
  int sign = +1;  // -1 = negated char class
  if (c == 'P')
    sign = -sign;
  StringPiece seq = *s;  // \p{Han} or \pL
  StringPiece name;  // Han or L
  s->remove_prefix(2);  // '\\', 'p'

  if (!StringPieceToRune(&c, s, status))
    return kParseError;
  if (c != '{') {
    // Name is the bit of string we just skipped over for c.
    const char* p = seq.begin() + 2;
    name = StringPiece(p, static_cast<size_t>(s->begin() - p));
  } else {
    // Name is in braces. Look for closing }
    size_t end = s->find('}', 0);
    if (end == StringPiece::npos) {
      if (!IsValidUTF8(seq, status))
        return kParseError;
      status->set_code(kRegexpBadCharRange);
      status->set_error_arg(seq);
      return kParseError;
    }
    name = StringPiece(s->begin(), end);  // without '}'
    s->remove_prefix(end + 1);  // with '}'
    if (!IsValidUTF8(name, status))
      return kParseError;
  }

  // Chop seq where s now begins.
  seq = StringPiece(seq.begin(), static_cast<size_t>(s->begin() - seq.begin()));

  if (name.size() > 0 && name[0] == '^') {
    sign = -sign;
    name.remove_prefix(1);  // '^'
  }

#if !defined(RE2_USE_ICU)
  // Look up the group in the RE2 Unicode data.
  const UGroup *g = LookupUnicodeGroup(name);
  if (g == NULL) {
    status->set_code(kRegexpBadCharRange);
    status->set_error_arg(seq);
    return kParseError;
  }

  AddUGroup(cc, g, sign, parse_flags);
#else
  // Look up the group in the ICU Unicode data. Because ICU provides full
  // Unicode properties support, this could be more than a lookup by name.
  ::icu::UnicodeString ustr = ::icu::UnicodeString::fromUTF8(
      std::string("\\p{") + std::string(name) + std::string("}"));
  UErrorCode uerr = U_ZERO_ERROR;
  ::icu::UnicodeSet uset(ustr, uerr);
  if (U_FAILURE(uerr)) {
    status->set_code(kRegexpBadCharRange);
    status->set_error_arg(seq);
    return kParseError;
  }

  // Convert the UnicodeSet to a URange32 and UGroup that we can add.
  int nr = uset.getRangeCount();
  URange32* r = new URange32[nr];
  for (int i = 0; i < nr; i++) {
    r[i].lo = uset.getRangeStart(i);
    r[i].hi = uset.getRangeEnd(i);
  }
  UGroup g = {"", +1, 0, 0, r, nr};
  AddUGroup(cc, &g, sign, parse_flags);
  delete[] r;
#endif

  return kParseOk;
}

// Parses a character class name like [:alnum:].
// Sets *s to span the remainder of the string.
// Adds the ranges corresponding to the class to ranges.
static ParseStatus ParseCCName(StringPiece* s, Regexp::ParseFlags parse_flags,
                               CharClassBuilder *cc,
                               RegexpStatus* status) {
  // Check begins with [:
  const char* p = s->data();
  const char* ep = s->data() + s->size();
  if (ep - p < 2 || p[0] != '[' || p[1] != ':')
    return kParseNothing;

  // Look for closing :].
  const char* q;
  for (q = p+2; q <= ep-2 && (*q != ':' || *(q+1) != ']'); q++)
    ;

  // If no closing :], then ignore.
  if (q > ep-2)
    return kParseNothing;

  // Got it.  Check that it's valid.
  q += 2;
  StringPiece name(p, static_cast<size_t>(q - p));

  const UGroup *g = LookupPosixGroup(name);
  if (g == NULL) {
    status->set_code(kRegexpBadCharRange);
    status->set_error_arg(name);
    return kParseError;
  }

  s->remove_prefix(name.size());
  AddUGroup(cc, g, g->sign, parse_flags);
  return kParseOk;
}

// Parses a character inside a character class.
// There are fewer special characters here than in the rest of the regexp.
// Sets *s to span the remainder of the string.
// Sets *rp to the character.
bool Regexp::ParseState::ParseCCCharacter(StringPiece* s, Rune *rp,
                                          const StringPiece& whole_class,
                                          RegexpStatus* status) {
  if (s->size() == 0) {
    status->set_code(kRegexpMissingBracket);
    status->set_error_arg(whole_class);
    return false;
  }

  // Allow regular escape sequences even though
  // many need not be escaped in this context.
  if (s->size() >= 1 && (*s)[0] == '\\')
    return ParseEscape(s, rp, status, rune_max_);

  // Otherwise take the next rune.
  return StringPieceToRune(rp, s, status) >= 0;
}

// Parses a character class character, or, if the character
// is followed by a hyphen, parses a character class range.
// For single characters, rr->lo == rr->hi.
// Sets *s to span the remainder of the string.
// Sets *rp to the character.
bool Regexp::ParseState::ParseCCRange(StringPiece* s, RuneRange* rr,
                                      const StringPiece& whole_class,
                                      RegexpStatus* status) {
  StringPiece os = *s;
  if (!ParseCCCharacter(s, &rr->lo, whole_class, status))
    return false;
  // [a-] means (a|-), so check for final ].
  if (s->size() >= 2 && (*s)[0] == '-' && (*s)[1] != ']') {
    s->remove_prefix(1);  // '-'
    if (!ParseCCCharacter(s, &rr->hi, whole_class, status))
      return false;
    if (rr->hi < rr->lo) {
      status->set_code(kRegexpBadCharRange);
      status->set_error_arg(
          StringPiece(os.data(), static_cast<size_t>(s->data() - os.data())));
      return false;
    }
  } else {
    rr->hi = rr->lo;
  }
  return true;
}

// Parses a possibly-negated character class expression like [^abx-z[:digit:]].
// Sets *s to span the remainder of the string.
// Sets *out_re to the regexp for the class.
bool Regexp::ParseState::ParseCharClass(StringPiece* s,
                                        Regexp** out_re,
                                        RegexpStatus* status) {
  StringPiece whole_class = *s;
  if (s->size() == 0 || (*s)[0] != '[') {
    // Caller checked this.
    status->set_code(kRegexpInternalError);
    status->set_error_arg(StringPiece());
    return false;
  }
  bool negated = false;
  Regexp* re = new Regexp(kRegexpCharClass, flags_ & ~FoldCase);
  re->ccb_ = new CharClassBuilder;
  s->remove_prefix(1);  // '['
  if (s->size() > 0 && (*s)[0] == '^') {
    s->remove_prefix(1);  // '^'
    negated = true;
    if (!(flags_ & ClassNL) || (flags_ & NeverNL)) {
      // If NL can't match implicitly, then pretend
      // negated classes include a leading \n.
      re->ccb_->AddRange('\n', '\n');
    }
  }
  bool first = true;  // ] is okay as first char in class
  while (s->size() > 0 && ((*s)[0] != ']' || first)) {
    // - is only okay unescaped as first or last in class.
    // Except that Perl allows - anywhere.
    if ((*s)[0] == '-' && !first && !(flags_&PerlX) &&
        (s->size() == 1 || (*s)[1] != ']')) {
      StringPiece t = *s;
      t.remove_prefix(1);  // '-'
      Rune r;
      int n = StringPieceToRune(&r, &t, status);
      if (n < 0) {
        re->Decref();
        return false;
      }
      status->set_code(kRegexpBadCharRange);
      status->set_error_arg(StringPiece(s->data(), 1+n));
      re->Decref();
      return false;
    }
    first = false;

    // Look for [:alnum:] etc.
    if (s->size() > 2 && (*s)[0] == '[' && (*s)[1] == ':') {
      switch (ParseCCName(s, flags_, re->ccb_, status)) {
        case kParseOk:
          continue;
        case kParseError:
          re->Decref();
          return false;
        case kParseNothing:
          break;
      }
    }

    // Look for Unicode character group like \p{Han}
    if (s->size() > 2 &&
        (*s)[0] == '\\' &&
        ((*s)[1] == 'p' || (*s)[1] == 'P')) {
      switch (ParseUnicodeGroup(s, flags_, re->ccb_, status)) {
        case kParseOk:
          continue;
        case kParseError:
          re->Decref();
          return false;
        case kParseNothing:
          break;
      }
    }

    // Look for Perl character class symbols (extension).
    const UGroup *g = MaybeParsePerlCCEscape(s, flags_);
    if (g != NULL) {
      AddUGroup(re->ccb_, g, g->sign, flags_);
      continue;
    }

    // Otherwise assume single character or simple range.
    RuneRange rr;
    if (!ParseCCRange(s, &rr, whole_class, status)) {
      re->Decref();
      return false;
    }
    // AddRangeFlags is usually called in response to a class like
    // \p{Foo} or [[:foo:]]; for those, it filters \n out unless
    // Regexp::ClassNL is set.  In an explicit range or singleton
    // like we just parsed, we do not filter \n out, so set ClassNL
    // in the flags.
    re->ccb_->AddRangeFlags(rr.lo, rr.hi, flags_ | Regexp::ClassNL);
  }
  if (s->size() == 0) {
    status->set_code(kRegexpMissingBracket);
    status->set_error_arg(whole_class);
    re->Decref();
    return false;
  }
  s->remove_prefix(1);  // ']'

  if (negated)
    re->ccb_->Negate();

  *out_re = re;
  return true;
}

// Is this a valid capture name?  [A-Za-z0-9_]+
// PCRE limits names to 32 bytes.
// Python rejects names starting with digits.
// We don't enforce either of those.
static bool IsValidCaptureName(const StringPiece& name) {
  if (name.size() == 0)
    return false;
  for (size_t i = 0; i < name.size(); i++) {
    int c = name[i];
    if (('0' <= c && c <= '9') ||
        ('a' <= c && c <= 'z') ||
        ('A' <= c && c <= 'Z') ||
        c == '_')
      continue;
    return false;
  }
  return true;
}

// Parses a Perl flag setting or non-capturing group or both,
// like (?i) or (?: or (?i:.  Removes from s, updates parse state.
// The caller must check that s begins with "(?".
// Returns true on success.  If the Perl flag is not
// well-formed or not supported, sets status_ and returns false.
bool Regexp::ParseState::ParsePerlFlags(StringPiece* s) {
  StringPiece t = *s;

  // Caller is supposed to check this.
  if (!(flags_ & PerlX) || t.size() < 2 || t[0] != '(' || t[1] != '?') {
    LOG(DFATAL) << "Bad call to ParseState::ParsePerlFlags";
    status_->set_code(kRegexpInternalError);
    return false;
  }

  t.remove_prefix(2);  // "(?"

  // Check for named captures, first introduced in Python's regexp library.
  // As usual, there are three slightly different syntaxes:
  //
  //   (?P<name>expr)   the original, introduced by Python
  //   (?<name>expr)    the .NET alteration, adopted by Perl 5.10
  //   (?'name'expr)    another .NET alteration, adopted by Perl 5.10
  //
  // Perl 5.10 gave in and implemented the Python version too,
  // but they claim that the last two are the preferred forms.
  // PCRE and languages based on it (specifically, PHP and Ruby)
  // support all three as well.  EcmaScript 4 uses only the Python form.
  //
  // In both the open source world (via Code Search) and the
  // Google source tree, (?P<expr>name) is the dominant form,
  // so that's the one we implement.  One is enough.
  if (t.size() > 2 && t[0] == 'P' && t[1] == '<') {
    // Pull out name.
    size_t end = t.find('>', 2);
    if (end == StringPiece::npos) {
      if (!IsValidUTF8(*s, status_))
        return false;
      status_->set_code(kRegexpBadNamedCapture);
      status_->set_error_arg(*s);
      return false;
    }

    // t is "P<name>...", t[end] == '>'
    StringPiece capture(t.begin()-2, end+3);  // "(?P<name>"
    StringPiece name(t.begin()+2, end-2);     // "name"
    if (!IsValidUTF8(name, status_))
      return false;
    if (!IsValidCaptureName(name)) {
      status_->set_code(kRegexpBadNamedCapture);
      status_->set_error_arg(capture);
      return false;
    }

    if (!DoLeftParen(name)) {
      // DoLeftParen's failure set status_.
      return false;
    }

    s->remove_prefix(static_cast<size_t>(capture.end() - s->begin()));
    return true;
  }

  bool negated = false;
  bool sawflags = false;
  int nflags = flags_;
  Rune c;
  for (bool done = false; !done; ) {
    if (t.size() == 0)
      goto BadPerlOp;
    if (StringPieceToRune(&c, &t, status_) < 0)
      return false;
    switch (c) {
      default:
        goto BadPerlOp;

      // Parse flags.
      case 'i':
        sawflags = true;
        if (negated)
          nflags &= ~FoldCase;
        else
          nflags |= FoldCase;
        break;

      case 'm':  // opposite of our OneLine
        sawflags = true;
        if (negated)
          nflags |= OneLine;
        else
          nflags &= ~OneLine;
        break;

      case 's':
        sawflags = true;
        if (negated)
          nflags &= ~DotNL;
        else
          nflags |= DotNL;
        break;

      case 'U':
        sawflags = true;
        if (negated)
          nflags &= ~NonGreedy;
        else
          nflags |= NonGreedy;
        break;

      // Negation
      case '-':
        if (negated)
          goto BadPerlOp;
        negated = true;
        sawflags = false;
        break;

      // Open new group.
      case ':':
        if (!DoLeftParenNoCapture()) {
          // DoLeftParenNoCapture's failure set status_.
          return false;
        }
        done = true;
        break;

      // Finish flags.
      case ')':
        done = true;
        break;
    }
  }

  if (negated && !sawflags)
    goto BadPerlOp;

  flags_ = static_cast<Regexp::ParseFlags>(nflags);
  *s = t;
  return true;

BadPerlOp:
  status_->set_code(kRegexpBadPerlOp);
  status_->set_error_arg(
      StringPiece(s->begin(), static_cast<size_t>(t.begin() - s->begin())));
  return false;
}

// Converts latin1 (assumed to be encoded as Latin1 bytes)
// into UTF8 encoding in string.
// Can't use EncodingUtils::EncodeLatin1AsUTF8 because it is
// deprecated and because it rejects code points 0x80-0x9F.
void ConvertLatin1ToUTF8(const StringPiece& latin1, std::string* utf) {
  char buf[UTFmax];

  utf->clear();
  for (size_t i = 0; i < latin1.size(); i++) {
    Rune r = latin1[i] & 0xFF;
    int n = runetochar(buf, &r);
    utf->append(buf, n);
  }
}

// Parses the regular expression given by s,
// returning the corresponding Regexp tree.
// The caller must Decref the return value when done with it.
// Returns NULL on error.
Regexp* Regexp::Parse(const StringPiece& s, ParseFlags global_flags,
                      RegexpStatus* status) {
  // Make status non-NULL (easier on everyone else).
  RegexpStatus xstatus;
  if (status == NULL)
    status = &xstatus;

  ParseState ps(global_flags, s, status);
  StringPiece t = s;

  // Convert regexp to UTF-8 (easier on the rest of the parser).
  if (global_flags & Latin1) {
    std::string* tmp = new std::string;
    ConvertLatin1ToUTF8(t, tmp);
    status->set_tmp(tmp);
    t = *tmp;
  }

  if (global_flags & Literal) {
    // Special parse loop for literal string.
    while (t.size() > 0) {
      Rune r;
      if (StringPieceToRune(&r, &t, status) < 0)
        return NULL;
      if (!ps.PushLiteral(r))
        return NULL;
    }
    return ps.DoFinish();
  }

  StringPiece lastunary = StringPiece();
  while (t.size() > 0) {
    StringPiece isunary = StringPiece();
    switch (t[0]) {
      default: {
        Rune r;
        if (StringPieceToRune(&r, &t, status) < 0)
          return NULL;
        if (!ps.PushLiteral(r))
          return NULL;
        break;
      }

      case '(':
        // "(?" introduces Perl escape.
        if ((ps.flags() & PerlX) && (t.size() >= 2 && t[1] == '?')) {
          // Flag changes and non-capturing groups.
          if (!ps.ParsePerlFlags(&t))
            return NULL;
          break;
        }
        if (ps.flags() & NeverCapture) {
          if (!ps.DoLeftParenNoCapture())
            return NULL;
        } else {
          if (!ps.DoLeftParen(StringPiece()))
            return NULL;
        }
        t.remove_prefix(1);  // '('
        break;

      case '|':
        if (!ps.DoVerticalBar())
          return NULL;
        t.remove_prefix(1);  // '|'
        break;

      case ')':
        if (!ps.DoRightParen())
          return NULL;
        t.remove_prefix(1);  // ')'
        break;

      case '^':  // Beginning of line.
        if (!ps.PushCarat())
          return NULL;
        t.remove_prefix(1);  // '^'
        break;

      case '$':  // End of line.
        if (!ps.PushDollar())
          return NULL;
        t.remove_prefix(1);  // '$'
        break;

      case '.':  // Any character (possibly except newline).
        if (!ps.PushDot())
          return NULL;
        t.remove_prefix(1);  // '.'
        break;

      case '[': {  // Character class.
        Regexp* re;
        if (!ps.ParseCharClass(&t, &re, status))
          return NULL;
        if (!ps.PushRegexp(re))
          return NULL;
        break;
      }

      case '*': {  // Zero or more.
        RegexpOp op;
        op = kRegexpStar;
        goto Rep;
      case '+':  // One or more.
        op = kRegexpPlus;
        goto Rep;
      case '?':  // Zero or one.
        op = kRegexpQuest;
        goto Rep;
      Rep:
        StringPiece opstr = t;
        bool nongreedy = false;
        t.remove_prefix(1);  // '*' or '+' or '?'
        if (ps.flags() & PerlX) {
          if (t.size() > 0 && t[0] == '?') {
            nongreedy = true;
            t.remove_prefix(1);  // '?'
          }
          if (lastunary.size() > 0) {
            // In Perl it is not allowed to stack repetition operators:
            //   a** is a syntax error, not a double-star.
            // (and a++ means something else entirely, which we don't support!)
            status->set_code(kRegexpRepeatOp);
            status->set_error_arg(StringPiece(
                lastunary.begin(),
                static_cast<size_t>(t.begin() - lastunary.begin())));
            return NULL;
          }
        }
        opstr = StringPiece(opstr.data(),
                            static_cast<size_t>(t.data() - opstr.data()));
        if (!ps.PushRepeatOp(op, opstr, nongreedy))
          return NULL;
        isunary = opstr;
        break;
      }

      case '{': {  // Counted repetition.
        int lo, hi;
        StringPiece opstr = t;
        if (!MaybeParseRepetition(&t, &lo, &hi)) {
          // Treat like a literal.
          if (!ps.PushLiteral('{'))
            return NULL;
          t.remove_prefix(1);  // '{'
          break;
        }
        bool nongreedy = false;
        if (ps.flags() & PerlX) {
          if (t.size() > 0 && t[0] == '?') {
            nongreedy = true;
            t.remove_prefix(1);  // '?'
          }
          if (lastunary.size() > 0) {
            // Not allowed to stack repetition operators.
            status->set_code(kRegexpRepeatOp);
            status->set_error_arg(StringPiece(
                lastunary.begin(),
                static_cast<size_t>(t.begin() - lastunary.begin())));
            return NULL;
          }
        }
        opstr = StringPiece(opstr.data(),
                            static_cast<size_t>(t.data() - opstr.data()));
        if (!ps.PushRepetition(lo, hi, opstr, nongreedy))
          return NULL;
        isunary = opstr;
        break;
      }

      case '\\': {  // Escaped character or Perl sequence.
        // \b and \B: word boundary or not
        if ((ps.flags() & Regexp::PerlB) &&
            t.size() >= 2 && (t[1] == 'b' || t[1] == 'B')) {
          if (!ps.PushWordBoundary(t[1] == 'b'))
            return NULL;
          t.remove_prefix(2);  // '\\', 'b'
          break;
        }

        if ((ps.flags() & Regexp::PerlX) && t.size() >= 2) {
          if (t[1] == 'A') {
            if (!ps.PushSimpleOp(kRegexpBeginText))
              return NULL;
            t.remove_prefix(2);  // '\\', 'A'
            break;
          }
          if (t[1] == 'z') {
            if (!ps.PushSimpleOp(kRegexpEndText))
              return NULL;
            t.remove_prefix(2);  // '\\', 'z'
            break;
          }
          // Do not recognize \Z, because this library can't
          // implement the exact Perl/PCRE semantics.
          // (This library treats "(?-m)$" as \z, even though
          // in Perl and PCRE it is equivalent to \Z.)

          if (t[1] == 'C') {  // \C: any byte [sic]
            if (!ps.PushSimpleOp(kRegexpAnyByte))
              return NULL;
            t.remove_prefix(2);  // '\\', 'C'
            break;
          }

          if (t[1] == 'Q') {  // \Q ... \E: the ... is always literals
            t.remove_prefix(2);  // '\\', 'Q'
            while (t.size() > 0) {
              if (t.size() >= 2 && t[0] == '\\' && t[1] == 'E') {
                t.remove_prefix(2);  // '\\', 'E'
                break;
              }
              Rune r;
              if (StringPieceToRune(&r, &t, status) < 0)
                return NULL;
              if (!ps.PushLiteral(r))
                return NULL;
            }
            break;
          }
        }

        if (t.size() >= 2 && (t[1] == 'p' || t[1] == 'P')) {
          Regexp* re = new Regexp(kRegexpCharClass, ps.flags() & ~FoldCase);
          re->ccb_ = new CharClassBuilder;
          switch (ParseUnicodeGroup(&t, ps.flags(), re->ccb_, status)) {
            case kParseOk:
              if (!ps.PushRegexp(re))
                return NULL;
              goto Break2;
            case kParseError:
              re->Decref();
              return NULL;
            case kParseNothing:
              re->Decref();
              break;
          }
        }

        const UGroup *g = MaybeParsePerlCCEscape(&t, ps.flags());
        if (g != NULL) {
          Regexp* re = new Regexp(kRegexpCharClass, ps.flags() & ~FoldCase);
          re->ccb_ = new CharClassBuilder;
          AddUGroup(re->ccb_, g, g->sign, ps.flags());
          if (!ps.PushRegexp(re))
            return NULL;
          break;
        }

        Rune r;
        if (!ParseEscape(&t, &r, status, ps.rune_max()))
          return NULL;
        if (!ps.PushLiteral(r))
          return NULL;
        break;
      }
    }
  Break2:
    lastunary = isunary;
  }
  return ps.DoFinish();
}

}  // namespace re2
// GENERATED BY make_perl_groups.pl; DO NOT EDIT.
// make_perl_groups.pl >perl_groups.cc



namespace re2 {

static const URange16 code1[] = {  /* \d */
	{ 0x30, 0x39 },
};
static const URange16 code2[] = {  /* \s */
	{ 0x9, 0xa },
	{ 0xc, 0xd },
	{ 0x20, 0x20 },
};
static const URange16 code3[] = {  /* \w */
	{ 0x30, 0x39 },
	{ 0x41, 0x5a },
	{ 0x5f, 0x5f },
	{ 0x61, 0x7a },
};
const UGroup perl_groups[] = {
	{ "\\d", +1, code1, 1 },
	{ "\\D", -1, code1, 1 },
	{ "\\s", +1, code2, 3 },
	{ "\\S", -1, code2, 3 },
	{ "\\w", +1, code3, 4 },
	{ "\\W", -1, code3, 4 },
};
const int num_perl_groups = 6;
static const URange16 code4[] = {  /* [:alnum:] */
	{ 0x30, 0x39 },
	{ 0x41, 0x5a },
	{ 0x61, 0x7a },
};
static const URange16 code5[] = {  /* [:alpha:] */
	{ 0x41, 0x5a },
	{ 0x61, 0x7a },
};
static const URange16 code6[] = {  /* [:ascii:] */
	{ 0x0, 0x7f },
};
static const URange16 code7[] = {  /* [:blank:] */
	{ 0x9, 0x9 },
	{ 0x20, 0x20 },
};
static const URange16 code8[] = {  /* [:cntrl:] */
	{ 0x0, 0x1f },
	{ 0x7f, 0x7f },
};
static const URange16 code9[] = {  /* [:digit:] */
	{ 0x30, 0x39 },
};
static const URange16 code10[] = {  /* [:graph:] */
	{ 0x21, 0x7e },
};
static const URange16 code11[] = {  /* [:lower:] */
	{ 0x61, 0x7a },
};
static const URange16 code12[] = {  /* [:print:] */
	{ 0x20, 0x7e },
};
static const URange16 code13[] = {  /* [:punct:] */
	{ 0x21, 0x2f },
	{ 0x3a, 0x40 },
	{ 0x5b, 0x60 },
	{ 0x7b, 0x7e },
};
static const URange16 code14[] = {  /* [:space:] */
	{ 0x9, 0xd },
	{ 0x20, 0x20 },
};
static const URange16 code15[] = {  /* [:upper:] */
	{ 0x41, 0x5a },
};
static const URange16 code16[] = {  /* [:word:] */
	{ 0x30, 0x39 },
	{ 0x41, 0x5a },
	{ 0x5f, 0x5f },
	{ 0x61, 0x7a },
};
static const URange16 code17[] = {  /* [:xdigit:] */
	{ 0x30, 0x39 },
	{ 0x41, 0x46 },
	{ 0x61, 0x66 },
};
const UGroup posix_groups[] = {
	{ "[:alnum:]", +1, code4, 3 },
	{ "[:^alnum:]", -1, code4, 3 },
	{ "[:alpha:]", +1, code5, 2 },
	{ "[:^alpha:]", -1, code5, 2 },
	{ "[:ascii:]", +1, code6, 1 },
	{ "[:^ascii:]", -1, code6, 1 },
	{ "[:blank:]", +1, code7, 2 },
	{ "[:^blank:]", -1, code7, 2 },
	{ "[:cntrl:]", +1, code8, 2 },
	{ "[:^cntrl:]", -1, code8, 2 },
	{ "[:digit:]", +1, code9, 1 },
	{ "[:^digit:]", -1, code9, 1 },
	{ "[:graph:]", +1, code10, 1 },
	{ "[:^graph:]", -1, code10, 1 },
	{ "[:lower:]", +1, code11, 1 },
	{ "[:^lower:]", -1, code11, 1 },
	{ "[:print:]", +1, code12, 1 },
	{ "[:^print:]", -1, code12, 1 },
	{ "[:punct:]", +1, code13, 4 },
	{ "[:^punct:]", -1, code13, 4 },
	{ "[:space:]", +1, code14, 2 },
	{ "[:^space:]", -1, code14, 2 },
	{ "[:upper:]", +1, code15, 1 },
	{ "[:^upper:]", -1, code15, 1 },
	{ "[:word:]", +1, code16, 4 },
	{ "[:^word:]", -1, code16, 4 },
	{ "[:xdigit:]", +1, code17, 3 },
	{ "[:^xdigit:]", -1, code17, 3 },
};
const int num_posix_groups = 28;

}  // namespace re2
// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.



#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>









namespace re2 {

typedef std::set<std::string>::iterator SSIter;
typedef std::set<std::string>::const_iterator ConstSSIter;

// Initializes a Prefilter, allocating subs_ as necessary.
Prefilter::Prefilter(Op op) {
  op_ = op;
  subs_ = NULL;
  if (op_ == AND || op_ == OR)
    subs_ = new std::vector<Prefilter*>;
}

// Destroys a Prefilter.
Prefilter::~Prefilter() {
  if (subs_) {
    for (size_t i = 0; i < subs_->size(); i++)
      delete (*subs_)[i];
    delete subs_;
    subs_ = NULL;
  }
}

// Simplify if the node is an empty Or or And.
Prefilter* Prefilter::Simplify() {
  if (op_ != AND && op_ != OR) {
    return this;
  }

  // Nothing left in the AND/OR.
  if (subs_->empty()) {
    if (op_ == AND)
      op_ = ALL;  // AND of nothing is true
    else
      op_ = NONE;  // OR of nothing is false

    return this;
  }

  // Just one subnode: throw away wrapper.
  if (subs_->size() == 1) {
    Prefilter* a = (*subs_)[0];
    subs_->clear();
    delete this;
    return a->Simplify();
  }

  return this;
}

// Combines two Prefilters together to create an "op" (AND or OR).
// The passed Prefilters will be part of the returned Prefilter or deleted.
// Does lots of work to avoid creating unnecessarily complicated structures.
Prefilter* Prefilter::AndOr(Op op, Prefilter* a, Prefilter* b) {
  // If a, b can be rewritten as op, do so.
  a = a->Simplify();
  b = b->Simplify();

  // Canonicalize: a->op <= b->op.
  if (a->op() > b->op()) {
    Prefilter* t = a;
    a = b;
    b = t;
  }

  // Trivial cases.
  //    ALL AND b = b
  //    NONE OR b = b
  //    ALL OR b   = ALL
  //    NONE AND b = NONE
  // Don't need to look at b, because of canonicalization above.
  // ALL and NONE are smallest opcodes.
  if (a->op() == ALL || a->op() == NONE) {
    if ((a->op() == ALL && op == AND) ||
        (a->op() == NONE && op == OR)) {
      delete a;
      return b;
    } else {
      delete b;
      return a;
    }
  }

  // If a and b match op, merge their contents.
  if (a->op() == op && b->op() == op) {
    for (size_t i = 0; i < b->subs()->size(); i++) {
      Prefilter* bb = (*b->subs())[i];
      a->subs()->push_back(bb);
    }
    b->subs()->clear();
    delete b;
    return a;
  }

  // If a already has the same op as the op that is under construction
  // add in b (similarly if b already has the same op, add in a).
  if (b->op() == op) {
    Prefilter* t = a;
    a = b;
    b = t;
  }
  if (a->op() == op) {
    a->subs()->push_back(b);
    return a;
  }

  // Otherwise just return the op.
  Prefilter* c = new Prefilter(op);
  c->subs()->push_back(a);
  c->subs()->push_back(b);
  return c;
}

Prefilter* Prefilter::And(Prefilter* a, Prefilter* b) {
  return AndOr(AND, a, b);
}

Prefilter* Prefilter::Or(Prefilter* a, Prefilter* b) {
  return AndOr(OR, a, b);
}

static void SimplifyStringSet(std::set<std::string> *ss) {
  // Now make sure that the strings aren't redundant.  For example, if
  // we know "ab" is a required string, then it doesn't help at all to
  // know that "abc" is also a required string, so delete "abc". This
  // is because, when we are performing a string search to filter
  // regexps, matching ab will already allow this regexp to be a
  // candidate for match, so further matching abc is redundant.

  for (SSIter i = ss->begin(); i != ss->end(); ++i) {
    SSIter j = i;
    ++j;
    while (j != ss->end()) {
      // Increment j early so that we can erase the element it points to.
      SSIter old_j = j;
      ++j;
      if (old_j->find(*i) != std::string::npos)
        ss->erase(old_j);
    }
  }
}

Prefilter* Prefilter::OrStrings(std::set<std::string>* ss) {
  SimplifyStringSet(ss);
  Prefilter* or_prefilter = NULL;
  if (!ss->empty()) {
    or_prefilter = new Prefilter(NONE);
    for (SSIter i = ss->begin(); i != ss->end(); ++i)
      or_prefilter = Or(or_prefilter, FromString(*i));
  }
  return or_prefilter;
}

static Rune ToLowerRune(Rune r) {
  if (r < Runeself) {
    if ('A' <= r && r <= 'Z')
      r += 'a' - 'A';
    return r;
  }

  const CaseFold *f = LookupCaseFold(unicode_tolower, num_unicode_tolower, r);
  if (f == NULL || r < f->lo)
    return r;
  return ApplyFold(f, r);
}

static Rune ToLowerRuneLatin1(Rune r) {
  if ('A' <= r && r <= 'Z')
    r += 'a' - 'A';
  return r;
}

Prefilter* Prefilter::FromString(const std::string& str) {
  Prefilter* m = new Prefilter(Prefilter::ATOM);
  m->atom_ = str;
  return m;
}

// Information about a regexp used during computation of Prefilter.
// Can be thought of as information about the set of strings matching
// the given regular expression.
class Prefilter::Info {
 public:
  Info();
  ~Info();

  // More constructors.  They delete their Info* arguments.
  static Info* Alt(Info* a, Info* b);
  static Info* Concat(Info* a, Info* b);
  static Info* And(Info* a, Info* b);
  static Info* Star(Info* a);
  static Info* Plus(Info* a);
  static Info* Quest(Info* a);
  static Info* EmptyString();
  static Info* NoMatch();
  static Info* AnyCharOrAnyByte();
  static Info* CClass(CharClass* cc, bool latin1);
  static Info* Literal(Rune r);
  static Info* LiteralLatin1(Rune r);
  static Info* AnyMatch();

  // Format Info as a string.
  std::string ToString();

  // Caller takes ownership of the Prefilter.
  Prefilter* TakeMatch();

  std::set<std::string>& exact() { return exact_; }

  bool is_exact() const { return is_exact_; }

  class Walker;

 private:
  std::set<std::string> exact_;

  // When is_exact_ is true, the strings that match
  // are placed in exact_. When it is no longer an exact
  // set of strings that match this RE, then is_exact_
  // is false and the match_ contains the required match
  // criteria.
  bool is_exact_;

  // Accumulated Prefilter query that any
  // match for this regexp is guaranteed to match.
  Prefilter* match_;
};


Prefilter::Info::Info()
  : is_exact_(false),
    match_(NULL) {
}

Prefilter::Info::~Info() {
  delete match_;
}

Prefilter* Prefilter::Info::TakeMatch() {
  if (is_exact_) {
    match_ = Prefilter::OrStrings(&exact_);
    is_exact_ = false;
  }
  Prefilter* m = match_;
  match_ = NULL;
  return m;
}

// Format a Info in string form.
std::string Prefilter::Info::ToString() {
  if (is_exact_) {
    int n = 0;
    std::string s;
    for (SSIter i = exact_.begin(); i != exact_.end(); ++i) {
      if (n++ > 0)
        s += ",";
      s += *i;
    }
    return s;
  }

  if (match_)
    return match_->DebugString();

  return "";
}

// Add the strings from src to dst.
static void CopyIn(const std::set<std::string>& src,
                   std::set<std::string>* dst) {
  for (ConstSSIter i = src.begin(); i != src.end(); ++i)
    dst->insert(*i);
}

// Add the cross-product of a and b to dst.
// (For each string i in a and j in b, add i+j.)
static void CrossProduct(const std::set<std::string>& a,
                         const std::set<std::string>& b,
                         std::set<std::string>* dst) {
  for (ConstSSIter i = a.begin(); i != a.end(); ++i)
    for (ConstSSIter j = b.begin(); j != b.end(); ++j)
      dst->insert(*i + *j);
}

// Concats a and b. Requires that both are exact sets.
// Forms an exact set that is a crossproduct of a and b.
Prefilter::Info* Prefilter::Info::Concat(Info* a, Info* b) {
  if (a == NULL)
    return b;
  DCHECK(a->is_exact_);
  DCHECK(b && b->is_exact_);
  Info *ab = new Info();

  CrossProduct(a->exact_, b->exact_, &ab->exact_);
  ab->is_exact_ = true;

  delete a;
  delete b;
  return ab;
}

// Constructs an inexact Info for ab given a and b.
// Used only when a or b is not exact or when the
// exact cross product is likely to be too big.
Prefilter::Info* Prefilter::Info::And(Info* a, Info* b) {
  if (a == NULL)
    return b;
  if (b == NULL)
    return a;

  Info *ab = new Info();

  ab->match_ = Prefilter::And(a->TakeMatch(), b->TakeMatch());
  ab->is_exact_ = false;
  delete a;
  delete b;
  return ab;
}

// Constructs Info for a|b given a and b.
Prefilter::Info* Prefilter::Info::Alt(Info* a, Info* b) {
  Info *ab = new Info();

  if (a->is_exact_ && b->is_exact_) {
    CopyIn(a->exact_, &ab->exact_);
    CopyIn(b->exact_, &ab->exact_);
    ab->is_exact_ = true;
  } else {
    // Either a or b has is_exact_ = false. If the other
    // one has is_exact_ = true, we move it to match_ and
    // then create a OR of a,b. The resulting Info has
    // is_exact_ = false.
    ab->match_ = Prefilter::Or(a->TakeMatch(), b->TakeMatch());
    ab->is_exact_ = false;
  }

  delete a;
  delete b;
  return ab;
}

// Constructs Info for a? given a.
Prefilter::Info* Prefilter::Info::Quest(Info *a) {
  Info *ab = new Info();

  ab->is_exact_ = false;
  ab->match_ = new Prefilter(ALL);
  delete a;
  return ab;
}

// Constructs Info for a* given a.
// Same as a? -- not much to do.
Prefilter::Info* Prefilter::Info::Star(Info *a) {
  return Quest(a);
}

// Constructs Info for a+ given a. If a was exact set, it isn't
// anymore.
Prefilter::Info* Prefilter::Info::Plus(Info *a) {
  Info *ab = new Info();

  ab->match_ = a->TakeMatch();
  ab->is_exact_ = false;

  delete a;
  return ab;
}

static std::string RuneToString(Rune r) {
  char buf[UTFmax];
  int n = runetochar(buf, &r);
  return std::string(buf, n);
}

static std::string RuneToStringLatin1(Rune r) {
  char c = r & 0xff;
  return std::string(&c, 1);
}

// Constructs Info for literal rune.
Prefilter::Info* Prefilter::Info::Literal(Rune r) {
  Info* info = new Info();
  info->exact_.insert(RuneToString(ToLowerRune(r)));
  info->is_exact_ = true;
  return info;
}

// Constructs Info for literal rune for Latin1 encoded string.
Prefilter::Info* Prefilter::Info::LiteralLatin1(Rune r) {
  Info* info = new Info();
  info->exact_.insert(RuneToStringLatin1(ToLowerRuneLatin1(r)));
  info->is_exact_ = true;
  return info;
}

// Constructs Info for dot (any character) or \C (any byte).
Prefilter::Info* Prefilter::Info::AnyCharOrAnyByte() {
  Prefilter::Info* info = new Prefilter::Info();
  info->match_ = new Prefilter(ALL);
  return info;
}

// Constructs Prefilter::Info for no possible match.
Prefilter::Info* Prefilter::Info::NoMatch() {
  Prefilter::Info* info = new Prefilter::Info();
  info->match_ = new Prefilter(NONE);
  return info;
}

// Constructs Prefilter::Info for any possible match.
// This Prefilter::Info is valid for any regular expression,
// since it makes no assertions whatsoever about the
// strings being matched.
Prefilter::Info* Prefilter::Info::AnyMatch() {
  Prefilter::Info *info = new Prefilter::Info();
  info->match_ = new Prefilter(ALL);
  return info;
}

// Constructs Prefilter::Info for just the empty string.
Prefilter::Info* Prefilter::Info::EmptyString() {
  Prefilter::Info* info = new Prefilter::Info();
  info->is_exact_ = true;
  info->exact_.insert("");
  return info;
}

// Constructs Prefilter::Info for a character class.
typedef CharClass::iterator CCIter;
Prefilter::Info* Prefilter::Info::CClass(CharClass *cc,
                                         bool latin1) {
  // If the class is too large, it's okay to overestimate.
  if (cc->size() > 10)
    return AnyCharOrAnyByte();

  Prefilter::Info *a = new Prefilter::Info();
  for (CCIter i = cc->begin(); i != cc->end(); ++i)
    for (Rune r = i->lo; r <= i->hi; r++) {
      if (latin1) {
        a->exact_.insert(RuneToStringLatin1(ToLowerRuneLatin1(r)));
      } else {
        a->exact_.insert(RuneToString(ToLowerRune(r)));
      }
    }


  a->is_exact_ = true;

  return a;
}

class Prefilter::Info::Walker : public Regexp::Walker<Prefilter::Info*> {
 public:
  Walker(bool latin1) : latin1_(latin1) {}

  virtual Info* PostVisit(
      Regexp* re, Info* parent_arg,
      Info* pre_arg,
      Info** child_args, int nchild_args);

  virtual Info* ShortVisit(
      Regexp* re,
      Info* parent_arg);

  bool latin1() { return latin1_; }
 private:
  bool latin1_;

  Walker(const Walker&) = delete;
  Walker& operator=(const Walker&) = delete;
};

Prefilter::Info* Prefilter::BuildInfo(Regexp* re) {
  bool latin1 = (re->parse_flags() & Regexp::Latin1) != 0;
  Prefilter::Info::Walker w(latin1);
  Prefilter::Info* info = w.WalkExponential(re, NULL, 100000);

  if (w.stopped_early()) {
    delete info;
    return NULL;
  }

  return info;
}

Prefilter::Info* Prefilter::Info::Walker::ShortVisit(
    Regexp* re, Prefilter::Info* parent_arg) {
  return AnyMatch();
}

// Constructs the Prefilter::Info for the given regular expression.
// Assumes re is simplified.
Prefilter::Info* Prefilter::Info::Walker::PostVisit(
    Regexp* re, Prefilter::Info* parent_arg,
    Prefilter::Info* pre_arg, Prefilter::Info** child_args,
    int nchild_args) {
  Prefilter::Info *info;
  switch (re->op()) {
    default:
    case kRegexpRepeat:
      LOG(DFATAL) << "Bad regexp op " << re->op();
      info = EmptyString();
      break;

    case kRegexpNoMatch:
      info = NoMatch();
      break;

    // These ops match the empty string:
    case kRegexpEmptyMatch:      // anywhere
    case kRegexpBeginLine:       // at beginning of line
    case kRegexpEndLine:         // at end of line
    case kRegexpBeginText:       // at beginning of text
    case kRegexpEndText:         // at end of text
    case kRegexpWordBoundary:    // at word boundary
    case kRegexpNoWordBoundary:  // not at word boundary
      info = EmptyString();
      break;

    case kRegexpLiteral:
      if (latin1()) {
        info = LiteralLatin1(re->rune());
      }
      else {
        info = Literal(re->rune());
      }
      break;

    case kRegexpLiteralString:
      if (re->nrunes() == 0) {
        info = NoMatch();
        break;
      }
      if (latin1()) {
        info = LiteralLatin1(re->runes()[0]);
        for (int i = 1; i < re->nrunes(); i++) {
          info = Concat(info, LiteralLatin1(re->runes()[i]));
        }
      } else {
        info = Literal(re->runes()[0]);
        for (int i = 1; i < re->nrunes(); i++) {
          info = Concat(info, Literal(re->runes()[i]));
        }
      }
      break;

    case kRegexpConcat: {
      // Accumulate in info.
      // Exact is concat of recent contiguous exact nodes.
      info = NULL;
      Info* exact = NULL;
      for (int i = 0; i < nchild_args; i++) {
        Info* ci = child_args[i];  // child info
        if (!ci->is_exact() ||
            (exact && ci->exact().size() * exact->exact().size() > 16)) {
          // Exact run is over.
          info = And(info, exact);
          exact = NULL;
          // Add this child's info.
          info = And(info, ci);
        } else {
          // Append to exact run.
          exact = Concat(exact, ci);
        }
      }
      info = And(info, exact);
    }
      break;

    case kRegexpAlternate:
      info = child_args[0];
      for (int i = 1; i < nchild_args; i++)
        info = Alt(info, child_args[i]);
      break;

    case kRegexpStar:
      info = Star(child_args[0]);
      break;

    case kRegexpQuest:
      info = Quest(child_args[0]);
      break;

    case kRegexpPlus:
      info = Plus(child_args[0]);
      break;

    case kRegexpAnyChar:
    case kRegexpAnyByte:
      // Claim nothing, except that it's not empty.
      info = AnyCharOrAnyByte();
      break;

    case kRegexpCharClass:
      info = CClass(re->cc(), latin1());
      break;

    case kRegexpCapture:
      // These don't affect the set of matching strings.
      info = child_args[0];
      break;
  }

  return info;
}


Prefilter* Prefilter::FromRegexp(Regexp* re) {
  if (re == NULL)
    return NULL;

  Regexp* simple = re->Simplify();
  Prefilter::Info *info = BuildInfo(simple);

  simple->Decref();
  if (info == NULL)
    return NULL;

  Prefilter* m = info->TakeMatch();

  delete info;
  return m;
}

std::string Prefilter::DebugString() const {
  switch (op_) {
    default:
      LOG(DFATAL) << "Bad op in Prefilter::DebugString: " << op_;
      return StringPrintf("op%d", op_);
    case NONE:
      return "*no-matches*";
    case ATOM:
      return atom_;
    case ALL:
      return "";
    case AND: {
      std::string s = "";
      for (size_t i = 0; i < subs_->size(); i++) {
        if (i > 0)
          s += " ";
        Prefilter* sub = (*subs_)[i];
        s += sub ? sub->DebugString() : "<nil>";
      }
      return s;
    }
    case OR: {
      std::string s = "(";
      for (size_t i = 0; i < subs_->size(); i++) {
        if (i > 0)
          s += "|";
        Prefilter* sub = (*subs_)[i];
        s += sub ? sub->DebugString() : "<nil>";
      }
      s += ")";
      return s;
    }
  }
}

Prefilter* Prefilter::FromRE2(const RE2* re2) {
  if (re2 == NULL)
    return NULL;

  Regexp* regexp = re2->Regexp();
  if (regexp == NULL)
    return NULL;

  return FromRegexp(regexp);
}


}  // namespace re2
// Copyright 2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.



#include <stddef.h>
#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>







namespace re2 {

PrefilterTree::PrefilterTree()
    : compiled_(false),
      min_atom_len_(3) {
}

PrefilterTree::PrefilterTree(int min_atom_len)
    : compiled_(false),
      min_atom_len_(min_atom_len) {
}

PrefilterTree::~PrefilterTree() {
  for (size_t i = 0; i < prefilter_vec_.size(); i++)
    delete prefilter_vec_[i];

  for (size_t i = 0; i < entries_.size(); i++)
    delete entries_[i].parents;
}

void PrefilterTree::Add(Prefilter* prefilter) {
  if (compiled_) {
    LOG(DFATAL) << "Add called after Compile.";
    return;
  }
  if (prefilter != NULL && !KeepNode(prefilter)) {
    delete prefilter;
    prefilter = NULL;
  }

  prefilter_vec_.push_back(prefilter);
}

void PrefilterTree::Compile(std::vector<std::string>* atom_vec) {
  if (compiled_) {
    LOG(DFATAL) << "Compile called already.";
    return;
  }

  // Some legacy users of PrefilterTree call Compile() before
  // adding any regexps and expect Compile() to have no effect.
  if (prefilter_vec_.empty())
    return;

  compiled_ = true;

  // TODO(junyer): Use std::unordered_set<Prefilter*> instead?
  NodeMap nodes;
  AssignUniqueIds(&nodes, atom_vec);

  // Identify nodes that are too common among prefilters and are
  // triggering too many parents. Then get rid of them if possible.
  // Note that getting rid of a prefilter node simply means they are
  // no longer necessary for their parent to trigger; that is, we do
  // not miss out on any regexps triggering by getting rid of a
  // prefilter node.
  for (size_t i = 0; i < entries_.size(); i++) {
    StdIntMap* parents = entries_[i].parents;
    if (parents->size() > 8) {
      // This one triggers too many things. If all the parents are AND
      // nodes and have other things guarding them, then get rid of
      // this trigger. TODO(vsri): Adjust the threshold appropriately,
      // make it a function of total number of nodes?
      bool have_other_guard = true;
      for (StdIntMap::iterator it = parents->begin();
           it != parents->end(); ++it) {
        have_other_guard = have_other_guard &&
            (entries_[it->first].propagate_up_at_count > 1);
      }

      if (have_other_guard) {
        for (StdIntMap::iterator it = parents->begin();
             it != parents->end(); ++it)
          entries_[it->first].propagate_up_at_count -= 1;

        parents->clear();  // Forget the parents
      }
    }
  }
}

Prefilter* PrefilterTree::CanonicalNode(NodeMap* nodes, Prefilter* node) {
  std::string node_string = NodeString(node);
  std::map<std::string, Prefilter*>::iterator iter = nodes->find(node_string);
  if (iter == nodes->end())
    return NULL;
  return (*iter).second;
}

std::string PrefilterTree::NodeString(Prefilter* node) const {
  // Adding the operation disambiguates AND/OR/atom nodes.
  std::string s = StringPrintf("%d", node->op()) + ":";
  if (node->op() == Prefilter::ATOM) {
    s += node->atom();
  } else {
    for (size_t i = 0; i < node->subs()->size(); i++) {
      if (i > 0)
        s += ',';
      s += StringPrintf("%d", (*node->subs())[i]->unique_id());
    }
  }
  return s;
}

bool PrefilterTree::KeepNode(Prefilter* node) const {
  if (node == NULL)
    return false;

  switch (node->op()) {
    default:
      LOG(DFATAL) << "Unexpected op in KeepNode: " << node->op();
      return false;

    case Prefilter::ALL:
    case Prefilter::NONE:
      return false;

    case Prefilter::ATOM:
      return node->atom().size() >= static_cast<size_t>(min_atom_len_);

    case Prefilter::AND: {
      int j = 0;
      std::vector<Prefilter*>* subs = node->subs();
      for (size_t i = 0; i < subs->size(); i++)
        if (KeepNode((*subs)[i]))
          (*subs)[j++] = (*subs)[i];
        else
          delete (*subs)[i];

      subs->resize(j);
      return j > 0;
    }

    case Prefilter::OR:
      for (size_t i = 0; i < node->subs()->size(); i++)
        if (!KeepNode((*node->subs())[i]))
          return false;
      return true;
  }
}

void PrefilterTree::AssignUniqueIds(NodeMap* nodes,
                                    std::vector<std::string>* atom_vec) {
  atom_vec->clear();

  // Build vector of all filter nodes, sorted topologically
  // from top to bottom in v.
  std::vector<Prefilter*> v;

  // Add the top level nodes of each regexp prefilter.
  for (size_t i = 0; i < prefilter_vec_.size(); i++) {
    Prefilter* f = prefilter_vec_[i];
    if (f == NULL)
      unfiltered_.push_back(static_cast<int>(i));

    // We push NULL also on to v, so that we maintain the
    // mapping of index==regexpid for level=0 prefilter nodes.
    v.push_back(f);
  }

  // Now add all the descendant nodes.
  for (size_t i = 0; i < v.size(); i++) {
    Prefilter* f = v[i];
    if (f == NULL)
      continue;
    if (f->op() == Prefilter::AND || f->op() == Prefilter::OR) {
      const std::vector<Prefilter*>& subs = *f->subs();
      for (size_t j = 0; j < subs.size(); j++)
        v.push_back(subs[j]);
    }
  }

  // Identify unique nodes.
  int unique_id = 0;
  for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
    Prefilter *node = v[i];
    if (node == NULL)
      continue;
    node->set_unique_id(-1);
    Prefilter* canonical = CanonicalNode(nodes, node);
    if (canonical == NULL) {
      // Any further nodes that have the same node string
      // will find this node as the canonical node.
      nodes->emplace(NodeString(node), node);
      if (node->op() == Prefilter::ATOM) {
        atom_vec->push_back(node->atom());
        atom_index_to_id_.push_back(unique_id);
      }
      node->set_unique_id(unique_id++);
    } else {
      node->set_unique_id(canonical->unique_id());
    }
  }
  entries_.resize(nodes->size());

  // Create parent StdIntMap for the entries.
  for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
    Prefilter* prefilter = v[i];
    if (prefilter == NULL)
      continue;

    if (CanonicalNode(nodes, prefilter) != prefilter)
      continue;

    Entry* entry = &entries_[prefilter->unique_id()];
    entry->parents = new StdIntMap();
  }

  // Fill the entries.
  for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
    Prefilter* prefilter = v[i];
    if (prefilter == NULL)
      continue;

    if (CanonicalNode(nodes, prefilter) != prefilter)
      continue;

    Entry* entry = &entries_[prefilter->unique_id()];

    switch (prefilter->op()) {
      default:
      case Prefilter::ALL:
        LOG(DFATAL) << "Unexpected op: " << prefilter->op();
        return;

      case Prefilter::ATOM:
        entry->propagate_up_at_count = 1;
        break;

      case Prefilter::OR:
      case Prefilter::AND: {
        std::set<int> uniq_child;
        for (size_t j = 0; j < prefilter->subs()->size(); j++) {
          Prefilter* child = (*prefilter->subs())[j];
          Prefilter* canonical = CanonicalNode(nodes, child);
          if (canonical == NULL) {
            LOG(DFATAL) << "Null canonical node";
            return;
          }
          int child_id = canonical->unique_id();
          uniq_child.insert(child_id);
          // To the child, we want to add to parent indices.
          Entry* child_entry = &entries_[child_id];
          if (child_entry->parents->find(prefilter->unique_id()) ==
              child_entry->parents->end()) {
            (*child_entry->parents)[prefilter->unique_id()] = 1;
          }
        }
        entry->propagate_up_at_count = prefilter->op() == Prefilter::AND
                                           ? static_cast<int>(uniq_child.size())
                                           : 1;

        break;
      }
    }
  }

  // For top level nodes, populate regexp id.
  for (size_t i = 0; i < prefilter_vec_.size(); i++) {
    if (prefilter_vec_[i] == NULL)
      continue;
    int id = CanonicalNode(nodes, prefilter_vec_[i])->unique_id();
    DCHECK_LE(0, id);
    Entry* entry = &entries_[id];
    entry->regexps.push_back(static_cast<int>(i));
  }
}

// Functions for triggering during search.
void PrefilterTree::RegexpsGivenStrings(
    const std::vector<int>& matched_atoms,
    std::vector<int>* regexps) const {
  regexps->clear();
  if (!compiled_) {
    // Some legacy users of PrefilterTree call Compile() before
    // adding any regexps and expect Compile() to have no effect.
    // This kludge is a counterpart to that kludge.
    if (prefilter_vec_.empty())
      return;

    LOG(ERROR) << "RegexpsGivenStrings called before Compile.";
    for (size_t i = 0; i < prefilter_vec_.size(); i++)
      regexps->push_back(static_cast<int>(i));
  } else {
    IntMap regexps_map(static_cast<int>(prefilter_vec_.size()));
    std::vector<int> matched_atom_ids;
    for (size_t j = 0; j < matched_atoms.size(); j++)
      matched_atom_ids.push_back(atom_index_to_id_[matched_atoms[j]]);
    PropagateMatch(matched_atom_ids, &regexps_map);
    for (IntMap::iterator it = regexps_map.begin();
         it != regexps_map.end();
         ++it)
      regexps->push_back(it->index());

    regexps->insert(regexps->end(), unfiltered_.begin(), unfiltered_.end());
  }
  std::sort(regexps->begin(), regexps->end());
}

void PrefilterTree::PropagateMatch(const std::vector<int>& atom_ids,
                                   IntMap* regexps) const {
  IntMap count(static_cast<int>(entries_.size()));
  IntMap work(static_cast<int>(entries_.size()));
  for (size_t i = 0; i < atom_ids.size(); i++)
    work.set(atom_ids[i], 1);
  for (IntMap::iterator it = work.begin(); it != work.end(); ++it) {
    const Entry& entry = entries_[it->index()];
    // Record regexps triggered.
    for (size_t i = 0; i < entry.regexps.size(); i++)
      regexps->set(entry.regexps[i], 1);
    int c;
    // Pass trigger up to parents.
    for (StdIntMap::iterator it = entry.parents->begin();
         it != entry.parents->end();
         ++it) {
      int j = it->first;
      const Entry& parent = entries_[j];
      // Delay until all the children have succeeded.
      if (parent.propagate_up_at_count > 1) {
        if (count.has_index(j)) {
          c = count.get_existing(j) + 1;
          count.set_existing(j, c);
        } else {
          c = 1;
          count.set_new(j, c);
        }
        if (c < parent.propagate_up_at_count)
          continue;
      }
      // Trigger the parent.
      work.set(j, 1);
    }
  }
}

// Debugging help.
void PrefilterTree::PrintPrefilter(int regexpid) {
  LOG(ERROR) << DebugNodeString(prefilter_vec_[regexpid]);
}

void PrefilterTree::PrintDebugInfo(NodeMap* nodes) {
  LOG(ERROR) << "#Unique Atoms: " << atom_index_to_id_.size();
  LOG(ERROR) << "#Unique Nodes: " << entries_.size();

  for (size_t i = 0; i < entries_.size(); i++) {
    StdIntMap* parents = entries_[i].parents;
    const std::vector<int>& regexps = entries_[i].regexps;
    LOG(ERROR) << "EntryId: " << i
               << " N: " << parents->size() << " R: " << regexps.size();
    for (StdIntMap::iterator it = parents->begin(); it != parents->end(); ++it)
      LOG(ERROR) << it->first;
  }
  LOG(ERROR) << "Map:";
  for (std::map<std::string, Prefilter*>::const_iterator iter = nodes->begin();
       iter != nodes->end(); ++iter)
    LOG(ERROR) << "NodeId: " << (*iter).second->unique_id()
               << " Str: " << (*iter).first;
}

std::string PrefilterTree::DebugNodeString(Prefilter* node) const {
  std::string node_string = "";
  if (node->op() == Prefilter::ATOM) {
    DCHECK(!node->atom().empty());
    node_string += node->atom();
  } else {
    // Adding the operation disambiguates AND and OR nodes.
    node_string +=  node->op() == Prefilter::AND ? "AND" : "OR";
    node_string += "(";
    for (size_t i = 0; i < node->subs()->size(); i++) {
      if (i > 0)
        node_string += ',';
      node_string += StringPrintf("%d", (*node->subs())[i]->unique_id());
      node_string += ":";
      node_string += DebugNodeString((*node->subs())[i]);
    }
    node_string += ")";
  }
  return node_string;
}

}  // namespace re2
// Copyright 2007 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Compiled regular expression representation.
// Tested by compile_test.cc



#include <stdint.h>
#include <string.h>
#include <algorithm>
#include <memory>
#include <utility>




// Copyright 2016 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_BITMAP256_H_
#define RE2_BITMAP256_H_

#ifdef _MSC_VER
#include <intrin.h>
#endif
#include <stdint.h>
#include <string.h>




namespace re2 {

class Bitmap256 {
 public:
  Bitmap256() {
    Clear();
  }

  // Clears all of the bits.
  void Clear() {
    memset(words_, 0, sizeof words_);
  }

  // Tests the bit with index c.
  bool Test(int c) const {
    DCHECK_GE(c, 0);
    DCHECK_LE(c, 255);

    return (words_[c / 64] & (1ULL << (c % 64))) != 0;
  }

  // Sets the bit with index c.
  void Set(int c) {
    DCHECK_GE(c, 0);
    DCHECK_LE(c, 255);

    words_[c / 64] |= (1ULL << (c % 64));
  }

  // Finds the next non-zero bit with index >= c.
  // Returns -1 if no such bit exists.
  int FindNextSetBit(int c) const;

 private:
  // Finds the least significant non-zero bit in n.
  static int FindLSBSet(uint64_t n) {
    DCHECK_NE(n, 0);

#if defined(__GNUC__)
    return __builtin_ctzll(n);
#elif defined(_MSC_VER) && defined(_M_X64)
    unsigned long c;
    _BitScanForward64(&c, n);
    return static_cast<int>(c);
#elif defined(_MSC_VER) && defined(_M_IX86)
    unsigned long c;
    if (static_cast<uint32_t>(n) != 0) {
      _BitScanForward(&c, static_cast<uint32_t>(n));
      return static_cast<int>(c);
    } else {
      _BitScanForward(&c, static_cast<uint32_t>(n >> 32));
      return static_cast<int>(c) + 32;
    }
#else
    int c = 63;
    for (int shift = 1 << 5; shift != 0; shift >>= 1) {
      uint64_t word = n << shift;
      if (word != 0) {
        n = word;
        c -= shift;
      }
    }
    return c;
#endif
  }

  uint64_t words_[4];
};

int Bitmap256::FindNextSetBit(int c) const {
  DCHECK_GE(c, 0);
  DCHECK_LE(c, 255);

  // Check the word that contains the bit. Mask out any lower bits.
  int i = c / 64;
  uint64_t word = words_[i] & (~0ULL << (c % 64));
  if (word != 0)
    return (i * 64) + FindLSBSet(word);

  // Check any following words.
  i++;
  switch (i) {
    case 1:
      if (words_[1] != 0)
        return (1 * 64) + FindLSBSet(words_[1]);
      FALLTHROUGH_INTENDED;
    case 2:
      if (words_[2] != 0)
        return (2 * 64) + FindLSBSet(words_[2]);
      FALLTHROUGH_INTENDED;
    case 3:
      if (words_[3] != 0)
        return (3 * 64) + FindLSBSet(words_[3]);
      FALLTHROUGH_INTENDED;
    default:
      return -1;
  }
}

}  // namespace re2

#endif  // RE2_BITMAP256_H_



namespace re2 {

// Constructors per Inst opcode

void Prog::Inst::InitAlt(uint32_t out, uint32_t out1) {
  DCHECK_EQ(out_opcode_, 0);
  set_out_opcode(out, kInstAlt);
  out1_ = out1;
}

void Prog::Inst::InitByteRange(int lo, int hi, int foldcase, uint32_t out) {
  DCHECK_EQ(out_opcode_, 0);
  set_out_opcode(out, kInstByteRange);
  lo_ = lo & 0xFF;
  hi_ = hi & 0xFF;
  hint_foldcase_ = foldcase&1;
}

void Prog::Inst::InitCapture(int cap, uint32_t out) {
  DCHECK_EQ(out_opcode_, 0);
  set_out_opcode(out, kInstCapture);
  cap_ = cap;
}

void Prog::Inst::InitEmptyWidth(EmptyOp empty, uint32_t out) {
  DCHECK_EQ(out_opcode_, 0);
  set_out_opcode(out, kInstEmptyWidth);
  empty_ = empty;
}

void Prog::Inst::InitMatch(int32_t id) {
  DCHECK_EQ(out_opcode_, 0);
  set_opcode(kInstMatch);
  match_id_ = id;
}

void Prog::Inst::InitNop(uint32_t out) {
  DCHECK_EQ(out_opcode_, 0);
  set_opcode(kInstNop);
}

void Prog::Inst::InitFail() {
  DCHECK_EQ(out_opcode_, 0);
  set_opcode(kInstFail);
}

std::string Prog::Inst::Dump() {
  switch (opcode()) {
    default:
      return StringPrintf("opcode %d", static_cast<int>(opcode()));

    case kInstAlt:
      return StringPrintf("alt -> %d | %d", out(), out1_);

    case kInstAltMatch:
      return StringPrintf("altmatch -> %d | %d", out(), out1_);

    case kInstByteRange:
      return StringPrintf("byte%s [%02x-%02x] %d -> %d",
                          foldcase() ? "/i" : "",
                          lo_, hi_, hint(), out());

    case kInstCapture:
      return StringPrintf("capture %d -> %d", cap_, out());

    case kInstEmptyWidth:
      return StringPrintf("emptywidth %#x -> %d",
                          static_cast<int>(empty_), out());

    case kInstMatch:
      return StringPrintf("match! %d", match_id());

    case kInstNop:
      return StringPrintf("nop -> %d", out());

    case kInstFail:
      return StringPrintf("fail");
  }
}

Prog::Prog()
  : anchor_start_(false),
    anchor_end_(false),
    reversed_(false),
    did_flatten_(false),
    did_onepass_(false),
    start_(0),
    start_unanchored_(0),
    size_(0),
    bytemap_range_(0),
    first_byte_(-1),
    flags_(0),
    list_count_(0),
    dfa_mem_(0),
    dfa_first_(NULL),
    dfa_longest_(NULL) {
}

Prog::~Prog() {
  DeleteDFA(dfa_longest_);
  DeleteDFA(dfa_first_);
}

typedef SparseSet Workq;

static inline void AddToQueue(Workq* q, int id) {
  if (id != 0)
    q->insert(id);
}

static std::string ProgToString(Prog* prog, Workq* q) {
  std::string s;
  for (Workq::iterator i = q->begin(); i != q->end(); ++i) {
    int id = *i;
    Prog::Inst* ip = prog->inst(id);
    StringAppendF(&s, "%d. %s\n", id, ip->Dump().c_str());
    AddToQueue(q, ip->out());
    if (ip->opcode() == kInstAlt || ip->opcode() == kInstAltMatch)
      AddToQueue(q, ip->out1());
  }
  return s;
}

static std::string FlattenedProgToString(Prog* prog, int start) {
  std::string s;
  for (int id = start; id < prog->size(); id++) {
    Prog::Inst* ip = prog->inst(id);
    if (ip->last())
      StringAppendF(&s, "%d. %s\n", id, ip->Dump().c_str());
    else
      StringAppendF(&s, "%d+ %s\n", id, ip->Dump().c_str());
  }
  return s;
}

std::string Prog::Dump() {
  if (did_flatten_)
    return FlattenedProgToString(this, start_);

  Workq q(size_);
  AddToQueue(&q, start_);
  return ProgToString(this, &q);
}

std::string Prog::DumpUnanchored() {
  if (did_flatten_)
    return FlattenedProgToString(this, start_unanchored_);

  Workq q(size_);
  AddToQueue(&q, start_unanchored_);
  return ProgToString(this, &q);
}

std::string Prog::DumpByteMap() {
  std::string map;
  for (int c = 0; c < 256; c++) {
    int b = bytemap_[c];
    int lo = c;
    while (c < 256-1 && bytemap_[c+1] == b)
      c++;
    int hi = c;
    StringAppendF(&map, "[%02x-%02x] -> %d\n", lo, hi, b);
  }
  return map;
}

int Prog::first_byte() {
  std::call_once(first_byte_once_, [](Prog* prog) {
    prog->first_byte_ = prog->ComputeFirstByte();
  }, this);
  return first_byte_;
}

static bool IsMatch(Prog*, Prog::Inst*);

// Peep-hole optimizer.
void Prog::Optimize() {
  Workq q(size_);

  // Eliminate nops.  Most are taken out during compilation
  // but a few are hard to avoid.
  q.clear();
  AddToQueue(&q, start_);
  for (Workq::iterator i = q.begin(); i != q.end(); ++i) {
    int id = *i;

    Inst* ip = inst(id);
    int j = ip->out();
    Inst* jp;
    while (j != 0 && (jp=inst(j))->opcode() == kInstNop) {
      j = jp->out();
    }
    ip->set_out(j);
    AddToQueue(&q, ip->out());

    if (ip->opcode() == kInstAlt) {
      j = ip->out1();
      while (j != 0 && (jp=inst(j))->opcode() == kInstNop) {
        j = jp->out();
      }
      ip->out1_ = j;
      AddToQueue(&q, ip->out1());
    }
  }

  // Insert kInstAltMatch instructions
  // Look for
  //   ip: Alt -> j | k
  //	  j: ByteRange [00-FF] -> ip
  //    k: Match
  // or the reverse (the above is the greedy one).
  // Rewrite Alt to AltMatch.
  q.clear();
  AddToQueue(&q, start_);
  for (Workq::iterator i = q.begin(); i != q.end(); ++i) {
    int id = *i;
    Inst* ip = inst(id);
    AddToQueue(&q, ip->out());
    if (ip->opcode() == kInstAlt)
      AddToQueue(&q, ip->out1());

    if (ip->opcode() == kInstAlt) {
      Inst* j = inst(ip->out());
      Inst* k = inst(ip->out1());
      if (j->opcode() == kInstByteRange && j->out() == id &&
          j->lo() == 0x00 && j->hi() == 0xFF &&
          IsMatch(this, k)) {
        ip->set_opcode(kInstAltMatch);
        continue;
      }
      if (IsMatch(this, j) &&
          k->opcode() == kInstByteRange && k->out() == id &&
          k->lo() == 0x00 && k->hi() == 0xFF) {
        ip->set_opcode(kInstAltMatch);
      }
    }
  }
}

// Is ip a guaranteed match at end of text, perhaps after some capturing?
static bool IsMatch(Prog* prog, Prog::Inst* ip) {
  for (;;) {
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "Unexpected opcode in IsMatch: " << ip->opcode();
        return false;

      case kInstAlt:
      case kInstAltMatch:
      case kInstByteRange:
      case kInstFail:
      case kInstEmptyWidth:
        return false;

      case kInstCapture:
      case kInstNop:
        ip = prog->inst(ip->out());
        break;

      case kInstMatch:
        return true;
    }
  }
}

uint32_t Prog::EmptyFlags(const StringPiece& text, const char* p) {
  int flags = 0;

  // ^ and \A
  if (p == text.begin())
    flags |= kEmptyBeginText | kEmptyBeginLine;
  else if (p[-1] == '\n')
    flags |= kEmptyBeginLine;

  // $ and \z
  if (p == text.end())
    flags |= kEmptyEndText | kEmptyEndLine;
  else if (p < text.end() && p[0] == '\n')
    flags |= kEmptyEndLine;

  // \b and \B
  if (p == text.begin() && p == text.end()) {
    // no word boundary here
  } else if (p == text.begin()) {
    if (IsWordChar(p[0]))
      flags |= kEmptyWordBoundary;
  } else if (p == text.end()) {
    if (IsWordChar(p[-1]))
      flags |= kEmptyWordBoundary;
  } else {
    if (IsWordChar(p[-1]) != IsWordChar(p[0]))
      flags |= kEmptyWordBoundary;
  }
  if (!(flags & kEmptyWordBoundary))
    flags |= kEmptyNonWordBoundary;

  return flags;
}

// ByteMapBuilder implements a coloring algorithm.
//
// The first phase is a series of "mark and merge" batches: we mark one or more
// [lo-hi] ranges, then merge them into our internal state. Batching is not for
// performance; rather, it means that the ranges are treated indistinguishably.
//
// Internally, the ranges are represented using a bitmap that stores the splits
// and a vector that stores the colors; both of them are indexed by the ranges'
// last bytes. Thus, in order to merge a [lo-hi] range, we split at lo-1 and at
// hi (if not already split), then recolor each range in between. The color map
// (i.e. from the old color to the new color) is maintained for the lifetime of
// the batch and so underpins this somewhat obscure approach to set operations.
//
// The second phase builds the bytemap from our internal state: we recolor each
// range, then store the new color (which is now the byte class) in each of the
// corresponding array elements. Finally, we output the number of byte classes.
class ByteMapBuilder {
 public:
  ByteMapBuilder() {
    // Initial state: the [0-255] range has color 256.
    // This will avoid problems during the second phase,
    // in which we assign byte classes numbered from 0.
    splits_.Set(255);
    colors_[255] = 256;
    nextcolor_ = 257;
  }

  void Mark(int lo, int hi);
  void Merge();
  void Build(uint8_t* bytemap, int* bytemap_range);

 private:
  int Recolor(int oldcolor);

  Bitmap256 splits_;
  int colors_[256];
  int nextcolor_;
  std::vector<std::pair<int, int>> colormap_;
  std::vector<std::pair<int, int>> ranges_;

  ByteMapBuilder(const ByteMapBuilder&) = delete;
  ByteMapBuilder& operator=(const ByteMapBuilder&) = delete;
};

void ByteMapBuilder::Mark(int lo, int hi) {
  DCHECK_GE(lo, 0);
  DCHECK_GE(hi, 0);
  DCHECK_LE(lo, 255);
  DCHECK_LE(hi, 255);
  DCHECK_LE(lo, hi);

  // Ignore any [0-255] ranges. They cause us to recolor every range, which
  // has no effect on the eventual result and is therefore a waste of time.
  if (lo == 0 && hi == 255)
    return;

  ranges_.emplace_back(lo, hi);
}

void ByteMapBuilder::Merge() {
  for (std::vector<std::pair<int, int>>::const_iterator it = ranges_.begin();
       it != ranges_.end();
       ++it) {
    int lo = it->first-1;
    int hi = it->second;

    if (0 <= lo && !splits_.Test(lo)) {
      splits_.Set(lo);
      int next = splits_.FindNextSetBit(lo+1);
      colors_[lo] = colors_[next];
    }
    if (!splits_.Test(hi)) {
      splits_.Set(hi);
      int next = splits_.FindNextSetBit(hi+1);
      colors_[hi] = colors_[next];
    }

    int c = lo+1;
    while (c < 256) {
      int next = splits_.FindNextSetBit(c);
      colors_[next] = Recolor(colors_[next]);
      if (next == hi)
        break;
      c = next+1;
    }
  }
  colormap_.clear();
  ranges_.clear();
}

void ByteMapBuilder::Build(uint8_t* bytemap, int* bytemap_range) {
  // Assign byte classes numbered from 0.
  nextcolor_ = 0;

  int c = 0;
  while (c < 256) {
    int next = splits_.FindNextSetBit(c);
    uint8_t b = static_cast<uint8_t>(Recolor(colors_[next]));
    while (c <= next) {
      bytemap[c] = b;
      c++;
    }
  }

  *bytemap_range = nextcolor_;
}

int ByteMapBuilder::Recolor(int oldcolor) {
  // Yes, this is a linear search. There can be at most 256
  // colors and there will typically be far fewer than that.
  // Also, we need to consider keys *and* values in order to
  // avoid recoloring a given range more than once per batch.
  std::vector<std::pair<int, int>>::const_iterator it =
      std::find_if(colormap_.begin(), colormap_.end(),
                   [=](const std::pair<int, int>& kv) -> bool {
                     return kv.first == oldcolor || kv.second == oldcolor;
                   });
  if (it != colormap_.end())
    return it->second;
  int newcolor = nextcolor_;
  nextcolor_++;
  colormap_.emplace_back(oldcolor, newcolor);
  return newcolor;
}

void Prog::ComputeByteMap() {
  // Fill in bytemap with byte classes for the program.
  // Ranges of bytes that are treated indistinguishably
  // will be mapped to a single byte class.
  ByteMapBuilder builder;

  // Don't repeat the work for ^ and $.
  bool marked_line_boundaries = false;
  // Don't repeat the work for \b and \B.
  bool marked_word_boundaries = false;

  for (int id = 0; id < size(); id++) {
    Inst* ip = inst(id);
    if (ip->opcode() == kInstByteRange) {
      int lo = ip->lo();
      int hi = ip->hi();
      builder.Mark(lo, hi);
      if (ip->foldcase() && lo <= 'z' && hi >= 'a') {
        int foldlo = lo;
        int foldhi = hi;
        if (foldlo < 'a')
          foldlo = 'a';
        if (foldhi > 'z')
          foldhi = 'z';
        if (foldlo <= foldhi) {
          foldlo += 'A' - 'a';
          foldhi += 'A' - 'a';
          builder.Mark(foldlo, foldhi);
        }
      }
      // If this Inst is not the last Inst in its list AND the next Inst is
      // also a ByteRange AND the Insts have the same out, defer the merge.
      if (!ip->last() &&
          inst(id+1)->opcode() == kInstByteRange &&
          ip->out() == inst(id+1)->out())
        continue;
      builder.Merge();
    } else if (ip->opcode() == kInstEmptyWidth) {
      if (ip->empty() & (kEmptyBeginLine|kEmptyEndLine) &&
          !marked_line_boundaries) {
        builder.Mark('\n', '\n');
        builder.Merge();
        marked_line_boundaries = true;
      }
      if (ip->empty() & (kEmptyWordBoundary|kEmptyNonWordBoundary) &&
          !marked_word_boundaries) {
        // We require two batches here: the first for ranges that are word
        // characters, the second for ranges that are not word characters.
        for (bool isword : {true, false}) {
          int j;
          for (int i = 0; i < 256; i = j) {
            for (j = i + 1; j < 256 &&
                            Prog::IsWordChar(static_cast<uint8_t>(i)) ==
                                Prog::IsWordChar(static_cast<uint8_t>(j));
                 j++)
              ;
            if (Prog::IsWordChar(static_cast<uint8_t>(i)) == isword)
              builder.Mark(i, j - 1);
          }
          builder.Merge();
        }
        marked_word_boundaries = true;
      }
    }
  }

  builder.Build(bytemap_, &bytemap_range_);
}

// Prog::Flatten() implements a graph rewriting algorithm.
//
// The overall process is similar to epsilon removal, but retains some epsilon
// transitions: those from Capture and EmptyWidth instructions; and those from
// nullable subexpressions. (The latter avoids quadratic blowup in transitions
// in the worst case.) It might be best thought of as Alt instruction elision.
//
// In conceptual terms, it divides the Prog into "trees" of instructions, then
// traverses the "trees" in order to produce "lists" of instructions. A "tree"
// is one or more instructions that grow from one "root" instruction to one or
// more "leaf" instructions; if a "tree" has exactly one instruction, then the
// "root" is also the "leaf". In most cases, a "root" is the successor of some
// "leaf" (i.e. the "leaf" instruction's out() returns the "root" instruction)
// and is considered a "successor root". A "leaf" can be a ByteRange, Capture,
// EmptyWidth or Match instruction. However, this is insufficient for handling
// nested nullable subexpressions correctly, so in some cases, a "root" is the
// dominator of the instructions reachable from some "successor root" (i.e. it
// has an unreachable predecessor) and is considered a "dominator root". Since
// only Alt instructions can be "dominator roots" (other instructions would be
// "leaves"), only Alt instructions are required to be marked as predecessors.
//
// Dividing the Prog into "trees" comprises two passes: marking the "successor
// roots" and the predecessors; and marking the "dominator roots". Sorting the
// "successor roots" by their bytecode offsets enables iteration in order from
// greatest to least during the second pass; by working backwards in this case
// and flooding the graph no further than "leaves" and already marked "roots",
// it becomes possible to mark "dominator roots" without doing excessive work.
//
// Traversing the "trees" is just iterating over the "roots" in order of their
// marking and flooding the graph no further than "leaves" and "roots". When a
// "leaf" is reached, the instruction is copied with its successor remapped to
// its "root" number. When a "root" is reached, a Nop instruction is generated
// with its successor remapped similarly. As each "list" is produced, its last
// instruction is marked as such. After all of the "lists" have been produced,
// a pass over their instructions remaps their successors to bytecode offsets.
void Prog::Flatten() {
  if (did_flatten_)
    return;
  did_flatten_ = true;

  // Scratch structures. It's important that these are reused by functions
  // that we call in loops because they would thrash the heap otherwise.
  SparseSet reachable(size());
  std::vector<int> stk;
  stk.reserve(size());

  // First pass: Marks "successor roots" and predecessors.
  // Builds the mapping from inst-ids to root-ids.
  SparseArray<int> rootmap(size());
  SparseArray<int> predmap(size());
  std::vector<std::vector<int>> predvec;
  MarkSuccessors(&rootmap, &predmap, &predvec, &reachable, &stk);

  // Second pass: Marks "dominator roots".
  SparseArray<int> sorted(rootmap);
  std::sort(sorted.begin(), sorted.end(), sorted.less);
  for (SparseArray<int>::const_iterator i = sorted.end() - 1;
       i != sorted.begin();
       --i) {
    if (i->index() != start_unanchored() && i->index() != start())
      MarkDominator(i->index(), &rootmap, &predmap, &predvec, &reachable, &stk);
  }

  // Third pass: Emits "lists". Remaps outs to root-ids.
  // Builds the mapping from root-ids to flat-ids.
  std::vector<int> flatmap(rootmap.size());
  std::vector<Inst> flat;
  flat.reserve(size());
  for (SparseArray<int>::const_iterator i = rootmap.begin();
       i != rootmap.end();
       ++i) {
    flatmap[i->value()] = static_cast<int>(flat.size());
    EmitList(i->index(), &rootmap, &flat, &reachable, &stk);
    flat.back().set_last();
    // We have the bounds of the "list", so this is the
    // most convenient point at which to compute hints.
    ComputeHints(&flat, flatmap[i->value()], static_cast<int>(flat.size()));
  }

  list_count_ = static_cast<int>(flatmap.size());
  for (int i = 0; i < kNumInst; i++)
    inst_count_[i] = 0;

  // Fourth pass: Remaps outs to flat-ids.
  // Counts instructions by opcode.
  for (int id = 0; id < static_cast<int>(flat.size()); id++) {
    Inst* ip = &flat[id];
    if (ip->opcode() != kInstAltMatch)  // handled in EmitList()
      ip->set_out(flatmap[ip->out()]);
    inst_count_[ip->opcode()]++;
  }

  int total = 0;
  for (int i = 0; i < kNumInst; i++)
    total += inst_count_[i];
  DCHECK_EQ(total, static_cast<int>(flat.size()));

  // Remap start_unanchored and start.
  if (start_unanchored() == 0) {
    DCHECK_EQ(start(), 0);
  } else if (start_unanchored() == start()) {
    set_start_unanchored(flatmap[1]);
    set_start(flatmap[1]);
  } else {
    set_start_unanchored(flatmap[1]);
    set_start(flatmap[2]);
  }

  // Finally, replace the old instructions with the new instructions.
  size_ = static_cast<int>(flat.size());
  inst_ = PODArray<Inst>(size_);
  memmove(inst_.data(), flat.data(), size_*sizeof inst_[0]);

  // Populate the list heads for BitState.
  // 512 instructions limits the memory footprint to 1KiB.
  if (size_ <= 512) {
    list_heads_ = PODArray<uint16_t>(size_);
    // 0xFF makes it more obvious if we try to look up a non-head.
    memset(list_heads_.data(), 0xFF, size_*sizeof list_heads_[0]);
    for (int i = 0; i < list_count_; ++i)
      list_heads_[flatmap[i]] = i;
  }
}

void Prog::MarkSuccessors(SparseArray<int>* rootmap,
                          SparseArray<int>* predmap,
                          std::vector<std::vector<int>>* predvec,
                          SparseSet* reachable, std::vector<int>* stk) {
  // Mark the kInstFail instruction.
  rootmap->set_new(0, rootmap->size());

  // Mark the start_unanchored and start instructions.
  if (!rootmap->has_index(start_unanchored()))
    rootmap->set_new(start_unanchored(), rootmap->size());
  if (!rootmap->has_index(start()))
    rootmap->set_new(start(), rootmap->size());

  reachable->clear();
  stk->clear();
  stk->push_back(start_unanchored());
  while (!stk->empty()) {
    int id = stk->back();
    stk->pop_back();
  Loop:
    if (reachable->contains(id))
      continue;
    reachable->insert_new(id);

    Inst* ip = inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
        break;

      case kInstAltMatch:
      case kInstAlt:
        // Mark this instruction as a predecessor of each out.
        for (int out : {ip->out(), ip->out1()}) {
          if (!predmap->has_index(out)) {
            predmap->set_new(out, static_cast<int>(predvec->size()));
            predvec->emplace_back();
          }
          (*predvec)[predmap->get_existing(out)].emplace_back(id);
        }
        stk->push_back(ip->out1());
        id = ip->out();
        goto Loop;

      case kInstByteRange:
      case kInstCapture:
      case kInstEmptyWidth:
        // Mark the out of this instruction as a "root".
        if (!rootmap->has_index(ip->out()))
          rootmap->set_new(ip->out(), rootmap->size());
        id = ip->out();
        goto Loop;

      case kInstNop:
        id = ip->out();
        goto Loop;

      case kInstMatch:
      case kInstFail:
        break;
    }
  }
}

void Prog::MarkDominator(int root, SparseArray<int>* rootmap,
                         SparseArray<int>* predmap,
                         std::vector<std::vector<int>>* predvec,
                         SparseSet* reachable, std::vector<int>* stk) {
  reachable->clear();
  stk->clear();
  stk->push_back(root);
  while (!stk->empty()) {
    int id = stk->back();
    stk->pop_back();
  Loop:
    if (reachable->contains(id))
      continue;
    reachable->insert_new(id);

    if (id != root && rootmap->has_index(id)) {
      // We reached another "tree" via epsilon transition.
      continue;
    }

    Inst* ip = inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
        break;

      case kInstAltMatch:
      case kInstAlt:
        stk->push_back(ip->out1());
        id = ip->out();
        goto Loop;

      case kInstByteRange:
      case kInstCapture:
      case kInstEmptyWidth:
        break;

      case kInstNop:
        id = ip->out();
        goto Loop;

      case kInstMatch:
      case kInstFail:
        break;
    }
  }

  for (SparseSet::const_iterator i = reachable->begin();
       i != reachable->end();
       ++i) {
    int id = *i;
    if (predmap->has_index(id)) {
      for (int pred : (*predvec)[predmap->get_existing(id)]) {
        if (!reachable->contains(pred)) {
          // id has a predecessor that cannot be reached from root!
          // Therefore, id must be a "root" too - mark it as such.
          if (!rootmap->has_index(id))
            rootmap->set_new(id, rootmap->size());
        }
      }
    }
  }
}

void Prog::EmitList(int root, SparseArray<int>* rootmap,
                    std::vector<Inst>* flat,
                    SparseSet* reachable, std::vector<int>* stk) {
  reachable->clear();
  stk->clear();
  stk->push_back(root);
  while (!stk->empty()) {
    int id = stk->back();
    stk->pop_back();
  Loop:
    if (reachable->contains(id))
      continue;
    reachable->insert_new(id);

    if (id != root && rootmap->has_index(id)) {
      // We reached another "tree" via epsilon transition. Emit a kInstNop
      // instruction so that the Prog does not become quadratically larger.
      flat->emplace_back();
      flat->back().set_opcode(kInstNop);
      flat->back().set_out(rootmap->get_existing(id));
      continue;
    }

    Inst* ip = inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled opcode: " << ip->opcode();
        break;

      case kInstAltMatch:
        flat->emplace_back();
        flat->back().set_opcode(kInstAltMatch);
        flat->back().set_out(static_cast<int>(flat->size()));
        flat->back().out1_ = static_cast<uint32_t>(flat->size())+1;
        FALLTHROUGH_INTENDED;

      case kInstAlt:
        stk->push_back(ip->out1());
        id = ip->out();
        goto Loop;

      case kInstByteRange:
      case kInstCapture:
      case kInstEmptyWidth:
        flat->emplace_back();
        memmove(&flat->back(), ip, sizeof *ip);
        flat->back().set_out(rootmap->get_existing(ip->out()));
        break;

      case kInstNop:
        id = ip->out();
        goto Loop;

      case kInstMatch:
      case kInstFail:
        flat->emplace_back();
        memmove(&flat->back(), ip, sizeof *ip);
        break;
    }
  }
}

// For each ByteRange instruction in [begin, end), computes a hint to execution
// engines: the delta to the next instruction (in flat) worth exploring iff the
// current instruction matched.
//
// Implements a coloring algorithm related to ByteMapBuilder, but in this case,
// colors are instructions and recoloring ranges precisely identifies conflicts
// between instructions. Iterating backwards over [begin, end) is guaranteed to
// identify the nearest conflict (if any) with only linear complexity.
void Prog::ComputeHints(std::vector<Inst>* flat, int begin, int end) {
  Bitmap256 splits;
  int colors[256];

  bool dirty = false;
  for (int id = end; id >= begin; --id) {
    if (id == end ||
        (*flat)[id].opcode() != kInstByteRange) {
      if (dirty) {
        dirty = false;
        splits.Clear();
      }
      splits.Set(255);
      colors[255] = id;
      // At this point, the [0-255] range is colored with id.
      // Thus, hints cannot point beyond id; and if id == end,
      // hints that would have pointed to id will be 0 instead.
      continue;
    }
    dirty = true;

    // We recolor the [lo-hi] range with id. Note that first ratchets backwards
    // from end to the nearest conflict (if any) during recoloring.
    int first = end;
    auto Recolor = [&](int lo, int hi) {
      // Like ByteMapBuilder, we split at lo-1 and at hi.
      --lo;

      if (0 <= lo && !splits.Test(lo)) {
        splits.Set(lo);
        int next = splits.FindNextSetBit(lo+1);
        colors[lo] = colors[next];
      }
      if (!splits.Test(hi)) {
        splits.Set(hi);
        int next = splits.FindNextSetBit(hi+1);
        colors[hi] = colors[next];
      }

      int c = lo+1;
      while (c < 256) {
        int next = splits.FindNextSetBit(c);
        // Ratchet backwards...
        first = std::min(first, colors[next]);
        // Recolor with id - because it's the new nearest conflict!
        colors[next] = id;
        if (next == hi)
          break;
        c = next+1;
      }
    };

    Inst* ip = &(*flat)[id];
    int lo = ip->lo();
    int hi = ip->hi();
    Recolor(lo, hi);
    if (ip->foldcase() && lo <= 'z' && hi >= 'a') {
      int foldlo = lo;
      int foldhi = hi;
      if (foldlo < 'a')
        foldlo = 'a';
      if (foldhi > 'z')
        foldhi = 'z';
      if (foldlo <= foldhi) {
        foldlo += 'A' - 'a';
        foldhi += 'A' - 'a';
        Recolor(foldlo, foldhi);
      }
    }

    if (first != end) {
      uint16_t hint = static_cast<uint16_t>(std::min(first - id, 32767));
      ip->hint_foldcase_ |= hint<<1;
    }
  }
}

}  // namespace re2
// Copyright 2003-2009 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Regular expression interface RE2.
//
// Originally the PCRE C++ wrapper, but adapted to use
// the new automata-based regular expression engines.



#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iterator>
#include <mutex>
#include <string>
#include <utility>
#include <vector>









namespace re2 {

// Maximum number of args we can set
static const int kMaxArgs = 16;
static const int kVecSize = 1+kMaxArgs;

const int RE2::Options::kDefaultMaxMem;  // initialized in re2.h

RE2::Options::Options(RE2::CannedOptions opt)
  : encoding_(opt == RE2::Latin1 ? EncodingLatin1 : EncodingUTF8),
    posix_syntax_(opt == RE2::POSIX),
    longest_match_(opt == RE2::POSIX),
    log_errors_(opt != RE2::Quiet),
    max_mem_(kDefaultMaxMem),
    literal_(false),
    never_nl_(false),
    dot_nl_(false),
    never_capture_(false),
    case_sensitive_(true),
    perl_classes_(false),
    word_boundary_(false),
    one_line_(false) {
}

// static empty objects for use as const references.
// To avoid global constructors, allocated in RE2::Init().
static const std::string* empty_string;
static const std::map<std::string, int>* empty_named_groups;
static const std::map<int, std::string>* empty_group_names;

// Converts from Regexp error code to RE2 error code.
// Maybe some day they will diverge.  In any event, this
// hides the existence of Regexp from RE2 users.
static RE2::ErrorCode RegexpErrorToRE2(re2::RegexpStatusCode code) {
  switch (code) {
    case re2::kRegexpSuccess:
      return RE2::NoError;
    case re2::kRegexpInternalError:
      return RE2::ErrorInternal;
    case re2::kRegexpBadEscape:
      return RE2::ErrorBadEscape;
    case re2::kRegexpBadCharClass:
      return RE2::ErrorBadCharClass;
    case re2::kRegexpBadCharRange:
      return RE2::ErrorBadCharRange;
    case re2::kRegexpMissingBracket:
      return RE2::ErrorMissingBracket;
    case re2::kRegexpMissingParen:
      return RE2::ErrorMissingParen;
    case re2::kRegexpTrailingBackslash:
      return RE2::ErrorTrailingBackslash;
    case re2::kRegexpRepeatArgument:
      return RE2::ErrorRepeatArgument;
    case re2::kRegexpRepeatSize:
      return RE2::ErrorRepeatSize;
    case re2::kRegexpRepeatOp:
      return RE2::ErrorRepeatOp;
    case re2::kRegexpBadPerlOp:
      return RE2::ErrorBadPerlOp;
    case re2::kRegexpBadUTF8:
      return RE2::ErrorBadUTF8;
    case re2::kRegexpBadNamedCapture:
      return RE2::ErrorBadNamedCapture;
  }
  return RE2::ErrorInternal;
}

static std::string trunc(const StringPiece& pattern) {
  if (pattern.size() < 100)
    return std::string(pattern);
  return std::string(pattern.substr(0, 100)) + "...";
}


RE2::RE2(const char* pattern) {
  Init(pattern, DefaultOptions);
}

RE2::RE2(const std::string& pattern) {
  Init(pattern, DefaultOptions);
}

RE2::RE2(const StringPiece& pattern) {
  Init(pattern, DefaultOptions);
}

RE2::RE2(const StringPiece& pattern, const Options& options) {
  Init(pattern, options);
}

int RE2::Options::ParseFlags() const {
  int flags = Regexp::ClassNL;
  switch (encoding()) {
    default:
      if (log_errors())
        LOG(ERROR) << "Unknown encoding " << encoding();
      break;
    case RE2::Options::EncodingUTF8:
      break;
    case RE2::Options::EncodingLatin1:
      flags |= Regexp::Latin1;
      break;
  }

  if (!posix_syntax())
    flags |= Regexp::LikePerl;

  if (literal())
    flags |= Regexp::Literal;

  if (never_nl())
    flags |= Regexp::NeverNL;

  if (dot_nl())
    flags |= Regexp::DotNL;

  if (never_capture())
    flags |= Regexp::NeverCapture;

  if (!case_sensitive())
    flags |= Regexp::FoldCase;

  if (perl_classes())
    flags |= Regexp::PerlClasses;

  if (word_boundary())
    flags |= Regexp::PerlB;

  if (one_line())
    flags |= Regexp::OneLine;

  return flags;
}

void RE2::Init(const StringPiece& pattern, const Options& options) {
  static std::once_flag empty_once;
  std::call_once(empty_once, []() {
    empty_string = new std::string;
    empty_named_groups = new std::map<std::string, int>;
    empty_group_names = new std::map<int, std::string>;
  });

  pattern_ = std::string(pattern);
  options_.Copy(options);
  entire_regexp_ = NULL;
  suffix_regexp_ = NULL;
  prog_ = NULL;
  num_captures_ = -1;
  rprog_ = NULL;
  error_ = empty_string;
  error_code_ = NoError;
  named_groups_ = NULL;
  group_names_ = NULL;

  RegexpStatus status;
  entire_regexp_ = Regexp::Parse(
    pattern_,
    static_cast<Regexp::ParseFlags>(options_.ParseFlags()),
    &status);
  if (entire_regexp_ == NULL) {
    if (options_.log_errors()) {
      LOG(ERROR) << "Error parsing '" << trunc(pattern_) << "': "
                 << status.Text();
    }
    error_ = new std::string(status.Text());
    error_code_ = RegexpErrorToRE2(status.code());
    error_arg_ = std::string(status.error_arg());
    return;
  }

  re2::Regexp* suffix;
  if (entire_regexp_->RequiredPrefix(&prefix_, &prefix_foldcase_, &suffix))
    suffix_regexp_ = suffix;
  else
    suffix_regexp_ = entire_regexp_->Incref();

  // Two thirds of the memory goes to the forward Prog,
  // one third to the reverse prog, because the forward
  // Prog has two DFAs but the reverse prog has one.
  prog_ = suffix_regexp_->CompileToProg(options_.max_mem()*2/3);
  if (prog_ == NULL) {
    if (options_.log_errors())
      LOG(ERROR) << "Error compiling '" << trunc(pattern_) << "'";
    error_ = new std::string("pattern too large - compile failed");
    error_code_ = RE2::ErrorPatternTooLarge;
    return;
  }

  // We used to compute this lazily, but it's used during the
  // typical control flow for a match call, so we now compute
  // it eagerly, which avoids the overhead of std::once_flag.
  num_captures_ = suffix_regexp_->NumCaptures();

  // Could delay this until the first match call that
  // cares about submatch information, but the one-pass
  // machine's memory gets cut from the DFA memory budget,
  // and that is harder to do if the DFA has already
  // been built.
  is_one_pass_ = prog_->IsOnePass();
}

// Returns rprog_, computing it if needed.
re2::Prog* RE2::ReverseProg() const {
  std::call_once(rprog_once_, [](const RE2* re) {
    re->rprog_ =
        re->suffix_regexp_->CompileToReverseProg(re->options_.max_mem() / 3);
    if (re->rprog_ == NULL) {
      if (re->options_.log_errors())
        LOG(ERROR) << "Error reverse compiling '" << trunc(re->pattern_) << "'";
      re->error_ =
          new std::string("pattern too large - reverse compile failed");
      re->error_code_ = RE2::ErrorPatternTooLarge;
    }
  }, this);
  return rprog_;
}

RE2::~RE2() {
  if (suffix_regexp_)
    suffix_regexp_->Decref();
  if (entire_regexp_)
    entire_regexp_->Decref();
  delete prog_;
  delete rprog_;
  if (error_ != empty_string)
    delete error_;
  if (named_groups_ != NULL && named_groups_ != empty_named_groups)
    delete named_groups_;
  if (group_names_ != NULL &&  group_names_ != empty_group_names)
    delete group_names_;
}

int RE2::ProgramSize() const {
  if (prog_ == NULL)
    return -1;
  return prog_->size();
}

int RE2::ReverseProgramSize() const {
  if (prog_ == NULL)
    return -1;
  Prog* prog = ReverseProg();
  if (prog == NULL)
    return -1;
  return prog->size();
}

static int Fanout(Prog* prog, std::map<int, int>* histogram) {
  SparseArray<int> fanout(prog->size());
  prog->Fanout(&fanout);
  histogram->clear();
  for (SparseArray<int>::iterator i = fanout.begin(); i != fanout.end(); ++i) {
    // TODO(junyer): Optimise this?
    int bucket = 0;
    while (1 << bucket < i->value()) {
      bucket++;
    }
    (*histogram)[bucket]++;
  }
  return histogram->rbegin()->first;
}

int RE2::ProgramFanout(std::map<int, int>* histogram) const {
  if (prog_ == NULL)
    return -1;
  return Fanout(prog_, histogram);
}

int RE2::ReverseProgramFanout(std::map<int, int>* histogram) const {
  if (prog_ == NULL)
    return -1;
  Prog* prog = ReverseProg();
  if (prog == NULL)
    return -1;
  return Fanout(prog, histogram);
}

// Returns named_groups_, computing it if needed.
const std::map<std::string, int>& RE2::NamedCapturingGroups() const {
  std::call_once(named_groups_once_, [](const RE2* re) {
    if (re->suffix_regexp_ != NULL)
      re->named_groups_ = re->suffix_regexp_->NamedCaptures();
    if (re->named_groups_ == NULL)
      re->named_groups_ = empty_named_groups;
  }, this);
  return *named_groups_;
}

// Returns group_names_, computing it if needed.
const std::map<int, std::string>& RE2::CapturingGroupNames() const {
  std::call_once(group_names_once_, [](const RE2* re) {
    if (re->suffix_regexp_ != NULL)
      re->group_names_ = re->suffix_regexp_->CaptureNames();
    if (re->group_names_ == NULL)
      re->group_names_ = empty_group_names;
  }, this);
  return *group_names_;
}

/***** Convenience interfaces *****/

bool RE2::FullMatchN(const StringPiece& text, const RE2& re,
                     const Arg* const args[], int n) {
  return re.DoMatch(text, ANCHOR_BOTH, NULL, args, n);
}

bool RE2::PartialMatchN(const StringPiece& text, const RE2& re,
                        const Arg* const args[], int n) {
  return re.DoMatch(text, UNANCHORED, NULL, args, n);
}

bool RE2::ConsumeN(StringPiece* input, const RE2& re,
                   const Arg* const args[], int n) {
  size_t consumed;
  if (re.DoMatch(*input, ANCHOR_START, &consumed, args, n)) {
    input->remove_prefix(consumed);
    return true;
  } else {
    return false;
  }
}

bool RE2::FindAndConsumeN(StringPiece* input, const RE2& re,
                          const Arg* const args[], int n) {
  size_t consumed;
  if (re.DoMatch(*input, UNANCHORED, &consumed, args, n)) {
    input->remove_prefix(consumed);
    return true;
  } else {
    return false;
  }
}

bool RE2::Replace(std::string* str,
                  const RE2& re,
                  const StringPiece& rewrite) {
  StringPiece vec[kVecSize];
  int nvec = 1 + MaxSubmatch(rewrite);
  if (nvec > arraysize(vec))
    return false;
  if (!re.Match(*str, 0, str->size(), UNANCHORED, vec, nvec))
    return false;

  std::string s;
  if (!re.Rewrite(&s, rewrite, vec, nvec))
    return false;

  assert(vec[0].begin() >= str->data());
  assert(vec[0].end() <= str->data()+str->size());
  str->replace(vec[0].data() - str->data(), vec[0].size(), s);
  return true;
}

int RE2::GlobalReplace(std::string* str,
                       const RE2& re,
                       const StringPiece& rewrite) {
  StringPiece vec[kVecSize];
  int nvec = 1 + MaxSubmatch(rewrite);
  if (nvec > arraysize(vec))
    return false;

  const char* p = str->data();
  const char* ep = p + str->size();
  const char* lastend = NULL;
  std::string out;
  int count = 0;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  // Iterate just once when fuzzing. Otherwise, we easily get bogged down
  // and coverage is unlikely to improve despite significant expense.
  while (p == str->data()) {
#else
  while (p <= ep) {
#endif
    if (!re.Match(*str, static_cast<size_t>(p - str->data()),
                  str->size(), UNANCHORED, vec, nvec))
      break;
    if (p < vec[0].begin())
      out.append(p, vec[0].begin() - p);
    if (vec[0].begin() == lastend && vec[0].size() == 0) {
      // Disallow empty match at end of last match: skip ahead.
      //
      // fullrune() takes int, not ptrdiff_t. However, it just looks
      // at the leading byte and treats any length >= 4 the same.
      if (re.options().encoding() == RE2::Options::EncodingUTF8 &&
          fullrune(p, static_cast<int>(std::min(ptrdiff_t{4}, ep - p)))) {
        // re is in UTF-8 mode and there is enough left of str
        // to allow us to advance by up to UTFmax bytes.
        Rune r;
        int n = chartorune(&r, p);
        // Some copies of chartorune have a bug that accepts
        // encodings of values in (10FFFF, 1FFFFF] as valid.
        if (r > Runemax) {
          n = 1;
          r = Runeerror;
        }
        if (!(n == 1 && r == Runeerror)) {  // no decoding error
          out.append(p, n);
          p += n;
          continue;
        }
      }
      // Most likely, re is in Latin-1 mode. If it is in UTF-8 mode,
      // we fell through from above and the GIGO principle applies.
      if (p < ep)
        out.append(p, 1);
      p++;
      continue;
    }
    re.Rewrite(&out, rewrite, vec, nvec);
    p = vec[0].end();
    lastend = p;
    count++;
  }

  if (count == 0)
    return 0;

  if (p < ep)
    out.append(p, ep - p);
  using std::swap;
  swap(out, *str);
  return count;
}

bool RE2::Extract(const StringPiece& text,
                  const RE2& re,
                  const StringPiece& rewrite,
                  std::string* out) {
  StringPiece vec[kVecSize];
  int nvec = 1 + MaxSubmatch(rewrite);
  if (nvec > arraysize(vec))
    return false;

  if (!re.Match(text, 0, text.size(), UNANCHORED, vec, nvec))
    return false;

  out->clear();
  return re.Rewrite(out, rewrite, vec, nvec);
}

std::string RE2::QuoteMeta(const StringPiece& unquoted) {
  std::string result;
  result.reserve(unquoted.size() << 1);

  // Escape any ascii character not in [A-Za-z_0-9].
  //
  // Note that it's legal to escape a character even if it has no
  // special meaning in a regular expression -- so this function does
  // that.  (This also makes it identical to the perl function of the
  // same name except for the null-character special case;
  // see `perldoc -f quotemeta`.)
  for (size_t ii = 0; ii < unquoted.size(); ++ii) {
    // Note that using 'isalnum' here raises the benchmark time from
    // 32ns to 58ns:
    if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') &&
        (unquoted[ii] < 'A' || unquoted[ii] > 'Z') &&
        (unquoted[ii] < '0' || unquoted[ii] > '9') &&
        unquoted[ii] != '_' &&
        // If this is the part of a UTF8 or Latin1 character, we need
        // to copy this byte without escaping.  Experimentally this is
        // what works correctly with the regexp library.
        !(unquoted[ii] & 128)) {
      if (unquoted[ii] == '\0') {  // Special handling for null chars.
        // Note that this special handling is not strictly required for RE2,
        // but this quoting is required for other regexp libraries such as
        // PCRE.
        // Can't use "\\0" since the next character might be a digit.
        result += "\\x00";
        continue;
      }
      result += '\\';
    }
    result += unquoted[ii];
  }

  return result;
}

bool RE2::PossibleMatchRange(std::string* min, std::string* max,
                             int maxlen) const {
  if (prog_ == NULL)
    return false;

  int n = static_cast<int>(prefix_.size());
  if (n > maxlen)
    n = maxlen;

  // Determine initial min max from prefix_ literal.
  *min = prefix_.substr(0, n);
  *max = prefix_.substr(0, n);
  if (prefix_foldcase_) {
    // prefix is ASCII lowercase; change *min to uppercase.
    for (int i = 0; i < n; i++) {
      char& c = (*min)[i];
      if ('a' <= c && c <= 'z')
        c += 'A' - 'a';
    }
  }

  // Add to prefix min max using PossibleMatchRange on regexp.
  std::string dmin, dmax;
  maxlen -= n;
  if (maxlen > 0 && prog_->PossibleMatchRange(&dmin, &dmax, maxlen)) {
    min->append(dmin);
    max->append(dmax);
  } else if (!max->empty()) {
    // prog_->PossibleMatchRange has failed us,
    // but we still have useful information from prefix_.
    // Round up *max to allow any possible suffix.
    PrefixSuccessor(max);
  } else {
    // Nothing useful.
    *min = "";
    *max = "";
    return false;
  }

  return true;
}

// Avoid possible locale nonsense in standard strcasecmp.
// The string a is known to be all lowercase.
static int ascii_strcasecmp(const char* a, const char* b, size_t len) {
  const char* ae = a + len;

  for (; a < ae; a++, b++) {
    uint8_t x = *a;
    uint8_t y = *b;
    if ('A' <= y && y <= 'Z')
      y += 'a' - 'A';
    if (x != y)
      return x - y;
  }
  return 0;
}


/***** Actual matching and rewriting code *****/

bool RE2::Match(const StringPiece& text,
                size_t startpos,
                size_t endpos,
                Anchor re_anchor,
                StringPiece* submatch,
                int nsubmatch) const {
  if (!ok()) {
    if (options_.log_errors())
      LOG(ERROR) << "Invalid RE2: " << *error_;
    return false;
  }

  if (startpos > endpos || endpos > text.size()) {
    if (options_.log_errors())
      LOG(ERROR) << "RE2: invalid startpos, endpos pair. ["
                 << "startpos: " << startpos << ", "
                 << "endpos: " << endpos << ", "
                 << "text size: " << text.size() << "]";
    return false;
  }

  StringPiece subtext = text;
  subtext.remove_prefix(startpos);
  subtext.remove_suffix(text.size() - endpos);

  // Use DFAs to find exact location of match, filter out non-matches.

  // Don't ask for the location if we won't use it.
  // SearchDFA can do extra optimizations in that case.
  StringPiece match;
  StringPiece* matchp = &match;
  if (nsubmatch == 0)
    matchp = NULL;

  int ncap = 1 + NumberOfCapturingGroups();
  if (ncap > nsubmatch)
    ncap = nsubmatch;

  // If the regexp is anchored explicitly, must not be in middle of text.
  if (prog_->anchor_start() && startpos != 0)
    return false;

  // If the regexp is anchored explicitly, update re_anchor
  // so that we can potentially fall into a faster case below.
  if (prog_->anchor_start() && prog_->anchor_end())
    re_anchor = ANCHOR_BOTH;
  else if (prog_->anchor_start() && re_anchor != ANCHOR_BOTH)
    re_anchor = ANCHOR_START;

  // Check for the required prefix, if any.
  size_t prefixlen = 0;
  if (!prefix_.empty()) {
    if (startpos != 0)
      return false;
    prefixlen = prefix_.size();
    if (prefixlen > subtext.size())
      return false;
    if (prefix_foldcase_) {
      if (ascii_strcasecmp(&prefix_[0], subtext.data(), prefixlen) != 0)
        return false;
    } else {
      if (memcmp(&prefix_[0], subtext.data(), prefixlen) != 0)
        return false;
    }
    subtext.remove_prefix(prefixlen);
    // If there is a required prefix, the anchor must be at least ANCHOR_START.
    if (re_anchor != ANCHOR_BOTH)
      re_anchor = ANCHOR_START;
  }

  Prog::Anchor anchor = Prog::kUnanchored;
  Prog::MatchKind kind = Prog::kFirstMatch;
  if (options_.longest_match())
    kind = Prog::kLongestMatch;
  bool skipped_test = false;

  bool can_one_pass = (is_one_pass_ && ncap <= Prog::kMaxOnePassCapture);

  // BitState allocates a bitmap of size prog_->list_count() * text.size().
  // It also allocates a stack of 3-word structures which could potentially
  // grow as large as prog_->list_count() * text.size(), but in practice is
  // much smaller.
  const int kMaxBitStateBitmapSize = 256*1024;  // bitmap size <= max (bits)
  bool can_bit_state = prog_->CanBitState();
  size_t bit_state_text_max = kMaxBitStateBitmapSize / prog_->list_count();

  bool dfa_failed = false;
  switch (re_anchor) {
    default:
    case UNANCHORED: {
      if (!prog_->SearchDFA(subtext, text, anchor, kind,
                            matchp, &dfa_failed, NULL)) {
        if (dfa_failed) {
          if (options_.log_errors())
            LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", "
                       << "bytemap range " << prog_->bytemap_range() << ", "
                       << "list count " << prog_->list_count();
          // Fall back to NFA below.
          skipped_test = true;
          break;
        }
        return false;
      }
      if (matchp == NULL)  // Matched.  Don't care where
        return true;
      // SearchDFA set match[0].end() but didn't know where the
      // match started.  Run the regexp backward from match[0].end()
      // to find the longest possible match -- that's where it started.
      Prog* prog = ReverseProg();
      if (prog == NULL)
        return false;
      if (!prog->SearchDFA(match, text, Prog::kAnchored,
                           Prog::kLongestMatch, &match, &dfa_failed, NULL)) {
        if (dfa_failed) {
          if (options_.log_errors())
            LOG(ERROR) << "DFA out of memory: size " << prog->size() << ", "
                       << "bytemap range " << prog->bytemap_range() << ", "
                       << "list count " << prog->list_count();
          // Fall back to NFA below.
          skipped_test = true;
          break;
        }
        if (options_.log_errors())
          LOG(ERROR) << "SearchDFA inconsistency";
        return false;
      }
      break;
    }

    case ANCHOR_BOTH:
    case ANCHOR_START:
      if (re_anchor == ANCHOR_BOTH)
        kind = Prog::kFullMatch;
      anchor = Prog::kAnchored;

      // If only a small amount of text and need submatch
      // information anyway and we're going to use OnePass or BitState
      // to get it, we might as well not even bother with the DFA:
      // OnePass or BitState will be fast enough.
      // On tiny texts, OnePass outruns even the DFA, and
      // it doesn't have the shared state and occasional mutex that
      // the DFA does.
      if (can_one_pass && text.size() <= 4096 &&
          (ncap > 1 || text.size() <= 8)) {
        skipped_test = true;
        break;
      }
      if (can_bit_state && text.size() <= bit_state_text_max && ncap > 1) {
        skipped_test = true;
        break;
      }
      if (!prog_->SearchDFA(subtext, text, anchor, kind,
                            &match, &dfa_failed, NULL)) {
        if (dfa_failed) {
          if (options_.log_errors())
            LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", "
                       << "bytemap range " << prog_->bytemap_range() << ", "
                       << "list count " << prog_->list_count();
          // Fall back to NFA below.
          skipped_test = true;
          break;
        }
        return false;
      }
      break;
  }

  if (!skipped_test && ncap <= 1) {
    // We know exactly where it matches.  That's enough.
    if (ncap == 1)
      submatch[0] = match;
  } else {
    StringPiece subtext1;
    if (skipped_test) {
      // DFA ran out of memory or was skipped:
      // need to search in entire original text.
      subtext1 = subtext;
    } else {
      // DFA found the exact match location:
      // let NFA run an anchored, full match search
      // to find submatch locations.
      subtext1 = match;
      anchor = Prog::kAnchored;
      kind = Prog::kFullMatch;
    }

    if (can_one_pass && anchor != Prog::kUnanchored) {
      if (!prog_->SearchOnePass(subtext1, text, anchor, kind, submatch, ncap)) {
        if (!skipped_test && options_.log_errors())
          LOG(ERROR) << "SearchOnePass inconsistency";
        return false;
      }
    } else if (can_bit_state && subtext1.size() <= bit_state_text_max) {
      if (!prog_->SearchBitState(subtext1, text, anchor,
                                 kind, submatch, ncap)) {
        if (!skipped_test && options_.log_errors())
          LOG(ERROR) << "SearchBitState inconsistency";
        return false;
      }
    } else {
      if (!prog_->SearchNFA(subtext1, text, anchor, kind, submatch, ncap)) {
        if (!skipped_test && options_.log_errors())
          LOG(ERROR) << "SearchNFA inconsistency";
        return false;
      }
    }
  }

  // Adjust overall match for required prefix that we stripped off.
  if (prefixlen > 0 && nsubmatch > 0)
    submatch[0] = StringPiece(submatch[0].data() - prefixlen,
                              submatch[0].size() + prefixlen);

  // Zero submatches that don't exist in the regexp.
  for (int i = ncap; i < nsubmatch; i++)
    submatch[i] = StringPiece();
  return true;
}

// Internal matcher - like Match() but takes Args not StringPieces.
bool RE2::DoMatch(const StringPiece& text,
                  Anchor re_anchor,
                  size_t* consumed,
                  const Arg* const* args,
                  int n) const {
  if (!ok()) {
    if (options_.log_errors())
      LOG(ERROR) << "Invalid RE2: " << *error_;
    return false;
  }

  if (NumberOfCapturingGroups() < n) {
    // RE has fewer capturing groups than number of Arg pointers passed in.
    return false;
  }

  // Count number of capture groups needed.
  int nvec;
  if (n == 0 && consumed == NULL)
    nvec = 0;
  else
    nvec = n+1;

  StringPiece* vec;
  StringPiece stkvec[kVecSize];
  StringPiece* heapvec = NULL;

  if (nvec <= arraysize(stkvec)) {
    vec = stkvec;
  } else {
    vec = new StringPiece[nvec];
    heapvec = vec;
  }

  if (!Match(text, 0, text.size(), re_anchor, vec, nvec)) {
    delete[] heapvec;
    return false;
  }

  if (consumed != NULL)
    *consumed = static_cast<size_t>(vec[0].end() - text.begin());

  if (n == 0 || args == NULL) {
    // We are not interested in results
    delete[] heapvec;
    return true;
  }

  // If we got here, we must have matched the whole pattern.
  for (int i = 0; i < n; i++) {
    const StringPiece& s = vec[i+1];
    if (!args[i]->Parse(s.data(), s.size())) {
      // TODO: Should we indicate what the error was?
      delete[] heapvec;
      return false;
    }
  }

  delete[] heapvec;
  return true;
}

// Checks that the rewrite string is well-formed with respect to this
// regular expression.
bool RE2::CheckRewriteString(const StringPiece& rewrite,
                             std::string* error) const {
  int max_token = -1;
  for (const char *s = rewrite.data(), *end = s + rewrite.size();
       s < end; s++) {
    int c = *s;
    if (c != '\\') {
      continue;
    }
    if (++s == end) {
      *error = "Rewrite schema error: '\\' not allowed at end.";
      return false;
    }
    c = *s;
    if (c == '\\') {
      continue;
    }
    if (!isdigit(c)) {
      *error = "Rewrite schema error: "
               "'\\' must be followed by a digit or '\\'.";
      return false;
    }
    int n = (c - '0');
    if (max_token < n) {
      max_token = n;
    }
  }

  if (max_token > NumberOfCapturingGroups()) {
    SStringPrintf(error, "Rewrite schema requests %d matches, "
                  "but the regexp only has %d parenthesized subexpressions.",
                  max_token, NumberOfCapturingGroups());
    return false;
  }
  return true;
}

// Returns the maximum submatch needed for the rewrite to be done by Replace().
// E.g. if rewrite == "foo \\2,\\1", returns 2.
int RE2::MaxSubmatch(const StringPiece& rewrite) {
  int max = 0;
  for (const char *s = rewrite.data(), *end = s + rewrite.size();
       s < end; s++) {
    if (*s == '\\') {
      s++;
      int c = (s < end) ? *s : -1;
      if (isdigit(c)) {
        int n = (c - '0');
        if (n > max)
          max = n;
      }
    }
  }
  return max;
}

// Append the "rewrite" string, with backslash subsitutions from "vec",
// to string "out".
bool RE2::Rewrite(std::string* out,
                  const StringPiece& rewrite,
                  const StringPiece* vec,
                  int veclen) const {
  for (const char *s = rewrite.data(), *end = s + rewrite.size();
       s < end; s++) {
    if (*s != '\\') {
      out->push_back(*s);
      continue;
    }
    s++;
    int c = (s < end) ? *s : -1;
    if (isdigit(c)) {
      int n = (c - '0');
      if (n >= veclen) {
        if (options_.log_errors()) {
          LOG(ERROR) << "requested group " << n
                     << " in regexp " << rewrite.data();
        }
        return false;
      }
      StringPiece snip = vec[n];
      if (snip.size() > 0)
        out->append(snip.data(), snip.size());
    } else if (c == '\\') {
      out->push_back('\\');
    } else {
      if (options_.log_errors())
        LOG(ERROR) << "invalid rewrite pattern: " << rewrite.data();
      return false;
    }
  }
  return true;
}

/***** Parsers for various types *****/

bool RE2::Arg::parse_null(const char* str, size_t n, void* dest) {
  // We fail if somebody asked us to store into a non-NULL void* pointer
  return (dest == NULL);
}

bool RE2::Arg::parse_string(const char* str, size_t n, void* dest) {
  if (dest == NULL) return true;
  reinterpret_cast<std::string*>(dest)->assign(str, n);
  return true;
}

bool RE2::Arg::parse_stringpiece(const char* str, size_t n, void* dest) {
  if (dest == NULL) return true;
  *(reinterpret_cast<StringPiece*>(dest)) = StringPiece(str, n);
  return true;
}

bool RE2::Arg::parse_char(const char* str, size_t n, void* dest) {
  if (n != 1) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<char*>(dest)) = str[0];
  return true;
}

bool RE2::Arg::parse_schar(const char* str, size_t n, void* dest) {
  if (n != 1) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<signed char*>(dest)) = str[0];
  return true;
}

bool RE2::Arg::parse_uchar(const char* str, size_t n, void* dest) {
  if (n != 1) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<unsigned char*>(dest)) = str[0];
  return true;
}

// Largest number spec that we are willing to parse
static const int kMaxNumberLength = 32;

// REQUIRES "buf" must have length at least nbuf.
// Copies "str" into "buf" and null-terminates.
// Overwrites *np with the new length.
static const char* TerminateNumber(char* buf, size_t nbuf, const char* str,
                                   size_t* np, bool accept_spaces) {
  size_t n = *np;
  if (n == 0) return "";
  if (n > 0 && isspace(*str)) {
    // We are less forgiving than the strtoxxx() routines and do not
    // allow leading spaces. We do allow leading spaces for floats.
    if (!accept_spaces) {
      return "";
    }
    while (n > 0 && isspace(*str)) {
      n--;
      str++;
    }
  }

  // Although buf has a fixed maximum size, we can still handle
  // arbitrarily large integers correctly by omitting leading zeros.
  // (Numbers that are still too long will be out of range.)
  // Before deciding whether str is too long,
  // remove leading zeros with s/000+/00/.
  // Leaving the leading two zeros in place means that
  // we don't change 0000x123 (invalid) into 0x123 (valid).
  // Skip over leading - before replacing.
  bool neg = false;
  if (n >= 1 && str[0] == '-') {
    neg = true;
    n--;
    str++;
  }

  if (n >= 3 && str[0] == '0' && str[1] == '0') {
    while (n >= 3 && str[2] == '0') {
      n--;
      str++;
    }
  }

  if (neg) {  // make room in buf for -
    n++;
    str--;
  }

  if (n > nbuf-1) return "";

  memmove(buf, str, n);
  if (neg) {
    buf[0] = '-';
  }
  buf[n] = '\0';
  *np = n;
  return buf;
}

bool RE2::Arg::parse_long_radix(const char* str,
                                size_t n,
                                void* dest,
                                int radix) {
  if (n == 0) return false;
  char buf[kMaxNumberLength+1];
  str = TerminateNumber(buf, sizeof buf, str, &n, false);
  char* end;
  errno = 0;
  long r = strtol(str, &end, radix);
  if (end != str + n) return false;   // Leftover junk
  if (errno) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<long*>(dest)) = r;
  return true;
}

bool RE2::Arg::parse_ulong_radix(const char* str,
                                 size_t n,
                                 void* dest,
                                 int radix) {
  if (n == 0) return false;
  char buf[kMaxNumberLength+1];
  str = TerminateNumber(buf, sizeof buf, str, &n, false);
  if (str[0] == '-') {
    // strtoul() will silently accept negative numbers and parse
    // them.  This module is more strict and treats them as errors.
    return false;
  }

  char* end;
  errno = 0;
  unsigned long r = strtoul(str, &end, radix);
  if (end != str + n) return false;   // Leftover junk
  if (errno) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<unsigned long*>(dest)) = r;
  return true;
}

bool RE2::Arg::parse_short_radix(const char* str,
                                 size_t n,
                                 void* dest,
                                 int radix) {
  long r;
  if (!parse_long_radix(str, n, &r, radix)) return false;  // Could not parse
  if ((short)r != r) return false;                         // Out of range
  if (dest == NULL) return true;
  *(reinterpret_cast<short*>(dest)) = (short)r;
  return true;
}

bool RE2::Arg::parse_ushort_radix(const char* str,
                                  size_t n,
                                  void* dest,
                                  int radix) {
  unsigned long r;
  if (!parse_ulong_radix(str, n, &r, radix)) return false;  // Could not parse
  if ((unsigned short)r != r) return false;                 // Out of range
  if (dest == NULL) return true;
  *(reinterpret_cast<unsigned short*>(dest)) = (unsigned short)r;
  return true;
}

bool RE2::Arg::parse_int_radix(const char* str,
                               size_t n,
                               void* dest,
                               int radix) {
  long r;
  if (!parse_long_radix(str, n, &r, radix)) return false;  // Could not parse
  if ((int)r != r) return false;                           // Out of range
  if (dest == NULL) return true;
  *(reinterpret_cast<int*>(dest)) = (int)r;
  return true;
}

bool RE2::Arg::parse_uint_radix(const char* str,
                                size_t n,
                                void* dest,
                                int radix) {
  unsigned long r;
  if (!parse_ulong_radix(str, n, &r, radix)) return false;  // Could not parse
  if ((unsigned int)r != r) return false;                   // Out of range
  if (dest == NULL) return true;
  *(reinterpret_cast<unsigned int*>(dest)) = (unsigned int)r;
  return true;
}

bool RE2::Arg::parse_longlong_radix(const char* str,
                                    size_t n,
                                    void* dest,
                                    int radix) {
  if (n == 0) return false;
  char buf[kMaxNumberLength+1];
  str = TerminateNumber(buf, sizeof buf, str, &n, false);
  char* end;
  errno = 0;
  long long r = strtoll(str, &end, radix);
  if (end != str + n) return false;   // Leftover junk
  if (errno) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<long long*>(dest)) = r;
  return true;
}

bool RE2::Arg::parse_ulonglong_radix(const char* str,
                                     size_t n,
                                     void* dest,
                                     int radix) {
  if (n == 0) return false;
  char buf[kMaxNumberLength+1];
  str = TerminateNumber(buf, sizeof buf, str, &n, false);
  if (str[0] == '-') {
    // strtoull() will silently accept negative numbers and parse
    // them.  This module is more strict and treats them as errors.
    return false;
  }
  char* end;
  errno = 0;
  unsigned long long r = strtoull(str, &end, radix);
  if (end != str + n) return false;   // Leftover junk
  if (errno) return false;
  if (dest == NULL) return true;
  *(reinterpret_cast<unsigned long long*>(dest)) = r;
  return true;
}

static bool parse_double_float(const char* str, size_t n, bool isfloat,
                               void* dest) {
  if (n == 0) return false;
  static const int kMaxLength = 200;
  char buf[kMaxLength+1];
  str = TerminateNumber(buf, sizeof buf, str, &n, true);
  char* end;
  errno = 0;
  double r;
  if (isfloat) {
    r = strtof(str, &end);
  } else {
    r = strtod(str, &end);
  }
  if (end != str + n) return false;   // Leftover junk
  if (errno) return false;
  if (dest == NULL) return true;
  if (isfloat) {
    *(reinterpret_cast<float*>(dest)) = (float)r;
  } else {
    *(reinterpret_cast<double*>(dest)) = r;
  }
  return true;
}

bool RE2::Arg::parse_double(const char* str, size_t n, void* dest) {
  return parse_double_float(str, n, false, dest);
}

bool RE2::Arg::parse_float(const char* str, size_t n, void* dest) {
  return parse_double_float(str, n, true, dest);
}

#define DEFINE_INTEGER_PARSER(name)                                            \
  bool RE2::Arg::parse_##name(const char* str, size_t n, void* dest) {         \
    return parse_##name##_radix(str, n, dest, 10);                             \
  }                                                                            \
  bool RE2::Arg::parse_##name##_hex(const char* str, size_t n, void* dest) {   \
    return parse_##name##_radix(str, n, dest, 16);                             \
  }                                                                            \
  bool RE2::Arg::parse_##name##_octal(const char* str, size_t n, void* dest) { \
    return parse_##name##_radix(str, n, dest, 8);                              \
  }                                                                            \
  bool RE2::Arg::parse_##name##_cradix(const char* str, size_t n,              \
                                       void* dest) {                           \
    return parse_##name##_radix(str, n, dest, 0);                              \
  }

DEFINE_INTEGER_PARSER(short);
DEFINE_INTEGER_PARSER(ushort);
DEFINE_INTEGER_PARSER(int);
DEFINE_INTEGER_PARSER(uint);
DEFINE_INTEGER_PARSER(long);
DEFINE_INTEGER_PARSER(ulong);
DEFINE_INTEGER_PARSER(longlong);
DEFINE_INTEGER_PARSER(ulonglong);

#undef DEFINE_INTEGER_PARSER

}  // namespace re2
// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Regular expression representation.
// Tested by parse_test.cc



#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <mutex>
#include <string>
#include <vector>








namespace re2 {

// Constructor.  Allocates vectors as appropriate for operator.
Regexp::Regexp(RegexpOp op, ParseFlags parse_flags)
  : op_(static_cast<uint8_t>(op)),
    simple_(false),
    parse_flags_(static_cast<uint16_t>(parse_flags)),
    ref_(1),
    nsub_(0),
    down_(NULL) {
  subone_ = NULL;
  memset(the_union_, 0, sizeof the_union_);
}

// Destructor.  Assumes already cleaned up children.
// Private: use Decref() instead of delete to destroy Regexps.
// Can't call Decref on the sub-Regexps here because
// that could cause arbitrarily deep recursion, so
// required Decref() to have handled them for us.
Regexp::~Regexp() {
  if (nsub_ > 0)
    LOG(DFATAL) << "Regexp not destroyed.";

  switch (op_) {
    default:
      break;
    case kRegexpCapture:
      delete name_;
      break;
    case kRegexpLiteralString:
      delete[] runes_;
      break;
    case kRegexpCharClass:
      if (cc_)
        cc_->Delete();
      delete ccb_;
      break;
  }
}

// If it's possible to destroy this regexp without recurring,
// do so and return true.  Else return false.
bool Regexp::QuickDestroy() {
  if (nsub_ == 0) {
    delete this;
    return true;
  }
  return false;
}

// Lazily allocated.
static Mutex* ref_mutex;
static std::map<Regexp*, int>* ref_map;

int Regexp::Ref() {
  if (ref_ < kMaxRef)
    return ref_;

  MutexLock l(ref_mutex);
  return (*ref_map)[this];
}

// Increments reference count, returns object as convenience.
Regexp* Regexp::Incref() {
  if (ref_ >= kMaxRef-1) {
    static std::once_flag ref_once;
    std::call_once(ref_once, []() {
      ref_mutex = new Mutex;
      ref_map = new std::map<Regexp*, int>;
    });

    // Store ref count in overflow map.
    MutexLock l(ref_mutex);
    if (ref_ == kMaxRef) {
      // already overflowed
      (*ref_map)[this]++;
    } else {
      // overflowing now
      (*ref_map)[this] = kMaxRef;
      ref_ = kMaxRef;
    }
    return this;
  }

  ref_++;
  return this;
}

// Decrements reference count and deletes this object if count reaches 0.
void Regexp::Decref() {
  if (ref_ == kMaxRef) {
    // Ref count is stored in overflow map.
    MutexLock l(ref_mutex);
    int r = (*ref_map)[this] - 1;
    if (r < kMaxRef) {
      ref_ = static_cast<uint16_t>(r);
      ref_map->erase(this);
    } else {
      (*ref_map)[this] = r;
    }
    return;
  }
  ref_--;
  if (ref_ == 0)
    Destroy();
}

// Deletes this object; ref count has count reached 0.
void Regexp::Destroy() {
  if (QuickDestroy())
    return;

  // Handle recursive Destroy with explicit stack
  // to avoid arbitrarily deep recursion on process stack [sigh].
  down_ = NULL;
  Regexp* stack = this;
  while (stack != NULL) {
    Regexp* re = stack;
    stack = re->down_;
    if (re->ref_ != 0)
      LOG(DFATAL) << "Bad reference count " << re->ref_;
    if (re->nsub_ > 0) {
      Regexp** subs = re->sub();
      for (int i = 0; i < re->nsub_; i++) {
        Regexp* sub = subs[i];
        if (sub == NULL)
          continue;
        if (sub->ref_ == kMaxRef)
          sub->Decref();
        else
          --sub->ref_;
        if (sub->ref_ == 0 && !sub->QuickDestroy()) {
          sub->down_ = stack;
          stack = sub;
        }
      }
      if (re->nsub_ > 1)
        delete[] subs;
      re->nsub_ = 0;
    }
    delete re;
  }
}

void Regexp::AddRuneToString(Rune r) {
  DCHECK(op_ == kRegexpLiteralString);
  if (nrunes_ == 0) {
    // start with 8
    runes_ = new Rune[8];
  } else if (nrunes_ >= 8 && (nrunes_ & (nrunes_ - 1)) == 0) {
    // double on powers of two
    Rune *old = runes_;
    runes_ = new Rune[nrunes_ * 2];
    for (int i = 0; i < nrunes_; i++)
      runes_[i] = old[i];
    delete[] old;
  }

  runes_[nrunes_++] = r;
}

Regexp* Regexp::HaveMatch(int match_id, ParseFlags flags) {
  Regexp* re = new Regexp(kRegexpHaveMatch, flags);
  re->match_id_ = match_id;
  return re;
}

Regexp* Regexp::StarPlusOrQuest(RegexpOp op, Regexp* sub, ParseFlags flags) {
  // Squash **, ++ and ??.
  if (op == sub->op() && flags == sub->parse_flags())
    return sub;

  // Squash *+, *?, +*, +?, ?* and ?+. They all squash to *, so because
  // op is Star/Plus/Quest, we just have to check that sub->op() is too.
  if ((sub->op() == kRegexpStar ||
       sub->op() == kRegexpPlus ||
       sub->op() == kRegexpQuest) &&
      flags == sub->parse_flags()) {
    // If sub is Star, no need to rewrite it.
    if (sub->op() == kRegexpStar)
      return sub;

    // Rewrite sub to Star.
    Regexp* re = new Regexp(kRegexpStar, flags);
    re->AllocSub(1);
    re->sub()[0] = sub->sub()[0]->Incref();
    sub->Decref();  // We didn't consume the reference after all.
    return re;
  }

  Regexp* re = new Regexp(op, flags);
  re->AllocSub(1);
  re->sub()[0] = sub;
  return re;
}

Regexp* Regexp::Plus(Regexp* sub, ParseFlags flags) {
  return StarPlusOrQuest(kRegexpPlus, sub, flags);
}

Regexp* Regexp::Star(Regexp* sub, ParseFlags flags) {
  return StarPlusOrQuest(kRegexpStar, sub, flags);
}

Regexp* Regexp::Quest(Regexp* sub, ParseFlags flags) {
  return StarPlusOrQuest(kRegexpQuest, sub, flags);
}

Regexp* Regexp::ConcatOrAlternate(RegexpOp op, Regexp** sub, int nsub,
                                  ParseFlags flags, bool can_factor) {
  if (nsub == 1)
    return sub[0];

  if (nsub == 0) {
    if (op == kRegexpAlternate)
      return new Regexp(kRegexpNoMatch, flags);
    else
      return new Regexp(kRegexpEmptyMatch, flags);
  }

  Regexp** subcopy = NULL;
  if (op == kRegexpAlternate && can_factor) {
    // Going to edit sub; make a copy so we don't step on caller.
    subcopy = new Regexp*[nsub];
    memmove(subcopy, sub, nsub * sizeof sub[0]);
    sub = subcopy;
    nsub = FactorAlternation(sub, nsub, flags);
    if (nsub == 1) {
      Regexp* re = sub[0];
      delete[] subcopy;
      return re;
    }
  }

  if (nsub > kMaxNsub) {
    // Too many subexpressions to fit in a single Regexp.
    // Make a two-level tree.  Two levels gets us to 65535^2.
    int nbigsub = (nsub+kMaxNsub-1)/kMaxNsub;
    Regexp* re = new Regexp(op, flags);
    re->AllocSub(nbigsub);
    Regexp** subs = re->sub();
    for (int i = 0; i < nbigsub - 1; i++)
      subs[i] = ConcatOrAlternate(op, sub+i*kMaxNsub, kMaxNsub, flags, false);
    subs[nbigsub - 1] = ConcatOrAlternate(op, sub+(nbigsub-1)*kMaxNsub,
                                          nsub - (nbigsub-1)*kMaxNsub, flags,
                                          false);
    delete[] subcopy;
    return re;
  }

  Regexp* re = new Regexp(op, flags);
  re->AllocSub(nsub);
  Regexp** subs = re->sub();
  for (int i = 0; i < nsub; i++)
    subs[i] = sub[i];

  delete[] subcopy;
  return re;
}

Regexp* Regexp::Concat(Regexp** sub, int nsub, ParseFlags flags) {
  return ConcatOrAlternate(kRegexpConcat, sub, nsub, flags, false);
}

Regexp* Regexp::Alternate(Regexp** sub, int nsub, ParseFlags flags) {
  return ConcatOrAlternate(kRegexpAlternate, sub, nsub, flags, true);
}

Regexp* Regexp::AlternateNoFactor(Regexp** sub, int nsub, ParseFlags flags) {
  return ConcatOrAlternate(kRegexpAlternate, sub, nsub, flags, false);
}

Regexp* Regexp::Capture(Regexp* sub, ParseFlags flags, int cap) {
  Regexp* re = new Regexp(kRegexpCapture, flags);
  re->AllocSub(1);
  re->sub()[0] = sub;
  re->cap_ = cap;
  return re;
}

Regexp* Regexp::Repeat(Regexp* sub, ParseFlags flags, int min, int max) {
  Regexp* re = new Regexp(kRegexpRepeat, flags);
  re->AllocSub(1);
  re->sub()[0] = sub;
  re->min_ = min;
  re->max_ = max;
  return re;
}

Regexp* Regexp::NewLiteral(Rune rune, ParseFlags flags) {
  Regexp* re = new Regexp(kRegexpLiteral, flags);
  re->rune_ = rune;
  return re;
}

Regexp* Regexp::LiteralString(Rune* runes, int nrunes, ParseFlags flags) {
  if (nrunes <= 0)
    return new Regexp(kRegexpEmptyMatch, flags);
  if (nrunes == 1)
    return NewLiteral(runes[0], flags);
  Regexp* re = new Regexp(kRegexpLiteralString, flags);
  for (int i = 0; i < nrunes; i++)
    re->AddRuneToString(runes[i]);
  return re;
}

Regexp* Regexp::NewCharClass(CharClass* cc, ParseFlags flags) {
  Regexp* re = new Regexp(kRegexpCharClass, flags);
  re->cc_ = cc;
  return re;
}

void Regexp::Swap(Regexp* that) {
  // Regexp is not trivially copyable, so we cannot freely copy it with
  // memmove(3), but swapping objects like so is safe for our purposes.
  char tmp[sizeof *this];
  void* vthis = reinterpret_cast<void*>(this);
  void* vthat = reinterpret_cast<void*>(that);
  memmove(tmp, vthis, sizeof *this);
  memmove(vthis, vthat, sizeof *this);
  memmove(vthat, tmp, sizeof *this);
}

// Tests equality of all top-level structure but not subregexps.
static bool TopEqual(Regexp* a, Regexp* b) {
  if (a->op() != b->op())
    return false;

  switch (a->op()) {
    case kRegexpNoMatch:
    case kRegexpEmptyMatch:
    case kRegexpAnyChar:
    case kRegexpAnyByte:
    case kRegexpBeginLine:
    case kRegexpEndLine:
    case kRegexpWordBoundary:
    case kRegexpNoWordBoundary:
    case kRegexpBeginText:
      return true;

    case kRegexpEndText:
      // The parse flags remember whether it's \z or (?-m:$),
      // which matters when testing against PCRE.
      return ((a->parse_flags() ^ b->parse_flags()) & Regexp::WasDollar) == 0;

    case kRegexpLiteral:
      return a->rune() == b->rune() &&
             ((a->parse_flags() ^ b->parse_flags()) & Regexp::FoldCase) == 0;

    case kRegexpLiteralString:
      return a->nrunes() == b->nrunes() &&
             ((a->parse_flags() ^ b->parse_flags()) & Regexp::FoldCase) == 0 &&
             memcmp(a->runes(), b->runes(),
                    a->nrunes() * sizeof a->runes()[0]) == 0;

    case kRegexpAlternate:
    case kRegexpConcat:
      return a->nsub() == b->nsub();

    case kRegexpStar:
    case kRegexpPlus:
    case kRegexpQuest:
      return ((a->parse_flags() ^ b->parse_flags()) & Regexp::NonGreedy) == 0;

    case kRegexpRepeat:
      return ((a->parse_flags() ^ b->parse_flags()) & Regexp::NonGreedy) == 0 &&
             a->min() == b->min() &&
             a->max() == b->max();

    case kRegexpCapture:
      return a->cap() == b->cap() && a->name() == b->name();

    case kRegexpHaveMatch:
      return a->match_id() == b->match_id();

    case kRegexpCharClass: {
      CharClass* acc = a->cc();
      CharClass* bcc = b->cc();
      return acc->size() == bcc->size() &&
             acc->end() - acc->begin() == bcc->end() - bcc->begin() &&
             memcmp(acc->begin(), bcc->begin(),
                    (acc->end() - acc->begin()) * sizeof acc->begin()[0]) == 0;
    }
  }

  LOG(DFATAL) << "Unexpected op in Regexp::Equal: " << a->op();
  return 0;
}

bool Regexp::Equal(Regexp* a, Regexp* b) {
  if (a == NULL || b == NULL)
    return a == b;

  if (!TopEqual(a, b))
    return false;

  // Fast path:
  // return without allocating vector if there are no subregexps.
  switch (a->op()) {
    case kRegexpAlternate:
    case kRegexpConcat:
    case kRegexpStar:
    case kRegexpPlus:
    case kRegexpQuest:
    case kRegexpRepeat:
    case kRegexpCapture:
      break;

    default:
      return true;
  }

  // Committed to doing real work.
  // The stack (vector) has pairs of regexps waiting to
  // be compared.  The regexps are only equal if
  // all the pairs end up being equal.
  std::vector<Regexp*> stk;

  for (;;) {
    // Invariant: TopEqual(a, b) == true.
    Regexp* a2;
    Regexp* b2;
    switch (a->op()) {
      default:
        break;
      case kRegexpAlternate:
      case kRegexpConcat:
        for (int i = 0; i < a->nsub(); i++) {
          a2 = a->sub()[i];
          b2 = b->sub()[i];
          if (!TopEqual(a2, b2))
            return false;
          stk.push_back(a2);
          stk.push_back(b2);
        }
        break;

      case kRegexpStar:
      case kRegexpPlus:
      case kRegexpQuest:
      case kRegexpRepeat:
      case kRegexpCapture:
        a2 = a->sub()[0];
        b2 = b->sub()[0];
        if (!TopEqual(a2, b2))
          return false;
        // Really:
        //   stk.push_back(a2);
        //   stk.push_back(b2);
        //   break;
        // but faster to assign directly and loop.
        a = a2;
        b = b2;
        continue;
    }

    size_t n = stk.size();
    if (n == 0)
      break;

    DCHECK_GE(n, 2);
    a = stk[n-2];
    b = stk[n-1];
    stk.resize(n-2);
  }

  return true;
}

// Keep in sync with enum RegexpStatusCode in regexp.h
static const char *kErrorStrings[] = {
  "no error",
  "unexpected error",
  "invalid escape sequence",
  "invalid character class",
  "invalid character class range",
  "missing ]",
  "missing )",
  "trailing \\",
  "no argument for repetition operator",
  "invalid repetition size",
  "bad repetition operator",
  "invalid perl operator",
  "invalid UTF-8",
  "invalid named capture group",
};

std::string RegexpStatus::CodeText(enum RegexpStatusCode code) {
  if (code < 0 || code >= arraysize(kErrorStrings))
    code = kRegexpInternalError;
  return kErrorStrings[code];
}

std::string RegexpStatus::Text() const {
  if (error_arg_.empty())
    return CodeText(code_);
  std::string s;
  s.append(CodeText(code_));
  s.append(": ");
  s.append(error_arg_.data(), error_arg_.size());
  return s;
}

void RegexpStatus::Copy(const RegexpStatus& status) {
  code_ = status.code_;
  error_arg_ = status.error_arg_;
}

typedef int Ignored;  // Walker<void> doesn't exist

// Walker subclass to count capturing parens in regexp.
class NumCapturesWalker : public Regexp::Walker<Ignored> {
 public:
  NumCapturesWalker() : ncapture_(0) {}
  int ncapture() { return ncapture_; }

  virtual Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) {
    if (re->op() == kRegexpCapture)
      ncapture_++;
    return ignored;
  }
  virtual Ignored ShortVisit(Regexp* re, Ignored ignored) {
    // Should never be called: we use Walk not WalkExponential.
    LOG(DFATAL) << "NumCapturesWalker::ShortVisit called";
    return ignored;
  }

 private:
  int ncapture_;

  NumCapturesWalker(const NumCapturesWalker&) = delete;
  NumCapturesWalker& operator=(const NumCapturesWalker&) = delete;
};

int Regexp::NumCaptures() {
  NumCapturesWalker w;
  w.Walk(this, 0);
  return w.ncapture();
}

// Walker class to build map of named capture groups and their indices.
class NamedCapturesWalker : public Regexp::Walker<Ignored> {
 public:
  NamedCapturesWalker() : map_(NULL) {}
  ~NamedCapturesWalker() { delete map_; }

  std::map<std::string, int>* TakeMap() {
    std::map<std::string, int>* m = map_;
    map_ = NULL;
    return m;
  }

  Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) {
    if (re->op() == kRegexpCapture && re->name() != NULL) {
      // Allocate map once we find a name.
      if (map_ == NULL)
        map_ = new std::map<std::string, int>;

      // Record first occurrence of each name.
      // (The rule is that if you have the same name
      // multiple times, only the leftmost one counts.)
      if (map_->find(*re->name()) == map_->end())
        (*map_)[*re->name()] = re->cap();
    }
    return ignored;
  }

  virtual Ignored ShortVisit(Regexp* re, Ignored ignored) {
    // Should never be called: we use Walk not WalkExponential.
    LOG(DFATAL) << "NamedCapturesWalker::ShortVisit called";
    return ignored;
  }

 private:
  std::map<std::string, int>* map_;

  NamedCapturesWalker(const NamedCapturesWalker&) = delete;
  NamedCapturesWalker& operator=(const NamedCapturesWalker&) = delete;
};

std::map<std::string, int>* Regexp::NamedCaptures() {
  NamedCapturesWalker w;
  w.Walk(this, 0);
  return w.TakeMap();
}

// Walker class to build map from capture group indices to their names.
class CaptureNamesWalker : public Regexp::Walker<Ignored> {
 public:
  CaptureNamesWalker() : map_(NULL) {}
  ~CaptureNamesWalker() { delete map_; }

  std::map<int, std::string>* TakeMap() {
    std::map<int, std::string>* m = map_;
    map_ = NULL;
    return m;
  }

  Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) {
    if (re->op() == kRegexpCapture && re->name() != NULL) {
      // Allocate map once we find a name.
      if (map_ == NULL)
        map_ = new std::map<int, std::string>;

      (*map_)[re->cap()] = *re->name();
    }
    return ignored;
  }

  virtual Ignored ShortVisit(Regexp* re, Ignored ignored) {
    // Should never be called: we use Walk not WalkExponential.
    LOG(DFATAL) << "CaptureNamesWalker::ShortVisit called";
    return ignored;
  }

 private:
  std::map<int, std::string>* map_;

  CaptureNamesWalker(const CaptureNamesWalker&) = delete;
  CaptureNamesWalker& operator=(const CaptureNamesWalker&) = delete;
};

std::map<int, std::string>* Regexp::CaptureNames() {
  CaptureNamesWalker w;
  w.Walk(this, 0);
  return w.TakeMap();
}

// Determines whether regexp matches must be anchored
// with a fixed string prefix.  If so, returns the prefix and
// the regexp that remains after the prefix.  The prefix might
// be ASCII case-insensitive.
bool Regexp::RequiredPrefix(std::string* prefix, bool* foldcase,
                            Regexp** suffix) {
  // No need for a walker: the regexp must be of the form
  // 1. some number of ^ anchors
  // 2. a literal char or string
  // 3. the rest
  prefix->clear();
  *foldcase = false;
  *suffix = NULL;
  if (op_ != kRegexpConcat)
    return false;

  // Some number of anchors, then a literal or concatenation.
  int i = 0;
  Regexp** sub = this->sub();
  while (i < nsub_ && sub[i]->op_ == kRegexpBeginText)
    i++;
  if (i == 0 || i >= nsub_)
    return false;

  Regexp* re = sub[i];
  switch (re->op_) {
    default:
      return false;

    case kRegexpLiteralString:
      // Convert to string in proper encoding.
      if (re->parse_flags() & Latin1) {
        prefix->resize(re->nrunes_);
        for (int j = 0; j < re->nrunes_; j++)
          (*prefix)[j] = static_cast<char>(re->runes_[j]);
      } else {
        // Convert to UTF-8 in place.
        // Assume worst-case space and then trim.
        prefix->resize(re->nrunes_ * UTFmax);
        char *p = &(*prefix)[0];
        for (int j = 0; j < re->nrunes_; j++) {
          Rune r = re->runes_[j];
          if (r < Runeself)
            *p++ = static_cast<char>(r);
          else
            p += runetochar(p, &r);
        }
        prefix->resize(p - &(*prefix)[0]);
      }
      break;

    case kRegexpLiteral:
      if ((re->parse_flags() & Latin1) || re->rune_ < Runeself) {
        prefix->append(1, static_cast<char>(re->rune_));
      } else {
        char buf[UTFmax];
        prefix->append(buf, runetochar(buf, &re->rune_));
      }
      break;
  }
  *foldcase = (sub[i]->parse_flags() & FoldCase) != 0;
  i++;

  // The rest.
  if (i < nsub_) {
    for (int j = i; j < nsub_; j++)
      sub[j]->Incref();
    re = Concat(sub + i, nsub_ - i, parse_flags());
  } else {
    re = new Regexp(kRegexpEmptyMatch, parse_flags());
  }
  *suffix = re;
  return true;
}

// Character class builder is a balanced binary tree (STL set)
// containing non-overlapping, non-abutting RuneRanges.
// The less-than operator used in the tree treats two
// ranges as equal if they overlap at all, so that
// lookups for a particular Rune are possible.

CharClassBuilder::CharClassBuilder() {
  nrunes_ = 0;
  upper_ = 0;
  lower_ = 0;
}

// Add lo-hi to the class; return whether class got bigger.
bool CharClassBuilder::AddRange(Rune lo, Rune hi) {
  if (hi < lo)
    return false;

  if (lo <= 'z' && hi >= 'A') {
    // Overlaps some alpha, maybe not all.
    // Update bitmaps telling which ASCII letters are in the set.
    Rune lo1 = std::max<Rune>(lo, 'A');
    Rune hi1 = std::min<Rune>(hi, 'Z');
    if (lo1 <= hi1)
      upper_ |= ((1 << (hi1 - lo1 + 1)) - 1) << (lo1 - 'A');

    lo1 = std::max<Rune>(lo, 'a');
    hi1 = std::min<Rune>(hi, 'z');
    if (lo1 <= hi1)
      lower_ |= ((1 << (hi1 - lo1 + 1)) - 1) << (lo1 - 'a');
  }

  {  // Check whether lo, hi is already in the class.
    iterator it = ranges_.find(RuneRange(lo, lo));
    if (it != end() && it->lo <= lo && hi <= it->hi)
      return false;
  }

  // Look for a range abutting lo on the left.
  // If it exists, take it out and increase our range.
  if (lo > 0) {
    iterator it = ranges_.find(RuneRange(lo-1, lo-1));
    if (it != end()) {
      lo = it->lo;
      if (it->hi > hi)
        hi = it->hi;
      nrunes_ -= it->hi - it->lo + 1;
      ranges_.erase(it);
    }
  }

  // Look for a range abutting hi on the right.
  // If it exists, take it out and increase our range.
  if (hi < Runemax) {
    iterator it = ranges_.find(RuneRange(hi+1, hi+1));
    if (it != end()) {
      hi = it->hi;
      nrunes_ -= it->hi - it->lo + 1;
      ranges_.erase(it);
    }
  }

  // Look for ranges between lo and hi.  Take them out.
  // This is only safe because the set has no overlapping ranges.
  // We've already removed any ranges abutting lo and hi, so
  // any that overlap [lo, hi] must be contained within it.
  for (;;) {
    iterator it = ranges_.find(RuneRange(lo, hi));
    if (it == end())
      break;
    nrunes_ -= it->hi - it->lo + 1;
    ranges_.erase(it);
  }

  // Finally, add [lo, hi].
  nrunes_ += hi - lo + 1;
  ranges_.insert(RuneRange(lo, hi));
  return true;
}

void CharClassBuilder::AddCharClass(CharClassBuilder *cc) {
  for (iterator it = cc->begin(); it != cc->end(); ++it)
    AddRange(it->lo, it->hi);
}

bool CharClassBuilder::Contains(Rune r) {
  return ranges_.find(RuneRange(r, r)) != end();
}

// Does the character class behave the same on A-Z as on a-z?
bool CharClassBuilder::FoldsASCII() {
  return ((upper_ ^ lower_) & AlphaMask) == 0;
}

CharClassBuilder* CharClassBuilder::Copy() {
  CharClassBuilder* cc = new CharClassBuilder;
  for (iterator it = begin(); it != end(); ++it)
    cc->ranges_.insert(RuneRange(it->lo, it->hi));
  cc->upper_ = upper_;
  cc->lower_ = lower_;
  cc->nrunes_ = nrunes_;
  return cc;
}



void CharClassBuilder::RemoveAbove(Rune r) {
  if (r >= Runemax)
    return;

  if (r < 'z') {
    if (r < 'a')
      lower_ = 0;
    else
      lower_ &= AlphaMask >> ('z' - r);
  }

  if (r < 'Z') {
    if (r < 'A')
      upper_ = 0;
    else
      upper_ &= AlphaMask >> ('Z' - r);
  }

  for (;;) {

    iterator it = ranges_.find(RuneRange(r + 1, Runemax));
    if (it == end())
      break;
    RuneRange rr = *it;
    ranges_.erase(it);
    nrunes_ -= rr.hi - rr.lo + 1;
    if (rr.lo <= r) {
      rr.hi = r;
      ranges_.insert(rr);
      nrunes_ += rr.hi - rr.lo + 1;
    }
  }
}

void CharClassBuilder::Negate() {
  // Build up negation and then copy in.
  // Could edit ranges in place, but C++ won't let me.
  std::vector<RuneRange> v;
  v.reserve(ranges_.size() + 1);

  // In negation, first range begins at 0, unless
  // the current class begins at 0.
  iterator it = begin();
  if (it == end()) {
    v.push_back(RuneRange(0, Runemax));
  } else {
    int nextlo = 0;
    if (it->lo == 0) {
      nextlo = it->hi + 1;
      ++it;
    }
    for (; it != end(); ++it) {
      v.push_back(RuneRange(nextlo, it->lo - 1));
      nextlo = it->hi + 1;
    }
    if (nextlo <= Runemax)
      v.push_back(RuneRange(nextlo, Runemax));
  }

  ranges_.clear();
  for (size_t i = 0; i < v.size(); i++)
    ranges_.insert(v[i]);

  upper_ = AlphaMask & ~upper_;
  lower_ = AlphaMask & ~lower_;
  nrunes_ = Runemax+1 - nrunes_;
}

// Character class is a sorted list of ranges.
// The ranges are allocated in the same block as the header,
// necessitating a special allocator and Delete method.

CharClass* CharClass::New(int maxranges) {
  CharClass* cc;
  uint8_t* data = new uint8_t[sizeof *cc + maxranges*sizeof cc->ranges_[0]];
  cc = reinterpret_cast<CharClass*>(data);
  cc->ranges_ = reinterpret_cast<RuneRange*>(data + sizeof *cc);
  cc->nranges_ = 0;
  cc->folds_ascii_ = false;
  cc->nrunes_ = 0;
  return cc;
}

void CharClass::Delete() {
  uint8_t* data = reinterpret_cast<uint8_t*>(this);
  delete[] data;
}

CharClass* CharClass::Negate() {
  CharClass* cc = CharClass::New(nranges_+1);
  cc->folds_ascii_ = folds_ascii_;
  cc->nrunes_ = Runemax + 1 - nrunes_;
  int n = 0;
  int nextlo = 0;
  for (CharClass::iterator it = begin(); it != end(); ++it) {
    if (it->lo == nextlo) {
      nextlo = it->hi + 1;
    } else {
      cc->ranges_[n++] = RuneRange(nextlo, it->lo - 1);
      nextlo = it->hi + 1;
    }
  }
  if (nextlo <= Runemax)
    cc->ranges_[n++] = RuneRange(nextlo, Runemax);
  cc->nranges_ = n;
  return cc;
}

bool CharClass::Contains(Rune r) {
  RuneRange* rr = ranges_;
  int n = nranges_;
  while (n > 0) {
    int m = n/2;
    if (rr[m].hi < r) {
      rr += m+1;
      n -= m+1;
    } else if (r < rr[m].lo) {
      n = m;
    } else {  // rr[m].lo <= r && r <= rr[m].hi
      return true;
    }
  }
  return false;
}

CharClass* CharClassBuilder::GetCharClass() {
  CharClass* cc = CharClass::New(static_cast<int>(ranges_.size()));
  int n = 0;
  for (iterator it = begin(); it != end(); ++it)
    cc->ranges_[n++] = *it;
  cc->nranges_ = n;
  DCHECK_LE(n, static_cast<int>(ranges_.size()));
  cc->nrunes_ = nrunes_;
  cc->folds_ascii_ = FoldsASCII();
  return cc;
}

}  // namespace re2
// Copyright 2010 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Copyright 2010 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef RE2_SET_H_
#define RE2_SET_H_

#include <string>
#include <utility>
#include <vector>



namespace re2 {
class Prog;
class Regexp;
}  // namespace re2

namespace re2 {

// An RE2::Set represents a collection of regexps that can
// be searched for simultaneously.
class RE2::Set {
 public:
  enum ErrorKind {
    kNoError = 0,
    kNotCompiled,   // The set is not compiled.
    kOutOfMemory,   // The DFA ran out of memory.
    kInconsistent,  // The result is inconsistent. This should never happen.
  };

  struct ErrorInfo {
    ErrorKind kind;
  };

  Set(const RE2::Options& options, RE2::Anchor anchor);
  ~Set();

  // Adds pattern to the set using the options passed to the constructor.
  // Returns the index that will identify the regexp in the output of Match(),
  // or -1 if the regexp cannot be parsed.
  // Indices are assigned in sequential order starting from 0.
  // Errors do not increment the index; if error is not NULL, *error will hold
  // the error message from the parser.
  int Add(const StringPiece& pattern, std::string* error);

  // Compiles the set in preparation for matching.
  // Returns false if the compiler runs out of memory.
  // Add() must not be called again after Compile().
  // Compile() must be called before Match().
  bool Compile();

  // Returns true if text matches at least one of the regexps in the set.
  // Fills v (if not NULL) with the indices of the matching regexps.
  // Callers must not expect v to be sorted.
  bool Match(const StringPiece& text, std::vector<int>* v) const;

  // As above, but populates error_info (if not NULL) when none of the regexps
  // in the set matched. This can inform callers when DFA execution fails, for
  // example, because they might wish to handle that case differently.
  bool Match(const StringPiece& text, std::vector<int>* v,
             ErrorInfo* error_info) const;

 private:
  typedef std::pair<std::string, re2::Regexp*> Elem;

  RE2::Options options_;
  RE2::Anchor anchor_;
  std::vector<Elem> elem_;
  re2::Prog* prog_;
  bool compiled_;
  int size_;

  Set(const Set&) = delete;
  Set& operator=(const Set&) = delete;
};

}  // namespace re2

#endif  // RE2_SET_H_


#include <stddef.h>
#include <algorithm>
#include <memory>









namespace re2 {

RE2::Set::Set(const RE2::Options& options, RE2::Anchor anchor) {
  options_.Copy(options);
  options_.set_never_capture(true);  // might unblock some optimisations
  anchor_ = anchor;
  prog_ = NULL;
  compiled_ = false;
  size_ = 0;
}

RE2::Set::~Set() {
  for (size_t i = 0; i < elem_.size(); i++)
    elem_[i].second->Decref();
  delete prog_;
}

int RE2::Set::Add(const StringPiece& pattern, std::string* error) {
  if (compiled_) {
    LOG(DFATAL) << "RE2::Set::Add() called after compiling";
    return -1;
  }

  Regexp::ParseFlags pf = static_cast<Regexp::ParseFlags>(
    options_.ParseFlags());
  RegexpStatus status;
  re2::Regexp* re = Regexp::Parse(pattern, pf, &status);
  if (re == NULL) {
    if (error != NULL)
      *error = status.Text();
    if (options_.log_errors())
      LOG(ERROR) << "Error parsing '" << pattern << "': " << status.Text();
    return -1;
  }

  // Concatenate with match index and push on vector.
  int n = static_cast<int>(elem_.size());
  re2::Regexp* m = re2::Regexp::HaveMatch(n, pf);
  if (re->op() == kRegexpConcat) {
    int nsub = re->nsub();
    PODArray<re2::Regexp*> sub(nsub + 1);
    for (int i = 0; i < nsub; i++)
      sub[i] = re->sub()[i]->Incref();
    sub[nsub] = m;
    re->Decref();
    re = re2::Regexp::Concat(sub.data(), nsub + 1, pf);
  } else {
    re2::Regexp* sub[2];
    sub[0] = re;
    sub[1] = m;
    re = re2::Regexp::Concat(sub, 2, pf);
  }
  elem_.emplace_back(std::string(pattern), re);
  return n;
}

bool RE2::Set::Compile() {
  if (compiled_) {
    LOG(DFATAL) << "RE2::Set::Compile() called more than once";
    return false;
  }
  compiled_ = true;
  size_ = static_cast<int>(elem_.size());

  // Sort the elements by their patterns. This is good enough for now
  // until we have a Regexp comparison function. (Maybe someday...)
  std::sort(elem_.begin(), elem_.end(),
            [](const Elem& a, const Elem& b) -> bool {
              return a.first < b.first;
            });

  PODArray<re2::Regexp*> sub(size_);
  for (int i = 0; i < size_; i++)
    sub[i] = elem_[i].second;
  elem_.clear();
  elem_.shrink_to_fit();

  Regexp::ParseFlags pf = static_cast<Regexp::ParseFlags>(
    options_.ParseFlags());
  re2::Regexp* re = re2::Regexp::Alternate(sub.data(), size_, pf);

  prog_ = Prog::CompileSet(re, anchor_, options_.max_mem());
  re->Decref();
  return prog_ != NULL;
}

bool RE2::Set::Match(const StringPiece& text, std::vector<int>* v) const {
  return Match(text, v, NULL);
}

bool RE2::Set::Match(const StringPiece& text, std::vector<int>* v,
                     ErrorInfo* error_info) const {
  if (!compiled_) {
    LOG(DFATAL) << "RE2::Set::Match() called before compiling";
    if (error_info != NULL)
      error_info->kind = kNotCompiled;
    return false;
  }
  bool dfa_failed = false;
  std::unique_ptr<SparseSet> matches;
  if (v != NULL) {
    matches.reset(new SparseSet(size_));
    v->clear();
  }
  bool ret = prog_->SearchDFA(text, text, Prog::kAnchored, Prog::kManyMatch,
                              NULL, &dfa_failed, matches.get());
  if (dfa_failed) {
    if (options_.log_errors())
      LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", "
                 << "bytemap range " << prog_->bytemap_range() << ", "
                 << "list count " << prog_->list_count();
    if (error_info != NULL)
      error_info->kind = kOutOfMemory;
    return false;
  }
  if (ret == false) {
    if (error_info != NULL)
      error_info->kind = kNoError;
    return false;
  }
  if (v != NULL) {
    if (matches->empty()) {
      LOG(DFATAL) << "RE2::Set::Match() matched, but no matches returned?!";
      if (error_info != NULL)
        error_info->kind = kInconsistent;
      return false;
    }
    v->assign(matches->begin(), matches->end());
  }
  if (error_info != NULL)
    error_info->kind = kNoError;
  return true;
}

}  // namespace re2
// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Rewrite POSIX and other features in re
// to use simple extended regular expression features.
// Also sort and simplify character classes.

#include <string>








namespace re2 {

// Parses the regexp src and then simplifies it and sets *dst to the
// string representation of the simplified form.  Returns true on success.
// Returns false and sets *error (if error != NULL) on error.
bool Regexp::SimplifyRegexp(const StringPiece& src, ParseFlags flags,
                            std::string* dst, RegexpStatus* status) {
  Regexp* re = Parse(src, flags, status);
  if (re == NULL)
    return false;
  Regexp* sre = re->Simplify();
  re->Decref();
  if (sre == NULL) {
    // Should not happen, since Simplify never fails.
    LOG(ERROR) << "Simplify failed on " << src;
    if (status) {
      status->set_code(kRegexpInternalError);
      status->set_error_arg(src);
    }
    return false;
  }
  *dst = sre->ToString();
  sre->Decref();
  return true;
}

// Assuming the simple_ flags on the children are accurate,
// is this Regexp* simple?
bool Regexp::ComputeSimple() {
  Regexp** subs;
  auto ccb = ccb_;
  auto cc = cc_;

  switch (op_) {
    case kRegexpNoMatch:
    case kRegexpEmptyMatch:
    case kRegexpLiteral:
    case kRegexpLiteralString:
    case kRegexpBeginLine:
    case kRegexpEndLine:
    case kRegexpBeginText:
    case kRegexpWordBoundary:
    case kRegexpNoWordBoundary:
    case kRegexpEndText:
    case kRegexpAnyChar:
    case kRegexpAnyByte:
    case kRegexpHaveMatch:
      return true;
    case kRegexpConcat:
    case kRegexpAlternate:
      // These are simple as long as the subpieces are simple.
      subs = sub();
      for (int i = 0; i < nsub_; i++)
        if (!subs[i]->simple())
          return false;
      return true;
    case kRegexpCharClass:
      // Simple as long as the char class is not empty, not full.
      if (ccb != NULL)
        return !ccb->empty() && !ccb->full();
      return !cc->empty() && !cc->full();
    case kRegexpCapture:
      subs = sub();
      return subs[0]->simple();
    case kRegexpStar:
    case kRegexpPlus:
    case kRegexpQuest:
      subs = sub();
      if (!subs[0]->simple())
        return false;
      switch (subs[0]->op_) {
        case kRegexpStar:
        case kRegexpPlus:
        case kRegexpQuest:
        case kRegexpEmptyMatch:
        case kRegexpNoMatch:
          return false;
        default:
          break;
      }
      return true;
    case kRegexpRepeat:
      return false;
  }
  LOG(DFATAL) << "Case not handled in ComputeSimple: " << op_;
  return false;
}

// Walker subclass used by Simplify.
// Coalesces runs of star/plus/quest/repeat of the same literal along with any
// occurrences of that literal into repeats of that literal. It also works for
// char classes, any char and any byte.
// PostVisit creates the coalesced result, which should then be simplified.
class CoalesceWalker : public Regexp::Walker<Regexp*> {
 public:
  CoalesceWalker() {}
  virtual Regexp* PostVisit(Regexp* re, Regexp* parent_arg, Regexp* pre_arg,
                            Regexp** child_args, int nchild_args);
  virtual Regexp* Copy(Regexp* re);
  virtual Regexp* ShortVisit(Regexp* re, Regexp* parent_arg);

 private:
  // These functions are declared inside CoalesceWalker so that
  // they can edit the private fields of the Regexps they construct.

  // Returns true if r1 and r2 can be coalesced. In particular, ensures that
  // the parse flags are consistent. (They will not be checked again later.)
  static bool CanCoalesce(Regexp* r1, Regexp* r2);

  // Coalesces *r1ptr and *r2ptr. In most cases, the array elements afterwards
  // will be empty match and the coalesced op. In other cases, where part of a
  // literal string was removed to be coalesced, the array elements afterwards
  // will be the coalesced op and the remainder of the literal string.
  static void DoCoalesce(Regexp** r1ptr, Regexp** r2ptr);

  CoalesceWalker(const CoalesceWalker&) = delete;
  CoalesceWalker& operator=(const CoalesceWalker&) = delete;
};

// Walker subclass used by Simplify.
// The simplify walk is purely post-recursive: given the simplified children,
// PostVisit creates the simplified result.
// The child_args are simplified Regexp*s.
class SimplifyWalker : public Regexp::Walker<Regexp*> {
 public:
  SimplifyWalker() {}
  virtual Regexp* PreVisit(Regexp* re, Regexp* parent_arg, bool* stop);
  virtual Regexp* PostVisit(Regexp* re, Regexp* parent_arg, Regexp* pre_arg,
                            Regexp** child_args, int nchild_args);
  virtual Regexp* Copy(Regexp* re);
  virtual Regexp* ShortVisit(Regexp* re, Regexp* parent_arg);

 private:
  // These functions are declared inside SimplifyWalker so that
  // they can edit the private fields of the Regexps they construct.

  // Creates a concatenation of two Regexp, consuming refs to re1 and re2.
  // Caller must Decref return value when done with it.
  static Regexp* Concat2(Regexp* re1, Regexp* re2, Regexp::ParseFlags flags);

  // Simplifies the expression re{min,max} in terms of *, +, and ?.
  // Returns a new regexp.  Does not edit re.  Does not consume reference to re.
  // Caller must Decref return value when done with it.
  static Regexp* SimplifyRepeat(Regexp* re, int min, int max,
                                Regexp::ParseFlags parse_flags);

  // Simplifies a character class by expanding any named classes
  // into rune ranges.  Does not edit re.  Does not consume ref to re.
  // Caller must Decref return value when done with it.
  static Regexp* SimplifyCharClass(Regexp* re);

  SimplifyWalker(const SimplifyWalker&) = delete;
  SimplifyWalker& operator=(const SimplifyWalker&) = delete;
};

// Simplifies a regular expression, returning a new regexp.
// The new regexp uses traditional Unix egrep features only,
// plus the Perl (?:) non-capturing parentheses.
// Otherwise, no POSIX or Perl additions.  The new regexp
// captures exactly the same subexpressions (with the same indices)
// as the original.
// Does not edit current object.
// Caller must Decref() return value when done with it.

Regexp* Regexp::Simplify() {
  CoalesceWalker cw;
  Regexp* cre = cw.Walk(this, NULL);
  if (cre == NULL)
    return cre;
  SimplifyWalker sw;
  Regexp* sre = sw.Walk(cre, NULL);
  cre->Decref();
  return sre;
}

// Utility function for PostVisit implementations that compares re->sub() with
// child_args to determine whether any child_args changed. In the common case,
// where nothing changed, calls Decref() for all child_args and returns false,
// so PostVisit must return re->Incref(). Otherwise, returns true.
static bool ChildArgsChanged(Regexp* re, Regexp** child_args) {
  for (int i = 0; i < re->nsub(); i++) {
    Regexp* sub = re->sub()[i];
    Regexp* newsub = child_args[i];
    if (newsub != sub)
      return true;
  }
  for (int i = 0; i < re->nsub(); i++) {
    Regexp* newsub = child_args[i];
    newsub->Decref();
  }
  return false;
}

Regexp* CoalesceWalker::Copy(Regexp* re) {
  return re->Incref();
}

Regexp* CoalesceWalker::ShortVisit(Regexp* re, Regexp* parent_arg) {
  // This should never be called, since we use Walk and not
  // WalkExponential.
  LOG(DFATAL) << "CoalesceWalker::ShortVisit called";
  return re->Incref();
}

Regexp* CoalesceWalker::PostVisit(Regexp* re,
                                  Regexp* parent_arg,
                                  Regexp* pre_arg,
                                  Regexp** child_args,
                                  int nchild_args) {
  if (re->nsub() == 0)
    return re->Incref();

  if (re->op() != kRegexpConcat) {
    if (!ChildArgsChanged(re, child_args))
      return re->Incref();

    // Something changed. Build a new op.
    Regexp* nre = new Regexp(re->op(), re->parse_flags());
    nre->AllocSub(re->nsub());
    Regexp** nre_subs = nre->sub();
    for (int i = 0; i < re->nsub(); i++)
      nre_subs[i] = child_args[i];
    // Repeats and Captures have additional data that must be copied.
    if (re->op() == kRegexpRepeat) {
      nre->min_ = re->min();
      nre->max_ = re->max();
    } else if (re->op() == kRegexpCapture) {
      nre->cap_ = re->cap();
    }
    return nre;
  }

  bool can_coalesce = false;
  for (int i = 0; i < re->nsub(); i++) {
    if (i+1 < re->nsub() &&
        CanCoalesce(child_args[i], child_args[i+1])) {
      can_coalesce = true;
      break;
    }
  }
  if (!can_coalesce) {
    if (!ChildArgsChanged(re, child_args))
      return re->Incref();

    // Something changed. Build a new op.
    Regexp* nre = new Regexp(re->op(), re->parse_flags());
    nre->AllocSub(re->nsub());
    Regexp** nre_subs = nre->sub();
    for (int i = 0; i < re->nsub(); i++)
      nre_subs[i] = child_args[i];
    return nre;
  }

  for (int i = 0; i < re->nsub(); i++) {
    if (i+1 < re->nsub() &&
        CanCoalesce(child_args[i], child_args[i+1]))
      DoCoalesce(&child_args[i], &child_args[i+1]);
  }
  // Determine how many empty matches were left by DoCoalesce.
  int n = 0;
  for (int i = n; i < re->nsub(); i++) {
    if (child_args[i]->op() == kRegexpEmptyMatch)
      n++;
  }
  // Build a new op.
  Regexp* nre = new Regexp(re->op(), re->parse_flags());
  nre->AllocSub(re->nsub() - n);
  Regexp** nre_subs = nre->sub();
  for (int i = 0, j = 0; i < re->nsub(); i++) {
    if (child_args[i]->op() == kRegexpEmptyMatch) {
      child_args[i]->Decref();
      continue;
    }
    nre_subs[j] = child_args[i];
    j++;
  }
  return nre;
}

bool CoalesceWalker::CanCoalesce(Regexp* r1, Regexp* r2) {
  // r1 must be a star/plus/quest/repeat of a literal, char class, any char or
  // any byte.
  if ((r1->op() == kRegexpStar ||
       r1->op() == kRegexpPlus ||
       r1->op() == kRegexpQuest ||
       r1->op() == kRegexpRepeat) &&
      (r1->sub()[0]->op() == kRegexpLiteral ||
       r1->sub()[0]->op() == kRegexpCharClass ||
       r1->sub()[0]->op() == kRegexpAnyChar ||
       r1->sub()[0]->op() == kRegexpAnyByte)) {
    // r2 must be a star/plus/quest/repeat of the same literal, char class,
    // any char or any byte.
    if ((r2->op() == kRegexpStar ||
         r2->op() == kRegexpPlus ||
         r2->op() == kRegexpQuest ||
         r2->op() == kRegexpRepeat) &&
        Regexp::Equal(r1->sub()[0], r2->sub()[0]) &&
        // The parse flags must be consistent.
        ((r1->parse_flags() & Regexp::NonGreedy) ==
         (r2->parse_flags() & Regexp::NonGreedy))) {
      return true;
    }
    // ... OR an occurrence of that literal, char class, any char or any byte
    if (Regexp::Equal(r1->sub()[0], r2)) {
      return true;
    }
    // ... OR a literal string that begins with that literal.
    if (r1->sub()[0]->op() == kRegexpLiteral &&
        r2->op() == kRegexpLiteralString &&
        r2->runes()[0] == r1->sub()[0]->rune() &&
        // The parse flags must be consistent.
        ((r1->sub()[0]->parse_flags() & Regexp::FoldCase) ==
         (r2->parse_flags() & Regexp::FoldCase))) {
      return true;
    }
  }
  return false;
}

void CoalesceWalker::DoCoalesce(Regexp** r1ptr, Regexp** r2ptr) {
  Regexp* r1 = *r1ptr;
  Regexp* r2 = *r2ptr;

  Regexp* nre = Regexp::Repeat(
      r1->sub()[0]->Incref(), r1->parse_flags(), 0, 0);

  switch (r1->op()) {
    case kRegexpStar:
      nre->min_ = 0;
      nre->max_ = -1;
      break;

    case kRegexpPlus:
      nre->min_ = 1;
      nre->max_ = -1;
      break;

    case kRegexpQuest:
      nre->min_ = 0;
      nre->max_ = 1;
      break;

    case kRegexpRepeat:
      nre->min_ = r1->min();
      nre->max_ = r1->max();
      break;

    default:
      LOG(DFATAL) << "DoCoalesce failed: r1->op() is " << r1->op();
      nre->Decref();
      return;
  }

  switch (r2->op()) {
    case kRegexpStar:
      nre->max_ = -1;
      goto LeaveEmpty;

    case kRegexpPlus:
      nre->min_++;
      nre->max_ = -1;
      goto LeaveEmpty;

    case kRegexpQuest:
      if (nre->max() != -1)
        nre->max_++;
      goto LeaveEmpty;

    case kRegexpRepeat:
      nre->min_ += r2->min();
      if (r2->max() == -1)
        nre->max_ = -1;
      else if (nre->max() != -1)
        nre->max_ += r2->max();
      goto LeaveEmpty;

    case kRegexpLiteral:
    case kRegexpCharClass:
    case kRegexpAnyChar:
    case kRegexpAnyByte:
      nre->min_++;
      if (nre->max() != -1)
        nre->max_++;
      goto LeaveEmpty;

    LeaveEmpty:
      *r1ptr = new Regexp(kRegexpEmptyMatch, Regexp::NoParseFlags);
      *r2ptr = nre;
      break;

    case kRegexpLiteralString: {
      Rune r = r1->sub()[0]->rune();
      // Determine how much of the literal string is removed.
      // We know that we have at least one rune. :)
      int n = 1;
      while (n < r2->nrunes() && r2->runes()[n] == r)
        n++;
      nre->min_ += n;
      if (nre->max() != -1)
        nre->max_ += n;
      if (n == r2->nrunes())
        goto LeaveEmpty;
      *r1ptr = nre;
      *r2ptr = Regexp::LiteralString(
          &r2->runes()[n], r2->nrunes() - n, r2->parse_flags());
      break;
    }

    default:
      LOG(DFATAL) << "DoCoalesce failed: r2->op() is " << r2->op();
      nre->Decref();
      return;
  }

  r1->Decref();
  r2->Decref();
}

Regexp* SimplifyWalker::Copy(Regexp* re) {
  return re->Incref();
}

Regexp* SimplifyWalker::ShortVisit(Regexp* re, Regexp* parent_arg) {
  // This should never be called, since we use Walk and not
  // WalkExponential.
  LOG(DFATAL) << "SimplifyWalker::ShortVisit called";
  return re->Incref();
}

Regexp* SimplifyWalker::PreVisit(Regexp* re, Regexp* parent_arg, bool* stop) {
  if (re->simple()) {
    *stop = true;
    return re->Incref();
  }
  return NULL;
}

Regexp* SimplifyWalker::PostVisit(Regexp* re,
                                  Regexp* parent_arg,
                                  Regexp* pre_arg,
                                  Regexp** child_args,
                                  int nchild_args) {
  switch (re->op()) {
    case kRegexpNoMatch:
    case kRegexpEmptyMatch:
    case kRegexpLiteral:
    case kRegexpLiteralString:
    case kRegexpBeginLine:
    case kRegexpEndLine:
    case kRegexpBeginText:
    case kRegexpWordBoundary:
    case kRegexpNoWordBoundary:
    case kRegexpEndText:
    case kRegexpAnyChar:
    case kRegexpAnyByte:
    case kRegexpHaveMatch:
      // All these are always simple.
      re->simple_ = true;
      return re->Incref();

    case kRegexpConcat:
    case kRegexpAlternate: {
      // These are simple as long as the subpieces are simple.
      if (!ChildArgsChanged(re, child_args)) {
        re->simple_ = true;
        return re->Incref();
      }
      Regexp* nre = new Regexp(re->op(), re->parse_flags());
      nre->AllocSub(re->nsub());
      Regexp** nre_subs = nre->sub();
      for (int i = 0; i < re->nsub(); i++)
        nre_subs[i] = child_args[i];
      nre->simple_ = true;
      return nre;
    }

    case kRegexpCapture: {
      Regexp* newsub = child_args[0];
      if (newsub == re->sub()[0]) {
        newsub->Decref();
        re->simple_ = true;
        return re->Incref();
      }
      Regexp* nre = new Regexp(kRegexpCapture, re->parse_flags());
      nre->AllocSub(1);
      nre->sub()[0] = newsub;
      nre->cap_ = re->cap();
      nre->simple_ = true;
      return nre;
    }

    case kRegexpStar:
    case kRegexpPlus:
    case kRegexpQuest: {
      Regexp* newsub = child_args[0];
      // Special case: repeat the empty string as much as
      // you want, but it's still the empty string.
      if (newsub->op() == kRegexpEmptyMatch)
        return newsub;

      // These are simple as long as the subpiece is simple.
      if (newsub == re->sub()[0]) {
        newsub->Decref();
        re->simple_ = true;
        return re->Incref();
      }

      // These are also idempotent if flags are constant.
      if (re->op() == newsub->op() &&
          re->parse_flags() == newsub->parse_flags())
        return newsub;

      Regexp* nre = new Regexp(re->op(), re->parse_flags());
      nre->AllocSub(1);
      nre->sub()[0] = newsub;
      nre->simple_ = true;
      return nre;
    }

    case kRegexpRepeat: {
      Regexp* newsub = child_args[0];
      // Special case: repeat the empty string as much as
      // you want, but it's still the empty string.
      if (newsub->op() == kRegexpEmptyMatch)
        return newsub;

      Regexp* nre = SimplifyRepeat(newsub, re->min_, re->max_,
                                   re->parse_flags());
      newsub->Decref();
      nre->simple_ = true;
      return nre;
    }

    case kRegexpCharClass: {
      Regexp* nre = SimplifyCharClass(re);
      nre->simple_ = true;
      return nre;
    }
  }

  LOG(ERROR) << "Simplify case not handled: " << re->op();
  return re->Incref();
}

// Creates a concatenation of two Regexp, consuming refs to re1 and re2.
// Returns a new Regexp, handing the ref to the caller.
Regexp* SimplifyWalker::Concat2(Regexp* re1, Regexp* re2,
                                Regexp::ParseFlags parse_flags) {
  Regexp* re = new Regexp(kRegexpConcat, parse_flags);
  re->AllocSub(2);
  Regexp** subs = re->sub();
  subs[0] = re1;
  subs[1] = re2;
  return re;
}

// Simplifies the expression re{min,max} in terms of *, +, and ?.
// Returns a new regexp.  Does not edit re.  Does not consume reference to re.
// Caller must Decref return value when done with it.
// The result will *not* necessarily have the right capturing parens
// if you call ToString() and re-parse it: (x){2} becomes (x)(x),
// but in the Regexp* representation, both (x) are marked as $1.
Regexp* SimplifyWalker::SimplifyRepeat(Regexp* re, int min, int max,
                                       Regexp::ParseFlags f) {
  // x{n,} means at least n matches of x.
  if (max == -1) {
    // Special case: x{0,} is x*
    if (min == 0)
      return Regexp::Star(re->Incref(), f);

    // Special case: x{1,} is x+
    if (min == 1)
      return Regexp::Plus(re->Incref(), f);

    // General case: x{4,} is xxxx+
    PODArray<Regexp*> nre_subs(min);
    for (int i = 0; i < min-1; i++)
      nre_subs[i] = re->Incref();
    nre_subs[min-1] = Regexp::Plus(re->Incref(), f);
    return Regexp::Concat(nre_subs.data(), min, f);
  }

  // Special case: (x){0} matches only empty string.
  if (min == 0 && max == 0)
    return new Regexp(kRegexpEmptyMatch, f);

  // Special case: x{1} is just x.
  if (min == 1 && max == 1)
    return re->Incref();

  // General case: x{n,m} means n copies of x and m copies of x?.
  // The machine will do less work if we nest the final m copies,
  // so that x{2,5} = xx(x(x(x)?)?)?

  // Build leading prefix: xx.  Capturing only on the last one.
  Regexp* nre = NULL;
  if (min > 0) {
    PODArray<Regexp*> nre_subs(min);
    for (int i = 0; i < min; i++)
      nre_subs[i] = re->Incref();
    nre = Regexp::Concat(nre_subs.data(), min, f);
  }

  // Build and attach suffix: (x(x(x)?)?)?
  if (max > min) {
    Regexp* suf = Regexp::Quest(re->Incref(), f);
    for (int i = min+1; i < max; i++)
      suf = Regexp::Quest(Concat2(re->Incref(), suf, f), f);
    if (nre == NULL)
      nre = suf;
    else
      nre = Concat2(nre, suf, f);
  }

  if (nre == NULL) {
    // Some degenerate case, like min > max, or min < max < 0.
    // This shouldn't happen, because the parser rejects such regexps.
    LOG(DFATAL) << "Malformed repeat " << re->ToString() << " " << min << " " << max;
    return new Regexp(kRegexpNoMatch, f);
  }

  return nre;
}

// Simplifies a character class.
// Caller must Decref return value when done with it.
Regexp* SimplifyWalker::SimplifyCharClass(Regexp* re) {
  CharClass* cc = re->cc();

  // Special cases
  if (cc->empty())
    return new Regexp(kRegexpNoMatch, re->parse_flags());
  if (cc->full())
    return new Regexp(kRegexpAnyChar, re->parse_flags());

  return re->Incref();
}

}  // namespace re2
// Copyright 2004 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.



#include <ostream>



namespace re2 {

const StringPiece::size_type StringPiece::npos;  // initialized in stringpiece.h

StringPiece::size_type StringPiece::copy(char* buf, size_type n,
                                         size_type pos) const {
  size_type ret = std::min(size_ - pos, n);
  memcpy(buf, data_ + pos, ret);
  return ret;
}

StringPiece StringPiece::substr(size_type pos, size_type n) const {
  if (pos > size_) pos = size_;
  if (n > size_ - pos) n = size_ - pos;
  return StringPiece(data_ + pos, n);
}

StringPiece::size_type StringPiece::find(const StringPiece& s,
                                         size_type pos) const {
  if (pos > size_) return npos;
  const_pointer result = std::search(data_ + pos, data_ + size_,
                                     s.data_, s.data_ + s.size_);
  size_type xpos = result - data_;
  return xpos + s.size_ <= size_ ? xpos : npos;
}

StringPiece::size_type StringPiece::find(char c, size_type pos) const {
  if (size_ <= 0 || pos >= size_) return npos;
  const_pointer result = std::find(data_ + pos, data_ + size_, c);
  return result != data_ + size_ ? result - data_ : npos;
}

StringPiece::size_type StringPiece::rfind(const StringPiece& s,
                                          size_type pos) const {
  if (size_ < s.size_) return npos;
  if (s.size_ == 0) return std::min(size_, pos);
  const_pointer last = data_ + std::min(size_ - s.size_, pos) + s.size_;
  const_pointer result = std::find_end(data_, last, s.data_, s.data_ + s.size_);
  return result != last ? result - data_ : npos;
}

StringPiece::size_type StringPiece::rfind(char c, size_type pos) const {
  if (size_ <= 0) return npos;
  for (size_t i = std::min(pos + 1, size_); i != 0;) {
    if (data_[--i] == c) return i;
  }
  return npos;
}

std::ostream& operator<<(std::ostream& o, const StringPiece& p) {
  o.write(p.data(), p.size());
  return o;
}

}  // namespace re2
// Copyright 2006 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Format a regular expression structure as a string.
// Tested by parse_test.cc

#include <string.h>
#include <string>








namespace re2 {

enum {
  PrecAtom,
  PrecUnary,
  PrecConcat,
  PrecAlternate,
  PrecEmpty,
  PrecParen,
  PrecToplevel,
};

// Helper function.  See description below.
static void AppendCCRange(std::string* t, Rune lo, Rune hi);

// Walker to generate string in s_.
// The arg pointers are actually integers giving the
// context precedence.
// The child_args are always NULL.
class ToStringWalker : public Regexp::Walker<int> {
 public:
  explicit ToStringWalker(std::string* t) : t_(t) {}

  virtual int PreVisit(Regexp* re, int parent_arg, bool* stop);
  virtual int PostVisit(Regexp* re, int parent_arg, int pre_arg,
                        int* child_args, int nchild_args);
  virtual int ShortVisit(Regexp* re, int parent_arg) {
    return 0;
  }

 private:
  std::string* t_;  // The string the walker appends to.

  ToStringWalker(const ToStringWalker&) = delete;
  ToStringWalker& operator=(const ToStringWalker&) = delete;
};

std::string Regexp::ToString() {
  std::string t;
  ToStringWalker w(&t);
  w.WalkExponential(this, PrecToplevel, 100000);
  if (w.stopped_early())
    t += " [truncated]";
  return t;
}

// Visits re before children are processed.
// Appends ( if needed and passes new precedence to children.
int ToStringWalker::PreVisit(Regexp* re, int parent_arg, bool* stop) {
  int prec = parent_arg;
  int nprec = PrecAtom;

  switch (re->op()) {
    case kRegexpNoMatch:
    case kRegexpEmptyMatch:
    case kRegexpLiteral:
    case kRegexpAnyChar:
    case kRegexpAnyByte:
    case kRegexpBeginLine:
    case kRegexpEndLine:
    case kRegexpBeginText:
    case kRegexpEndText:
    case kRegexpWordBoundary:
    case kRegexpNoWordBoundary:
    case kRegexpCharClass:
    case kRegexpHaveMatch:
      nprec = PrecAtom;
      break;

    case kRegexpConcat:
    case kRegexpLiteralString:
      if (prec < PrecConcat)
        t_->append("(?:");
      nprec = PrecConcat;
      break;

    case kRegexpAlternate:
      if (prec < PrecAlternate)
        t_->append("(?:");
      nprec = PrecAlternate;
      break;

    case kRegexpCapture:
      t_->append("(");
      if (re->cap() == 0)
        LOG(DFATAL) << "kRegexpCapture cap() == 0";
      if (re->name()) {
        t_->append("?P<");
        t_->append(*re->name());
        t_->append(">");
      }
      nprec = PrecParen;
      break;

    case kRegexpStar:
    case kRegexpPlus:
    case kRegexpQuest:
    case kRegexpRepeat:
      if (prec < PrecUnary)
        t_->append("(?:");
      // The subprecedence here is PrecAtom instead of PrecUnary
      // because PCRE treats two unary ops in a row as a parse error.
      nprec = PrecAtom;
      break;
  }

  return nprec;
}

static void AppendLiteral(std::string *t, Rune r, bool foldcase) {
  if (r != 0 && r < 0x80 && strchr("(){}[]*+?|.^$\\", r)) {
    t->append(1, '\\');
    t->append(1, static_cast<char>(r));
  } else if (foldcase && 'a' <= r && r <= 'z') {
    r -= 'a' - 'A';
    t->append(1, '[');
    t->append(1, static_cast<char>(r));
    t->append(1, static_cast<char>(r) + 'a' - 'A');
    t->append(1, ']');
  } else {
    AppendCCRange(t, r, r);
  }
}

// Visits re after children are processed.
// For childless regexps, all the work is done here.
// For regexps with children, append any unary suffixes or ).
int ToStringWalker::PostVisit(Regexp* re, int parent_arg, int pre_arg,
                              int* child_args, int nchild_args) {
  int prec = parent_arg;
  switch (re->op()) {
    case kRegexpNoMatch:
      // There's no simple symbol for "no match", but
      // [^0-Runemax] excludes everything.
      t_->append("[^\\x00-\\x{10ffff}]");
      break;

    case kRegexpEmptyMatch:
      // Append (?:) to make empty string visible,
      // unless this is already being parenthesized.
      if (prec < PrecEmpty)
        t_->append("(?:)");
      break;

    case kRegexpLiteral:
      AppendLiteral(t_, re->rune(),
                    (re->parse_flags() & Regexp::FoldCase) != 0);
      break;

    case kRegexpLiteralString:
      for (int i = 0; i < re->nrunes(); i++)
        AppendLiteral(t_, re->runes()[i],
                      (re->parse_flags() & Regexp::FoldCase) != 0);
      if (prec < PrecConcat)
        t_->append(")");
      break;

    case kRegexpConcat:
      if (prec < PrecConcat)
        t_->append(")");
      break;

    case kRegexpAlternate:
      // Clumsy but workable: the children all appended |
      // at the end of their strings, so just remove the last one.
      if ((*t_)[t_->size()-1] == '|')
        t_->erase(t_->size()-1);
      else
        LOG(DFATAL) << "Bad final char: " << t_;
      if (prec < PrecAlternate)
        t_->append(")");
      break;

    case kRegexpStar:
      t_->append("*");
      if (re->parse_flags() & Regexp::NonGreedy)
        t_->append("?");
      if (prec < PrecUnary)
        t_->append(")");
      break;

    case kRegexpPlus:
      t_->append("+");
      if (re->parse_flags() & Regexp::NonGreedy)
        t_->append("?");
      if (prec < PrecUnary)
        t_->append(")");
      break;

    case kRegexpQuest:
      t_->append("?");
      if (re->parse_flags() & Regexp::NonGreedy)
        t_->append("?");
      if (prec < PrecUnary)
        t_->append(")");
      break;

    case kRegexpRepeat:
      if (re->max() == -1)
        t_->append(StringPrintf("{%d,}", re->min()));
      else if (re->min() == re->max())
        t_->append(StringPrintf("{%d}", re->min()));
      else
        t_->append(StringPrintf("{%d,%d}", re->min(), re->max()));
      if (re->parse_flags() & Regexp::NonGreedy)
        t_->append("?");
      if (prec < PrecUnary)
        t_->append(")");
      break;

    case kRegexpAnyChar:
      t_->append(".");
      break;

    case kRegexpAnyByte:
      t_->append("\\C");
      break;

    case kRegexpBeginLine:
      t_->append("^");
      break;

    case kRegexpEndLine:
      t_->append("$");
      break;

    case kRegexpBeginText:
      t_->append("(?-m:^)");
      break;

    case kRegexpEndText:
      if (re->parse_flags() & Regexp::WasDollar)
        t_->append("(?-m:$)");
      else
        t_->append("\\z");
      break;

    case kRegexpWordBoundary:
      t_->append("\\b");
      break;

    case kRegexpNoWordBoundary:
      t_->append("\\B");
      break;

    case kRegexpCharClass: {
      if (re->cc()->size() == 0) {
        t_->append("[^\\x00-\\x{10ffff}]");
        break;
      }
      t_->append("[");
      // Heuristic: show class as negated if it contains the
      // non-character 0xFFFE.
      CharClass* cc = re->cc();
      if (cc->Contains(0xFFFE)) {
        cc = cc->Negate();
        t_->append("^");
      }
      for (CharClass::iterator i = cc->begin(); i != cc->end(); ++i)
        AppendCCRange(t_, i->lo, i->hi);
      if (cc != re->cc())
        cc->Delete();
      t_->append("]");
      break;
    }

    case kRegexpCapture:
      t_->append(")");
      break;

    case kRegexpHaveMatch:
      // There's no syntax accepted by the parser to generate
      // this node (it is generated by RE2::Set) so make something
      // up that is readable but won't compile.
      t_->append("(?HaveMatch:%d)", re->match_id());
      break;
  }

  // If the parent is an alternation, append the | for it.
  if (prec == PrecAlternate)
    t_->append("|");

  return 0;
}

// Appends a rune for use in a character class to the string t.
static void AppendCCChar(std::string* t, Rune r) {
  if (0x20 <= r && r <= 0x7E) {
    if (strchr("[]^-\\", r))
      t->append("\\");
    t->append(1, static_cast<char>(r));
    return;
  }
  switch (r) {
    default:
      break;

    case '\r':
      t->append("\\r");
      return;

    case '\t':
      t->append("\\t");
      return;

    case '\n':
      t->append("\\n");
      return;

    case '\f':
      t->append("\\f");
      return;
  }

  if (r < 0x100) {
    StringAppendF(t, "\\x%02x", static_cast<int>(r));
    return;
  }
  StringAppendF(t, "\\x{%x}", static_cast<int>(r));
}

static void AppendCCRange(std::string* t, Rune lo, Rune hi) {
  if (lo > hi)
    return;
  AppendCCChar(t, lo);
  if (lo < hi) {
    t->append("-");
    AppendCCChar(t, hi);
  }
}

}  // namespace re2

// GENERATED BY make_unicode_casefold.py; DO NOT EDIT.
// make_unicode_casefold.py >unicode_casefold.cc



namespace re2 {


// 1374 groups, 2778 pairs, 349 ranges
const CaseFold unicode_casefold[] = {
	{ 65, 90, 32 },
	{ 97, 106, -32 },
	{ 107, 107, 8383 },
	{ 108, 114, -32 },
	{ 115, 115, 268 },
	{ 116, 122, -32 },
	{ 181, 181, 743 },
	{ 192, 214, 32 },
	{ 216, 222, 32 },
	{ 223, 223, 7615 },
	{ 224, 228, -32 },
	{ 229, 229, 8262 },
	{ 230, 246, -32 },
	{ 248, 254, -32 },
	{ 255, 255, 121 },
	{ 256, 303, EvenOdd },
	{ 306, 311, EvenOdd },
	{ 313, 328, OddEven },
	{ 330, 375, EvenOdd },
	{ 376, 376, -121 },
	{ 377, 382, OddEven },
	{ 383, 383, -300 },
	{ 384, 384, 195 },
	{ 385, 385, 210 },
	{ 386, 389, EvenOdd },
	{ 390, 390, 206 },
	{ 391, 392, OddEven },
	{ 393, 394, 205 },
	{ 395, 396, OddEven },
	{ 398, 398, 79 },
	{ 399, 399, 202 },
	{ 400, 400, 203 },
	{ 401, 402, OddEven },
	{ 403, 403, 205 },
	{ 404, 404, 207 },
	{ 405, 405, 97 },
	{ 406, 406, 211 },
	{ 407, 407, 209 },
	{ 408, 409, EvenOdd },
	{ 410, 410, 163 },
	{ 412, 412, 211 },
	{ 413, 413, 213 },
	{ 414, 414, 130 },
	{ 415, 415, 214 },
	{ 416, 421, EvenOdd },
	{ 422, 422, 218 },
	{ 423, 424, OddEven },
	{ 425, 425, 218 },
	{ 428, 429, EvenOdd },
	{ 430, 430, 218 },
	{ 431, 432, OddEven },
	{ 433, 434, 217 },
	{ 435, 438, OddEven },
	{ 439, 439, 219 },
	{ 440, 441, EvenOdd },
	{ 444, 445, EvenOdd },
	{ 447, 447, 56 },
	{ 452, 452, EvenOdd },
	{ 453, 453, OddEven },
	{ 454, 454, -2 },
	{ 455, 455, OddEven },
	{ 456, 456, EvenOdd },
	{ 457, 457, -2 },
	{ 458, 458, EvenOdd },
	{ 459, 459, OddEven },
	{ 460, 460, -2 },
	{ 461, 476, OddEven },
	{ 477, 477, -79 },
	{ 478, 495, EvenOdd },
	{ 497, 497, OddEven },
	{ 498, 498, EvenOdd },
	{ 499, 499, -2 },
	{ 500, 501, EvenOdd },
	{ 502, 502, -97 },
	{ 503, 503, -56 },
	{ 504, 543, EvenOdd },
	{ 544, 544, -130 },
	{ 546, 563, EvenOdd },
	{ 570, 570, 10795 },
	{ 571, 572, OddEven },
	{ 573, 573, -163 },
	{ 574, 574, 10792 },
	{ 575, 576, 10815 },
	{ 577, 578, OddEven },
	{ 579, 579, -195 },
	{ 580, 580, 69 },
	{ 581, 581, 71 },
	{ 582, 591, EvenOdd },
	{ 592, 592, 10783 },
	{ 593, 593, 10780 },
	{ 594, 594, 10782 },
	{ 595, 595, -210 },
	{ 596, 596, -206 },
	{ 598, 599, -205 },
	{ 601, 601, -202 },
	{ 603, 603, -203 },
	{ 604, 604, 42319 },
	{ 608, 608, -205 },
	{ 609, 609, 42315 },
	{ 611, 611, -207 },
	{ 613, 613, 42280 },
	{ 614, 614, 42308 },
	{ 616, 616, -209 },
	{ 617, 617, -211 },
	{ 618, 618, 42308 },
	{ 619, 619, 10743 },
	{ 620, 620, 42305 },
	{ 623, 623, -211 },
	{ 625, 625, 10749 },
	{ 626, 626, -213 },
	{ 629, 629, -214 },
	{ 637, 637, 10727 },
	{ 640, 640, -218 },
	{ 643, 643, -218 },
	{ 647, 647, 42282 },
	{ 648, 648, -218 },
	{ 649, 649, -69 },
	{ 650, 651, -217 },
	{ 652, 652, -71 },
	{ 658, 658, -219 },
	{ 669, 669, 42261 },
	{ 670, 670, 42258 },
	{ 837, 837, 84 },
	{ 880, 883, EvenOdd },
	{ 886, 887, EvenOdd },
	{ 891, 893, 130 },
	{ 895, 895, 116 },
	{ 902, 902, 38 },
	{ 904, 906, 37 },
	{ 908, 908, 64 },
	{ 910, 911, 63 },
	{ 913, 929, 32 },
	{ 931, 931, 31 },
	{ 932, 939, 32 },
	{ 940, 940, -38 },
	{ 941, 943, -37 },
	{ 945, 945, -32 },
	{ 946, 946, 30 },
	{ 947, 948, -32 },
	{ 949, 949, 64 },
	{ 950, 951, -32 },
	{ 952, 952, 25 },
	{ 953, 953, 7173 },
	{ 954, 954, 54 },
	{ 955, 955, -32 },
	{ 956, 956, -775 },
	{ 957, 959, -32 },
	{ 960, 960, 22 },
	{ 961, 961, 48 },
	{ 962, 962, EvenOdd },
	{ 963, 965, -32 },
	{ 966, 966, 15 },
	{ 967, 968, -32 },
	{ 969, 969, 7517 },
	{ 970, 971, -32 },
	{ 972, 972, -64 },
	{ 973, 974, -63 },
	{ 975, 975, 8 },
	{ 976, 976, -62 },
	{ 977, 977, 35 },
	{ 981, 981, -47 },
	{ 982, 982, -54 },
	{ 983, 983, -8 },
	{ 984, 1007, EvenOdd },
	{ 1008, 1008, -86 },
	{ 1009, 1009, -80 },
	{ 1010, 1010, 7 },
	{ 1011, 1011, -116 },
	{ 1012, 1012, -92 },
	{ 1013, 1013, -96 },
	{ 1015, 1016, OddEven },
	{ 1017, 1017, -7 },
	{ 1018, 1019, EvenOdd },
	{ 1021, 1023, -130 },
	{ 1024, 1039, 80 },
	{ 1040, 1071, 32 },
	{ 1072, 1073, -32 },
	{ 1074, 1074, 6222 },
	{ 1075, 1075, -32 },
	{ 1076, 1076, 6221 },
	{ 1077, 1085, -32 },
	{ 1086, 1086, 6212 },
	{ 1087, 1088, -32 },
	{ 1089, 1090, 6210 },
	{ 1091, 1097, -32 },
	{ 1098, 1098, 6204 },
	{ 1099, 1103, -32 },
	{ 1104, 1119, -80 },
	{ 1120, 1122, EvenOdd },
	{ 1123, 1123, 6180 },
	{ 1124, 1153, EvenOdd },
	{ 1162, 1215, EvenOdd },
	{ 1216, 1216, 15 },
	{ 1217, 1230, OddEven },
	{ 1231, 1231, -15 },
	{ 1232, 1327, EvenOdd },
	{ 1329, 1366, 48 },
	{ 1377, 1414, -48 },
	{ 4256, 4293, 7264 },
	{ 4295, 4295, 7264 },
	{ 4301, 4301, 7264 },
	{ 4304, 4346, 3008 },
	{ 4349, 4351, 3008 },
	{ 5024, 5103, 38864 },
	{ 5104, 5109, 8 },
	{ 5112, 5117, -8 },
	{ 7296, 7296, -6254 },
	{ 7297, 7297, -6253 },
	{ 7298, 7298, -6244 },
	{ 7299, 7299, -6242 },
	{ 7300, 7300, EvenOdd },
	{ 7301, 7301, -6243 },
	{ 7302, 7302, -6236 },
	{ 7303, 7303, -6181 },
	{ 7304, 7304, 35266 },
	{ 7312, 7354, -3008 },
	{ 7357, 7359, -3008 },
	{ 7545, 7545, 35332 },
	{ 7549, 7549, 3814 },
	{ 7680, 7776, EvenOdd },
	{ 7777, 7777, 58 },
	{ 7778, 7829, EvenOdd },
	{ 7835, 7835, -59 },
	{ 7838, 7838, -7615 },
	{ 7840, 7935, EvenOdd },
	{ 7936, 7943, 8 },
	{ 7944, 7951, -8 },
	{ 7952, 7957, 8 },
	{ 7960, 7965, -8 },
	{ 7968, 7975, 8 },
	{ 7976, 7983, -8 },
	{ 7984, 7991, 8 },
	{ 7992, 7999, -8 },
	{ 8000, 8005, 8 },
	{ 8008, 8013, -8 },
	{ 8017, 8017, 8 },
	{ 8019, 8019, 8 },
	{ 8021, 8021, 8 },
	{ 8023, 8023, 8 },
	{ 8025, 8025, -8 },
	{ 8027, 8027, -8 },
	{ 8029, 8029, -8 },
	{ 8031, 8031, -8 },
	{ 8032, 8039, 8 },
	{ 8040, 8047, -8 },
	{ 8048, 8049, 74 },
	{ 8050, 8053, 86 },
	{ 8054, 8055, 100 },
	{ 8056, 8057, 128 },
	{ 8058, 8059, 112 },
	{ 8060, 8061, 126 },
	{ 8064, 8071, 8 },
	{ 8072, 8079, -8 },
	{ 8080, 8087, 8 },
	{ 8088, 8095, -8 },
	{ 8096, 8103, 8 },
	{ 8104, 8111, -8 },
	{ 8112, 8113, 8 },
	{ 8115, 8115, 9 },
	{ 8120, 8121, -8 },
	{ 8122, 8123, -74 },
	{ 8124, 8124, -9 },
	{ 8126, 8126, -7289 },
	{ 8131, 8131, 9 },
	{ 8136, 8139, -86 },
	{ 8140, 8140, -9 },
	{ 8144, 8145, 8 },
	{ 8152, 8153, -8 },
	{ 8154, 8155, -100 },
	{ 8160, 8161, 8 },
	{ 8165, 8165, 7 },
	{ 8168, 8169, -8 },
	{ 8170, 8171, -112 },
	{ 8172, 8172, -7 },
	{ 8179, 8179, 9 },
	{ 8184, 8185, -128 },
	{ 8186, 8187, -126 },
	{ 8188, 8188, -9 },
	{ 8486, 8486, -7549 },
	{ 8490, 8490, -8415 },
	{ 8491, 8491, -8294 },
	{ 8498, 8498, 28 },
	{ 8526, 8526, -28 },
	{ 8544, 8559, 16 },
	{ 8560, 8575, -16 },
	{ 8579, 8580, OddEven },
	{ 9398, 9423, 26 },
	{ 9424, 9449, -26 },
	{ 11264, 11310, 48 },
	{ 11312, 11358, -48 },
	{ 11360, 11361, EvenOdd },
	{ 11362, 11362, -10743 },
	{ 11363, 11363, -3814 },
	{ 11364, 11364, -10727 },
	{ 11365, 11365, -10795 },
	{ 11366, 11366, -10792 },
	{ 11367, 11372, OddEven },
	{ 11373, 11373, -10780 },
	{ 11374, 11374, -10749 },
	{ 11375, 11375, -10783 },
	{ 11376, 11376, -10782 },
	{ 11378, 11379, EvenOdd },
	{ 11381, 11382, OddEven },
	{ 11390, 11391, -10815 },
	{ 11392, 11491, EvenOdd },
	{ 11499, 11502, OddEven },
	{ 11506, 11507, EvenOdd },
	{ 11520, 11557, -7264 },
	{ 11559, 11559, -7264 },
	{ 11565, 11565, -7264 },
	{ 42560, 42570, EvenOdd },
	{ 42571, 42571, -35267 },
	{ 42572, 42605, EvenOdd },
	{ 42624, 42651, EvenOdd },
	{ 42786, 42799, EvenOdd },
	{ 42802, 42863, EvenOdd },
	{ 42873, 42876, OddEven },
	{ 42877, 42877, -35332 },
	{ 42878, 42887, EvenOdd },
	{ 42891, 42892, OddEven },
	{ 42893, 42893, -42280 },
	{ 42896, 42899, EvenOdd },
	{ 42902, 42921, EvenOdd },
	{ 42922, 42922, -42308 },
	{ 42923, 42923, -42319 },
	{ 42924, 42924, -42315 },
	{ 42925, 42925, -42305 },
	{ 42926, 42926, -42308 },
	{ 42928, 42928, -42258 },
	{ 42929, 42929, -42282 },
	{ 42930, 42930, -42261 },
	{ 42931, 42931, 928 },
	{ 42932, 42937, EvenOdd },
	{ 43859, 43859, -928 },
	{ 43888, 43967, -38864 },
	{ 65313, 65338, 32 },
	{ 65345, 65370, -32 },
	{ 66560, 66599, 40 },
	{ 66600, 66639, -40 },
	{ 66736, 66771, 40 },
	{ 66776, 66811, -40 },
	{ 68736, 68786, 64 },
	{ 68800, 68850, -64 },
	{ 71840, 71871, 32 },
	{ 71872, 71903, -32 },
	{ 93760, 93791, 32 },
	{ 93792, 93823, -32 },
	{ 125184, 125217, 34 },
	{ 125218, 125251, -34 },
};
const int num_unicode_casefold = 349;

// 1374 groups, 1404 pairs, 194 ranges
const CaseFold unicode_tolower[] = {
	{ 65, 90, 32 },
	{ 181, 181, 775 },
	{ 192, 214, 32 },
	{ 216, 222, 32 },
	{ 256, 302, EvenOddSkip },
	{ 306, 310, EvenOddSkip },
	{ 313, 327, OddEvenSkip },
	{ 330, 374, EvenOddSkip },
	{ 376, 376, -121 },
	{ 377, 381, OddEvenSkip },
	{ 383, 383, -268 },
	{ 385, 385, 210 },
	{ 386, 388, EvenOddSkip },
	{ 390, 390, 206 },
	{ 391, 391, OddEven },
	{ 393, 394, 205 },
	{ 395, 395, OddEven },
	{ 398, 398, 79 },
	{ 399, 399, 202 },
	{ 400, 400, 203 },
	{ 401, 401, OddEven },
	{ 403, 403, 205 },
	{ 404, 404, 207 },
	{ 406, 406, 211 },
	{ 407, 407, 209 },
	{ 408, 408, EvenOdd },
	{ 412, 412, 211 },
	{ 413, 413, 213 },
	{ 415, 415, 214 },
	{ 416, 420, EvenOddSkip },
	{ 422, 422, 218 },
	{ 423, 423, OddEven },
	{ 425, 425, 218 },
	{ 428, 428, EvenOdd },
	{ 430, 430, 218 },
	{ 431, 431, OddEven },
	{ 433, 434, 217 },
	{ 435, 437, OddEvenSkip },
	{ 439, 439, 219 },
	{ 440, 440, EvenOdd },
	{ 444, 444, EvenOdd },
	{ 452, 452, 2 },
	{ 453, 453, OddEven },
	{ 455, 455, 2 },
	{ 456, 456, EvenOdd },
	{ 458, 458, 2 },
	{ 459, 475, OddEvenSkip },
	{ 478, 494, EvenOddSkip },
	{ 497, 497, 2 },
	{ 498, 500, EvenOddSkip },
	{ 502, 502, -97 },
	{ 503, 503, -56 },
	{ 504, 542, EvenOddSkip },
	{ 544, 544, -130 },
	{ 546, 562, EvenOddSkip },
	{ 570, 570, 10795 },
	{ 571, 571, OddEven },
	{ 573, 573, -163 },
	{ 574, 574, 10792 },
	{ 577, 577, OddEven },
	{ 579, 579, -195 },
	{ 580, 580, 69 },
	{ 581, 581, 71 },
	{ 582, 590, EvenOddSkip },
	{ 837, 837, 116 },
	{ 880, 882, EvenOddSkip },
	{ 886, 886, EvenOdd },
	{ 895, 895, 116 },
	{ 902, 902, 38 },
	{ 904, 906, 37 },
	{ 908, 908, 64 },
	{ 910, 911, 63 },
	{ 913, 929, 32 },
	{ 931, 939, 32 },
	{ 962, 962, EvenOdd },
	{ 975, 975, 8 },
	{ 976, 976, -30 },
	{ 977, 977, -25 },
	{ 981, 981, -15 },
	{ 982, 982, -22 },
	{ 984, 1006, EvenOddSkip },
	{ 1008, 1008, -54 },
	{ 1009, 1009, -48 },
	{ 1012, 1012, -60 },
	{ 1013, 1013, -64 },
	{ 1015, 1015, OddEven },
	{ 1017, 1017, -7 },
	{ 1018, 1018, EvenOdd },
	{ 1021, 1023, -130 },
	{ 1024, 1039, 80 },
	{ 1040, 1071, 32 },
	{ 1120, 1152, EvenOddSkip },
	{ 1162, 1214, EvenOddSkip },
	{ 1216, 1216, 15 },
	{ 1217, 1229, OddEvenSkip },
	{ 1232, 1326, EvenOddSkip },
	{ 1329, 1366, 48 },
	{ 4256, 4293, 7264 },
	{ 4295, 4295, 7264 },
	{ 4301, 4301, 7264 },
	{ 5112, 5117, -8 },
	{ 7296, 7296, -6222 },
	{ 7297, 7297, -6221 },
	{ 7298, 7298, -6212 },
	{ 7299, 7300, -6210 },
	{ 7301, 7301, -6211 },
	{ 7302, 7302, -6204 },
	{ 7303, 7303, -6180 },
	{ 7304, 7304, 35267 },
	{ 7312, 7354, -3008 },
	{ 7357, 7359, -3008 },
	{ 7680, 7828, EvenOddSkip },
	{ 7835, 7835, -58 },
	{ 7838, 7838, -7615 },
	{ 7840, 7934, EvenOddSkip },
	{ 7944, 7951, -8 },
	{ 7960, 7965, -8 },
	{ 7976, 7983, -8 },
	{ 7992, 7999, -8 },
	{ 8008, 8013, -8 },
	{ 8025, 8025, -8 },
	{ 8027, 8027, -8 },
	{ 8029, 8029, -8 },
	{ 8031, 8031, -8 },
	{ 8040, 8047, -8 },
	{ 8072, 8079, -8 },
	{ 8088, 8095, -8 },
	{ 8104, 8111, -8 },
	{ 8120, 8121, -8 },
	{ 8122, 8123, -74 },
	{ 8124, 8124, -9 },
	{ 8126, 8126, -7173 },
	{ 8136, 8139, -86 },
	{ 8140, 8140, -9 },
	{ 8152, 8153, -8 },
	{ 8154, 8155, -100 },
	{ 8168, 8169, -8 },
	{ 8170, 8171, -112 },
	{ 8172, 8172, -7 },
	{ 8184, 8185, -128 },
	{ 8186, 8187, -126 },
	{ 8188, 8188, -9 },
	{ 8486, 8486, -7517 },
	{ 8490, 8490, -8383 },
	{ 8491, 8491, -8262 },
	{ 8498, 8498, 28 },
	{ 8544, 8559, 16 },
	{ 8579, 8579, OddEven },
	{ 9398, 9423, 26 },
	{ 11264, 11310, 48 },
	{ 11360, 11360, EvenOdd },
	{ 11362, 11362, -10743 },
	{ 11363, 11363, -3814 },
	{ 11364, 11364, -10727 },
	{ 11367, 11371, OddEvenSkip },
	{ 11373, 11373, -10780 },
	{ 11374, 11374, -10749 },
	{ 11375, 11375, -10783 },
	{ 11376, 11376, -10782 },
	{ 11378, 11378, EvenOdd },
	{ 11381, 11381, OddEven },
	{ 11390, 11391, -10815 },
	{ 11392, 11490, EvenOddSkip },
	{ 11499, 11501, OddEvenSkip },
	{ 11506, 11506, EvenOdd },
	{ 42560, 42604, EvenOddSkip },
	{ 42624, 42650, EvenOddSkip },
	{ 42786, 42798, EvenOddSkip },
	{ 42802, 42862, EvenOddSkip },
	{ 42873, 42875, OddEvenSkip },
	{ 42877, 42877, -35332 },
	{ 42878, 42886, EvenOddSkip },
	{ 42891, 42891, OddEven },
	{ 42893, 42893, -42280 },
	{ 42896, 42898, EvenOddSkip },
	{ 42902, 42920, EvenOddSkip },
	{ 42922, 42922, -42308 },
	{ 42923, 42923, -42319 },
	{ 42924, 42924, -42315 },
	{ 42925, 42925, -42305 },
	{ 42926, 42926, -42308 },
	{ 42928, 42928, -42258 },
	{ 42929, 42929, -42282 },
	{ 42930, 42930, -42261 },
	{ 42931, 42931, 928 },
	{ 42932, 42936, EvenOddSkip },
	{ 43888, 43967, -38864 },
	{ 65313, 65338, 32 },
	{ 66560, 66599, 40 },
	{ 66736, 66771, 40 },
	{ 68736, 68786, 64 },
	{ 71840, 71871, 32 },
	{ 93760, 93791, 32 },
	{ 125184, 125217, 34 },
};
const int num_unicode_tolower = 194;



} // namespace re2



// GENERATED BY make_unicode_groups.py; DO NOT EDIT.
// make_unicode_groups.py >unicode_groups.cc



namespace re2 {


static const URange16 Ps_range16[] = {
	{ 40, 40 },
	{ 91, 91 },
	{ 123, 123 },
	{ 3898, 3898 },
	{ 3900, 3900 },
	{ 5787, 5787 },
	{ 8218, 8218 },
	{ 8222, 8222 },
	{ 8261, 8261 },
	{ 8317, 8317 },
	{ 8333, 8333 },
	{ 8968, 8968 },
	{ 8970, 8970 },
	{ 9001, 9001 },
	{ 10088, 10088 },
	{ 10090, 10090 },
	{ 10092, 10092 },
	{ 10094, 10094 },
	{ 10096, 10096 },
	{ 10098, 10098 },
	{ 10100, 10100 },
	{ 10181, 10181 },
	{ 10214, 10214 },
	{ 10216, 10216 },
	{ 10218, 10218 },
	{ 10220, 10220 },
	{ 10222, 10222 },
	{ 10627, 10627 },
	{ 10629, 10629 },
	{ 10631, 10631 },
	{ 10633, 10633 },
	{ 10635, 10635 },
	{ 10637, 10637 },
	{ 10639, 10639 },
	{ 10641, 10641 },
	{ 10643, 10643 },
	{ 10645, 10645 },
	{ 10647, 10647 },
	{ 10712, 10712 },
	{ 10714, 10714 },
	{ 10748, 10748 },
	{ 11810, 11810 },
	{ 11812, 11812 },
	{ 11814, 11814 },
	{ 11816, 11816 },
	{ 11842, 11842 },
	{ 12296, 12296 },
	{ 12298, 12298 },
	{ 12300, 12300 },
	{ 12302, 12302 },
	{ 12304, 12304 },
	{ 12308, 12308 },
	{ 12310, 12310 },
	{ 12312, 12312 },
	{ 12314, 12314 },
	{ 12317, 12317 },
	{ 64831, 64831 },
	{ 65047, 65047 },
	{ 65077, 65077 },
	{ 65079, 65079 },
	{ 65081, 65081 },
	{ 65083, 65083 },
	{ 65085, 65085 },
	{ 65087, 65087 },
	{ 65089, 65089 },
	{ 65091, 65091 },
	{ 65095, 65095 },
	{ 65113, 65113 },
	{ 65115, 65115 },
	{ 65117, 65117 },
	{ 65288, 65288 },
	{ 65339, 65339 },
	{ 65371, 65371 },
	{ 65375, 65375 },
	{ 65378, 65378 },
};
static const URange16 Nl_range16[] = {
	{ 5870, 5872 },
	{ 8544, 8578 },
	{ 8581, 8584 },
	{ 12295, 12295 },
	{ 12321, 12329 },
	{ 12344, 12346 },
	{ 42726, 42735 },
};
static const URange32 Nl_range32[] = {
	{ 65856, 65908 },
	{ 66369, 66369 },
	{ 66378, 66378 },
	{ 66513, 66517 },
	{ 74752, 74862 },
};
static const URange16 No_range16[] = {
	{ 178, 179 },
	{ 185, 185 },
	{ 188, 190 },
	{ 2548, 2553 },
	{ 2930, 2935 },
	{ 3056, 3058 },
	{ 3192, 3198 },
	{ 3416, 3422 },
	{ 3440, 3448 },
	{ 3882, 3891 },
	{ 4969, 4988 },
	{ 6128, 6137 },
	{ 6618, 6618 },
	{ 8304, 8304 },
	{ 8308, 8313 },
	{ 8320, 8329 },
	{ 8528, 8543 },
	{ 8585, 8585 },
	{ 9312, 9371 },
	{ 9450, 9471 },
	{ 10102, 10131 },
	{ 11517, 11517 },
	{ 12690, 12693 },
	{ 12832, 12841 },
	{ 12872, 12879 },
	{ 12881, 12895 },
	{ 12928, 12937 },
	{ 12977, 12991 },
	{ 43056, 43061 },
};
static const URange32 No_range32[] = {
	{ 65799, 65843 },
	{ 65909, 65912 },
	{ 65930, 65931 },
	{ 66273, 66299 },
	{ 66336, 66339 },
	{ 67672, 67679 },
	{ 67705, 67711 },
	{ 67751, 67759 },
	{ 67835, 67839 },
	{ 67862, 67867 },
	{ 68028, 68029 },
	{ 68032, 68047 },
	{ 68050, 68095 },
	{ 68160, 68168 },
	{ 68221, 68222 },
	{ 68253, 68255 },
	{ 68331, 68335 },
	{ 68440, 68447 },
	{ 68472, 68479 },
	{ 68521, 68527 },
	{ 68858, 68863 },
	{ 69216, 69246 },
	{ 69405, 69414 },
	{ 69457, 69460 },
	{ 69714, 69733 },
	{ 70113, 70132 },
	{ 71482, 71483 },
	{ 71914, 71922 },
	{ 72794, 72812 },
	{ 93019, 93025 },
	{ 93824, 93846 },
	{ 119520, 119539 },
	{ 119648, 119672 },
	{ 125127, 125135 },
	{ 126065, 126123 },
	{ 126125, 126127 },
	{ 126129, 126132 },
	{ 127232, 127244 },
};
static const URange16 Lo_range16[] = {
	{ 170, 170 },
	{ 186, 186 },
	{ 443, 443 },
	{ 448, 451 },
	{ 660, 660 },
	{ 1488, 1514 },
	{ 1519, 1522 },
	{ 1568, 1599 },
	{ 1601, 1610 },
	{ 1646, 1647 },
	{ 1649, 1747 },
	{ 1749, 1749 },
	{ 1774, 1775 },
	{ 1786, 1788 },
	{ 1791, 1791 },
	{ 1808, 1808 },
	{ 1810, 1839 },
	{ 1869, 1957 },
	{ 1969, 1969 },
	{ 1994, 2026 },
	{ 2048, 2069 },
	{ 2112, 2136 },
	{ 2144, 2154 },
	{ 2208, 2228 },
	{ 2230, 2237 },
	{ 2308, 2361 },
	{ 2365, 2365 },
	{ 2384, 2384 },
	{ 2392, 2401 },
	{ 2418, 2432 },
	{ 2437, 2444 },
	{ 2447, 2448 },
	{ 2451, 2472 },
	{ 2474, 2480 },
	{ 2482, 2482 },
	{ 2486, 2489 },
	{ 2493, 2493 },
	{ 2510, 2510 },
	{ 2524, 2525 },
	{ 2527, 2529 },
	{ 2544, 2545 },
	{ 2556, 2556 },
	{ 2565, 2570 },
	{ 2575, 2576 },
	{ 2579, 2600 },
	{ 2602, 2608 },
	{ 2610, 2611 },
	{ 2613, 2614 },
	{ 2616, 2617 },
	{ 2649, 2652 },
	{ 2654, 2654 },
	{ 2674, 2676 },
	{ 2693, 2701 },
	{ 2703, 2705 },
	{ 2707, 2728 },
	{ 2730, 2736 },
	{ 2738, 2739 },
	{ 2741, 2745 },
	{ 2749, 2749 },
	{ 2768, 2768 },
	{ 2784, 2785 },
	{ 2809, 2809 },
	{ 2821, 2828 },
	{ 2831, 2832 },
	{ 2835, 2856 },
	{ 2858, 2864 },
	{ 2866, 2867 },
	{ 2869, 2873 },
	{ 2877, 2877 },
	{ 2908, 2909 },
	{ 2911, 2913 },
	{ 2929, 2929 },
	{ 2947, 2947 },
	{ 2949, 2954 },
	{ 2958, 2960 },
	{ 2962, 2965 },
	{ 2969, 2970 },
	{ 2972, 2972 },
	{ 2974, 2975 },
	{ 2979, 2980 },
	{ 2984, 2986 },
	{ 2990, 3001 },
	{ 3024, 3024 },
	{ 3077, 3084 },
	{ 3086, 3088 },
	{ 3090, 3112 },
	{ 3114, 3129 },
	{ 3133, 3133 },
	{ 3160, 3162 },
	{ 3168, 3169 },
	{ 3200, 3200 },
	{ 3205, 3212 },
	{ 3214, 3216 },
	{ 3218, 3240 },
	{ 3242, 3251 },
	{ 3253, 3257 },
	{ 3261, 3261 },
	{ 3294, 3294 },
	{ 3296, 3297 },
	{ 3313, 3314 },
	{ 3333, 3340 },
	{ 3342, 3344 },
	{ 3346, 3386 },
	{ 3389, 3389 },
	{ 3406, 3406 },
	{ 3412, 3414 },
	{ 3423, 3425 },
	{ 3450, 3455 },
	{ 3461, 3478 },
	{ 3482, 3505 },
	{ 3507, 3515 },
	{ 3517, 3517 },
	{ 3520, 3526 },
	{ 3585, 3632 },
	{ 3634, 3635 },
	{ 3648, 3653 },
	{ 3713, 3714 },
	{ 3716, 3716 },
	{ 3719, 3720 },
	{ 3722, 3722 },
	{ 3725, 3725 },
	{ 3732, 3735 },
	{ 3737, 3743 },
	{ 3745, 3747 },
	{ 3749, 3749 },
	{ 3751, 3751 },
	{ 3754, 3755 },
	{ 3757, 3760 },
	{ 3762, 3763 },
	{ 3773, 3773 },
	{ 3776, 3780 },
	{ 3804, 3807 },
	{ 3840, 3840 },
	{ 3904, 3911 },
	{ 3913, 3948 },
	{ 3976, 3980 },
	{ 4096, 4138 },
	{ 4159, 4159 },
	{ 4176, 4181 },
	{ 4186, 4189 },
	{ 4193, 4193 },
	{ 4197, 4198 },
	{ 4206, 4208 },
	{ 4213, 4225 },
	{ 4238, 4238 },
	{ 4352, 4680 },
	{ 4682, 4685 },
	{ 4688, 4694 },
	{ 4696, 4696 },
	{ 4698, 4701 },
	{ 4704, 4744 },
	{ 4746, 4749 },
	{ 4752, 4784 },
	{ 4786, 4789 },
	{ 4792, 4798 },
	{ 4800, 4800 },
	{ 4802, 4805 },
	{ 4808, 4822 },
	{ 4824, 4880 },
	{ 4882, 4885 },
	{ 4888, 4954 },
	{ 4992, 5007 },
	{ 5121, 5740 },
	{ 5743, 5759 },
	{ 5761, 5786 },
	{ 5792, 5866 },
	{ 5873, 5880 },
	{ 5888, 5900 },
	{ 5902, 5905 },
	{ 5920, 5937 },
	{ 5952, 5969 },
	{ 5984, 5996 },
	{ 5998, 6000 },
	{ 6016, 6067 },
	{ 6108, 6108 },
	{ 6176, 6210 },
	{ 6212, 6264 },
	{ 6272, 6276 },
	{ 6279, 6312 },
	{ 6314, 6314 },
	{ 6320, 6389 },
	{ 6400, 6430 },
	{ 6480, 6509 },
	{ 6512, 6516 },
	{ 6528, 6571 },
	{ 6576, 6601 },
	{ 6656, 6678 },
	{ 6688, 6740 },
	{ 6917, 6963 },
	{ 6981, 6987 },
	{ 7043, 7072 },
	{ 7086, 7087 },
	{ 7098, 7141 },
	{ 7168, 7203 },
	{ 7245, 7247 },
	{ 7258, 7287 },
	{ 7401, 7404 },
	{ 7406, 7409 },
	{ 7413, 7414 },
	{ 8501, 8504 },
	{ 11568, 11623 },
	{ 11648, 11670 },
	{ 11680, 11686 },
	{ 11688, 11694 },
	{ 11696, 11702 },
	{ 11704, 11710 },
	{ 11712, 11718 },
	{ 11720, 11726 },
	{ 11728, 11734 },
	{ 11736, 11742 },
	{ 12294, 12294 },
	{ 12348, 12348 },
	{ 12353, 12438 },
	{ 12447, 12447 },
	{ 12449, 12538 },
	{ 12543, 12543 },
	{ 12549, 12591 },
	{ 12593, 12686 },
	{ 12704, 12730 },
	{ 12784, 12799 },
	{ 13312, 19893 },
	{ 19968, 40943 },
	{ 40960, 40980 },
	{ 40982, 42124 },
	{ 42192, 42231 },
	{ 42240, 42507 },
	{ 42512, 42527 },
	{ 42538, 42539 },
	{ 42606, 42606 },
	{ 42656, 42725 },
	{ 42895, 42895 },
	{ 42999, 42999 },
	{ 43003, 43009 },
	{ 43011, 43013 },
	{ 43015, 43018 },
	{ 43020, 43042 },
	{ 43072, 43123 },
	{ 43138, 43187 },
	{ 43250, 43255 },
	{ 43259, 43259 },
	{ 43261, 43262 },
	{ 43274, 43301 },
	{ 43312, 43334 },
	{ 43360, 43388 },
	{ 43396, 43442 },
	{ 43488, 43492 },
	{ 43495, 43503 },
	{ 43514, 43518 },
	{ 43520, 43560 },
	{ 43584, 43586 },
	{ 43588, 43595 },
	{ 43616, 43631 },
	{ 43633, 43638 },
	{ 43642, 43642 },
	{ 43646, 43695 },
	{ 43697, 43697 },
	{ 43701, 43702 },
	{ 43705, 43709 },
	{ 43712, 43712 },
	{ 43714, 43714 },
	{ 43739, 43740 },
	{ 43744, 43754 },
	{ 43762, 43762 },
	{ 43777, 43782 },
	{ 43785, 43790 },
	{ 43793, 43798 },
	{ 43808, 43814 },
	{ 43816, 43822 },
	{ 43968, 44002 },
	{ 44032, 55203 },
	{ 55216, 55238 },
	{ 55243, 55291 },
	{ 63744, 64109 },
	{ 64112, 64217 },
	{ 64285, 64285 },
	{ 64287, 64296 },
	{ 64298, 64310 },
	{ 64312, 64316 },
	{ 64318, 64318 },
	{ 64320, 64321 },
	{ 64323, 64324 },
	{ 64326, 64433 },
	{ 64467, 64829 },
	{ 64848, 64911 },
	{ 64914, 64967 },
	{ 65008, 65019 },
	{ 65136, 65140 },
	{ 65142, 65276 },
	{ 65382, 65391 },
	{ 65393, 65437 },
	{ 65440, 65470 },
	{ 65474, 65479 },
	{ 65482, 65487 },
	{ 65490, 65495 },
	{ 65498, 65500 },
};
static const URange32 Lo_range32[] = {
	{ 65536, 65547 },
	{ 65549, 65574 },
	{ 65576, 65594 },
	{ 65596, 65597 },
	{ 65599, 65613 },
	{ 65616, 65629 },
	{ 65664, 65786 },
	{ 66176, 66204 },
	{ 66208, 66256 },
	{ 66304, 66335 },
	{ 66349, 66368 },
	{ 66370, 66377 },
	{ 66384, 66421 },
	{ 66432, 66461 },
	{ 66464, 66499 },
	{ 66504, 66511 },
	{ 66640, 66717 },
	{ 66816, 66855 },
	{ 66864, 66915 },
	{ 67072, 67382 },
	{ 67392, 67413 },
	{ 67424, 67431 },
	{ 67584, 67589 },
	{ 67592, 67592 },
	{ 67594, 67637 },
	{ 67639, 67640 },
	{ 67644, 67644 },
	{ 67647, 67669 },
	{ 67680, 67702 },
	{ 67712, 67742 },
	{ 67808, 67826 },
	{ 67828, 67829 },
	{ 67840, 67861 },
	{ 67872, 67897 },
	{ 67968, 68023 },
	{ 68030, 68031 },
	{ 68096, 68096 },
	{ 68112, 68115 },
	{ 68117, 68119 },
	{ 68121, 68149 },
	{ 68192, 68220 },
	{ 68224, 68252 },
	{ 68288, 68295 },
	{ 68297, 68324 },
	{ 68352, 68405 },
	{ 68416, 68437 },
	{ 68448, 68466 },
	{ 68480, 68497 },
	{ 68608, 68680 },
	{ 68864, 68899 },
	{ 69376, 69404 },
	{ 69415, 69415 },
	{ 69424, 69445 },
	{ 69635, 69687 },
	{ 69763, 69807 },
	{ 69840, 69864 },
	{ 69891, 69926 },
	{ 69956, 69956 },
	{ 69968, 70002 },
	{ 70006, 70006 },
	{ 70019, 70066 },
	{ 70081, 70084 },
	{ 70106, 70106 },
	{ 70108, 70108 },
	{ 70144, 70161 },
	{ 70163, 70187 },
	{ 70272, 70278 },
	{ 70280, 70280 },
	{ 70282, 70285 },
	{ 70287, 70301 },
	{ 70303, 70312 },
	{ 70320, 70366 },
	{ 70405, 70412 },
	{ 70415, 70416 },
	{ 70419, 70440 },
	{ 70442, 70448 },
	{ 70450, 70451 },
	{ 70453, 70457 },
	{ 70461, 70461 },
	{ 70480, 70480 },
	{ 70493, 70497 },
	{ 70656, 70708 },
	{ 70727, 70730 },
	{ 70784, 70831 },
	{ 70852, 70853 },
	{ 70855, 70855 },
	{ 71040, 71086 },
	{ 71128, 71131 },
	{ 71168, 71215 },
	{ 71236, 71236 },
	{ 71296, 71338 },
	{ 71424, 71450 },
	{ 71680, 71723 },
	{ 71935, 71935 },
	{ 72192, 72192 },
	{ 72203, 72242 },
	{ 72250, 72250 },
	{ 72272, 72272 },
	{ 72284, 72323 },
	{ 72326, 72329 },
	{ 72349, 72349 },
	{ 72384, 72440 },
	{ 72704, 72712 },
	{ 72714, 72750 },
	{ 72768, 72768 },
	{ 72818, 72847 },
	{ 72960, 72966 },
	{ 72968, 72969 },
	{ 72971, 73008 },
	{ 73030, 73030 },
	{ 73056, 73061 },
	{ 73063, 73064 },
	{ 73066, 73097 },
	{ 73112, 73112 },
	{ 73440, 73458 },
	{ 73728, 74649 },
	{ 74880, 75075 },
	{ 77824, 78894 },
	{ 82944, 83526 },
	{ 92160, 92728 },
	{ 92736, 92766 },
	{ 92880, 92909 },
	{ 92928, 92975 },
	{ 93027, 93047 },
	{ 93053, 93071 },
	{ 93952, 94020 },
	{ 94032, 94032 },
	{ 94208, 100337 },
	{ 100352, 101106 },
	{ 110592, 110878 },
	{ 110960, 111355 },
	{ 113664, 113770 },
	{ 113776, 113788 },
	{ 113792, 113800 },
	{ 113808, 113817 },
	{ 124928, 125124 },
	{ 126464, 126467 },
	{ 126469, 126495 },
	{ 126497, 126498 },
	{ 126500, 126500 },
	{ 126503, 126503 },
	{ 126505, 126514 },
	{ 126516, 126519 },
	{ 126521, 126521 },
	{ 126523, 126523 },
	{ 126530, 126530 },
	{ 126535, 126535 },
	{ 126537, 126537 },
	{ 126539, 126539 },
	{ 126541, 126543 },
	{ 126545, 126546 },
	{ 126548, 126548 },
	{ 126551, 126551 },
	{ 126553, 126553 },
	{ 126555, 126555 },
	{ 126557, 126557 },
	{ 126559, 126559 },
	{ 126561, 126562 },
	{ 126564, 126564 },
	{ 126567, 126570 },
	{ 126572, 126578 },
	{ 126580, 126583 },
	{ 126585, 126588 },
	{ 126590, 126590 },
	{ 126592, 126601 },
	{ 126603, 126619 },
	{ 126625, 126627 },
	{ 126629, 126633 },
	{ 126635, 126651 },
	{ 131072, 173782 },
	{ 173824, 177972 },
	{ 177984, 178205 },
	{ 178208, 183969 },
	{ 183984, 191456 },
	{ 194560, 195101 },
};
static const URange16 Ll_range16[] = {
	{ 97, 122 },
	{ 181, 181 },
	{ 223, 246 },
	{ 248, 255 },
	{ 257, 257 },
	{ 259, 259 },
	{ 261, 261 },
	{ 263, 263 },
	{ 265, 265 },
	{ 267, 267 },
	{ 269, 269 },
	{ 271, 271 },
	{ 273, 273 },
	{ 275, 275 },
	{ 277, 277 },
	{ 279, 279 },
	{ 281, 281 },
	{ 283, 283 },
	{ 285, 285 },
	{ 287, 287 },
	{ 289, 289 },
	{ 291, 291 },
	{ 293, 293 },
	{ 295, 295 },
	{ 297, 297 },
	{ 299, 299 },
	{ 301, 301 },
	{ 303, 303 },
	{ 305, 305 },
	{ 307, 307 },
	{ 309, 309 },
	{ 311, 312 },
	{ 314, 314 },
	{ 316, 316 },
	{ 318, 318 },
	{ 320, 320 },
	{ 322, 322 },
	{ 324, 324 },
	{ 326, 326 },
	{ 328, 329 },
	{ 331, 331 },
	{ 333, 333 },
	{ 335, 335 },
	{ 337, 337 },
	{ 339, 339 },
	{ 341, 341 },
	{ 343, 343 },
	{ 345, 345 },
	{ 347, 347 },
	{ 349, 349 },
	{ 351, 351 },
	{ 353, 353 },
	{ 355, 355 },
	{ 357, 357 },
	{ 359, 359 },
	{ 361, 361 },
	{ 363, 363 },
	{ 365, 365 },
	{ 367, 367 },
	{ 369, 369 },
	{ 371, 371 },
	{ 373, 373 },
	{ 375, 375 },
	{ 378, 378 },
	{ 380, 380 },
	{ 382, 384 },
	{ 387, 387 },
	{ 389, 389 },
	{ 392, 392 },
	{ 396, 397 },
	{ 402, 402 },
	{ 405, 405 },
	{ 409, 411 },
	{ 414, 414 },
	{ 417, 417 },
	{ 419, 419 },
	{ 421, 421 },
	{ 424, 424 },
	{ 426, 427 },
	{ 429, 429 },
	{ 432, 432 },
	{ 436, 436 },
	{ 438, 438 },
	{ 441, 442 },
	{ 445, 447 },
	{ 454, 454 },
	{ 457, 457 },
	{ 460, 460 },
	{ 462, 462 },
	{ 464, 464 },
	{ 466, 466 },
	{ 468, 468 },
	{ 470, 470 },
	{ 472, 472 },
	{ 474, 474 },
	{ 476, 477 },
	{ 479, 479 },
	{ 481, 481 },
	{ 483, 483 },
	{ 485, 485 },
	{ 487, 487 },
	{ 489, 489 },
	{ 491, 491 },
	{ 493, 493 },
	{ 495, 496 },
	{ 499, 499 },
	{ 501, 501 },
	{ 505, 505 },
	{ 507, 507 },
	{ 509, 509 },
	{ 511, 511 },
	{ 513, 513 },
	{ 515, 515 },
	{ 517, 517 },
	{ 519, 519 },
	{ 521, 521 },
	{ 523, 523 },
	{ 525, 525 },
	{ 527, 527 },
	{ 529, 529 },
	{ 531, 531 },
	{ 533, 533 },
	{ 535, 535 },
	{ 537, 537 },
	{ 539, 539 },
	{ 541, 541 },
	{ 543, 543 },
	{ 545, 545 },
	{ 547, 547 },
	{ 549, 549 },
	{ 551, 551 },
	{ 553, 553 },
	{ 555, 555 },
	{ 557, 557 },
	{ 559, 559 },
	{ 561, 561 },
	{ 563, 569 },
	{ 572, 572 },
	{ 575, 576 },
	{ 578, 578 },
	{ 583, 583 },
	{ 585, 585 },
	{ 587, 587 },
	{ 589, 589 },
	{ 591, 659 },
	{ 661, 687 },
	{ 881, 881 },
	{ 883, 883 },
	{ 887, 887 },
	{ 891, 893 },
	{ 912, 912 },
	{ 940, 974 },
	{ 976, 977 },
	{ 981, 983 },
	{ 985, 985 },
	{ 987, 987 },
	{ 989, 989 },
	{ 991, 991 },
	{ 993, 993 },
	{ 995, 995 },
	{ 997, 997 },
	{ 999, 999 },
	{ 1001, 1001 },
	{ 1003, 1003 },
	{ 1005, 1005 },
	{ 1007, 1011 },
	{ 1013, 1013 },
	{ 1016, 1016 },
	{ 1019, 1020 },
	{ 1072, 1119 },
	{ 1121, 1121 },
	{ 1123, 1123 },
	{ 1125, 1125 },
	{ 1127, 1127 },
	{ 1129, 1129 },
	{ 1131, 1131 },
	{ 1133, 1133 },
	{ 1135, 1135 },
	{ 1137, 1137 },
	{ 1139, 1139 },
	{ 1141, 1141 },
	{ 1143, 1143 },
	{ 1145, 1145 },
	{ 1147, 1147 },
	{ 1149, 1149 },
	{ 1151, 1151 },
	{ 1153, 1153 },
	{ 1163, 1163 },
	{ 1165, 1165 },
	{ 1167, 1167 },
	{ 1169, 1169 },
	{ 1171, 1171 },
	{ 1173, 1173 },
	{ 1175, 1175 },
	{ 1177, 1177 },
	{ 1179, 1179 },
	{ 1181, 1181 },
	{ 1183, 1183 },
	{ 1185, 1185 },
	{ 1187, 1187 },
	{ 1189, 1189 },
	{ 1191, 1191 },
	{ 1193, 1193 },
	{ 1195, 1195 },
	{ 1197, 1197 },
	{ 1199, 1199 },
	{ 1201, 1201 },
	{ 1203, 1203 },
	{ 1205, 1205 },
	{ 1207, 1207 },
	{ 1209, 1209 },
	{ 1211, 1211 },
	{ 1213, 1213 },
	{ 1215, 1215 },
	{ 1218, 1218 },
	{ 1220, 1220 },
	{ 1222, 1222 },
	{ 1224, 1224 },
	{ 1226, 1226 },
	{ 1228, 1228 },
	{ 1230, 1231 },
	{ 1233, 1233 },
	{ 1235, 1235 },
	{ 1237, 1237 },
	{ 1239, 1239 },
	{ 1241, 1241 },
	{ 1243, 1243 },
	{ 1245, 1245 },
	{ 1247, 1247 },
	{ 1249, 1249 },
	{ 1251, 1251 },
	{ 1253, 1253 },
	{ 1255, 1255 },
	{ 1257, 1257 },
	{ 1259, 1259 },
	{ 1261, 1261 },
	{ 1263, 1263 },
	{ 1265, 1265 },
	{ 1267, 1267 },
	{ 1269, 1269 },
	{ 1271, 1271 },
	{ 1273, 1273 },
	{ 1275, 1275 },
	{ 1277, 1277 },
	{ 1279, 1279 },
	{ 1281, 1281 },
	{ 1283, 1283 },
	{ 1285, 1285 },
	{ 1287, 1287 },
	{ 1289, 1289 },
	{ 1291, 1291 },
	{ 1293, 1293 },
	{ 1295, 1295 },
	{ 1297, 1297 },
	{ 1299, 1299 },
	{ 1301, 1301 },
	{ 1303, 1303 },
	{ 1305, 1305 },
	{ 1307, 1307 },
	{ 1309, 1309 },
	{ 1311, 1311 },
	{ 1313, 1313 },
	{ 1315, 1315 },
	{ 1317, 1317 },
	{ 1319, 1319 },
	{ 1321, 1321 },
	{ 1323, 1323 },
	{ 1325, 1325 },
	{ 1327, 1327 },
	{ 1376, 1416 },
	{ 4304, 4346 },
	{ 4349, 4351 },
	{ 5112, 5117 },
	{ 7296, 7304 },
	{ 7424, 7467 },
	{ 7531, 7543 },
	{ 7545, 7578 },
	{ 7681, 7681 },
	{ 7683, 7683 },
	{ 7685, 7685 },
	{ 7687, 7687 },
	{ 7689, 7689 },
	{ 7691, 7691 },
	{ 7693, 7693 },
	{ 7695, 7695 },
	{ 7697, 7697 },
	{ 7699, 7699 },
	{ 7701, 7701 },
	{ 7703, 7703 },
	{ 7705, 7705 },
	{ 7707, 7707 },
	{ 7709, 7709 },
	{ 7711, 7711 },
	{ 7713, 7713 },
	{ 7715, 7715 },
	{ 7717, 7717 },
	{ 7719, 7719 },
	{ 7721, 7721 },
	{ 7723, 7723 },
	{ 7725, 7725 },
	{ 7727, 7727 },
	{ 7729, 7729 },
	{ 7731, 7731 },
	{ 7733, 7733 },
	{ 7735, 7735 },
	{ 7737, 7737 },
	{ 7739, 7739 },
	{ 7741, 7741 },
	{ 7743, 7743 },
	{ 7745, 7745 },
	{ 7747, 7747 },
	{ 7749, 7749 },
	{ 7751, 7751 },
	{ 7753, 7753 },
	{ 7755, 7755 },
	{ 7757, 7757 },
	{ 7759, 7759 },
	{ 7761, 7761 },
	{ 7763, 7763 },
	{ 7765, 7765 },
	{ 7767, 7767 },
	{ 7769, 7769 },
	{ 7771, 7771 },
	{ 7773, 7773 },
	{ 7775, 7775 },
	{ 7777, 7777 },
	{ 7779, 7779 },
	{ 7781, 7781 },
	{ 7783, 7783 },
	{ 7785, 7785 },
	{ 7787, 7787 },
	{ 7789, 7789 },
	{ 7791, 7791 },
	{ 7793, 7793 },
	{ 7795, 7795 },
	{ 7797, 7797 },
	{ 7799, 7799 },
	{ 7801, 7801 },
	{ 7803, 7803 },
	{ 7805, 7805 },
	{ 7807, 7807 },
	{ 7809, 7809 },
	{ 7811, 7811 },
	{ 7813, 7813 },
	{ 7815, 7815 },
	{ 7817, 7817 },
	{ 7819, 7819 },
	{ 7821, 7821 },
	{ 7823, 7823 },
	{ 7825, 7825 },
	{ 7827, 7827 },
	{ 7829, 7837 },
	{ 7839, 7839 },
	{ 7841, 7841 },
	{ 7843, 7843 },
	{ 7845, 7845 },
	{ 7847, 7847 },
	{ 7849, 7849 },
	{ 7851, 7851 },
	{ 7853, 7853 },
	{ 7855, 7855 },
	{ 7857, 7857 },
	{ 7859, 7859 },
	{ 7861, 7861 },
	{ 7863, 7863 },
	{ 7865, 7865 },
	{ 7867, 7867 },
	{ 7869, 7869 },
	{ 7871, 7871 },
	{ 7873, 7873 },
	{ 7875, 7875 },
	{ 7877, 7877 },
	{ 7879, 7879 },
	{ 7881, 7881 },
	{ 7883, 7883 },
	{ 7885, 7885 },
	{ 7887, 7887 },
	{ 7889, 7889 },
	{ 7891, 7891 },
	{ 7893, 7893 },
	{ 7895, 7895 },
	{ 7897, 7897 },
	{ 7899, 7899 },
	{ 7901, 7901 },
	{ 7903, 7903 },
	{ 7905, 7905 },
	{ 7907, 7907 },
	{ 7909, 7909 },
	{ 7911, 7911 },
	{ 7913, 7913 },
	{ 7915, 7915 },
	{ 7917, 7917 },
	{ 7919, 7919 },
	{ 7921, 7921 },
	{ 7923, 7923 },
	{ 7925, 7925 },
	{ 7927, 7927 },
	{ 7929, 7929 },
	{ 7931, 7931 },
	{ 7933, 7933 },
	{ 7935, 7943 },
	{ 7952, 7957 },
	{ 7968, 7975 },
	{ 7984, 7991 },
	{ 8000, 8005 },
	{ 8016, 8023 },
	{ 8032, 8039 },
	{ 8048, 8061 },
	{ 8064, 8071 },
	{ 8080, 8087 },
	{ 8096, 8103 },
	{ 8112, 8116 },
	{ 8118, 8119 },
	{ 8126, 8126 },
	{ 8130, 8132 },
	{ 8134, 8135 },
	{ 8144, 8147 },
	{ 8150, 8151 },
	{ 8160, 8167 },
	{ 8178, 8180 },
	{ 8182, 8183 },
	{ 8458, 8458 },
	{ 8462, 8463 },
	{ 8467, 8467 },
	{ 8495, 8495 },
	{ 8500, 8500 },
	{ 8505, 8505 },
	{ 8508, 8509 },
	{ 8518, 8521 },
	{ 8526, 8526 },
	{ 8580, 8580 },
	{ 11312, 11358 },
	{ 11361, 11361 },
	{ 11365, 11366 },
	{ 11368, 11368 },
	{ 11370, 11370 },
	{ 11372, 11372 },
	{ 11377, 11377 },
	{ 11379, 11380 },
	{ 11382, 11387 },
	{ 11393, 11393 },
	{ 11395, 11395 },
	{ 11397, 11397 },
	{ 11399, 11399 },
	{ 11401, 11401 },
	{ 11403, 11403 },
	{ 11405, 11405 },
	{ 11407, 11407 },
	{ 11409, 11409 },
	{ 11411, 11411 },
	{ 11413, 11413 },
	{ 11415, 11415 },
	{ 11417, 11417 },
	{ 11419, 11419 },
	{ 11421, 11421 },
	{ 11423, 11423 },
	{ 11425, 11425 },
	{ 11427, 11427 },
	{ 11429, 11429 },
	{ 11431, 11431 },
	{ 11433, 11433 },
	{ 11435, 11435 },
	{ 11437, 11437 },
	{ 11439, 11439 },
	{ 11441, 11441 },
	{ 11443, 11443 },
	{ 11445, 11445 },
	{ 11447, 11447 },
	{ 11449, 11449 },
	{ 11451, 11451 },
	{ 11453, 11453 },
	{ 11455, 11455 },
	{ 11457, 11457 },
	{ 11459, 11459 },
	{ 11461, 11461 },
	{ 11463, 11463 },
	{ 11465, 11465 },
	{ 11467, 11467 },
	{ 11469, 11469 },
	{ 11471, 11471 },
	{ 11473, 11473 },
	{ 11475, 11475 },
	{ 11477, 11477 },
	{ 11479, 11479 },
	{ 11481, 11481 },
	{ 11483, 11483 },
	{ 11485, 11485 },
	{ 11487, 11487 },
	{ 11489, 11489 },
	{ 11491, 11492 },
	{ 11500, 11500 },
	{ 11502, 11502 },
	{ 11507, 11507 },
	{ 11520, 11557 },
	{ 11559, 11559 },
	{ 11565, 11565 },
	{ 42561, 42561 },
	{ 42563, 42563 },
	{ 42565, 42565 },
	{ 42567, 42567 },
	{ 42569, 42569 },
	{ 42571, 42571 },
	{ 42573, 42573 },
	{ 42575, 42575 },
	{ 42577, 42577 },
	{ 42579, 42579 },
	{ 42581, 42581 },
	{ 42583, 42583 },
	{ 42585, 42585 },
	{ 42587, 42587 },
	{ 42589, 42589 },
	{ 42591, 42591 },
	{ 42593, 42593 },
	{ 42595, 42595 },
	{ 42597, 42597 },
	{ 42599, 42599 },
	{ 42601, 42601 },
	{ 42603, 42603 },
	{ 42605, 42605 },
	{ 42625, 42625 },
	{ 42627, 42627 },
	{ 42629, 42629 },
	{ 42631, 42631 },
	{ 42633, 42633 },
	{ 42635, 42635 },
	{ 42637, 42637 },
	{ 42639, 42639 },
	{ 42641, 42641 },
	{ 42643, 42643 },
	{ 42645, 42645 },
	{ 42647, 42647 },
	{ 42649, 42649 },
	{ 42651, 42651 },
	{ 42787, 42787 },
	{ 42789, 42789 },
	{ 42791, 42791 },
	{ 42793, 42793 },
	{ 42795, 42795 },
	{ 42797, 42797 },
	{ 42799, 42801 },
	{ 42803, 42803 },
	{ 42805, 42805 },
	{ 42807, 42807 },
	{ 42809, 42809 },
	{ 42811, 42811 },
	{ 42813, 42813 },
	{ 42815, 42815 },
	{ 42817, 42817 },
	{ 42819, 42819 },
	{ 42821, 42821 },
	{ 42823, 42823 },
	{ 42825, 42825 },
	{ 42827, 42827 },
	{ 42829, 42829 },
	{ 42831, 42831 },
	{ 42833, 42833 },
	{ 42835, 42835 },
	{ 42837, 42837 },
	{ 42839, 42839 },
	{ 42841, 42841 },
	{ 42843, 42843 },
	{ 42845, 42845 },
	{ 42847, 42847 },
	{ 42849, 42849 },
	{ 42851, 42851 },
	{ 42853, 42853 },
	{ 42855, 42855 },
	{ 42857, 42857 },
	{ 42859, 42859 },
	{ 42861, 42861 },
	{ 42863, 42863 },
	{ 42865, 42872 },
	{ 42874, 42874 },
	{ 42876, 42876 },
	{ 42879, 42879 },
	{ 42881, 42881 },
	{ 42883, 42883 },
	{ 42885, 42885 },
	{ 42887, 42887 },
	{ 42892, 42892 },
	{ 42894, 42894 },
	{ 42897, 42897 },
	{ 42899, 42901 },
	{ 42903, 42903 },
	{ 42905, 42905 },
	{ 42907, 42907 },
	{ 42909, 42909 },
	{ 42911, 42911 },
	{ 42913, 42913 },
	{ 42915, 42915 },
	{ 42917, 42917 },
	{ 42919, 42919 },
	{ 42921, 42921 },
	{ 42927, 42927 },
	{ 42933, 42933 },
	{ 42935, 42935 },
	{ 42937, 42937 },
	{ 43002, 43002 },
	{ 43824, 43866 },
	{ 43872, 43877 },
	{ 43888, 43967 },
	{ 64256, 64262 },
	{ 64275, 64279 },
	{ 65345, 65370 },
};
static const URange32 Ll_range32[] = {
	{ 66600, 66639 },
	{ 66776, 66811 },
	{ 68800, 68850 },
	{ 71872, 71903 },
	{ 93792, 93823 },
	{ 119834, 119859 },
	{ 119886, 119892 },
	{ 119894, 119911 },
	{ 119938, 119963 },
	{ 119990, 119993 },
	{ 119995, 119995 },
	{ 119997, 120003 },
	{ 120005, 120015 },
	{ 120042, 120067 },
	{ 120094, 120119 },
	{ 120146, 120171 },
	{ 120198, 120223 },
	{ 120250, 120275 },
	{ 120302, 120327 },
	{ 120354, 120379 },
	{ 120406, 120431 },
	{ 120458, 120485 },
	{ 120514, 120538 },
	{ 120540, 120545 },
	{ 120572, 120596 },
	{ 120598, 120603 },
	{ 120630, 120654 },
	{ 120656, 120661 },
	{ 120688, 120712 },
	{ 120714, 120719 },
	{ 120746, 120770 },
	{ 120772, 120777 },
	{ 120779, 120779 },
	{ 125218, 125251 },
};
static const URange16 Lm_range16[] = {
	{ 688, 705 },
	{ 710, 721 },
	{ 736, 740 },
	{ 748, 748 },
	{ 750, 750 },
	{ 884, 884 },
	{ 890, 890 },
	{ 1369, 1369 },
	{ 1600, 1600 },
	{ 1765, 1766 },
	{ 2036, 2037 },
	{ 2042, 2042 },
	{ 2074, 2074 },
	{ 2084, 2084 },
	{ 2088, 2088 },
	{ 2417, 2417 },
	{ 3654, 3654 },
	{ 3782, 3782 },
	{ 4348, 4348 },
	{ 6103, 6103 },
	{ 6211, 6211 },
	{ 6823, 6823 },
	{ 7288, 7293 },
	{ 7468, 7530 },
	{ 7544, 7544 },
	{ 7579, 7615 },
	{ 8305, 8305 },
	{ 8319, 8319 },
	{ 8336, 8348 },
	{ 11388, 11389 },
	{ 11631, 11631 },
	{ 11823, 11823 },
	{ 12293, 12293 },
	{ 12337, 12341 },
	{ 12347, 12347 },
	{ 12445, 12446 },
	{ 12540, 12542 },
	{ 40981, 40981 },
	{ 42232, 42237 },
	{ 42508, 42508 },
	{ 42623, 42623 },
	{ 42652, 42653 },
	{ 42775, 42783 },
	{ 42864, 42864 },
	{ 42888, 42888 },
	{ 43000, 43001 },
	{ 43471, 43471 },
	{ 43494, 43494 },
	{ 43632, 43632 },
	{ 43741, 43741 },
	{ 43763, 43764 },
	{ 43868, 43871 },
	{ 65392, 65392 },
	{ 65438, 65439 },
};
static const URange32 Lm_range32[] = {
	{ 92992, 92995 },
	{ 94099, 94111 },
	{ 94176, 94177 },
};
static const URange16 Nd_range16[] = {
	{ 48, 57 },
	{ 1632, 1641 },
	{ 1776, 1785 },
	{ 1984, 1993 },
	{ 2406, 2415 },
	{ 2534, 2543 },
	{ 2662, 2671 },
	{ 2790, 2799 },
	{ 2918, 2927 },
	{ 3046, 3055 },
	{ 3174, 3183 },
	{ 3302, 3311 },
	{ 3430, 3439 },
	{ 3558, 3567 },
	{ 3664, 3673 },
	{ 3792, 3801 },
	{ 3872, 3881 },
	{ 4160, 4169 },
	{ 4240, 4249 },
	{ 6112, 6121 },
	{ 6160, 6169 },
	{ 6470, 6479 },
	{ 6608, 6617 },
	{ 6784, 6793 },
	{ 6800, 6809 },
	{ 6992, 7001 },
	{ 7088, 7097 },
	{ 7232, 7241 },
	{ 7248, 7257 },
	{ 42528, 42537 },
	{ 43216, 43225 },
	{ 43264, 43273 },
	{ 43472, 43481 },
	{ 43504, 43513 },
	{ 43600, 43609 },
	{ 44016, 44025 },
	{ 65296, 65305 },
};
static const URange32 Nd_range32[] = {
	{ 66720, 66729 },
	{ 68912, 68921 },
	{ 69734, 69743 },
	{ 69872, 69881 },
	{ 69942, 69951 },
	{ 70096, 70105 },
	{ 70384, 70393 },
	{ 70736, 70745 },
	{ 70864, 70873 },
	{ 71248, 71257 },
	{ 71360, 71369 },
	{ 71472, 71481 },
	{ 71904, 71913 },
	{ 72784, 72793 },
	{ 73040, 73049 },
	{ 73120, 73129 },
	{ 92768, 92777 },
	{ 93008, 93017 },
	{ 120782, 120831 },
	{ 125264, 125273 },
};
static const URange16 Pc_range16[] = {
	{ 95, 95 },
	{ 8255, 8256 },
	{ 8276, 8276 },
	{ 65075, 65076 },
	{ 65101, 65103 },
	{ 65343, 65343 },
};
static const URange16 Lt_range16[] = {
	{ 453, 453 },
	{ 456, 456 },
	{ 459, 459 },
	{ 498, 498 },
	{ 8072, 8079 },
	{ 8088, 8095 },
	{ 8104, 8111 },
	{ 8124, 8124 },
	{ 8140, 8140 },
	{ 8188, 8188 },
};
static const URange16 Lu_range16[] = {
	{ 65, 90 },
	{ 192, 214 },
	{ 216, 222 },
	{ 256, 256 },
	{ 258, 258 },
	{ 260, 260 },
	{ 262, 262 },
	{ 264, 264 },
	{ 266, 266 },
	{ 268, 268 },
	{ 270, 270 },
	{ 272, 272 },
	{ 274, 274 },
	{ 276, 276 },
	{ 278, 278 },
	{ 280, 280 },
	{ 282, 282 },
	{ 284, 284 },
	{ 286, 286 },
	{ 288, 288 },
	{ 290, 290 },
	{ 292, 292 },
	{ 294, 294 },
	{ 296, 296 },
	{ 298, 298 },
	{ 300, 300 },
	{ 302, 302 },
	{ 304, 304 },
	{ 306, 306 },
	{ 308, 308 },
	{ 310, 310 },
	{ 313, 313 },
	{ 315, 315 },
	{ 317, 317 },
	{ 319, 319 },
	{ 321, 321 },
	{ 323, 323 },
	{ 325, 325 },
	{ 327, 327 },
	{ 330, 330 },
	{ 332, 332 },
	{ 334, 334 },
	{ 336, 336 },
	{ 338, 338 },
	{ 340, 340 },
	{ 342, 342 },
	{ 344, 344 },
	{ 346, 346 },
	{ 348, 348 },
	{ 350, 350 },
	{ 352, 352 },
	{ 354, 354 },
	{ 356, 356 },
	{ 358, 358 },
	{ 360, 360 },
	{ 362, 362 },
	{ 364, 364 },
	{ 366, 366 },
	{ 368, 368 },
	{ 370, 370 },
	{ 372, 372 },
	{ 374, 374 },
	{ 376, 377 },
	{ 379, 379 },
	{ 381, 381 },
	{ 385, 386 },
	{ 388, 388 },
	{ 390, 391 },
	{ 393, 395 },
	{ 398, 401 },
	{ 403, 404 },
	{ 406, 408 },
	{ 412, 413 },
	{ 415, 416 },
	{ 418, 418 },
	{ 420, 420 },
	{ 422, 423 },
	{ 425, 425 },
	{ 428, 428 },
	{ 430, 431 },
	{ 433, 435 },
	{ 437, 437 },
	{ 439, 440 },
	{ 444, 444 },
	{ 452, 452 },
	{ 455, 455 },
	{ 458, 458 },
	{ 461, 461 },
	{ 463, 463 },
	{ 465, 465 },
	{ 467, 467 },
	{ 469, 469 },
	{ 471, 471 },
	{ 473, 473 },
	{ 475, 475 },
	{ 478, 478 },
	{ 480, 480 },
	{ 482, 482 },
	{ 484, 484 },
	{ 486, 486 },
	{ 488, 488 },
	{ 490, 490 },
	{ 492, 492 },
	{ 494, 494 },
	{ 497, 497 },
	{ 500, 500 },
	{ 502, 504 },
	{ 506, 506 },
	{ 508, 508 },
	{ 510, 510 },
	{ 512, 512 },
	{ 514, 514 },
	{ 516, 516 },
	{ 518, 518 },
	{ 520, 520 },
	{ 522, 522 },
	{ 524, 524 },
	{ 526, 526 },
	{ 528, 528 },
	{ 530, 530 },
	{ 532, 532 },
	{ 534, 534 },
	{ 536, 536 },
	{ 538, 538 },
	{ 540, 540 },
	{ 542, 542 },
	{ 544, 544 },
	{ 546, 546 },
	{ 548, 548 },
	{ 550, 550 },
	{ 552, 552 },
	{ 554, 554 },
	{ 556, 556 },
	{ 558, 558 },
	{ 560, 560 },
	{ 562, 562 },
	{ 570, 571 },
	{ 573, 574 },
	{ 577, 577 },
	{ 579, 582 },
	{ 584, 584 },
	{ 586, 586 },
	{ 588, 588 },
	{ 590, 590 },
	{ 880, 880 },
	{ 882, 882 },
	{ 886, 886 },
	{ 895, 895 },
	{ 902, 902 },
	{ 904, 906 },
	{ 908, 908 },
	{ 910, 911 },
	{ 913, 929 },
	{ 931, 939 },
	{ 975, 975 },
	{ 978, 980 },
	{ 984, 984 },
	{ 986, 986 },
	{ 988, 988 },
	{ 990, 990 },
	{ 992, 992 },
	{ 994, 994 },
	{ 996, 996 },
	{ 998, 998 },
	{ 1000, 1000 },
	{ 1002, 1002 },
	{ 1004, 1004 },
	{ 1006, 1006 },
	{ 1012, 1012 },
	{ 1015, 1015 },
	{ 1017, 1018 },
	{ 1021, 1071 },
	{ 1120, 1120 },
	{ 1122, 1122 },
	{ 1124, 1124 },
	{ 1126, 1126 },
	{ 1128, 1128 },
	{ 1130, 1130 },
	{ 1132, 1132 },
	{ 1134, 1134 },
	{ 1136, 1136 },
	{ 1138, 1138 },
	{ 1140, 1140 },
	{ 1142, 1142 },
	{ 1144, 1144 },
	{ 1146, 1146 },
	{ 1148, 1148 },
	{ 1150, 1150 },
	{ 1152, 1152 },
	{ 1162, 1162 },
	{ 1164, 1164 },
	{ 1166, 1166 },
	{ 1168, 1168 },
	{ 1170, 1170 },
	{ 1172, 1172 },
	{ 1174, 1174 },
	{ 1176, 1176 },
	{ 1178, 1178 },
	{ 1180, 1180 },
	{ 1182, 1182 },
	{ 1184, 1184 },
	{ 1186, 1186 },
	{ 1188, 1188 },
	{ 1190, 1190 },
	{ 1192, 1192 },
	{ 1194, 1194 },
	{ 1196, 1196 },
	{ 1198, 1198 },
	{ 1200, 1200 },
	{ 1202, 1202 },
	{ 1204, 1204 },
	{ 1206, 1206 },
	{ 1208, 1208 },
	{ 1210, 1210 },
	{ 1212, 1212 },
	{ 1214, 1214 },
	{ 1216, 1217 },
	{ 1219, 1219 },
	{ 1221, 1221 },
	{ 1223, 1223 },
	{ 1225, 1225 },
	{ 1227, 1227 },
	{ 1229, 1229 },
	{ 1232, 1232 },
	{ 1234, 1234 },
	{ 1236, 1236 },
	{ 1238, 1238 },
	{ 1240, 1240 },
	{ 1242, 1242 },
	{ 1244, 1244 },
	{ 1246, 1246 },
	{ 1248, 1248 },
	{ 1250, 1250 },
	{ 1252, 1252 },
	{ 1254, 1254 },
	{ 1256, 1256 },
	{ 1258, 1258 },
	{ 1260, 1260 },
	{ 1262, 1262 },
	{ 1264, 1264 },
	{ 1266, 1266 },
	{ 1268, 1268 },
	{ 1270, 1270 },
	{ 1272, 1272 },
	{ 1274, 1274 },
	{ 1276, 1276 },
	{ 1278, 1278 },
	{ 1280, 1280 },
	{ 1282, 1282 },
	{ 1284, 1284 },
	{ 1286, 1286 },
	{ 1288, 1288 },
	{ 1290, 1290 },
	{ 1292, 1292 },
	{ 1294, 1294 },
	{ 1296, 1296 },
	{ 1298, 1298 },
	{ 1300, 1300 },
	{ 1302, 1302 },
	{ 1304, 1304 },
	{ 1306, 1306 },
	{ 1308, 1308 },
	{ 1310, 1310 },
	{ 1312, 1312 },
	{ 1314, 1314 },
	{ 1316, 1316 },
	{ 1318, 1318 },
	{ 1320, 1320 },
	{ 1322, 1322 },
	{ 1324, 1324 },
	{ 1326, 1326 },
	{ 1329, 1366 },
	{ 4256, 4293 },
	{ 4295, 4295 },
	{ 4301, 4301 },
	{ 5024, 5109 },
	{ 7312, 7354 },
	{ 7357, 7359 },
	{ 7680, 7680 },
	{ 7682, 7682 },
	{ 7684, 7684 },
	{ 7686, 7686 },
	{ 7688, 7688 },
	{ 7690, 7690 },
	{ 7692, 7692 },
	{ 7694, 7694 },
	{ 7696, 7696 },
	{ 7698, 7698 },
	{ 7700, 7700 },
	{ 7702, 7702 },
	{ 7704, 7704 },
	{ 7706, 7706 },
	{ 7708, 7708 },
	{ 7710, 7710 },
	{ 7712, 7712 },
	{ 7714, 7714 },
	{ 7716, 7716 },
	{ 7718, 7718 },
	{ 7720, 7720 },
	{ 7722, 7722 },
	{ 7724, 7724 },
	{ 7726, 7726 },
	{ 7728, 7728 },
	{ 7730, 7730 },
	{ 7732, 7732 },
	{ 7734, 7734 },
	{ 7736, 7736 },
	{ 7738, 7738 },
	{ 7740, 7740 },
	{ 7742, 7742 },
	{ 7744, 7744 },
	{ 7746, 7746 },
	{ 7748, 7748 },
	{ 7750, 7750 },
	{ 7752, 7752 },
	{ 7754, 7754 },
	{ 7756, 7756 },
	{ 7758, 7758 },
	{ 7760, 7760 },
	{ 7762, 7762 },
	{ 7764, 7764 },
	{ 7766, 7766 },
	{ 7768, 7768 },
	{ 7770, 7770 },
	{ 7772, 7772 },
	{ 7774, 7774 },
	{ 7776, 7776 },
	{ 7778, 7778 },
	{ 7780, 7780 },
	{ 7782, 7782 },
	{ 7784, 7784 },
	{ 7786, 7786 },
	{ 7788, 7788 },
	{ 7790, 7790 },
	{ 7792, 7792 },
	{ 7794, 7794 },
	{ 7796, 7796 },
	{ 7798, 7798 },
	{ 7800, 7800 },
	{ 7802, 7802 },
	{ 7804, 7804 },
	{ 7806, 7806 },
	{ 7808, 7808 },
	{ 7810, 7810 },
	{ 7812, 7812 },
	{ 7814, 7814 },
	{ 7816, 7816 },
	{ 7818, 7818 },
	{ 7820, 7820 },
	{ 7822, 7822 },
	{ 7824, 7824 },
	{ 7826, 7826 },
	{ 7828, 7828 },
	{ 7838, 7838 },
	{ 7840, 7840 },
	{ 7842, 7842 },
	{ 7844, 7844 },
	{ 7846, 7846 },
	{ 7848, 7848 },
	{ 7850, 7850 },
	{ 7852, 7852 },
	{ 7854, 7854 },
	{ 7856, 7856 },
	{ 7858, 7858 },
	{ 7860, 7860 },
	{ 7862, 7862 },
	{ 7864, 7864 },
	{ 7866, 7866 },
	{ 7868, 7868 },
	{ 7870, 7870 },
	{ 7872, 7872 },
	{ 7874, 7874 },
	{ 7876, 7876 },
	{ 7878, 7878 },
	{ 7880, 7880 },
	{ 7882, 7882 },
	{ 7884, 7884 },
	{ 7886, 7886 },
	{ 7888, 7888 },
	{ 7890, 7890 },
	{ 7892, 7892 },
	{ 7894, 7894 },
	{ 7896, 7896 },
	{ 7898, 7898 },
	{ 7900, 7900 },
	{ 7902, 7902 },
	{ 7904, 7904 },
	{ 7906, 7906 },
	{ 7908, 7908 },
	{ 7910, 7910 },
	{ 7912, 7912 },
	{ 7914, 7914 },
	{ 7916, 7916 },
	{ 7918, 7918 },
	{ 7920, 7920 },
	{ 7922, 7922 },
	{ 7924, 7924 },
	{ 7926, 7926 },
	{ 7928, 7928 },
	{ 7930, 7930 },
	{ 7932, 7932 },
	{ 7934, 7934 },
	{ 7944, 7951 },
	{ 7960, 7965 },
	{ 7976, 7983 },
	{ 7992, 7999 },
	{ 8008, 8013 },
	{ 8025, 8025 },
	{ 8027, 8027 },
	{ 8029, 8029 },
	{ 8031, 8031 },
	{ 8040, 8047 },
	{ 8120, 8123 },
	{ 8136, 8139 },
	{ 8152, 8155 },
	{ 8168, 8172 },
	{ 8184, 8187 },
	{ 8450, 8450 },
	{ 8455, 8455 },
	{ 8459, 8461 },
	{ 8464, 8466 },
	{ 8469, 8469 },
	{ 8473, 8477 },
	{ 8484, 8484 },
	{ 8486, 8486 },
	{ 8488, 8488 },
	{ 8490, 8493 },
	{ 8496, 8499 },
	{ 8510, 8511 },
	{ 8517, 8517 },
	{ 8579, 8579 },
	{ 11264, 11310 },
	{ 11360, 11360 },
	{ 11362, 11364 },
	{ 11367, 11367 },
	{ 11369, 11369 },
	{ 11371, 11371 },
	{ 11373, 11376 },
	{ 11378, 11378 },
	{ 11381, 11381 },
	{ 11390, 11392 },
	{ 11394, 11394 },
	{ 11396, 11396 },
	{ 11398, 11398 },
	{ 11400, 11400 },
	{ 11402, 11402 },
	{ 11404, 11404 },
	{ 11406, 11406 },
	{ 11408, 11408 },
	{ 11410, 11410 },
	{ 11412, 11412 },
	{ 11414, 11414 },
	{ 11416, 11416 },
	{ 11418, 11418 },
	{ 11420, 11420 },
	{ 11422, 11422 },
	{ 11424, 11424 },
	{ 11426, 11426 },
	{ 11428, 11428 },
	{ 11430, 11430 },
	{ 11432, 11432 },
	{ 11434, 11434 },
	{ 11436, 11436 },
	{ 11438, 11438 },
	{ 11440, 11440 },
	{ 11442, 11442 },
	{ 11444, 11444 },
	{ 11446, 11446 },
	{ 11448, 11448 },
	{ 11450, 11450 },
	{ 11452, 11452 },
	{ 11454, 11454 },
	{ 11456, 11456 },
	{ 11458, 11458 },
	{ 11460, 11460 },
	{ 11462, 11462 },
	{ 11464, 11464 },
	{ 11466, 11466 },
	{ 11468, 11468 },
	{ 11470, 11470 },
	{ 11472, 11472 },
	{ 11474, 11474 },
	{ 11476, 11476 },
	{ 11478, 11478 },
	{ 11480, 11480 },
	{ 11482, 11482 },
	{ 11484, 11484 },
	{ 11486, 11486 },
	{ 11488, 11488 },
	{ 11490, 11490 },
	{ 11499, 11499 },
	{ 11501, 11501 },
	{ 11506, 11506 },
	{ 42560, 42560 },
	{ 42562, 42562 },
	{ 42564, 42564 },
	{ 42566, 42566 },
	{ 42568, 42568 },
	{ 42570, 42570 },
	{ 42572, 42572 },
	{ 42574, 42574 },
	{ 42576, 42576 },
	{ 42578, 42578 },
	{ 42580, 42580 },
	{ 42582, 42582 },
	{ 42584, 42584 },
	{ 42586, 42586 },
	{ 42588, 42588 },
	{ 42590, 42590 },
	{ 42592, 42592 },
	{ 42594, 42594 },
	{ 42596, 42596 },
	{ 42598, 42598 },
	{ 42600, 42600 },
	{ 42602, 42602 },
	{ 42604, 42604 },
	{ 42624, 42624 },
	{ 42626, 42626 },
	{ 42628, 42628 },
	{ 42630, 42630 },
	{ 42632, 42632 },
	{ 42634, 42634 },
	{ 42636, 42636 },
	{ 42638, 42638 },
	{ 42640, 42640 },
	{ 42642, 42642 },
	{ 42644, 42644 },
	{ 42646, 42646 },
	{ 42648, 42648 },
	{ 42650, 42650 },
	{ 42786, 42786 },
	{ 42788, 42788 },
	{ 42790, 42790 },
	{ 42792, 42792 },
	{ 42794, 42794 },
	{ 42796, 42796 },
	{ 42798, 42798 },
	{ 42802, 42802 },
	{ 42804, 42804 },
	{ 42806, 42806 },
	{ 42808, 42808 },
	{ 42810, 42810 },
	{ 42812, 42812 },
	{ 42814, 42814 },
	{ 42816, 42816 },
	{ 42818, 42818 },
	{ 42820, 42820 },
	{ 42822, 42822 },
	{ 42824, 42824 },
	{ 42826, 42826 },
	{ 42828, 42828 },
	{ 42830, 42830 },
	{ 42832, 42832 },
	{ 42834, 42834 },
	{ 42836, 42836 },
	{ 42838, 42838 },
	{ 42840, 42840 },
	{ 42842, 42842 },
	{ 42844, 42844 },
	{ 42846, 42846 },
	{ 42848, 42848 },
	{ 42850, 42850 },
	{ 42852, 42852 },
	{ 42854, 42854 },
	{ 42856, 42856 },
	{ 42858, 42858 },
	{ 42860, 42860 },
	{ 42862, 42862 },
	{ 42873, 42873 },
	{ 42875, 42875 },
	{ 42877, 42878 },
	{ 42880, 42880 },
	{ 42882, 42882 },
	{ 42884, 42884 },
	{ 42886, 42886 },
	{ 42891, 42891 },
	{ 42893, 42893 },
	{ 42896, 42896 },
	{ 42898, 42898 },
	{ 42902, 42902 },
	{ 42904, 42904 },
	{ 42906, 42906 },
	{ 42908, 42908 },
	{ 42910, 42910 },
	{ 42912, 42912 },
	{ 42914, 42914 },
	{ 42916, 42916 },
	{ 42918, 42918 },
	{ 42920, 42920 },
	{ 42922, 42926 },
	{ 42928, 42932 },
	{ 42934, 42934 },
	{ 42936, 42936 },
	{ 65313, 65338 },
};
static const URange32 Lu_range32[] = {
	{ 66560, 66599 },
	{ 66736, 66771 },
	{ 68736, 68786 },
	{ 71840, 71871 },
	{ 93760, 93791 },
	{ 119808, 119833 },
	{ 119860, 119885 },
	{ 119912, 119937 },
	{ 119964, 119964 },
	{ 119966, 119967 },
	{ 119970, 119970 },
	{ 119973, 119974 },
	{ 119977, 119980 },
	{ 119982, 119989 },
	{ 120016, 120041 },
	{ 120068, 120069 },
	{ 120071, 120074 },
	{ 120077, 120084 },
	{ 120086, 120092 },
	{ 120120, 120121 },
	{ 120123, 120126 },
	{ 120128, 120132 },
	{ 120134, 120134 },
	{ 120138, 120144 },
	{ 120172, 120197 },
	{ 120224, 120249 },
	{ 120276, 120301 },
	{ 120328, 120353 },
	{ 120380, 120405 },
	{ 120432, 120457 },
	{ 120488, 120512 },
	{ 120546, 120570 },
	{ 120604, 120628 },
	{ 120662, 120686 },
	{ 120720, 120744 },
	{ 120778, 120778 },
	{ 125184, 125217 },
};
static const URange16 Pf_range16[] = {
	{ 187, 187 },
	{ 8217, 8217 },
	{ 8221, 8221 },
	{ 8250, 8250 },
	{ 11779, 11779 },
	{ 11781, 11781 },
	{ 11786, 11786 },
	{ 11789, 11789 },
	{ 11805, 11805 },
	{ 11809, 11809 },
};
static const URange16 Pd_range16[] = {
	{ 45, 45 },
	{ 1418, 1418 },
	{ 1470, 1470 },
	{ 5120, 5120 },
	{ 6150, 6150 },
	{ 8208, 8213 },
	{ 11799, 11799 },
	{ 11802, 11802 },
	{ 11834, 11835 },
	{ 11840, 11840 },
	{ 12316, 12316 },
	{ 12336, 12336 },
	{ 12448, 12448 },
	{ 65073, 65074 },
	{ 65112, 65112 },
	{ 65123, 65123 },
	{ 65293, 65293 },
};
static const URange16 Pe_range16[] = {
	{ 41, 41 },
	{ 93, 93 },
	{ 125, 125 },
	{ 3899, 3899 },
	{ 3901, 3901 },
	{ 5788, 5788 },
	{ 8262, 8262 },
	{ 8318, 8318 },
	{ 8334, 8334 },
	{ 8969, 8969 },
	{ 8971, 8971 },
	{ 9002, 9002 },
	{ 10089, 10089 },
	{ 10091, 10091 },
	{ 10093, 10093 },
	{ 10095, 10095 },
	{ 10097, 10097 },
	{ 10099, 10099 },
	{ 10101, 10101 },
	{ 10182, 10182 },
	{ 10215, 10215 },
	{ 10217, 10217 },
	{ 10219, 10219 },
	{ 10221, 10221 },
	{ 10223, 10223 },
	{ 10628, 10628 },
	{ 10630, 10630 },
	{ 10632, 10632 },
	{ 10634, 10634 },
	{ 10636, 10636 },
	{ 10638, 10638 },
	{ 10640, 10640 },
	{ 10642, 10642 },
	{ 10644, 10644 },
	{ 10646, 10646 },
	{ 10648, 10648 },
	{ 10713, 10713 },
	{ 10715, 10715 },
	{ 10749, 10749 },
	{ 11811, 11811 },
	{ 11813, 11813 },
	{ 11815, 11815 },
	{ 11817, 11817 },
	{ 12297, 12297 },
	{ 12299, 12299 },
	{ 12301, 12301 },
	{ 12303, 12303 },
	{ 12305, 12305 },
	{ 12309, 12309 },
	{ 12311, 12311 },
	{ 12313, 12313 },
	{ 12315, 12315 },
	{ 12318, 12319 },
	{ 64830, 64830 },
	{ 65048, 65048 },
	{ 65078, 65078 },
	{ 65080, 65080 },
	{ 65082, 65082 },
	{ 65084, 65084 },
	{ 65086, 65086 },
	{ 65088, 65088 },
	{ 65090, 65090 },
	{ 65092, 65092 },
	{ 65096, 65096 },
	{ 65114, 65114 },
	{ 65116, 65116 },
	{ 65118, 65118 },
	{ 65289, 65289 },
	{ 65341, 65341 },
	{ 65373, 65373 },
	{ 65376, 65376 },
	{ 65379, 65379 },
};
static const URange16 Pi_range16[] = {
	{ 171, 171 },
	{ 8216, 8216 },
	{ 8219, 8220 },
	{ 8223, 8223 },
	{ 8249, 8249 },
	{ 11778, 11778 },
	{ 11780, 11780 },
	{ 11785, 11785 },
	{ 11788, 11788 },
	{ 11804, 11804 },
	{ 11808, 11808 },
};
static const URange16 Po_range16[] = {
	{ 33, 35 },
	{ 37, 39 },
	{ 42, 42 },
	{ 44, 44 },
	{ 46, 47 },
	{ 58, 59 },
	{ 63, 64 },
	{ 92, 92 },
	{ 161, 161 },
	{ 167, 167 },
	{ 182, 183 },
	{ 191, 191 },
	{ 894, 894 },
	{ 903, 903 },
	{ 1370, 1375 },
	{ 1417, 1417 },
	{ 1472, 1472 },
	{ 1475, 1475 },
	{ 1478, 1478 },
	{ 1523, 1524 },
	{ 1545, 1546 },
	{ 1548, 1549 },
	{ 1563, 1563 },
	{ 1566, 1567 },
	{ 1642, 1645 },
	{ 1748, 1748 },
	{ 1792, 1805 },
	{ 2039, 2041 },
	{ 2096, 2110 },
	{ 2142, 2142 },
	{ 2404, 2405 },
	{ 2416, 2416 },
	{ 2557, 2557 },
	{ 2678, 2678 },
	{ 2800, 2800 },
	{ 3204, 3204 },
	{ 3572, 3572 },
	{ 3663, 3663 },
	{ 3674, 3675 },
	{ 3844, 3858 },
	{ 3860, 3860 },
	{ 3973, 3973 },
	{ 4048, 4052 },
	{ 4057, 4058 },
	{ 4170, 4175 },
	{ 4347, 4347 },
	{ 4960, 4968 },
	{ 5741, 5742 },
	{ 5867, 5869 },
	{ 5941, 5942 },
	{ 6100, 6102 },
	{ 6104, 6106 },
	{ 6144, 6149 },
	{ 6151, 6154 },
	{ 6468, 6469 },
	{ 6686, 6687 },
	{ 6816, 6822 },
	{ 6824, 6829 },
	{ 7002, 7008 },
	{ 7164, 7167 },
	{ 7227, 7231 },
	{ 7294, 7295 },
	{ 7360, 7367 },
	{ 7379, 7379 },
	{ 8214, 8215 },
	{ 8224, 8231 },
	{ 8240, 8248 },
	{ 8251, 8254 },
	{ 8257, 8259 },
	{ 8263, 8273 },
	{ 8275, 8275 },
	{ 8277, 8286 },
	{ 11513, 11516 },
	{ 11518, 11519 },
	{ 11632, 11632 },
	{ 11776, 11777 },
	{ 11782, 11784 },
	{ 11787, 11787 },
	{ 11790, 11798 },
	{ 11800, 11801 },
	{ 11803, 11803 },
	{ 11806, 11807 },
	{ 11818, 11822 },
	{ 11824, 11833 },
	{ 11836, 11839 },
	{ 11841, 11841 },
	{ 11843, 11854 },
	{ 12289, 12291 },
	{ 12349, 12349 },
	{ 12539, 12539 },
	{ 42238, 42239 },
	{ 42509, 42511 },
	{ 42611, 42611 },
	{ 42622, 42622 },
	{ 42738, 42743 },
	{ 43124, 43127 },
	{ 43214, 43215 },
	{ 43256, 43258 },
	{ 43260, 43260 },
	{ 43310, 43311 },
	{ 43359, 43359 },
	{ 43457, 43469 },
	{ 43486, 43487 },
	{ 43612, 43615 },
	{ 43742, 43743 },
	{ 43760, 43761 },
	{ 44011, 44011 },
	{ 65040, 65046 },
	{ 65049, 65049 },
	{ 65072, 65072 },
	{ 65093, 65094 },
	{ 65097, 65100 },
	{ 65104, 65106 },
	{ 65108, 65111 },
	{ 65119, 65121 },
	{ 65128, 65128 },
	{ 65130, 65131 },
	{ 65281, 65283 },
	{ 65285, 65287 },
	{ 65290, 65290 },
	{ 65292, 65292 },
	{ 65294, 65295 },
	{ 65306, 65307 },
	{ 65311, 65312 },
	{ 65340, 65340 },
	{ 65377, 65377 },
	{ 65380, 65381 },
};
static const URange32 Po_range32[] = {
	{ 65792, 65794 },
	{ 66463, 66463 },
	{ 66512, 66512 },
	{ 66927, 66927 },
	{ 67671, 67671 },
	{ 67871, 67871 },
	{ 67903, 67903 },
	{ 68176, 68184 },
	{ 68223, 68223 },
	{ 68336, 68342 },
	{ 68409, 68415 },
	{ 68505, 68508 },
	{ 69461, 69465 },
	{ 69703, 69709 },
	{ 69819, 69820 },
	{ 69822, 69825 },
	{ 69952, 69955 },
	{ 70004, 70005 },
	{ 70085, 70088 },
	{ 70093, 70093 },
	{ 70107, 70107 },
	{ 70109, 70111 },
	{ 70200, 70205 },
	{ 70313, 70313 },
	{ 70731, 70735 },
	{ 70747, 70747 },
	{ 70749, 70749 },
	{ 70854, 70854 },
	{ 71105, 71127 },
	{ 71233, 71235 },
	{ 71264, 71276 },
	{ 71484, 71486 },
	{ 71739, 71739 },
	{ 72255, 72262 },
	{ 72346, 72348 },
	{ 72350, 72354 },
	{ 72769, 72773 },
	{ 72816, 72817 },
	{ 73463, 73464 },
	{ 74864, 74868 },
	{ 92782, 92783 },
	{ 92917, 92917 },
	{ 92983, 92987 },
	{ 92996, 92996 },
	{ 93847, 93850 },
	{ 113823, 113823 },
	{ 121479, 121483 },
	{ 125278, 125279 },
};
static const URange16 Me_range16[] = {
	{ 1160, 1161 },
	{ 6846, 6846 },
	{ 8413, 8416 },
	{ 8418, 8420 },
	{ 42608, 42610 },
};
static const URange16 C_range16[] = {
	{ 0, 31 },
	{ 127, 159 },
	{ 173, 173 },
	{ 1536, 1541 },
	{ 1564, 1564 },
	{ 1757, 1757 },
	{ 1807, 1807 },
	{ 2274, 2274 },
	{ 6158, 6158 },
	{ 8203, 8207 },
	{ 8234, 8238 },
	{ 8288, 8292 },
	{ 8294, 8303 },
	{ 55296, 63743 },
	{ 65279, 65279 },
	{ 65529, 65531 },
};
static const URange32 C_range32[] = {
	{ 69821, 69821 },
	{ 69837, 69837 },
	{ 113824, 113827 },
	{ 119155, 119162 },
	{ 917505, 917505 },
	{ 917536, 917631 },
	{ 983040, 1048573 },
	{ 1048576, 1114109 },
};
static const URange16 Mc_range16[] = {
	{ 2307, 2307 },
	{ 2363, 2363 },
	{ 2366, 2368 },
	{ 2377, 2380 },
	{ 2382, 2383 },
	{ 2434, 2435 },
	{ 2494, 2496 },
	{ 2503, 2504 },
	{ 2507, 2508 },
	{ 2519, 2519 },
	{ 2563, 2563 },
	{ 2622, 2624 },
	{ 2691, 2691 },
	{ 2750, 2752 },
	{ 2761, 2761 },
	{ 2763, 2764 },
	{ 2818, 2819 },
	{ 2878, 2878 },
	{ 2880, 2880 },
	{ 2887, 2888 },
	{ 2891, 2892 },
	{ 2903, 2903 },
	{ 3006, 3007 },
	{ 3009, 3010 },
	{ 3014, 3016 },
	{ 3018, 3020 },
	{ 3031, 3031 },
	{ 3073, 3075 },
	{ 3137, 3140 },
	{ 3202, 3203 },
	{ 3262, 3262 },
	{ 3264, 3268 },
	{ 3271, 3272 },
	{ 3274, 3275 },
	{ 3285, 3286 },
	{ 3330, 3331 },
	{ 3390, 3392 },
	{ 3398, 3400 },
	{ 3402, 3404 },
	{ 3415, 3415 },
	{ 3458, 3459 },
	{ 3535, 3537 },
	{ 3544, 3551 },
	{ 3570, 3571 },
	{ 3902, 3903 },
	{ 3967, 3967 },
	{ 4139, 4140 },
	{ 4145, 4145 },
	{ 4152, 4152 },
	{ 4155, 4156 },
	{ 4182, 4183 },
	{ 4194, 4196 },
	{ 4199, 4205 },
	{ 4227, 4228 },
	{ 4231, 4236 },
	{ 4239, 4239 },
	{ 4250, 4252 },
	{ 6070, 6070 },
	{ 6078, 6085 },
	{ 6087, 6088 },
	{ 6435, 6438 },
	{ 6441, 6443 },
	{ 6448, 6449 },
	{ 6451, 6456 },
	{ 6681, 6682 },
	{ 6741, 6741 },
	{ 6743, 6743 },
	{ 6753, 6753 },
	{ 6755, 6756 },
	{ 6765, 6770 },
	{ 6916, 6916 },
	{ 6965, 6965 },
	{ 6971, 6971 },
	{ 6973, 6977 },
	{ 6979, 6980 },
	{ 7042, 7042 },
	{ 7073, 7073 },
	{ 7078, 7079 },
	{ 7082, 7082 },
	{ 7143, 7143 },
	{ 7146, 7148 },
	{ 7150, 7150 },
	{ 7154, 7155 },
	{ 7204, 7211 },
	{ 7220, 7221 },
	{ 7393, 7393 },
	{ 7410, 7411 },
	{ 7415, 7415 },
	{ 12334, 12335 },
	{ 43043, 43044 },
	{ 43047, 43047 },
	{ 43136, 43137 },
	{ 43188, 43203 },
	{ 43346, 43347 },
	{ 43395, 43395 },
	{ 43444, 43445 },
	{ 43450, 43451 },
	{ 43453, 43456 },
	{ 43567, 43568 },
	{ 43571, 43572 },
	{ 43597, 43597 },
	{ 43643, 43643 },
	{ 43645, 43645 },
	{ 43755, 43755 },
	{ 43758, 43759 },
	{ 43765, 43765 },
	{ 44003, 44004 },
	{ 44006, 44007 },
	{ 44009, 44010 },
	{ 44012, 44012 },
};
static const URange32 Mc_range32[] = {
	{ 69632, 69632 },
	{ 69634, 69634 },
	{ 69762, 69762 },
	{ 69808, 69810 },
	{ 69815, 69816 },
	{ 69932, 69932 },
	{ 69957, 69958 },
	{ 70018, 70018 },
	{ 70067, 70069 },
	{ 70079, 70080 },
	{ 70188, 70190 },
	{ 70194, 70195 },
	{ 70197, 70197 },
	{ 70368, 70370 },
	{ 70402, 70403 },
	{ 70462, 70463 },
	{ 70465, 70468 },
	{ 70471, 70472 },
	{ 70475, 70477 },
	{ 70487, 70487 },
	{ 70498, 70499 },
	{ 70709, 70711 },
	{ 70720, 70721 },
	{ 70725, 70725 },
	{ 70832, 70834 },
	{ 70841, 70841 },
	{ 70843, 70846 },
	{ 70849, 70849 },
	{ 71087, 71089 },
	{ 71096, 71099 },
	{ 71102, 71102 },
	{ 71216, 71218 },
	{ 71227, 71228 },
	{ 71230, 71230 },
	{ 71340, 71340 },
	{ 71342, 71343 },
	{ 71350, 71350 },
	{ 71456, 71457 },
	{ 71462, 71462 },
	{ 71724, 71726 },
	{ 71736, 71736 },
	{ 72249, 72249 },
	{ 72279, 72280 },
	{ 72343, 72343 },
	{ 72751, 72751 },
	{ 72766, 72766 },
	{ 72873, 72873 },
	{ 72881, 72881 },
	{ 72884, 72884 },
	{ 73098, 73102 },
	{ 73107, 73108 },
	{ 73110, 73110 },
	{ 73461, 73462 },
	{ 94033, 94078 },
	{ 119141, 119142 },
	{ 119149, 119154 },
};
static const URange16 Mn_range16[] = {
	{ 768, 879 },
	{ 1155, 1159 },
	{ 1425, 1469 },
	{ 1471, 1471 },
	{ 1473, 1474 },
	{ 1476, 1477 },
	{ 1479, 1479 },
	{ 1552, 1562 },
	{ 1611, 1631 },
	{ 1648, 1648 },
	{ 1750, 1756 },
	{ 1759, 1764 },
	{ 1767, 1768 },
	{ 1770, 1773 },
	{ 1809, 1809 },
	{ 1840, 1866 },
	{ 1958, 1968 },
	{ 2027, 2035 },
	{ 2045, 2045 },
	{ 2070, 2073 },
	{ 2075, 2083 },
	{ 2085, 2087 },
	{ 2089, 2093 },
	{ 2137, 2139 },
	{ 2259, 2273 },
	{ 2275, 2306 },
	{ 2362, 2362 },
	{ 2364, 2364 },
	{ 2369, 2376 },
	{ 2381, 2381 },
	{ 2385, 2391 },
	{ 2402, 2403 },
	{ 2433, 2433 },
	{ 2492, 2492 },
	{ 2497, 2500 },
	{ 2509, 2509 },
	{ 2530, 2531 },
	{ 2558, 2558 },
	{ 2561, 2562 },
	{ 2620, 2620 },
	{ 2625, 2626 },
	{ 2631, 2632 },
	{ 2635, 2637 },
	{ 2641, 2641 },
	{ 2672, 2673 },
	{ 2677, 2677 },
	{ 2689, 2690 },
	{ 2748, 2748 },
	{ 2753, 2757 },
	{ 2759, 2760 },
	{ 2765, 2765 },
	{ 2786, 2787 },
	{ 2810, 2815 },
	{ 2817, 2817 },
	{ 2876, 2876 },
	{ 2879, 2879 },
	{ 2881, 2884 },
	{ 2893, 2893 },
	{ 2902, 2902 },
	{ 2914, 2915 },
	{ 2946, 2946 },
	{ 3008, 3008 },
	{ 3021, 3021 },
	{ 3072, 3072 },
	{ 3076, 3076 },
	{ 3134, 3136 },
	{ 3142, 3144 },
	{ 3146, 3149 },
	{ 3157, 3158 },
	{ 3170, 3171 },
	{ 3201, 3201 },
	{ 3260, 3260 },
	{ 3263, 3263 },
	{ 3270, 3270 },
	{ 3276, 3277 },
	{ 3298, 3299 },
	{ 3328, 3329 },
	{ 3387, 3388 },
	{ 3393, 3396 },
	{ 3405, 3405 },
	{ 3426, 3427 },
	{ 3530, 3530 },
	{ 3538, 3540 },
	{ 3542, 3542 },
	{ 3633, 3633 },
	{ 3636, 3642 },
	{ 3655, 3662 },
	{ 3761, 3761 },
	{ 3764, 3769 },
	{ 3771, 3772 },
	{ 3784, 3789 },
	{ 3864, 3865 },
	{ 3893, 3893 },
	{ 3895, 3895 },
	{ 3897, 3897 },
	{ 3953, 3966 },
	{ 3968, 3972 },
	{ 3974, 3975 },
	{ 3981, 3991 },
	{ 3993, 4028 },
	{ 4038, 4038 },
	{ 4141, 4144 },
	{ 4146, 4151 },
	{ 4153, 4154 },
	{ 4157, 4158 },
	{ 4184, 4185 },
	{ 4190, 4192 },
	{ 4209, 4212 },
	{ 4226, 4226 },
	{ 4229, 4230 },
	{ 4237, 4237 },
	{ 4253, 4253 },
	{ 4957, 4959 },
	{ 5906, 5908 },
	{ 5938, 5940 },
	{ 5970, 5971 },
	{ 6002, 6003 },
	{ 6068, 6069 },
	{ 6071, 6077 },
	{ 6086, 6086 },
	{ 6089, 6099 },
	{ 6109, 6109 },
	{ 6155, 6157 },
	{ 6277, 6278 },
	{ 6313, 6313 },
	{ 6432, 6434 },
	{ 6439, 6440 },
	{ 6450, 6450 },
	{ 6457, 6459 },
	{ 6679, 6680 },
	{ 6683, 6683 },
	{ 6742, 6742 },
	{ 6744, 6750 },
	{ 6752, 6752 },
	{ 6754, 6754 },
	{ 6757, 6764 },
	{ 6771, 6780 },
	{ 6783, 6783 },
	{ 6832, 6845 },
	{ 6912, 6915 },
	{ 6964, 6964 },
	{ 6966, 6970 },
	{ 6972, 6972 },
	{ 6978, 6978 },
	{ 7019, 7027 },
	{ 7040, 7041 },
	{ 7074, 7077 },
	{ 7080, 7081 },
	{ 7083, 7085 },
	{ 7142, 7142 },
	{ 7144, 7145 },
	{ 7149, 7149 },
	{ 7151, 7153 },
	{ 7212, 7219 },
	{ 7222, 7223 },
	{ 7376, 7378 },
	{ 7380, 7392 },
	{ 7394, 7400 },
	{ 7405, 7405 },
	{ 7412, 7412 },
	{ 7416, 7417 },
	{ 7616, 7673 },
	{ 7675, 7679 },
	{ 8400, 8412 },
	{ 8417, 8417 },
	{ 8421, 8432 },
	{ 11503, 11505 },
	{ 11647, 11647 },
	{ 11744, 11775 },
	{ 12330, 12333 },
	{ 12441, 12442 },
	{ 42607, 42607 },
	{ 42612, 42621 },
	{ 42654, 42655 },
	{ 42736, 42737 },
	{ 43010, 43010 },
	{ 43014, 43014 },
	{ 43019, 43019 },
	{ 43045, 43046 },
	{ 43204, 43205 },
	{ 43232, 43249 },
	{ 43263, 43263 },
	{ 43302, 43309 },
	{ 43335, 43345 },
	{ 43392, 43394 },
	{ 43443, 43443 },
	{ 43446, 43449 },
	{ 43452, 43452 },
	{ 43493, 43493 },
	{ 43561, 43566 },
	{ 43569, 43570 },
	{ 43573, 43574 },
	{ 43587, 43587 },
	{ 43596, 43596 },
	{ 43644, 43644 },
	{ 43696, 43696 },
	{ 43698, 43700 },
	{ 43703, 43704 },
	{ 43710, 43711 },
	{ 43713, 43713 },
	{ 43756, 43757 },
	{ 43766, 43766 },
	{ 44005, 44005 },
	{ 44008, 44008 },
	{ 44013, 44013 },
	{ 64286, 64286 },
	{ 65024, 65039 },
	{ 65056, 65071 },
};
static const URange32 Mn_range32[] = {
	{ 66045, 66045 },
	{ 66272, 66272 },
	{ 66422, 66426 },
	{ 68097, 68099 },
	{ 68101, 68102 },
	{ 68108, 68111 },
	{ 68152, 68154 },
	{ 68159, 68159 },
	{ 68325, 68326 },
	{ 68900, 68903 },
	{ 69446, 69456 },
	{ 69633, 69633 },
	{ 69688, 69702 },
	{ 69759, 69761 },
	{ 69811, 69814 },
	{ 69817, 69818 },
	{ 69888, 69890 },
	{ 69927, 69931 },
	{ 69933, 69940 },
	{ 70003, 70003 },
	{ 70016, 70017 },
	{ 70070, 70078 },
	{ 70089, 70092 },
	{ 70191, 70193 },
	{ 70196, 70196 },
	{ 70198, 70199 },
	{ 70206, 70206 },
	{ 70367, 70367 },
	{ 70371, 70378 },
	{ 70400, 70401 },
	{ 70459, 70460 },
	{ 70464, 70464 },
	{ 70502, 70508 },
	{ 70512, 70516 },
	{ 70712, 70719 },
	{ 70722, 70724 },
	{ 70726, 70726 },
	{ 70750, 70750 },
	{ 70835, 70840 },
	{ 70842, 70842 },
	{ 70847, 70848 },
	{ 70850, 70851 },
	{ 71090, 71093 },
	{ 71100, 71101 },
	{ 71103, 71104 },
	{ 71132, 71133 },
	{ 71219, 71226 },
	{ 71229, 71229 },
	{ 71231, 71232 },
	{ 71339, 71339 },
	{ 71341, 71341 },
	{ 71344, 71349 },
	{ 71351, 71351 },
	{ 71453, 71455 },
	{ 71458, 71461 },
	{ 71463, 71467 },
	{ 71727, 71735 },
	{ 71737, 71738 },
	{ 72193, 72202 },
	{ 72243, 72248 },
	{ 72251, 72254 },
	{ 72263, 72263 },
	{ 72273, 72278 },
	{ 72281, 72283 },
	{ 72330, 72342 },
	{ 72344, 72345 },
	{ 72752, 72758 },
	{ 72760, 72765 },
	{ 72767, 72767 },
	{ 72850, 72871 },
	{ 72874, 72880 },
	{ 72882, 72883 },
	{ 72885, 72886 },
	{ 73009, 73014 },
	{ 73018, 73018 },
	{ 73020, 73021 },
	{ 73023, 73029 },
	{ 73031, 73031 },
	{ 73104, 73105 },
	{ 73109, 73109 },
	{ 73111, 73111 },
	{ 73459, 73460 },
	{ 92912, 92916 },
	{ 92976, 92982 },
	{ 94095, 94098 },
	{ 113821, 113822 },
	{ 119143, 119145 },
	{ 119163, 119170 },
	{ 119173, 119179 },
	{ 119210, 119213 },
	{ 119362, 119364 },
	{ 121344, 121398 },
	{ 121403, 121452 },
	{ 121461, 121461 },
	{ 121476, 121476 },
	{ 121499, 121503 },
	{ 121505, 121519 },
	{ 122880, 122886 },
	{ 122888, 122904 },
	{ 122907, 122913 },
	{ 122915, 122916 },
	{ 122918, 122922 },
	{ 125136, 125142 },
	{ 125252, 125258 },
	{ 917760, 917999 },
};
static const URange16 M_range16[] = {
	{ 768, 879 },
	{ 1155, 1161 },
	{ 1425, 1469 },
	{ 1471, 1471 },
	{ 1473, 1474 },
	{ 1476, 1477 },
	{ 1479, 1479 },
	{ 1552, 1562 },
	{ 1611, 1631 },
	{ 1648, 1648 },
	{ 1750, 1756 },
	{ 1759, 1764 },
	{ 1767, 1768 },
	{ 1770, 1773 },
	{ 1809, 1809 },
	{ 1840, 1866 },
	{ 1958, 1968 },
	{ 2027, 2035 },
	{ 2045, 2045 },
	{ 2070, 2073 },
	{ 2075, 2083 },
	{ 2085, 2087 },
	{ 2089, 2093 },
	{ 2137, 2139 },
	{ 2259, 2273 },
	{ 2275, 2307 },
	{ 2362, 2364 },
	{ 2366, 2383 },
	{ 2385, 2391 },
	{ 2402, 2403 },
	{ 2433, 2435 },
	{ 2492, 2492 },
	{ 2494, 2500 },
	{ 2503, 2504 },
	{ 2507, 2509 },
	{ 2519, 2519 },
	{ 2530, 2531 },
	{ 2558, 2558 },
	{ 2561, 2563 },
	{ 2620, 2620 },
	{ 2622, 2626 },
	{ 2631, 2632 },
	{ 2635, 2637 },
	{ 2641, 2641 },
	{ 2672, 2673 },
	{ 2677, 2677 },
	{ 2689, 2691 },
	{ 2748, 2748 },
	{ 2750, 2757 },
	{ 2759, 2761 },
	{ 2763, 2765 },
	{ 2786, 2787 },
	{ 2810, 2815 },
	{ 2817, 2819 },
	{ 2876, 2876 },
	{ 2878, 2884 },
	{ 2887, 2888 },
	{ 2891, 2893 },
	{ 2902, 2903 },
	{ 2914, 2915 },
	{ 2946, 2946 },
	{ 3006, 3010 },
	{ 3014, 3016 },
	{ 3018, 3021 },
	{ 3031, 3031 },
	{ 3072, 3076 },
	{ 3134, 3140 },
	{ 3142, 3144 },
	{ 3146, 3149 },
	{ 3157, 3158 },
	{ 3170, 3171 },
	{ 3201, 3203 },
	{ 3260, 3260 },
	{ 3262, 3268 },
	{ 3270, 3272 },
	{ 3274, 3277 },
	{ 3285, 3286 },
	{ 3298, 3299 },
	{ 3328, 3331 },
	{ 3387, 3388 },
	{ 3390, 3396 },
	{ 3398, 3400 },
	{ 3402, 3405 },
	{ 3415, 3415 },
	{ 3426, 3427 },
	{ 3458, 3459 },
	{ 3530, 3530 },
	{ 3535, 3540 },
	{ 3542, 3542 },
	{ 3544, 3551 },
	{ 3570, 3571 },
	{ 3633, 3633 },
	{ 3636, 3642 },
	{ 3655, 3662 },
	{ 3761, 3761 },
	{ 3764, 3769 },
	{ 3771, 3772 },
	{ 3784, 3789 },
	{ 3864, 3865 },
	{ 3893, 3893 },
	{ 3895, 3895 },
	{ 3897, 3897 },
	{ 3902, 3903 },
	{ 3953, 3972 },
	{ 3974, 3975 },
	{ 3981, 3991 },
	{ 3993, 4028 },
	{ 4038, 4038 },
	{ 4139, 4158 },
	{ 4182, 4185 },
	{ 4190, 4192 },
	{ 4194, 4196 },
	{ 4199, 4205 },
	{ 4209, 4212 },
	{ 4226, 4237 },
	{ 4239, 4239 },
	{ 4250, 4253 },
	{ 4957, 4959 },
	{ 5906, 5908 },
	{ 5938, 5940 },
	{ 5970, 5971 },
	{ 6002, 6003 },
	{ 6068, 6099 },
	{ 6109, 6109 },
	{ 6155, 6157 },
	{ 6277, 6278 },
	{ 6313, 6313 },
	{ 6432, 6443 },
	{ 6448, 6459 },
	{ 6679, 6683 },
	{ 6741, 6750 },
	{ 6752, 6780 },
	{ 6783, 6783 },
	{ 6832, 6846 },
	{ 6912, 6916 },
	{ 6964, 6980 },
	{ 7019, 7027 },
	{ 7040, 7042 },
	{ 7073, 7085 },
	{ 7142, 7155 },
	{ 7204, 7223 },
	{ 7376, 7378 },
	{ 7380, 7400 },
	{ 7405, 7405 },
	{ 7410, 7412 },
	{ 7415, 7417 },
	{ 7616, 7673 },
	{ 7675, 7679 },
	{ 8400, 8432 },
	{ 11503, 11505 },
	{ 11647, 11647 },
	{ 11744, 11775 },
	{ 12330, 12335 },
	{ 12441, 12442 },
	{ 42607, 42610 },
	{ 42612, 42621 },
	{ 42654, 42655 },
	{ 42736, 42737 },
	{ 43010, 43010 },
	{ 43014, 43014 },
	{ 43019, 43019 },
	{ 43043, 43047 },
	{ 43136, 43137 },
	{ 43188, 43205 },
	{ 43232, 43249 },
	{ 43263, 43263 },
	{ 43302, 43309 },
	{ 43335, 43347 },
	{ 43392, 43395 },
	{ 43443, 43456 },
	{ 43493, 43493 },
	{ 43561, 43574 },
	{ 43587, 43587 },
	{ 43596, 43597 },
	{ 43643, 43645 },
	{ 43696, 43696 },
	{ 43698, 43700 },
	{ 43703, 43704 },
	{ 43710, 43711 },
	{ 43713, 43713 },
	{ 43755, 43759 },
	{ 43765, 43766 },
	{ 44003, 44010 },
	{ 44012, 44013 },
	{ 64286, 64286 },
	{ 65024, 65039 },
	{ 65056, 65071 },
};
static const URange32 M_range32[] = {
	{ 66045, 66045 },
	{ 66272, 66272 },
	{ 66422, 66426 },
	{ 68097, 68099 },
	{ 68101, 68102 },
	{ 68108, 68111 },
	{ 68152, 68154 },
	{ 68159, 68159 },
	{ 68325, 68326 },
	{ 68900, 68903 },
	{ 69446, 69456 },
	{ 69632, 69634 },
	{ 69688, 69702 },
	{ 69759, 69762 },
	{ 69808, 69818 },
	{ 69888, 69890 },
	{ 69927, 69940 },
	{ 69957, 69958 },
	{ 70003, 70003 },
	{ 70016, 70018 },
	{ 70067, 70080 },
	{ 70089, 70092 },
	{ 70188, 70199 },
	{ 70206, 70206 },
	{ 70367, 70378 },
	{ 70400, 70403 },
	{ 70459, 70460 },
	{ 70462, 70468 },
	{ 70471, 70472 },
	{ 70475, 70477 },
	{ 70487, 70487 },
	{ 70498, 70499 },
	{ 70502, 70508 },
	{ 70512, 70516 },
	{ 70709, 70726 },
	{ 70750, 70750 },
	{ 70832, 70851 },
	{ 71087, 71093 },
	{ 71096, 71104 },
	{ 71132, 71133 },
	{ 71216, 71232 },
	{ 71339, 71351 },
	{ 71453, 71467 },
	{ 71724, 71738 },
	{ 72193, 72202 },
	{ 72243, 72249 },
	{ 72251, 72254 },
	{ 72263, 72263 },
	{ 72273, 72283 },
	{ 72330, 72345 },
	{ 72751, 72758 },
	{ 72760, 72767 },
	{ 72850, 72871 },
	{ 72873, 72886 },
	{ 73009, 73014 },
	{ 73018, 73018 },
	{ 73020, 73021 },
	{ 73023, 73029 },
	{ 73031, 73031 },
	{ 73098, 73102 },
	{ 73104, 73105 },
	{ 73107, 73111 },
	{ 73459, 73462 },
	{ 92912, 92916 },
	{ 92976, 92982 },
	{ 94033, 94078 },
	{ 94095, 94098 },
	{ 113821, 113822 },
	{ 119141, 119145 },
	{ 119149, 119154 },
	{ 119163, 119170 },
	{ 119173, 119179 },
	{ 119210, 119213 },
	{ 119362, 119364 },
	{ 121344, 121398 },
	{ 121403, 121452 },
	{ 121461, 121461 },
	{ 121476, 121476 },
	{ 121499, 121503 },
	{ 121505, 121519 },
	{ 122880, 122886 },
	{ 122888, 122904 },
	{ 122907, 122913 },
	{ 122915, 122916 },
	{ 122918, 122922 },
	{ 125136, 125142 },
	{ 125252, 125258 },
	{ 917760, 917999 },
};
static const URange16 L_range16[] = {
	{ 65, 90 },
	{ 97, 122 },
	{ 170, 170 },
	{ 181, 181 },
	{ 186, 186 },
	{ 192, 214 },
	{ 216, 246 },
	{ 248, 705 },
	{ 710, 721 },
	{ 736, 740 },
	{ 748, 748 },
	{ 750, 750 },
	{ 880, 884 },
	{ 886, 887 },
	{ 890, 893 },
	{ 895, 895 },
	{ 902, 902 },
	{ 904, 906 },
	{ 908, 908 },
	{ 910, 929 },
	{ 931, 1013 },
	{ 1015, 1153 },
	{ 1162, 1327 },
	{ 1329, 1366 },
	{ 1369, 1369 },
	{ 1376, 1416 },
	{ 1488, 1514 },
	{ 1519, 1522 },
	{ 1568, 1610 },
	{ 1646, 1647 },
	{ 1649, 1747 },
	{ 1749, 1749 },
	{ 1765, 1766 },
	{ 1774, 1775 },
	{ 1786, 1788 },
	{ 1791, 1791 },
	{ 1808, 1808 },
	{ 1810, 1839 },
	{ 1869, 1957 },
	{ 1969, 1969 },
	{ 1994, 2026 },
	{ 2036, 2037 },
	{ 2042, 2042 },
	{ 2048, 2069 },
	{ 2074, 2074 },
	{ 2084, 2084 },
	{ 2088, 2088 },
	{ 2112, 2136 },
	{ 2144, 2154 },
	{ 2208, 2228 },
	{ 2230, 2237 },
	{ 2308, 2361 },
	{ 2365, 2365 },
	{ 2384, 2384 },
	{ 2392, 2401 },
	{ 2417, 2432 },
	{ 2437, 2444 },
	{ 2447, 2448 },
	{ 2451, 2472 },
	{ 2474, 2480 },
	{ 2482, 2482 },
	{ 2486, 2489 },
	{ 2493, 2493 },
	{ 2510, 2510 },
	{ 2524, 2525 },
	{ 2527, 2529 },
	{ 2544, 2545 },
	{ 2556, 2556 },
	{ 2565, 2570 },
	{ 2575, 2576 },
	{ 2579, 2600 },
	{ 2602, 2608 },
	{ 2610, 2611 },
	{ 2613, 2614 },
	{ 2616, 2617 },
	{ 2649, 2652 },
	{ 2654, 2654 },
	{ 2674, 2676 },
	{ 2693, 2701 },
	{ 2703, 2705 },
	{ 2707, 2728 },
	{ 2730, 2736 },
	{ 2738, 2739 },
	{ 2741, 2745 },
	{ 2749, 2749 },
	{ 2768, 2768 },
	{ 2784, 2785 },
	{ 2809, 2809 },
	{ 2821, 2828 },
	{ 2831, 2832 },
	{ 2835, 2856 },
	{ 2858, 2864 },
	{ 2866, 2867 },
	{ 2869, 2873 },
	{ 2877, 2877 },
	{ 2908, 2909 },
	{ 2911, 2913 },
	{ 2929, 2929 },
	{ 2947, 2947 },
	{ 2949, 2954 },
	{ 2958, 2960 },
	{ 2962, 2965 },
	{ 2969, 2970 },
	{ 2972, 2972 },
	{ 2974, 2975 },
	{ 2979, 2980 },
	{ 2984, 2986 },
	{ 2990, 3001 },
	{ 3024, 3024 },
	{ 3077, 3084 },
	{ 3086, 3088 },
	{ 3090, 3112 },
	{ 3114, 3129 },
	{ 3133, 3133 },
	{ 3160, 3162 },
	{ 3168, 3169 },
	{ 3200, 3200 },
	{ 3205, 3212 },
	{ 3214, 3216 },
	{ 3218, 3240 },
	{ 3242, 3251 },
	{ 3253, 3257 },
	{ 3261, 3261 },
	{ 3294, 3294 },
	{ 3296, 3297 },
	{ 3313, 3314 },
	{ 3333, 3340 },
	{ 3342, 3344 },
	{ 3346, 3386 },
	{ 3389, 3389 },
	{ 3406, 3406 },
	{ 3412, 3414 },
	{ 3423, 3425 },
	{ 3450, 3455 },
	{ 3461, 3478 },
	{ 3482, 3505 },
	{ 3507, 3515 },
	{ 3517, 3517 },
	{ 3520, 3526 },
	{ 3585, 3632 },
	{ 3634, 3635 },
	{ 3648, 3654 },
	{ 3713, 3714 },
	{ 3716, 3716 },
	{ 3719, 3720 },
	{ 3722, 3722 },
	{ 3725, 3725 },
	{ 3732, 3735 },
	{ 3737, 3743 },
	{ 3745, 3747 },
	{ 3749, 3749 },
	{ 3751, 3751 },
	{ 3754, 3755 },
	{ 3757, 3760 },
	{ 3762, 3763 },
	{ 3773, 3773 },
	{ 3776, 3780 },
	{ 3782, 3782 },
	{ 3804, 3807 },
	{ 3840, 3840 },
	{ 3904, 3911 },
	{ 3913, 3948 },
	{ 3976, 3980 },
	{ 4096, 4138 },
	{ 4159, 4159 },
	{ 4176, 4181 },
	{ 4186, 4189 },
	{ 4193, 4193 },
	{ 4197, 4198 },
	{ 4206, 4208 },
	{ 4213, 4225 },
	{ 4238, 4238 },
	{ 4256, 4293 },
	{ 4295, 4295 },
	{ 4301, 4301 },
	{ 4304, 4346 },
	{ 4348, 4680 },
	{ 4682, 4685 },
	{ 4688, 4694 },
	{ 4696, 4696 },
	{ 4698, 4701 },
	{ 4704, 4744 },
	{ 4746, 4749 },
	{ 4752, 4784 },
	{ 4786, 4789 },
	{ 4792, 4798 },
	{ 4800, 4800 },
	{ 4802, 4805 },
	{ 4808, 4822 },
	{ 4824, 4880 },
	{ 4882, 4885 },
	{ 4888, 4954 },
	{ 4992, 5007 },
	{ 5024, 5109 },
	{ 5112, 5117 },
	{ 5121, 5740 },
	{ 5743, 5759 },
	{ 5761, 5786 },
	{ 5792, 5866 },
	{ 5873, 5880 },
	{ 5888, 5900 },
	{ 5902, 5905 },
	{ 5920, 5937 },
	{ 5952, 5969 },
	{ 5984, 5996 },
	{ 5998, 6000 },
	{ 6016, 6067 },
	{ 6103, 6103 },
	{ 6108, 6108 },
	{ 6176, 6264 },
	{ 6272, 6276 },
	{ 6279, 6312 },
	{ 6314, 6314 },
	{ 6320, 6389 },
	{ 6400, 6430 },
	{ 6480, 6509 },
	{ 6512, 6516 },
	{ 6528, 6571 },
	{ 6576, 6601 },
	{ 6656, 6678 },
	{ 6688, 6740 },
	{ 6823, 6823 },
	{ 6917, 6963 },
	{ 6981, 6987 },
	{ 7043, 7072 },
	{ 7086, 7087 },
	{ 7098, 7141 },
	{ 7168, 7203 },
	{ 7245, 7247 },
	{ 7258, 7293 },
	{ 7296, 7304 },
	{ 7312, 7354 },
	{ 7357, 7359 },
	{ 7401, 7404 },
	{ 7406, 7409 },
	{ 7413, 7414 },
	{ 7424, 7615 },
	{ 7680, 7957 },
	{ 7960, 7965 },
	{ 7968, 8005 },
	{ 8008, 8013 },
	{ 8016, 8023 },
	{ 8025, 8025 },
	{ 8027, 8027 },
	{ 8029, 8029 },
	{ 8031, 8061 },
	{ 8064, 8116 },
	{ 8118, 8124 },
	{ 8126, 8126 },
	{ 8130, 8132 },
	{ 8134, 8140 },
	{ 8144, 8147 },
	{ 8150, 8155 },
	{ 8160, 8172 },
	{ 8178, 8180 },
	{ 8182, 8188 },
	{ 8305, 8305 },
	{ 8319, 8319 },
	{ 8336, 8348 },
	{ 8450, 8450 },
	{ 8455, 8455 },
	{ 8458, 8467 },
	{ 8469, 8469 },
	{ 8473, 8477 },
	{ 8484, 8484 },
	{ 8486, 8486 },
	{ 8488, 8488 },
	{ 8490, 8493 },
	{ 8495, 8505 },
	{ 8508, 8511 },
	{ 8517, 8521 },
	{ 8526, 8526 },
	{ 8579, 8580 },
	{ 11264, 11310 },
	{ 11312, 11358 },
	{ 11360, 11492 },
	{ 11499, 11502 },
	{ 11506, 11507 },
	{ 11520, 11557 },
	{ 11559, 11559 },
	{ 11565, 11565 },
	{ 11568, 11623 },
	{ 11631, 11631 },
	{ 11648, 11670 },
	{ 11680, 11686 },
	{ 11688, 11694 },
	{ 11696, 11702 },
	{ 11704, 11710 },
	{ 11712, 11718 },
	{ 11720, 11726 },
	{ 11728, 11734 },
	{ 11736, 11742 },
	{ 11823, 11823 },
	{ 12293, 12294 },
	{ 12337, 12341 },
	{ 12347, 12348 },
	{ 12353, 12438 },
	{ 12445, 12447 },
	{ 12449, 12538 },
	{ 12540, 12543 },
	{ 12549, 12591 },
	{ 12593, 12686 },
	{ 12704, 12730 },
	{ 12784, 12799 },
	{ 13312, 19893 },
	{ 19968, 40943 },
	{ 40960, 42124 },
	{ 42192, 42237 },
	{ 42240, 42508 },
	{ 42512, 42527 },
	{ 42538, 42539 },
	{ 42560, 42606 },
	{ 42623, 42653 },
	{ 42656, 42725 },
	{ 42775, 42783 },
	{ 42786, 42888 },
	{ 42891, 42937 },
	{ 42999, 43009 },
	{ 43011, 43013 },
	{ 43015, 43018 },
	{ 43020, 43042 },
	{ 43072, 43123 },
	{ 43138, 43187 },
	{ 43250, 43255 },
	{ 43259, 43259 },
	{ 43261, 43262 },
	{ 43274, 43301 },
	{ 43312, 43334 },
	{ 43360, 43388 },
	{ 43396, 43442 },
	{ 43471, 43471 },
	{ 43488, 43492 },
	{ 43494, 43503 },
	{ 43514, 43518 },
	{ 43520, 43560 },
	{ 43584, 43586 },
	{ 43588, 43595 },
	{ 43616, 43638 },
	{ 43642, 43642 },
	{ 43646, 43695 },
	{ 43697, 43697 },
	{ 43701, 43702 },
	{ 43705, 43709 },
	{ 43712, 43712 },
	{ 43714, 43714 },
	{ 43739, 43741 },
	{ 43744, 43754 },
	{ 43762, 43764 },
	{ 43777, 43782 },
	{ 43785, 43790 },
	{ 43793, 43798 },
	{ 43808, 43814 },
	{ 43816, 43822 },
	{ 43824, 43866 },
	{ 43868, 43877 },
	{ 43888, 44002 },
	{ 44032, 55203 },
	{ 55216, 55238 },
	{ 55243, 55291 },
	{ 63744, 64109 },
	{ 64112, 64217 },
	{ 64256, 64262 },
	{ 64275, 64279 },
	{ 64285, 64285 },
	{ 64287, 64296 },
	{ 64298, 64310 },
	{ 64312, 64316 },
	{ 64318, 64318 },
	{ 64320, 64321 },
	{ 64323, 64324 },
	{ 64326, 64433 },
	{ 64467, 64829 },
	{ 64848, 64911 },
	{ 64914, 64967 },
	{ 65008, 65019 },
	{ 65136, 65140 },
	{ 65142, 65276 },
	{ 65313, 65338 },
	{ 65345, 65370 },
	{ 65382, 65470 },
	{ 65474, 65479 },
	{ 65482, 65487 },
	{ 65490, 65495 },
	{ 65498, 65500 },
};
static const URange32 L_range32[] = {
	{ 65536, 65547 },
	{ 65549, 65574 },
	{ 65576, 65594 },
	{ 65596, 65597 },
	{ 65599, 65613 },
	{ 65616, 65629 },
	{ 65664, 65786 },
	{ 66176, 66204 },
	{ 66208, 66256 },
	{ 66304, 66335 },
	{ 66349, 66368 },
	{ 66370, 66377 },
	{ 66384, 66421 },
	{ 66432, 66461 },
	{ 66464, 66499 },
	{ 66504, 66511 },
	{ 66560, 66717 },
	{ 66736, 66771 },
	{ 66776, 66811 },
	{ 66816, 66855 },
	{ 66864, 66915 },
	{ 67072, 67382 },
	{ 67392, 67413 },
	{ 67424, 67431 },
	{ 67584, 67589 },
	{ 67592, 67592 },
	{ 67594, 67637 },
	{ 67639, 67640 },
	{ 67644, 67644 },
	{ 67647, 67669 },
	{ 67680, 67702 },
	{ 67712, 67742 },
	{ 67808, 67826 },
	{ 67828, 67829 },
	{ 67840, 67861 },
	{ 67872, 67897 },
	{ 67968, 68023 },
	{ 68030, 68031 },
	{ 68096, 68096 },
	{ 68112, 68115 },
	{ 68117, 68119 },
	{ 68121, 68149 },
	{ 68192, 68220 },
	{ 68224, 68252 },
	{ 68288, 68295 },
	{ 68297, 68324 },
	{ 68352, 68405 },
	{ 68416, 68437 },
	{ 68448, 68466 },
	{ 68480, 68497 },
	{ 68608, 68680 },
	{ 68736, 68786 },
	{ 68800, 68850 },
	{ 68864, 68899 },
	{ 69376, 69404 },
	{ 69415, 69415 },
	{ 69424, 69445 },
	{ 69635, 69687 },
	{ 69763, 69807 },
	{ 69840, 69864 },
	{ 69891, 69926 },
	{ 69956, 69956 },
	{ 69968, 70002 },
	{ 70006, 70006 },
	{ 70019, 70066 },
	{ 70081, 70084 },
	{ 70106, 70106 },
	{ 70108, 70108 },
	{ 70144, 70161 },
	{ 70163, 70187 },
	{ 70272, 70278 },
	{ 70280, 70280 },
	{ 70282, 70285 },
	{ 70287, 70301 },
	{ 70303, 70312 },
	{ 70320, 70366 },
	{ 70405, 70412 },
	{ 70415, 70416 },
	{ 70419, 70440 },
	{ 70442, 70448 },
	{ 70450, 70451 },
	{ 70453, 70457 },
	{ 70461, 70461 },
	{ 70480, 70480 },
	{ 70493, 70497 },
	{ 70656, 70708 },
	{ 70727, 70730 },
	{ 70784, 70831 },
	{ 70852, 70853 },
	{ 70855, 70855 },
	{ 71040, 71086 },
	{ 71128, 71131 },
	{ 71168, 71215 },
	{ 71236, 71236 },
	{ 71296, 71338 },
	{ 71424, 71450 },
	{ 71680, 71723 },
	{ 71840, 71903 },
	{ 71935, 71935 },
	{ 72192, 72192 },
	{ 72203, 72242 },
	{ 72250, 72250 },
	{ 72272, 72272 },
	{ 72284, 72323 },
	{ 72326, 72329 },
	{ 72349, 72349 },
	{ 72384, 72440 },
	{ 72704, 72712 },
	{ 72714, 72750 },
	{ 72768, 72768 },
	{ 72818, 72847 },
	{ 72960, 72966 },
	{ 72968, 72969 },
	{ 72971, 73008 },
	{ 73030, 73030 },
	{ 73056, 73061 },
	{ 73063, 73064 },
	{ 73066, 73097 },
	{ 73112, 73112 },
	{ 73440, 73458 },
	{ 73728, 74649 },
	{ 74880, 75075 },
	{ 77824, 78894 },
	{ 82944, 83526 },
	{ 92160, 92728 },
	{ 92736, 92766 },
	{ 92880, 92909 },
	{ 92928, 92975 },
	{ 92992, 92995 },
	{ 93027, 93047 },
	{ 93053, 93071 },
	{ 93760, 93823 },
	{ 93952, 94020 },
	{ 94032, 94032 },
	{ 94099, 94111 },
	{ 94176, 94177 },
	{ 94208, 100337 },
	{ 100352, 101106 },
	{ 110592, 110878 },
	{ 110960, 111355 },
	{ 113664, 113770 },
	{ 113776, 113788 },
	{ 113792, 113800 },
	{ 113808, 113817 },
	{ 119808, 119892 },
	{ 119894, 119964 },
	{ 119966, 119967 },
	{ 119970, 119970 },
	{ 119973, 119974 },
	{ 119977, 119980 },
	{ 119982, 119993 },
	{ 119995, 119995 },
	{ 119997, 120003 },
	{ 120005, 120069 },
	{ 120071, 120074 },
	{ 120077, 120084 },
	{ 120086, 120092 },
	{ 120094, 120121 },
	{ 120123, 120126 },
	{ 120128, 120132 },
	{ 120134, 120134 },
	{ 120138, 120144 },
	{ 120146, 120485 },
	{ 120488, 120512 },
	{ 120514, 120538 },
	{ 120540, 120570 },
	{ 120572, 120596 },
	{ 120598, 120628 },
	{ 120630, 120654 },
	{ 120656, 120686 },
	{ 120688, 120712 },
	{ 120714, 120744 },
	{ 120746, 120770 },
	{ 120772, 120779 },
	{ 124928, 125124 },
	{ 125184, 125251 },
	{ 126464, 126467 },
	{ 126469, 126495 },
	{ 126497, 126498 },
	{ 126500, 126500 },
	{ 126503, 126503 },
	{ 126505, 126514 },
	{ 126516, 126519 },
	{ 126521, 126521 },
	{ 126523, 126523 },
	{ 126530, 126530 },
	{ 126535, 126535 },
	{ 126537, 126537 },
	{ 126539, 126539 },
	{ 126541, 126543 },
	{ 126545, 126546 },
	{ 126548, 126548 },
	{ 126551, 126551 },
	{ 126553, 126553 },
	{ 126555, 126555 },
	{ 126557, 126557 },
	{ 126559, 126559 },
	{ 126561, 126562 },
	{ 126564, 126564 },
	{ 126567, 126570 },
	{ 126572, 126578 },
	{ 126580, 126583 },
	{ 126585, 126588 },
	{ 126590, 126590 },
	{ 126592, 126601 },
	{ 126603, 126619 },
	{ 126625, 126627 },
	{ 126629, 126633 },
	{ 126635, 126651 },
	{ 131072, 173782 },
	{ 173824, 177972 },
	{ 177984, 178205 },
	{ 178208, 183969 },
	{ 183984, 191456 },
	{ 194560, 195101 },
};
static const URange16 N_range16[] = {
	{ 48, 57 },
	{ 178, 179 },
	{ 185, 185 },
	{ 188, 190 },
	{ 1632, 1641 },
	{ 1776, 1785 },
	{ 1984, 1993 },
	{ 2406, 2415 },
	{ 2534, 2543 },
	{ 2548, 2553 },
	{ 2662, 2671 },
	{ 2790, 2799 },
	{ 2918, 2927 },
	{ 2930, 2935 },
	{ 3046, 3058 },
	{ 3174, 3183 },
	{ 3192, 3198 },
	{ 3302, 3311 },
	{ 3416, 3422 },
	{ 3430, 3448 },
	{ 3558, 3567 },
	{ 3664, 3673 },
	{ 3792, 3801 },
	{ 3872, 3891 },
	{ 4160, 4169 },
	{ 4240, 4249 },
	{ 4969, 4988 },
	{ 5870, 5872 },
	{ 6112, 6121 },
	{ 6128, 6137 },
	{ 6160, 6169 },
	{ 6470, 6479 },
	{ 6608, 6618 },
	{ 6784, 6793 },
	{ 6800, 6809 },
	{ 6992, 7001 },
	{ 7088, 7097 },
	{ 7232, 7241 },
	{ 7248, 7257 },
	{ 8304, 8304 },
	{ 8308, 8313 },
	{ 8320, 8329 },
	{ 8528, 8578 },
	{ 8581, 8585 },
	{ 9312, 9371 },
	{ 9450, 9471 },
	{ 10102, 10131 },
	{ 11517, 11517 },
	{ 12295, 12295 },
	{ 12321, 12329 },
	{ 12344, 12346 },
	{ 12690, 12693 },
	{ 12832, 12841 },
	{ 12872, 12879 },
	{ 12881, 12895 },
	{ 12928, 12937 },
	{ 12977, 12991 },
	{ 42528, 42537 },
	{ 42726, 42735 },
	{ 43056, 43061 },
	{ 43216, 43225 },
	{ 43264, 43273 },
	{ 43472, 43481 },
	{ 43504, 43513 },
	{ 43600, 43609 },
	{ 44016, 44025 },
	{ 65296, 65305 },
};
static const URange32 N_range32[] = {
	{ 65799, 65843 },
	{ 65856, 65912 },
	{ 65930, 65931 },
	{ 66273, 66299 },
	{ 66336, 66339 },
	{ 66369, 66369 },
	{ 66378, 66378 },
	{ 66513, 66517 },
	{ 66720, 66729 },
	{ 67672, 67679 },
	{ 67705, 67711 },
	{ 67751, 67759 },
	{ 67835, 67839 },
	{ 67862, 67867 },
	{ 68028, 68029 },
	{ 68032, 68047 },
	{ 68050, 68095 },
	{ 68160, 68168 },
	{ 68221, 68222 },
	{ 68253, 68255 },
	{ 68331, 68335 },
	{ 68440, 68447 },
	{ 68472, 68479 },
	{ 68521, 68527 },
	{ 68858, 68863 },
	{ 68912, 68921 },
	{ 69216, 69246 },
	{ 69405, 69414 },
	{ 69457, 69460 },
	{ 69714, 69743 },
	{ 69872, 69881 },
	{ 69942, 69951 },
	{ 70096, 70105 },
	{ 70113, 70132 },
	{ 70384, 70393 },
	{ 70736, 70745 },
	{ 70864, 70873 },
	{ 71248, 71257 },
	{ 71360, 71369 },
	{ 71472, 71483 },
	{ 71904, 71922 },
	{ 72784, 72812 },
	{ 73040, 73049 },
	{ 73120, 73129 },
	{ 74752, 74862 },
	{ 92768, 92777 },
	{ 93008, 93017 },
	{ 93019, 93025 },
	{ 93824, 93846 },
	{ 119520, 119539 },
	{ 119648, 119672 },
	{ 120782, 120831 },
	{ 125127, 125135 },
	{ 125264, 125273 },
	{ 126065, 126123 },
	{ 126125, 126127 },
	{ 126129, 126132 },
	{ 127232, 127244 },
};
static const URange16 Sk_range16[] = {
	{ 94, 94 },
	{ 96, 96 },
	{ 168, 168 },
	{ 175, 175 },
	{ 180, 180 },
	{ 184, 184 },
	{ 706, 709 },
	{ 722, 735 },
	{ 741, 747 },
	{ 749, 749 },
	{ 751, 767 },
	{ 885, 885 },
	{ 900, 901 },
	{ 8125, 8125 },
	{ 8127, 8129 },
	{ 8141, 8143 },
	{ 8157, 8159 },
	{ 8173, 8175 },
	{ 8189, 8190 },
	{ 12443, 12444 },
	{ 42752, 42774 },
	{ 42784, 42785 },
	{ 42889, 42890 },
	{ 43867, 43867 },
	{ 64434, 64449 },
	{ 65342, 65342 },
	{ 65344, 65344 },
	{ 65507, 65507 },
};
static const URange32 Sk_range32[] = {
	{ 127995, 127999 },
};
static const URange16 P_range16[] = {
	{ 33, 35 },
	{ 37, 42 },
	{ 44, 47 },
	{ 58, 59 },
	{ 63, 64 },
	{ 91, 93 },
	{ 95, 95 },
	{ 123, 123 },
	{ 125, 125 },
	{ 161, 161 },
	{ 167, 167 },
	{ 171, 171 },
	{ 182, 183 },
	{ 187, 187 },
	{ 191, 191 },
	{ 894, 894 },
	{ 903, 903 },
	{ 1370, 1375 },
	{ 1417, 1418 },
	{ 1470, 1470 },
	{ 1472, 1472 },
	{ 1475, 1475 },
	{ 1478, 1478 },
	{ 1523, 1524 },
	{ 1545, 1546 },
	{ 1548, 1549 },
	{ 1563, 1563 },
	{ 1566, 1567 },
	{ 1642, 1645 },
	{ 1748, 1748 },
	{ 1792, 1805 },
	{ 2039, 2041 },
	{ 2096, 2110 },
	{ 2142, 2142 },
	{ 2404, 2405 },
	{ 2416, 2416 },
	{ 2557, 2557 },
	{ 2678, 2678 },
	{ 2800, 2800 },
	{ 3204, 3204 },
	{ 3572, 3572 },
	{ 3663, 3663 },
	{ 3674, 3675 },
	{ 3844, 3858 },
	{ 3860, 3860 },
	{ 3898, 3901 },
	{ 3973, 3973 },
	{ 4048, 4052 },
	{ 4057, 4058 },
	{ 4170, 4175 },
	{ 4347, 4347 },
	{ 4960, 4968 },
	{ 5120, 5120 },
	{ 5741, 5742 },
	{ 5787, 5788 },
	{ 5867, 5869 },
	{ 5941, 5942 },
	{ 6100, 6102 },
	{ 6104, 6106 },
	{ 6144, 6154 },
	{ 6468, 6469 },
	{ 6686, 6687 },
	{ 6816, 6822 },
	{ 6824, 6829 },
	{ 7002, 7008 },
	{ 7164, 7167 },
	{ 7227, 7231 },
	{ 7294, 7295 },
	{ 7360, 7367 },
	{ 7379, 7379 },
	{ 8208, 8231 },
	{ 8240, 8259 },
	{ 8261, 8273 },
	{ 8275, 8286 },
	{ 8317, 8318 },
	{ 8333, 8334 },
	{ 8968, 8971 },
	{ 9001, 9002 },
	{ 10088, 10101 },
	{ 10181, 10182 },
	{ 10214, 10223 },
	{ 10627, 10648 },
	{ 10712, 10715 },
	{ 10748, 10749 },
	{ 11513, 11516 },
	{ 11518, 11519 },
	{ 11632, 11632 },
	{ 11776, 11822 },
	{ 11824, 11854 },
	{ 12289, 12291 },
	{ 12296, 12305 },
	{ 12308, 12319 },
	{ 12336, 12336 },
	{ 12349, 12349 },
	{ 12448, 12448 },
	{ 12539, 12539 },
	{ 42238, 42239 },
	{ 42509, 42511 },
	{ 42611, 42611 },
	{ 42622, 42622 },
	{ 42738, 42743 },
	{ 43124, 43127 },
	{ 43214, 43215 },
	{ 43256, 43258 },
	{ 43260, 43260 },
	{ 43310, 43311 },
	{ 43359, 43359 },
	{ 43457, 43469 },
	{ 43486, 43487 },
	{ 43612, 43615 },
	{ 43742, 43743 },
	{ 43760, 43761 },
	{ 44011, 44011 },
	{ 64830, 64831 },
	{ 65040, 65049 },
	{ 65072, 65106 },
	{ 65108, 65121 },
	{ 65123, 65123 },
	{ 65128, 65128 },
	{ 65130, 65131 },
	{ 65281, 65283 },
	{ 65285, 65290 },
	{ 65292, 65295 },
	{ 65306, 65307 },
	{ 65311, 65312 },
	{ 65339, 65341 },
	{ 65343, 65343 },
	{ 65371, 65371 },
	{ 65373, 65373 },
	{ 65375, 65381 },
};
static const URange32 P_range32[] = {
	{ 65792, 65794 },
	{ 66463, 66463 },
	{ 66512, 66512 },
	{ 66927, 66927 },
	{ 67671, 67671 },
	{ 67871, 67871 },
	{ 67903, 67903 },
	{ 68176, 68184 },
	{ 68223, 68223 },
	{ 68336, 68342 },
	{ 68409, 68415 },
	{ 68505, 68508 },
	{ 69461, 69465 },
	{ 69703, 69709 },
	{ 69819, 69820 },
	{ 69822, 69825 },
	{ 69952, 69955 },
	{ 70004, 70005 },
	{ 70085, 70088 },
	{ 70093, 70093 },
	{ 70107, 70107 },
	{ 70109, 70111 },
	{ 70200, 70205 },
	{ 70313, 70313 },
	{ 70731, 70735 },
	{ 70747, 70747 },
	{ 70749, 70749 },
	{ 70854, 70854 },
	{ 71105, 71127 },
	{ 71233, 71235 },
	{ 71264, 71276 },
	{ 71484, 71486 },
	{ 71739, 71739 },
	{ 72255, 72262 },
	{ 72346, 72348 },
	{ 72350, 72354 },
	{ 72769, 72773 },
	{ 72816, 72817 },
	{ 73463, 73464 },
	{ 74864, 74868 },
	{ 92782, 92783 },
	{ 92917, 92917 },
	{ 92983, 92987 },
	{ 92996, 92996 },
	{ 93847, 93850 },
	{ 113823, 113823 },
	{ 121479, 121483 },
	{ 125278, 125279 },
};
static const URange16 S_range16[] = {
	{ 36, 36 },
	{ 43, 43 },
	{ 60, 62 },
	{ 94, 94 },
	{ 96, 96 },
	{ 124, 124 },
	{ 126, 126 },
	{ 162, 166 },
	{ 168, 169 },
	{ 172, 172 },
	{ 174, 177 },
	{ 180, 180 },
	{ 184, 184 },
	{ 215, 215 },
	{ 247, 247 },
	{ 706, 709 },
	{ 722, 735 },
	{ 741, 747 },
	{ 749, 749 },
	{ 751, 767 },
	{ 885, 885 },
	{ 900, 901 },
	{ 1014, 1014 },
	{ 1154, 1154 },
	{ 1421, 1423 },
	{ 1542, 1544 },
	{ 1547, 1547 },
	{ 1550, 1551 },
	{ 1758, 1758 },
	{ 1769, 1769 },
	{ 1789, 1790 },
	{ 2038, 2038 },
	{ 2046, 2047 },
	{ 2546, 2547 },
	{ 2554, 2555 },
	{ 2801, 2801 },
	{ 2928, 2928 },
	{ 3059, 3066 },
	{ 3199, 3199 },
	{ 3407, 3407 },
	{ 3449, 3449 },
	{ 3647, 3647 },
	{ 3841, 3843 },
	{ 3859, 3859 },
	{ 3861, 3863 },
	{ 3866, 3871 },
	{ 3892, 3892 },
	{ 3894, 3894 },
	{ 3896, 3896 },
	{ 4030, 4037 },
	{ 4039, 4044 },
	{ 4046, 4047 },
	{ 4053, 4056 },
	{ 4254, 4255 },
	{ 5008, 5017 },
	{ 6107, 6107 },
	{ 6464, 6464 },
	{ 6622, 6655 },
	{ 7009, 7018 },
	{ 7028, 7036 },
	{ 8125, 8125 },
	{ 8127, 8129 },
	{ 8141, 8143 },
	{ 8157, 8159 },
	{ 8173, 8175 },
	{ 8189, 8190 },
	{ 8260, 8260 },
	{ 8274, 8274 },
	{ 8314, 8316 },
	{ 8330, 8332 },
	{ 8352, 8383 },
	{ 8448, 8449 },
	{ 8451, 8454 },
	{ 8456, 8457 },
	{ 8468, 8468 },
	{ 8470, 8472 },
	{ 8478, 8483 },
	{ 8485, 8485 },
	{ 8487, 8487 },
	{ 8489, 8489 },
	{ 8494, 8494 },
	{ 8506, 8507 },
	{ 8512, 8516 },
	{ 8522, 8525 },
	{ 8527, 8527 },
	{ 8586, 8587 },
	{ 8592, 8967 },
	{ 8972, 9000 },
	{ 9003, 9254 },
	{ 9280, 9290 },
	{ 9372, 9449 },
	{ 9472, 10087 },
	{ 10132, 10180 },
	{ 10183, 10213 },
	{ 10224, 10626 },
	{ 10649, 10711 },
	{ 10716, 10747 },
	{ 10750, 11123 },
	{ 11126, 11157 },
	{ 11160, 11208 },
	{ 11210, 11262 },
	{ 11493, 11498 },
	{ 11904, 11929 },
	{ 11931, 12019 },
	{ 12032, 12245 },
	{ 12272, 12283 },
	{ 12292, 12292 },
	{ 12306, 12307 },
	{ 12320, 12320 },
	{ 12342, 12343 },
	{ 12350, 12351 },
	{ 12443, 12444 },
	{ 12688, 12689 },
	{ 12694, 12703 },
	{ 12736, 12771 },
	{ 12800, 12830 },
	{ 12842, 12871 },
	{ 12880, 12880 },
	{ 12896, 12927 },
	{ 12938, 12976 },
	{ 12992, 13054 },
	{ 13056, 13311 },
	{ 19904, 19967 },
	{ 42128, 42182 },
	{ 42752, 42774 },
	{ 42784, 42785 },
	{ 42889, 42890 },
	{ 43048, 43051 },
	{ 43062, 43065 },
	{ 43639, 43641 },
	{ 43867, 43867 },
	{ 64297, 64297 },
	{ 64434, 64449 },
	{ 65020, 65021 },
	{ 65122, 65122 },
	{ 65124, 65126 },
	{ 65129, 65129 },
	{ 65284, 65284 },
	{ 65291, 65291 },
	{ 65308, 65310 },
	{ 65342, 65342 },
	{ 65344, 65344 },
	{ 65372, 65372 },
	{ 65374, 65374 },
	{ 65504, 65510 },
	{ 65512, 65518 },
	{ 65532, 65533 },
};
static const URange32 S_range32[] = {
	{ 65847, 65855 },
	{ 65913, 65929 },
	{ 65932, 65934 },
	{ 65936, 65947 },
	{ 65952, 65952 },
	{ 66000, 66044 },
	{ 67703, 67704 },
	{ 68296, 68296 },
	{ 71487, 71487 },
	{ 92988, 92991 },
	{ 92997, 92997 },
	{ 113820, 113820 },
	{ 118784, 119029 },
	{ 119040, 119078 },
	{ 119081, 119140 },
	{ 119146, 119148 },
	{ 119171, 119172 },
	{ 119180, 119209 },
	{ 119214, 119272 },
	{ 119296, 119361 },
	{ 119365, 119365 },
	{ 119552, 119638 },
	{ 120513, 120513 },
	{ 120539, 120539 },
	{ 120571, 120571 },
	{ 120597, 120597 },
	{ 120629, 120629 },
	{ 120655, 120655 },
	{ 120687, 120687 },
	{ 120713, 120713 },
	{ 120745, 120745 },
	{ 120771, 120771 },
	{ 120832, 121343 },
	{ 121399, 121402 },
	{ 121453, 121460 },
	{ 121462, 121475 },
	{ 121477, 121478 },
	{ 126124, 126124 },
	{ 126128, 126128 },
	{ 126704, 126705 },
	{ 126976, 127019 },
	{ 127024, 127123 },
	{ 127136, 127150 },
	{ 127153, 127167 },
	{ 127169, 127183 },
	{ 127185, 127221 },
	{ 127248, 127339 },
	{ 127344, 127404 },
	{ 127462, 127490 },
	{ 127504, 127547 },
	{ 127552, 127560 },
	{ 127568, 127569 },
	{ 127584, 127589 },
	{ 127744, 128724 },
	{ 128736, 128748 },
	{ 128752, 128761 },
	{ 128768, 128883 },
	{ 128896, 128984 },
	{ 129024, 129035 },
	{ 129040, 129095 },
	{ 129104, 129113 },
	{ 129120, 129159 },
	{ 129168, 129197 },
	{ 129280, 129291 },
	{ 129296, 129342 },
	{ 129344, 129392 },
	{ 129395, 129398 },
	{ 129402, 129402 },
	{ 129404, 129442 },
	{ 129456, 129465 },
	{ 129472, 129474 },
	{ 129488, 129535 },
	{ 129632, 129645 },
};
static const URange16 So_range16[] = {
	{ 166, 166 },
	{ 169, 169 },
	{ 174, 174 },
	{ 176, 176 },
	{ 1154, 1154 },
	{ 1421, 1422 },
	{ 1550, 1551 },
	{ 1758, 1758 },
	{ 1769, 1769 },
	{ 1789, 1790 },
	{ 2038, 2038 },
	{ 2554, 2554 },
	{ 2928, 2928 },
	{ 3059, 3064 },
	{ 3066, 3066 },
	{ 3199, 3199 },
	{ 3407, 3407 },
	{ 3449, 3449 },
	{ 3841, 3843 },
	{ 3859, 3859 },
	{ 3861, 3863 },
	{ 3866, 3871 },
	{ 3892, 3892 },
	{ 3894, 3894 },
	{ 3896, 3896 },
	{ 4030, 4037 },
	{ 4039, 4044 },
	{ 4046, 4047 },
	{ 4053, 4056 },
	{ 4254, 4255 },
	{ 5008, 5017 },
	{ 6464, 6464 },
	{ 6622, 6655 },
	{ 7009, 7018 },
	{ 7028, 7036 },
	{ 8448, 8449 },
	{ 8451, 8454 },
	{ 8456, 8457 },
	{ 8468, 8468 },
	{ 8470, 8471 },
	{ 8478, 8483 },
	{ 8485, 8485 },
	{ 8487, 8487 },
	{ 8489, 8489 },
	{ 8494, 8494 },
	{ 8506, 8507 },
	{ 8522, 8522 },
	{ 8524, 8525 },
	{ 8527, 8527 },
	{ 8586, 8587 },
	{ 8597, 8601 },
	{ 8604, 8607 },
	{ 8609, 8610 },
	{ 8612, 8613 },
	{ 8615, 8621 },
	{ 8623, 8653 },
	{ 8656, 8657 },
	{ 8659, 8659 },
	{ 8661, 8691 },
	{ 8960, 8967 },
	{ 8972, 8991 },
	{ 8994, 9000 },
	{ 9003, 9083 },
	{ 9085, 9114 },
	{ 9140, 9179 },
	{ 9186, 9254 },
	{ 9280, 9290 },
	{ 9372, 9449 },
	{ 9472, 9654 },
	{ 9656, 9664 },
	{ 9666, 9719 },
	{ 9728, 9838 },
	{ 9840, 10087 },
	{ 10132, 10175 },
	{ 10240, 10495 },
	{ 11008, 11055 },
	{ 11077, 11078 },
	{ 11085, 11123 },
	{ 11126, 11157 },
	{ 11160, 11208 },
	{ 11210, 11262 },
	{ 11493, 11498 },
	{ 11904, 11929 },
	{ 11931, 12019 },
	{ 12032, 12245 },
	{ 12272, 12283 },
	{ 12292, 12292 },
	{ 12306, 12307 },
	{ 12320, 12320 },
	{ 12342, 12343 },
	{ 12350, 12351 },
	{ 12688, 12689 },
	{ 12694, 12703 },
	{ 12736, 12771 },
	{ 12800, 12830 },
	{ 12842, 12871 },
	{ 12880, 12880 },
	{ 12896, 12927 },
	{ 12938, 12976 },
	{ 12992, 13054 },
	{ 13056, 13311 },
	{ 19904, 19967 },
	{ 42128, 42182 },
	{ 43048, 43051 },
	{ 43062, 43063 },
	{ 43065, 43065 },
	{ 43639, 43641 },
	{ 65021, 65021 },
	{ 65508, 65508 },
	{ 65512, 65512 },
	{ 65517, 65518 },
	{ 65532, 65533 },
};
static const URange32 So_range32[] = {
	{ 65847, 65855 },
	{ 65913, 65929 },
	{ 65932, 65934 },
	{ 65936, 65947 },
	{ 65952, 65952 },
	{ 66000, 66044 },
	{ 67703, 67704 },
	{ 68296, 68296 },
	{ 71487, 71487 },
	{ 92988, 92991 },
	{ 92997, 92997 },
	{ 113820, 113820 },
	{ 118784, 119029 },
	{ 119040, 119078 },
	{ 119081, 119140 },
	{ 119146, 119148 },
	{ 119171, 119172 },
	{ 119180, 119209 },
	{ 119214, 119272 },
	{ 119296, 119361 },
	{ 119365, 119365 },
	{ 119552, 119638 },
	{ 120832, 121343 },
	{ 121399, 121402 },
	{ 121453, 121460 },
	{ 121462, 121475 },
	{ 121477, 121478 },
	{ 126124, 126124 },
	{ 126976, 127019 },
	{ 127024, 127123 },
	{ 127136, 127150 },
	{ 127153, 127167 },
	{ 127169, 127183 },
	{ 127185, 127221 },
	{ 127248, 127339 },
	{ 127344, 127404 },
	{ 127462, 127490 },
	{ 127504, 127547 },
	{ 127552, 127560 },
	{ 127568, 127569 },
	{ 127584, 127589 },
	{ 127744, 127994 },
	{ 128000, 128724 },
	{ 128736, 128748 },
	{ 128752, 128761 },
	{ 128768, 128883 },
	{ 128896, 128984 },
	{ 129024, 129035 },
	{ 129040, 129095 },
	{ 129104, 129113 },
	{ 129120, 129159 },
	{ 129168, 129197 },
	{ 129280, 129291 },
	{ 129296, 129342 },
	{ 129344, 129392 },
	{ 129395, 129398 },
	{ 129402, 129402 },
	{ 129404, 129442 },
	{ 129456, 129465 },
	{ 129472, 129474 },
	{ 129488, 129535 },
	{ 129632, 129645 },
};
static const URange16 Sm_range16[] = {
	{ 43, 43 },
	{ 60, 62 },
	{ 124, 124 },
	{ 126, 126 },
	{ 172, 172 },
	{ 177, 177 },
	{ 215, 215 },
	{ 247, 247 },
	{ 1014, 1014 },
	{ 1542, 1544 },
	{ 8260, 8260 },
	{ 8274, 8274 },
	{ 8314, 8316 },
	{ 8330, 8332 },
	{ 8472, 8472 },
	{ 8512, 8516 },
	{ 8523, 8523 },
	{ 8592, 8596 },
	{ 8602, 8603 },
	{ 8608, 8608 },
	{ 8611, 8611 },
	{ 8614, 8614 },
	{ 8622, 8622 },
	{ 8654, 8655 },
	{ 8658, 8658 },
	{ 8660, 8660 },
	{ 8692, 8959 },
	{ 8992, 8993 },
	{ 9084, 9084 },
	{ 9115, 9139 },
	{ 9180, 9185 },
	{ 9655, 9655 },
	{ 9665, 9665 },
	{ 9720, 9727 },
	{ 9839, 9839 },
	{ 10176, 10180 },
	{ 10183, 10213 },
	{ 10224, 10239 },
	{ 10496, 10626 },
	{ 10649, 10711 },
	{ 10716, 10747 },
	{ 10750, 11007 },
	{ 11056, 11076 },
	{ 11079, 11084 },
	{ 64297, 64297 },
	{ 65122, 65122 },
	{ 65124, 65126 },
	{ 65291, 65291 },
	{ 65308, 65310 },
	{ 65372, 65372 },
	{ 65374, 65374 },
	{ 65506, 65506 },
	{ 65513, 65516 },
};
static const URange32 Sm_range32[] = {
	{ 120513, 120513 },
	{ 120539, 120539 },
	{ 120571, 120571 },
	{ 120597, 120597 },
	{ 120629, 120629 },
	{ 120655, 120655 },
	{ 120687, 120687 },
	{ 120713, 120713 },
	{ 120745, 120745 },
	{ 120771, 120771 },
	{ 126704, 126705 },
};
static const URange16 Sc_range16[] = {
	{ 36, 36 },
	{ 162, 165 },
	{ 1423, 1423 },
	{ 1547, 1547 },
	{ 2046, 2047 },
	{ 2546, 2547 },
	{ 2555, 2555 },
	{ 2801, 2801 },
	{ 3065, 3065 },
	{ 3647, 3647 },
	{ 6107, 6107 },
	{ 8352, 8383 },
	{ 43064, 43064 },
	{ 65020, 65020 },
	{ 65129, 65129 },
	{ 65284, 65284 },
	{ 65504, 65505 },
	{ 65509, 65510 },
};
static const URange32 Sc_range32[] = {
	{ 126128, 126128 },
};
static const URange16 Z_range16[] = {
	{ 32, 32 },
	{ 160, 160 },
	{ 5760, 5760 },
	{ 8192, 8202 },
	{ 8232, 8233 },
	{ 8239, 8239 },
	{ 8287, 8287 },
	{ 12288, 12288 },
};
static const URange16 Zl_range16[] = {
	{ 8232, 8232 },
};
static const URange16 Co_range16[] = {
	{ 57344, 63743 },
};
static const URange32 Co_range32[] = {
	{ 983040, 1048573 },
	{ 1048576, 1114109 },
};
static const URange16 Cc_range16[] = {
	{ 0, 31 },
	{ 127, 159 },
};
static const URange16 Cf_range16[] = {
	{ 173, 173 },
	{ 1536, 1541 },
	{ 1564, 1564 },
	{ 1757, 1757 },
	{ 1807, 1807 },
	{ 2274, 2274 },
	{ 6158, 6158 },
	{ 8203, 8207 },
	{ 8234, 8238 },
	{ 8288, 8292 },
	{ 8294, 8303 },
	{ 65279, 65279 },
	{ 65529, 65531 },
};
static const URange32 Cf_range32[] = {
	{ 69821, 69821 },
	{ 69837, 69837 },
	{ 113824, 113827 },
	{ 119155, 119162 },
	{ 917505, 917505 },
	{ 917536, 917631 },
};
static const URange16 Cs_range16[] = {
	{ 55296, 57343 },
};
static const URange16 Zp_range16[] = {
	{ 8233, 8233 },
};
static const URange16 Zs_range16[] = {
	{ 32, 32 },
	{ 160, 160 },
	{ 5760, 5760 },
	{ 8192, 8202 },
	{ 8239, 8239 },
	{ 8287, 8287 },
	{ 12288, 12288 },
};
static const URange32 Tangut_range32[] = {
	{ 94176, 94176 },
	{ 94208, 100337 },
	{ 100352, 101106 },
};
static const URange16 Thaana_range16[] = {
	{ 1920, 1969 },
};
static const URange32 Adlam_range32[] = {
	{ 125184, 125258 },
	{ 125264, 125273 },
	{ 125278, 125279 },
};
static const URange16 Telugu_range16[] = {
	{ 3072, 3084 },
	{ 3086, 3088 },
	{ 3090, 3112 },
	{ 3114, 3129 },
	{ 3133, 3140 },
	{ 3142, 3144 },
	{ 3146, 3149 },
	{ 3157, 3158 },
	{ 3160, 3162 },
	{ 3168, 3171 },
	{ 3174, 3183 },
	{ 3192, 3199 },
};
static const URange16 Cyrillic_range16[] = {
	{ 1024, 1156 },
	{ 1159, 1327 },
	{ 7296, 7304 },
	{ 7467, 7467 },
	{ 7544, 7544 },
	{ 11744, 11775 },
	{ 42560, 42655 },
	{ 65070, 65071 },
};
static const URange32 Zanabazar_Square_range32[] = {
	{ 72192, 72263 },
};
static const URange16 Hangul_range16[] = {
	{ 4352, 4607 },
	{ 12334, 12335 },
	{ 12593, 12686 },
	{ 12800, 12830 },
	{ 12896, 12926 },
	{ 43360, 43388 },
	{ 44032, 55203 },
	{ 55216, 55238 },
	{ 55243, 55291 },
	{ 65440, 65470 },
	{ 65474, 65479 },
	{ 65482, 65487 },
	{ 65490, 65495 },
	{ 65498, 65500 },
};
static const URange32 Old_South_Arabian_range32[] = {
	{ 68192, 68223 },
};
static const URange16 Ethiopic_range16[] = {
	{ 4608, 4680 },
	{ 4682, 4685 },
	{ 4688, 4694 },
	{ 4696, 4696 },
	{ 4698, 4701 },
	{ 4704, 4744 },
	{ 4746, 4749 },
	{ 4752, 4784 },
	{ 4786, 4789 },
	{ 4792, 4798 },
	{ 4800, 4800 },
	{ 4802, 4805 },
	{ 4808, 4822 },
	{ 4824, 4880 },
	{ 4882, 4885 },
	{ 4888, 4954 },
	{ 4957, 4988 },
	{ 4992, 5017 },
	{ 11648, 11670 },
	{ 11680, 11686 },
	{ 11688, 11694 },
	{ 11696, 11702 },
	{ 11704, 11710 },
	{ 11712, 11718 },
	{ 11720, 11726 },
	{ 11728, 11734 },
	{ 11736, 11742 },
	{ 43777, 43782 },
	{ 43785, 43790 },
	{ 43793, 43798 },
	{ 43808, 43814 },
	{ 43816, 43822 },
};
static const URange16 Inherited_range16[] = {
	{ 768, 879 },
	{ 1157, 1158 },
	{ 1611, 1621 },
	{ 1648, 1648 },
	{ 2385, 2386 },
	{ 6832, 6846 },
	{ 7376, 7378 },
	{ 7380, 7392 },
	{ 7394, 7400 },
	{ 7405, 7405 },
	{ 7412, 7412 },
	{ 7416, 7417 },
	{ 7616, 7673 },
	{ 7675, 7679 },
	{ 8204, 8205 },
	{ 8400, 8432 },
	{ 12330, 12333 },
	{ 12441, 12442 },
	{ 65024, 65039 },
	{ 65056, 65069 },
};
static const URange32 Inherited_range32[] = {
	{ 66045, 66045 },
	{ 66272, 66272 },
	{ 70459, 70459 },
	{ 119143, 119145 },
	{ 119163, 119170 },
	{ 119173, 119179 },
	{ 119210, 119213 },
	{ 917760, 917999 },
};
static const URange32 Meroitic_Cursive_range32[] = {
	{ 68000, 68023 },
	{ 68028, 68047 },
	{ 68050, 68095 },
};
static const URange32 Bhaiksuki_range32[] = {
	{ 72704, 72712 },
	{ 72714, 72758 },
	{ 72760, 72773 },
	{ 72784, 72812 },
};
static const URange32 Ahom_range32[] = {
	{ 71424, 71450 },
	{ 71453, 71467 },
	{ 71472, 71487 },
};
static const URange16 Han_range16[] = {
	{ 11904, 11929 },
	{ 11931, 12019 },
	{ 12032, 12245 },
	{ 12293, 12293 },
	{ 12295, 12295 },
	{ 12321, 12329 },
	{ 12344, 12347 },
	{ 13312, 19893 },
	{ 19968, 40943 },
	{ 63744, 64109 },
	{ 64112, 64217 },
};
static const URange32 Han_range32[] = {
	{ 131072, 173782 },
	{ 173824, 177972 },
	{ 177984, 178205 },
	{ 178208, 183969 },
	{ 183984, 191456 },
	{ 194560, 195101 },
};
static const URange32 Old_North_Arabian_range32[] = {
	{ 68224, 68255 },
};
static const URange16 Armenian_range16[] = {
	{ 1329, 1366 },
	{ 1369, 1416 },
	{ 1418, 1418 },
	{ 1421, 1423 },
	{ 64275, 64279 },
};
static const URange16 Tamil_range16[] = {
	{ 2946, 2947 },
	{ 2949, 2954 },
	{ 2958, 2960 },
	{ 2962, 2965 },
	{ 2969, 2970 },
	{ 2972, 2972 },
	{ 2974, 2975 },
	{ 2979, 2980 },
	{ 2984, 2986 },
	{ 2990, 3001 },
	{ 3006, 3010 },
	{ 3014, 3016 },
	{ 3018, 3021 },
	{ 3024, 3024 },
	{ 3031, 3031 },
	{ 3046, 3066 },
};
static const URange16 Bopomofo_range16[] = {
	{ 746, 747 },
	{ 12549, 12591 },
	{ 12704, 12730 },
};
static const URange32 Bassa_Vah_range32[] = {
	{ 92880, 92909 },
	{ 92912, 92917 },
};
static const URange16 Sundanese_range16[] = {
	{ 7040, 7103 },
	{ 7360, 7367 },
};
static const URange32 Osage_range32[] = {
	{ 66736, 66771 },
	{ 66776, 66811 },
};
static const URange32 Old_Sogdian_range32[] = {
	{ 69376, 69415 },
};
static const URange16 Tagalog_range16[] = {
	{ 5888, 5900 },
	{ 5902, 5908 },
};
static const URange16 Malayalam_range16[] = {
	{ 3328, 3331 },
	{ 3333, 3340 },
	{ 3342, 3344 },
	{ 3346, 3396 },
	{ 3398, 3400 },
	{ 3402, 3407 },
	{ 3412, 3427 },
	{ 3430, 3455 },
};
static const URange32 Marchen_range32[] = {
	{ 72816, 72847 },
	{ 72850, 72871 },
	{ 72873, 72886 },
};
static const URange32 Carian_range32[] = {
	{ 66208, 66256 },
};
static const URange16 Hiragana_range16[] = {
	{ 12353, 12438 },
	{ 12445, 12447 },
};
static const URange32 Hiragana_range32[] = {
	{ 110593, 110878 },
	{ 127488, 127488 },
};
static const URange16 Tagbanwa_range16[] = {
	{ 5984, 5996 },
	{ 5998, 6000 },
	{ 6002, 6003 },
};
static const URange16 Meetei_Mayek_range16[] = {
	{ 43744, 43766 },
	{ 43968, 44013 },
	{ 44016, 44025 },
};
static const URange32 Hanifi_Rohingya_range32[] = {
	{ 68864, 68903 },
	{ 68912, 68921 },
};
static const URange32 Pahawh_Hmong_range32[] = {
	{ 92928, 92997 },
	{ 93008, 93017 },
	{ 93019, 93025 },
	{ 93027, 93047 },
	{ 93053, 93071 },
};
static const URange16 Tai_Le_range16[] = {
	{ 6480, 6509 },
	{ 6512, 6516 },
};
static const URange16 Kayah_Li_range16[] = {
	{ 43264, 43309 },
	{ 43311, 43311 },
};
static const URange16 Buginese_range16[] = {
	{ 6656, 6683 },
	{ 6686, 6687 },
};
static const URange32 Kharoshthi_range32[] = {
	{ 68096, 68099 },
	{ 68101, 68102 },
	{ 68108, 68115 },
	{ 68117, 68119 },
	{ 68121, 68149 },
	{ 68152, 68154 },
	{ 68159, 68168 },
	{ 68176, 68184 },
};
static const URange16 Tai_Tham_range16[] = {
	{ 6688, 6750 },
	{ 6752, 6780 },
	{ 6783, 6793 },
	{ 6800, 6809 },
	{ 6816, 6829 },
};
static const URange32 Old_Italic_range32[] = {
	{ 66304, 66339 },
	{ 66349, 66351 },
};
static const URange32 Old_Persian_range32[] = {
	{ 66464, 66499 },
	{ 66504, 66517 },
};
static const URange32 Warang_Citi_range32[] = {
	{ 71840, 71922 },
	{ 71935, 71935 },
};
static const URange16 Latin_range16[] = {
	{ 65, 90 },
	{ 97, 122 },
	{ 170, 170 },
	{ 186, 186 },
	{ 192, 214 },
	{ 216, 246 },
	{ 248, 696 },
	{ 736, 740 },
	{ 7424, 7461 },
	{ 7468, 7516 },
	{ 7522, 7525 },
	{ 7531, 7543 },
	{ 7545, 7614 },
	{ 7680, 7935 },
	{ 8305, 8305 },
	{ 8319, 8319 },
	{ 8336, 8348 },
	{ 8490, 8491 },
	{ 8498, 8498 },
	{ 8526, 8526 },
	{ 8544, 8584 },
	{ 11360, 11391 },
	{ 42786, 42887 },
	{ 42891, 42937 },
	{ 42999, 43007 },
	{ 43824, 43866 },
	{ 43868, 43876 },
	{ 64256, 64262 },
	{ 65313, 65338 },
	{ 65345, 65370 },
};
static const URange16 Saurashtra_range16[] = {
	{ 43136, 43205 },
	{ 43214, 43225 },
};
static const URange32 Shavian_range32[] = {
	{ 66640, 66687 },
};
static const URange16 Georgian_range16[] = {
	{ 4256, 4293 },
	{ 4295, 4295 },
	{ 4301, 4301 },
	{ 4304, 4346 },
	{ 4348, 4351 },
	{ 7312, 7354 },
	{ 7357, 7359 },
	{ 11520, 11557 },
	{ 11559, 11559 },
	{ 11565, 11565 },
};
static const URange32 Grantha_range32[] = {
	{ 70400, 70403 },
	{ 70405, 70412 },
	{ 70415, 70416 },
	{ 70419, 70440 },
	{ 70442, 70448 },
	{ 70450, 70451 },
	{ 70453, 70457 },
	{ 70460, 70468 },
	{ 70471, 70472 },
	{ 70475, 70477 },
	{ 70480, 70480 },
	{ 70487, 70487 },
	{ 70493, 70499 },
	{ 70502, 70508 },
	{ 70512, 70516 },
};
static const URange32 Duployan_range32[] = {
	{ 113664, 113770 },
	{ 113776, 113788 },
	{ 113792, 113800 },
	{ 113808, 113817 },
	{ 113820, 113823 },
};
static const URange16 Batak_range16[] = {
	{ 7104, 7155 },
	{ 7164, 7167 },
};
static const URange16 Devanagari_range16[] = {
	{ 2304, 2384 },
	{ 2387, 2403 },
	{ 2406, 2431 },
	{ 43232, 43263 },
};
static const URange16 Thai_range16[] = {
	{ 3585, 3642 },
	{ 3648, 3675 },
};
static const URange16 Tibetan_range16[] = {
	{ 3840, 3911 },
	{ 3913, 3948 },
	{ 3953, 3991 },
	{ 3993, 4028 },
	{ 4030, 4044 },
	{ 4046, 4052 },
	{ 4057, 4058 },
};
static const URange16 Tifinagh_range16[] = {
	{ 11568, 11623 },
	{ 11631, 11632 },
	{ 11647, 11647 },
};
static const URange32 Ugaritic_range32[] = {
	{ 66432, 66461 },
	{ 66463, 66463 },
};
static const URange16 Braille_range16[] = {
	{ 10240, 10495 },
};
static const URange32 Anatolian_Hieroglyphs_range32[] = {
	{ 82944, 83526 },
};
static const URange16 Greek_range16[] = {
	{ 880, 883 },
	{ 885, 887 },
	{ 890, 893 },
	{ 895, 895 },
	{ 900, 900 },
	{ 902, 902 },
	{ 904, 906 },
	{ 908, 908 },
	{ 910, 929 },
	{ 931, 993 },
	{ 1008, 1023 },
	{ 7462, 7466 },
	{ 7517, 7521 },
	{ 7526, 7530 },
	{ 7615, 7615 },
	{ 7936, 7957 },
	{ 7960, 7965 },
	{ 7968, 8005 },
	{ 8008, 8013 },
	{ 8016, 8023 },
	{ 8025, 8025 },
	{ 8027, 8027 },
	{ 8029, 8029 },
	{ 8031, 8061 },
	{ 8064, 8116 },
	{ 8118, 8132 },
	{ 8134, 8147 },
	{ 8150, 8155 },
	{ 8157, 8175 },
	{ 8178, 8180 },
	{ 8182, 8190 },
	{ 8486, 8486 },
	{ 43877, 43877 },
};
static const URange32 Greek_range32[] = {
	{ 65856, 65934 },
	{ 65952, 65952 },
	{ 119296, 119365 },
};
static const URange32 Lycian_range32[] = {
	{ 66176, 66204 },
};
static const URange32 Mende_Kikakui_range32[] = {
	{ 124928, 125124 },
	{ 125127, 125142 },
};
static const URange16 Tai_Viet_range16[] = {
	{ 43648, 43714 },
	{ 43739, 43743 },
};
static const URange16 Vai_range16[] = {
	{ 42240, 42539 },
};
static const URange16 Ogham_range16[] = {
	{ 5760, 5788 },
};
static const URange32 Inscriptional_Parthian_range32[] = {
	{ 68416, 68437 },
	{ 68440, 68447 },
};
static const URange16 Cham_range16[] = {
	{ 43520, 43574 },
	{ 43584, 43597 },
	{ 43600, 43609 },
	{ 43612, 43615 },
};
static const URange16 Syriac_range16[] = {
	{ 1792, 1805 },
	{ 1807, 1866 },
	{ 1869, 1871 },
	{ 2144, 2154 },
};
static const URange16 Runic_range16[] = {
	{ 5792, 5866 },
	{ 5870, 5880 },
};
static const URange32 Gothic_range32[] = {
	{ 66352, 66378 },
};
static const URange32 Mahajani_range32[] = {
	{ 69968, 70006 },
};
static const URange16 Katakana_range16[] = {
	{ 12449, 12538 },
	{ 12541, 12543 },
	{ 12784, 12799 },
	{ 13008, 13054 },
	{ 13056, 13143 },
	{ 65382, 65391 },
	{ 65393, 65437 },
};
static const URange32 Katakana_range32[] = {
	{ 110592, 110592 },
};
static const URange32 Osmanya_range32[] = {
	{ 66688, 66717 },
	{ 66720, 66729 },
};
static const URange16 New_Tai_Lue_range16[] = {
	{ 6528, 6571 },
	{ 6576, 6601 },
	{ 6608, 6618 },
	{ 6622, 6623 },
};
static const URange16 Ol_Chiki_range16[] = {
	{ 7248, 7295 },
};
static const URange32 Newa_range32[] = {
	{ 70656, 70745 },
	{ 70747, 70747 },
	{ 70749, 70750 },
};
static const URange16 Limbu_range16[] = {
	{ 6400, 6430 },
	{ 6432, 6443 },
	{ 6448, 6459 },
	{ 6464, 6464 },
	{ 6468, 6479 },
};
static const URange32 Pau_Cin_Hau_range32[] = {
	{ 72384, 72440 },
};
static const URange16 Cherokee_range16[] = {
	{ 5024, 5109 },
	{ 5112, 5117 },
	{ 43888, 43967 },
};
static const URange32 Miao_range32[] = {
	{ 93952, 94020 },
	{ 94032, 94078 },
	{ 94095, 94111 },
};
static const URange16 Oriya_range16[] = {
	{ 2817, 2819 },
	{ 2821, 2828 },
	{ 2831, 2832 },
	{ 2835, 2856 },
	{ 2858, 2864 },
	{ 2866, 2867 },
	{ 2869, 2873 },
	{ 2876, 2884 },
	{ 2887, 2888 },
	{ 2891, 2893 },
	{ 2902, 2903 },
	{ 2908, 2909 },
	{ 2911, 2915 },
	{ 2918, 2935 },
};
static const URange32 Medefaidrin_range32[] = {
	{ 93760, 93850 },
};
static const URange32 Sharada_range32[] = {
	{ 70016, 70093 },
	{ 70096, 70111 },
};
static const URange16 Gujarati_range16[] = {
	{ 2689, 2691 },
	{ 2693, 2701 },
	{ 2703, 2705 },
	{ 2707, 2728 },
	{ 2730, 2736 },
	{ 2738, 2739 },
	{ 2741, 2745 },
	{ 2748, 2757 },
	{ 2759, 2761 },
	{ 2763, 2765 },
	{ 2768, 2768 },
	{ 2784, 2787 },
	{ 2790, 2801 },
	{ 2809, 2815 },
};
static const URange32 Nushu_range32[] = {
	{ 94177, 94177 },
	{ 110960, 111355 },
};
static const URange32 Modi_range32[] = {
	{ 71168, 71236 },
	{ 71248, 71257 },
};
static const URange32 Gunjala_Gondi_range32[] = {
	{ 73056, 73061 },
	{ 73063, 73064 },
	{ 73066, 73102 },
	{ 73104, 73105 },
	{ 73107, 73112 },
	{ 73120, 73129 },
};
static const URange32 Inscriptional_Pahlavi_range32[] = {
	{ 68448, 68466 },
	{ 68472, 68479 },
};
static const URange32 Manichaean_range32[] = {
	{ 68288, 68326 },
	{ 68331, 68342 },
};
static const URange16 Khmer_range16[] = {
	{ 6016, 6109 },
	{ 6112, 6121 },
	{ 6128, 6137 },
	{ 6624, 6655 },
};
static const URange32 Cuneiform_range32[] = {
	{ 73728, 74649 },
	{ 74752, 74862 },
	{ 74864, 74868 },
	{ 74880, 75075 },
};
static const URange32 Khudawadi_range32[] = {
	{ 70320, 70378 },
	{ 70384, 70393 },
};
static const URange16 Mandaic_range16[] = {
	{ 2112, 2139 },
	{ 2142, 2142 },
};
static const URange32 Hatran_range32[] = {
	{ 67808, 67826 },
	{ 67828, 67829 },
	{ 67835, 67839 },
};
static const URange16 Syloti_Nagri_range16[] = {
	{ 43008, 43051 },
};
static const URange16 Nko_range16[] = {
	{ 1984, 2042 },
	{ 2045, 2047 },
};
static const URange16 Canadian_Aboriginal_range16[] = {
	{ 5120, 5759 },
	{ 6320, 6389 },
};
static const URange32 Meroitic_Hieroglyphs_range32[] = {
	{ 67968, 67999 },
};
static const URange32 Phoenician_range32[] = {
	{ 67840, 67867 },
	{ 67871, 67871 },
};
static const URange32 Nabataean_range32[] = {
	{ 67712, 67742 },
	{ 67751, 67759 },
};
static const URange16 Bengali_range16[] = {
	{ 2432, 2435 },
	{ 2437, 2444 },
	{ 2447, 2448 },
	{ 2451, 2472 },
	{ 2474, 2480 },
	{ 2482, 2482 },
	{ 2486, 2489 },
	{ 2492, 2500 },
	{ 2503, 2504 },
	{ 2507, 2510 },
	{ 2519, 2519 },
	{ 2524, 2525 },
	{ 2527, 2531 },
	{ 2534, 2558 },
};
static const URange32 Kaithi_range32[] = {
	{ 69760, 69825 },
	{ 69837, 69837 },
};
static const URange16 Glagolitic_range16[] = {
	{ 11264, 11310 },
	{ 11312, 11358 },
};
static const URange32 Glagolitic_range32[] = {
	{ 122880, 122886 },
	{ 122888, 122904 },
	{ 122907, 122913 },
	{ 122915, 122916 },
	{ 122918, 122922 },
};
static const URange32 Imperial_Aramaic_range32[] = {
	{ 67648, 67669 },
	{ 67671, 67679 },
};
static const URange32 Sora_Sompeng_range32[] = {
	{ 69840, 69864 },
	{ 69872, 69881 },
};
static const URange16 Gurmukhi_range16[] = {
	{ 2561, 2563 },
	{ 2565, 2570 },
	{ 2575, 2576 },
	{ 2579, 2600 },
	{ 2602, 2608 },
	{ 2610, 2611 },
	{ 2613, 2614 },
	{ 2616, 2617 },
	{ 2620, 2620 },
	{ 2622, 2626 },
	{ 2631, 2632 },
	{ 2635, 2637 },
	{ 2641, 2641 },
	{ 2649, 2652 },
	{ 2654, 2654 },
	{ 2662, 2678 },
};
static const URange16 Javanese_range16[] = {
	{ 43392, 43469 },
	{ 43472, 43481 },
	{ 43486, 43487 },
};
static const URange32 Old_Permic_range32[] = {
	{ 66384, 66426 },
};
static const URange16 Phags_Pa_range16[] = {
	{ 43072, 43127 },
};
static const URange32 Cypriot_range32[] = {
	{ 67584, 67589 },
	{ 67592, 67592 },
	{ 67594, 67637 },
	{ 67639, 67640 },
	{ 67644, 67644 },
	{ 67647, 67647 },
};
static const URange16 Kannada_range16[] = {
	{ 3200, 3212 },
	{ 3214, 3216 },
	{ 3218, 3240 },
	{ 3242, 3251 },
	{ 3253, 3257 },
	{ 3260, 3268 },
	{ 3270, 3272 },
	{ 3274, 3277 },
	{ 3285, 3286 },
	{ 3294, 3294 },
	{ 3296, 3299 },
	{ 3302, 3311 },
	{ 3313, 3314 },
};
static const URange32 Khojki_range32[] = {
	{ 70144, 70161 },
	{ 70163, 70206 },
};
static const URange16 Mongolian_range16[] = {
	{ 6144, 6145 },
	{ 6148, 6148 },
	{ 6150, 6158 },
	{ 6160, 6169 },
	{ 6176, 6264 },
	{ 6272, 6314 },
};
static const URange32 Mongolian_range32[] = {
	{ 71264, 71276 },
};
static const URange16 Sinhala_range16[] = {
	{ 3458, 3459 },
	{ 3461, 3478 },
	{ 3482, 3505 },
	{ 3507, 3515 },
	{ 3517, 3517 },
	{ 3520, 3526 },
	{ 3530, 3530 },
	{ 3535, 3540 },
	{ 3542, 3542 },
	{ 3544, 3551 },
	{ 3558, 3567 },
	{ 3570, 3572 },
};
static const URange32 Sinhala_range32[] = {
	{ 70113, 70132 },
};
static const URange32 Brahmi_range32[] = {
	{ 69632, 69709 },
	{ 69714, 69743 },
	{ 69759, 69759 },
};
static const URange32 Elbasan_range32[] = {
	{ 66816, 66855 },
};
static const URange32 Deseret_range32[] = {
	{ 66560, 66639 },
};
static const URange16 Rejang_range16[] = {
	{ 43312, 43347 },
	{ 43359, 43359 },
};
static const URange32 SignWriting_range32[] = {
	{ 120832, 121483 },
	{ 121499, 121503 },
	{ 121505, 121519 },
};
static const URange32 Multani_range32[] = {
	{ 70272, 70278 },
	{ 70280, 70280 },
	{ 70282, 70285 },
	{ 70287, 70301 },
	{ 70303, 70313 },
};
static const URange16 Yi_range16[] = {
	{ 40960, 42124 },
	{ 42128, 42182 },
};
static const URange16 Balinese_range16[] = {
	{ 6912, 6987 },
	{ 6992, 7036 },
};
static const URange16 Lao_range16[] = {
	{ 3713, 3714 },
	{ 3716, 3716 },
	{ 3719, 3720 },
	{ 3722, 3722 },
	{ 3725, 3725 },
	{ 3732, 3735 },
	{ 3737, 3743 },
	{ 3745, 3747 },
	{ 3749, 3749 },
	{ 3751, 3751 },
	{ 3754, 3755 },
	{ 3757, 3769 },
	{ 3771, 3773 },
	{ 3776, 3780 },
	{ 3782, 3782 },
	{ 3784, 3789 },
	{ 3792, 3801 },
	{ 3804, 3807 },
};
static const URange16 Hanunoo_range16[] = {
	{ 5920, 5940 },
};
static const URange32 Masaram_Gondi_range32[] = {
	{ 72960, 72966 },
	{ 72968, 72969 },
	{ 72971, 73014 },
	{ 73018, 73018 },
	{ 73020, 73021 },
	{ 73023, 73031 },
	{ 73040, 73049 },
};
static const URange32 Linear_B_range32[] = {
	{ 65536, 65547 },
	{ 65549, 65574 },
	{ 65576, 65594 },
	{ 65596, 65597 },
	{ 65599, 65613 },
	{ 65616, 65629 },
	{ 65664, 65786 },
};
static const URange32 Linear_A_range32[] = {
	{ 67072, 67382 },
	{ 67392, 67413 },
	{ 67424, 67431 },
};
static const URange32 Dogra_range32[] = {
	{ 71680, 71739 },
};
static const URange32 Old_Turkic_range32[] = {
	{ 68608, 68680 },
};
static const URange16 Lepcha_range16[] = {
	{ 7168, 7223 },
	{ 7227, 7241 },
	{ 7245, 7247 },
};
static const URange32 Lydian_range32[] = {
	{ 67872, 67897 },
	{ 67903, 67903 },
};
static const URange32 Egyptian_Hieroglyphs_range32[] = {
	{ 77824, 78894 },
};
static const URange32 Sogdian_range32[] = {
	{ 69424, 69465 },
};
static const URange32 Caucasian_Albanian_range32[] = {
	{ 66864, 66915 },
	{ 66927, 66927 },
};
static const URange32 Makasar_range32[] = {
	{ 73440, 73464 },
};
static const URange32 Old_Hungarian_range32[] = {
	{ 68736, 68786 },
	{ 68800, 68850 },
	{ 68858, 68863 },
};
static const URange16 Samaritan_range16[] = {
	{ 2048, 2093 },
	{ 2096, 2110 },
};
static const URange16 Lisu_range16[] = {
	{ 42192, 42239 },
};
static const URange16 Buhid_range16[] = {
	{ 5952, 5971 },
};
static const URange32 Palmyrene_range32[] = {
	{ 67680, 67711 },
};
static const URange32 Tirhuta_range32[] = {
	{ 70784, 70855 },
	{ 70864, 70873 },
};
static const URange32 Mro_range32[] = {
	{ 92736, 92766 },
	{ 92768, 92777 },
	{ 92782, 92783 },
};
static const URange16 Common_range16[] = {
	{ 0, 64 },
	{ 91, 96 },
	{ 123, 169 },
	{ 171, 185 },
	{ 187, 191 },
	{ 215, 215 },
	{ 247, 247 },
	{ 697, 735 },
	{ 741, 745 },
	{ 748, 767 },
	{ 884, 884 },
	{ 894, 894 },
	{ 901, 901 },
	{ 903, 903 },
	{ 1417, 1417 },
	{ 1541, 1541 },
	{ 1548, 1548 },
	{ 1563, 1563 },
	{ 1567, 1567 },
	{ 1600, 1600 },
	{ 1757, 1757 },
	{ 2274, 2274 },
	{ 2404, 2405 },
	{ 3647, 3647 },
	{ 4053, 4056 },
	{ 4347, 4347 },
	{ 5867, 5869 },
	{ 5941, 5942 },
	{ 6146, 6147 },
	{ 6149, 6149 },
	{ 7379, 7379 },
	{ 7393, 7393 },
	{ 7401, 7404 },
	{ 7406, 7411 },
	{ 7413, 7415 },
	{ 8192, 8203 },
	{ 8206, 8292 },
	{ 8294, 8304 },
	{ 8308, 8318 },
	{ 8320, 8334 },
	{ 8352, 8383 },
	{ 8448, 8485 },
	{ 8487, 8489 },
	{ 8492, 8497 },
	{ 8499, 8525 },
	{ 8527, 8543 },
	{ 8585, 8587 },
	{ 8592, 9254 },
	{ 9280, 9290 },
	{ 9312, 10239 },
	{ 10496, 11123 },
	{ 11126, 11157 },
	{ 11160, 11208 },
	{ 11210, 11262 },
	{ 11776, 11854 },
	{ 12272, 12283 },
	{ 12288, 12292 },
	{ 12294, 12294 },
	{ 12296, 12320 },
	{ 12336, 12343 },
	{ 12348, 12351 },
	{ 12443, 12444 },
	{ 12448, 12448 },
	{ 12539, 12540 },
	{ 12688, 12703 },
	{ 12736, 12771 },
	{ 12832, 12895 },
	{ 12927, 13007 },
	{ 13144, 13311 },
	{ 19904, 19967 },
	{ 42752, 42785 },
	{ 42888, 42890 },
	{ 43056, 43065 },
	{ 43310, 43310 },
	{ 43471, 43471 },
	{ 43867, 43867 },
	{ 64830, 64831 },
	{ 65040, 65049 },
	{ 65072, 65106 },
	{ 65108, 65126 },
	{ 65128, 65131 },
	{ 65279, 65279 },
	{ 65281, 65312 },
	{ 65339, 65344 },
	{ 65371, 65381 },
	{ 65392, 65392 },
	{ 65438, 65439 },
	{ 65504, 65510 },
	{ 65512, 65518 },
	{ 65529, 65533 },
};
static const URange32 Common_range32[] = {
	{ 65792, 65794 },
	{ 65799, 65843 },
	{ 65847, 65855 },
	{ 65936, 65947 },
	{ 66000, 66044 },
	{ 66273, 66299 },
	{ 113824, 113827 },
	{ 118784, 119029 },
	{ 119040, 119078 },
	{ 119081, 119142 },
	{ 119146, 119162 },
	{ 119171, 119172 },
	{ 119180, 119209 },
	{ 119214, 119272 },
	{ 119520, 119539 },
	{ 119552, 119638 },
	{ 119648, 119672 },
	{ 119808, 119892 },
	{ 119894, 119964 },
	{ 119966, 119967 },
	{ 119970, 119970 },
	{ 119973, 119974 },
	{ 119977, 119980 },
	{ 119982, 119993 },
	{ 119995, 119995 },
	{ 119997, 120003 },
	{ 120005, 120069 },
	{ 120071, 120074 },
	{ 120077, 120084 },
	{ 120086, 120092 },
	{ 120094, 120121 },
	{ 120123, 120126 },
	{ 120128, 120132 },
	{ 120134, 120134 },
	{ 120138, 120144 },
	{ 120146, 120485 },
	{ 120488, 120779 },
	{ 120782, 120831 },
	{ 126065, 126132 },
	{ 126976, 127019 },
	{ 127024, 127123 },
	{ 127136, 127150 },
	{ 127153, 127167 },
	{ 127169, 127183 },
	{ 127185, 127221 },
	{ 127232, 127244 },
	{ 127248, 127339 },
	{ 127344, 127404 },
	{ 127462, 127487 },
	{ 127489, 127490 },
	{ 127504, 127547 },
	{ 127552, 127560 },
	{ 127568, 127569 },
	{ 127584, 127589 },
	{ 127744, 128724 },
	{ 128736, 128748 },
	{ 128752, 128761 },
	{ 128768, 128883 },
	{ 128896, 128984 },
	{ 129024, 129035 },
	{ 129040, 129095 },
	{ 129104, 129113 },
	{ 129120, 129159 },
	{ 129168, 129197 },
	{ 129280, 129291 },
	{ 129296, 129342 },
	{ 129344, 129392 },
	{ 129395, 129398 },
	{ 129402, 129402 },
	{ 129404, 129442 },
	{ 129456, 129465 },
	{ 129472, 129474 },
	{ 129488, 129535 },
	{ 129632, 129645 },
	{ 917505, 917505 },
	{ 917536, 917631 },
};
static const URange16 Coptic_range16[] = {
	{ 994, 1007 },
	{ 11392, 11507 },
	{ 11513, 11519 },
};
static const URange32 Chakma_range32[] = {
	{ 69888, 69940 },
	{ 69942, 69958 },
};
static const URange16 Arabic_range16[] = {
	{ 1536, 1540 },
	{ 1542, 1547 },
	{ 1549, 1562 },
	{ 1564, 1564 },
	{ 1566, 1566 },
	{ 1568, 1599 },
	{ 1601, 1610 },
	{ 1622, 1647 },
	{ 1649, 1756 },
	{ 1758, 1791 },
	{ 1872, 1919 },
	{ 2208, 2228 },
	{ 2230, 2237 },
	{ 2259, 2273 },
	{ 2275, 2303 },
	{ 64336, 64449 },
	{ 64467, 64829 },
	{ 64848, 64911 },
	{ 64914, 64967 },
	{ 65008, 65021 },
	{ 65136, 65140 },
	{ 65142, 65276 },
};
static const URange32 Arabic_range32[] = {
	{ 69216, 69246 },
	{ 126464, 126467 },
	{ 126469, 126495 },
	{ 126497, 126498 },
	{ 126500, 126500 },
	{ 126503, 126503 },
	{ 126505, 126514 },
	{ 126516, 126519 },
	{ 126521, 126521 },
	{ 126523, 126523 },
	{ 126530, 126530 },
	{ 126535, 126535 },
	{ 126537, 126537 },
	{ 126539, 126539 },
	{ 126541, 126543 },
	{ 126545, 126546 },
	{ 126548, 126548 },
	{ 126551, 126551 },
	{ 126553, 126553 },
	{ 126555, 126555 },
	{ 126557, 126557 },
	{ 126559, 126559 },
	{ 126561, 126562 },
	{ 126564, 126564 },
	{ 126567, 126570 },
	{ 126572, 126578 },
	{ 126580, 126583 },
	{ 126585, 126588 },
	{ 126590, 126590 },
	{ 126592, 126601 },
	{ 126603, 126619 },
	{ 126625, 126627 },
	{ 126629, 126633 },
	{ 126635, 126651 },
	{ 126704, 126705 },
};
static const URange16 Bamum_range16[] = {
	{ 42656, 42743 },
};
static const URange32 Bamum_range32[] = {
	{ 92160, 92728 },
};
static const URange16 Myanmar_range16[] = {
	{ 4096, 4255 },
	{ 43488, 43518 },
	{ 43616, 43647 },
};
static const URange32 Siddham_range32[] = {
	{ 71040, 71093 },
	{ 71096, 71133 },
};
static const URange32 Soyombo_range32[] = {
	{ 72272, 72323 },
	{ 72326, 72354 },
};
static const URange32 Avestan_range32[] = {
	{ 68352, 68405 },
	{ 68409, 68415 },
};
static const URange16 Hebrew_range16[] = {
	{ 1425, 1479 },
	{ 1488, 1514 },
	{ 1519, 1524 },
	{ 64285, 64310 },
	{ 64312, 64316 },
	{ 64318, 64318 },
	{ 64320, 64321 },
	{ 64323, 64324 },
	{ 64326, 64335 },
};
static const URange32 Psalter_Pahlavi_range32[] = {
	{ 68480, 68497 },
	{ 68505, 68508 },
	{ 68521, 68527 },
};
static const URange32 Takri_range32[] = {
	{ 71296, 71351 },
	{ 71360, 71369 },
};
// 3994 16-bit ranges, 1429 32-bit ranges
const UGroup unicode_groups[] = {
	{ "Adlam", +1, 0, 0, Adlam_range32, 3 },
	{ "Ahom", +1, 0, 0, Ahom_range32, 3 },
	{ "Anatolian_Hieroglyphs", +1, 0, 0, Anatolian_Hieroglyphs_range32, 1 },
	{ "Arabic", +1, Arabic_range16, 22, Arabic_range32, 35 },
	{ "Armenian", +1, Armenian_range16, 5, 0, 0 },
	{ "Avestan", +1, 0, 0, Avestan_range32, 2 },
	{ "Balinese", +1, Balinese_range16, 2, 0, 0 },
	{ "Bamum", +1, Bamum_range16, 1, Bamum_range32, 1 },
	{ "Bassa_Vah", +1, 0, 0, Bassa_Vah_range32, 2 },
	{ "Batak", +1, Batak_range16, 2, 0, 0 },
	{ "Bengali", +1, Bengali_range16, 14, 0, 0 },
	{ "Bhaiksuki", +1, 0, 0, Bhaiksuki_range32, 4 },
	{ "Bopomofo", +1, Bopomofo_range16, 3, 0, 0 },
	{ "Brahmi", +1, 0, 0, Brahmi_range32, 3 },
	{ "Braille", +1, Braille_range16, 1, 0, 0 },
	{ "Buginese", +1, Buginese_range16, 2, 0, 0 },
	{ "Buhid", +1, Buhid_range16, 1, 0, 0 },
	{ "C", +1, C_range16, 16, C_range32, 8 },
	{ "Canadian_Aboriginal", +1, Canadian_Aboriginal_range16, 2, 0, 0 },
	{ "Carian", +1, 0, 0, Carian_range32, 1 },
	{ "Caucasian_Albanian", +1, 0, 0, Caucasian_Albanian_range32, 2 },
	{ "Cc", +1, Cc_range16, 2, 0, 0 },
	{ "Cf", +1, Cf_range16, 13, Cf_range32, 6 },
	{ "Chakma", +1, 0, 0, Chakma_range32, 2 },
	{ "Cham", +1, Cham_range16, 4, 0, 0 },
	{ "Cherokee", +1, Cherokee_range16, 3, 0, 0 },
	{ "Co", +1, Co_range16, 1, Co_range32, 2 },
	{ "Common", +1, Common_range16, 90, Common_range32, 76 },
	{ "Coptic", +1, Coptic_range16, 3, 0, 0 },
	{ "Cs", +1, Cs_range16, 1, 0, 0 },
	{ "Cuneiform", +1, 0, 0, Cuneiform_range32, 4 },
	{ "Cypriot", +1, 0, 0, Cypriot_range32, 6 },
	{ "Cyrillic", +1, Cyrillic_range16, 8, 0, 0 },
	{ "Deseret", +1, 0, 0, Deseret_range32, 1 },
	{ "Devanagari", +1, Devanagari_range16, 4, 0, 0 },
	{ "Dogra", +1, 0, 0, Dogra_range32, 1 },
	{ "Duployan", +1, 0, 0, Duployan_range32, 5 },
	{ "Egyptian_Hieroglyphs", +1, 0, 0, Egyptian_Hieroglyphs_range32, 1 },
	{ "Elbasan", +1, 0, 0, Elbasan_range32, 1 },
	{ "Ethiopic", +1, Ethiopic_range16, 32, 0, 0 },
	{ "Georgian", +1, Georgian_range16, 10, 0, 0 },
	{ "Glagolitic", +1, Glagolitic_range16, 2, Glagolitic_range32, 5 },
	{ "Gothic", +1, 0, 0, Gothic_range32, 1 },
	{ "Grantha", +1, 0, 0, Grantha_range32, 15 },
	{ "Greek", +1, Greek_range16, 33, Greek_range32, 3 },
	{ "Gujarati", +1, Gujarati_range16, 14, 0, 0 },
	{ "Gunjala_Gondi", +1, 0, 0, Gunjala_Gondi_range32, 6 },
	{ "Gurmukhi", +1, Gurmukhi_range16, 16, 0, 0 },
	{ "Han", +1, Han_range16, 11, Han_range32, 6 },
	{ "Hangul", +1, Hangul_range16, 14, 0, 0 },
	{ "Hanifi_Rohingya", +1, 0, 0, Hanifi_Rohingya_range32, 2 },
	{ "Hanunoo", +1, Hanunoo_range16, 1, 0, 0 },
	{ "Hatran", +1, 0, 0, Hatran_range32, 3 },
	{ "Hebrew", +1, Hebrew_range16, 9, 0, 0 },
	{ "Hiragana", +1, Hiragana_range16, 2, Hiragana_range32, 2 },
	{ "Imperial_Aramaic", +1, 0, 0, Imperial_Aramaic_range32, 2 },
	{ "Inherited", +1, Inherited_range16, 20, Inherited_range32, 8 },
	{ "Inscriptional_Pahlavi", +1, 0, 0, Inscriptional_Pahlavi_range32, 2 },
	{ "Inscriptional_Parthian", +1, 0, 0, Inscriptional_Parthian_range32, 2 },
	{ "Javanese", +1, Javanese_range16, 3, 0, 0 },
	{ "Kaithi", +1, 0, 0, Kaithi_range32, 2 },
	{ "Kannada", +1, Kannada_range16, 13, 0, 0 },
	{ "Katakana", +1, Katakana_range16, 7, Katakana_range32, 1 },
	{ "Kayah_Li", +1, Kayah_Li_range16, 2, 0, 0 },
	{ "Kharoshthi", +1, 0, 0, Kharoshthi_range32, 8 },
	{ "Khmer", +1, Khmer_range16, 4, 0, 0 },
	{ "Khojki", +1, 0, 0, Khojki_range32, 2 },
	{ "Khudawadi", +1, 0, 0, Khudawadi_range32, 2 },
	{ "L", +1, L_range16, 384, L_range32, 215 },
	{ "Lao", +1, Lao_range16, 18, 0, 0 },
	{ "Latin", +1, Latin_range16, 30, 0, 0 },
	{ "Lepcha", +1, Lepcha_range16, 3, 0, 0 },
	{ "Limbu", +1, Limbu_range16, 5, 0, 0 },
	{ "Linear_A", +1, 0, 0, Linear_A_range32, 3 },
	{ "Linear_B", +1, 0, 0, Linear_B_range32, 7 },
	{ "Lisu", +1, Lisu_range16, 1, 0, 0 },
	{ "Ll", +1, Ll_range16, 604, Ll_range32, 34 },
	{ "Lm", +1, Lm_range16, 54, Lm_range32, 3 },
	{ "Lo", +1, Lo_range16, 295, Lo_range32, 175 },
	{ "Lt", +1, Lt_range16, 10, 0, 0 },
	{ "Lu", +1, Lu_range16, 594, Lu_range32, 37 },
	{ "Lycian", +1, 0, 0, Lycian_range32, 1 },
	{ "Lydian", +1, 0, 0, Lydian_range32, 2 },
	{ "M", +1, M_range16, 187, M_range32, 88 },
	{ "Mahajani", +1, 0, 0, Mahajani_range32, 1 },
	{ "Makasar", +1, 0, 0, Makasar_range32, 1 },
	{ "Malayalam", +1, Malayalam_range16, 8, 0, 0 },
	{ "Mandaic", +1, Mandaic_range16, 2, 0, 0 },
	{ "Manichaean", +1, 0, 0, Manichaean_range32, 2 },
	{ "Marchen", +1, 0, 0, Marchen_range32, 3 },
	{ "Masaram_Gondi", +1, 0, 0, Masaram_Gondi_range32, 7 },
	{ "Mc", +1, Mc_range16, 110, Mc_range32, 56 },
	{ "Me", +1, Me_range16, 5, 0, 0 },
	{ "Medefaidrin", +1, 0, 0, Medefaidrin_range32, 1 },
	{ "Meetei_Mayek", +1, Meetei_Mayek_range16, 3, 0, 0 },
	{ "Mende_Kikakui", +1, 0, 0, Mende_Kikakui_range32, 2 },
	{ "Meroitic_Cursive", +1, 0, 0, Meroitic_Cursive_range32, 3 },
	{ "Meroitic_Hieroglyphs", +1, 0, 0, Meroitic_Hieroglyphs_range32, 1 },
	{ "Miao", +1, 0, 0, Miao_range32, 3 },
	{ "Mn", +1, Mn_range16, 208, Mn_range32, 105 },
	{ "Modi", +1, 0, 0, Modi_range32, 2 },
	{ "Mongolian", +1, Mongolian_range16, 6, Mongolian_range32, 1 },
	{ "Mro", +1, 0, 0, Mro_range32, 3 },
	{ "Multani", +1, 0, 0, Multani_range32, 5 },
	{ "Myanmar", +1, Myanmar_range16, 3, 0, 0 },
	{ "N", +1, N_range16, 67, N_range32, 58 },
	{ "Nabataean", +1, 0, 0, Nabataean_range32, 2 },
	{ "Nd", +1, Nd_range16, 37, Nd_range32, 20 },
	{ "New_Tai_Lue", +1, New_Tai_Lue_range16, 4, 0, 0 },
	{ "Newa", +1, 0, 0, Newa_range32, 3 },
	{ "Nko", +1, Nko_range16, 2, 0, 0 },
	{ "Nl", +1, Nl_range16, 7, Nl_range32, 5 },
	{ "No", +1, No_range16, 29, No_range32, 38 },
	{ "Nushu", +1, 0, 0, Nushu_range32, 2 },
	{ "Ogham", +1, Ogham_range16, 1, 0, 0 },
	{ "Ol_Chiki", +1, Ol_Chiki_range16, 1, 0, 0 },
	{ "Old_Hungarian", +1, 0, 0, Old_Hungarian_range32, 3 },
	{ "Old_Italic", +1, 0, 0, Old_Italic_range32, 2 },
	{ "Old_North_Arabian", +1, 0, 0, Old_North_Arabian_range32, 1 },
	{ "Old_Permic", +1, 0, 0, Old_Permic_range32, 1 },
	{ "Old_Persian", +1, 0, 0, Old_Persian_range32, 2 },
	{ "Old_Sogdian", +1, 0, 0, Old_Sogdian_range32, 1 },
	{ "Old_South_Arabian", +1, 0, 0, Old_South_Arabian_range32, 1 },
	{ "Old_Turkic", +1, 0, 0, Old_Turkic_range32, 1 },
	{ "Oriya", +1, Oriya_range16, 14, 0, 0 },
	{ "Osage", +1, 0, 0, Osage_range32, 2 },
	{ "Osmanya", +1, 0, 0, Osmanya_range32, 2 },
	{ "P", +1, P_range16, 130, P_range32, 48 },
	{ "Pahawh_Hmong", +1, 0, 0, Pahawh_Hmong_range32, 5 },
	{ "Palmyrene", +1, 0, 0, Palmyrene_range32, 1 },
	{ "Pau_Cin_Hau", +1, 0, 0, Pau_Cin_Hau_range32, 1 },
	{ "Pc", +1, Pc_range16, 6, 0, 0 },
	{ "Pd", +1, Pd_range16, 17, 0, 0 },
	{ "Pe", +1, Pe_range16, 72, 0, 0 },
	{ "Pf", +1, Pf_range16, 10, 0, 0 },
	{ "Phags_Pa", +1, Phags_Pa_range16, 1, 0, 0 },
	{ "Phoenician", +1, 0, 0, Phoenician_range32, 2 },
	{ "Pi", +1, Pi_range16, 11, 0, 0 },
	{ "Po", +1, Po_range16, 127, Po_range32, 48 },
	{ "Ps", +1, Ps_range16, 75, 0, 0 },
	{ "Psalter_Pahlavi", +1, 0, 0, Psalter_Pahlavi_range32, 3 },
	{ "Rejang", +1, Rejang_range16, 2, 0, 0 },
	{ "Runic", +1, Runic_range16, 2, 0, 0 },
	{ "S", +1, S_range16, 147, S_range32, 73 },
	{ "Samaritan", +1, Samaritan_range16, 2, 0, 0 },
	{ "Saurashtra", +1, Saurashtra_range16, 2, 0, 0 },
	{ "Sc", +1, Sc_range16, 18, Sc_range32, 1 },
	{ "Sharada", +1, 0, 0, Sharada_range32, 2 },
	{ "Shavian", +1, 0, 0, Shavian_range32, 1 },
	{ "Siddham", +1, 0, 0, Siddham_range32, 2 },
	{ "SignWriting", +1, 0, 0, SignWriting_range32, 3 },
	{ "Sinhala", +1, Sinhala_range16, 12, Sinhala_range32, 1 },
	{ "Sk", +1, Sk_range16, 28, Sk_range32, 1 },
	{ "Sm", +1, Sm_range16, 53, Sm_range32, 11 },
	{ "So", +1, So_range16, 112, So_range32, 62 },
	{ "Sogdian", +1, 0, 0, Sogdian_range32, 1 },
	{ "Sora_Sompeng", +1, 0, 0, Sora_Sompeng_range32, 2 },
	{ "Soyombo", +1, 0, 0, Soyombo_range32, 2 },
	{ "Sundanese", +1, Sundanese_range16, 2, 0, 0 },
	{ "Syloti_Nagri", +1, Syloti_Nagri_range16, 1, 0, 0 },
	{ "Syriac", +1, Syriac_range16, 4, 0, 0 },
	{ "Tagalog", +1, Tagalog_range16, 2, 0, 0 },
	{ "Tagbanwa", +1, Tagbanwa_range16, 3, 0, 0 },
	{ "Tai_Le", +1, Tai_Le_range16, 2, 0, 0 },
	{ "Tai_Tham", +1, Tai_Tham_range16, 5, 0, 0 },
	{ "Tai_Viet", +1, Tai_Viet_range16, 2, 0, 0 },
	{ "Takri", +1, 0, 0, Takri_range32, 2 },
	{ "Tamil", +1, Tamil_range16, 16, 0, 0 },
	{ "Tangut", +1, 0, 0, Tangut_range32, 3 },
	{ "Telugu", +1, Telugu_range16, 12, 0, 0 },
	{ "Thaana", +1, Thaana_range16, 1, 0, 0 },
	{ "Thai", +1, Thai_range16, 2, 0, 0 },
	{ "Tibetan", +1, Tibetan_range16, 7, 0, 0 },
	{ "Tifinagh", +1, Tifinagh_range16, 3, 0, 0 },
	{ "Tirhuta", +1, 0, 0, Tirhuta_range32, 2 },
	{ "Ugaritic", +1, 0, 0, Ugaritic_range32, 2 },
	{ "Vai", +1, Vai_range16, 1, 0, 0 },
	{ "Warang_Citi", +1, 0, 0, Warang_Citi_range32, 2 },
	{ "Yi", +1, Yi_range16, 2, 0, 0 },
	{ "Z", +1, Z_range16, 8, 0, 0 },
	{ "Zanabazar_Square", +1, 0, 0, Zanabazar_Square_range32, 1 },
	{ "Zl", +1, Zl_range16, 1, 0, 0 },
	{ "Zp", +1, Zp_range16, 1, 0, 0 },
	{ "Zs", +1, Zs_range16, 7, 0, 0 },
};
const int num_unicode_groups = 184;


}  // namespace re2


/*
 * The authors of this software are Rob Pike and Ken Thompson.
 *              Copyright (c) 2002 by Lucent Technologies.
 * Permission to use, copy, modify, and distribute this software for any
 * purpose without fee is hereby granted, provided that this entire notice
 * is included in all copies of any software which is or includes a copy
 * or modification of this software and in all copies of the supporting
 * documentation for such software.
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 */

#include <stdarg.h>
#include <string.h>



namespace re2 {

enum
{
	Bit1	= 7,
	Bitx	= 6,
	Bit2	= 5,
	Bit3	= 4,
	Bit4	= 3,
	Bit5	= 2, 

	T1	= ((1<<(Bit1+1))-1) ^ 0xFF,	/* 0000 0000 */
	Tx	= ((1<<(Bitx+1))-1) ^ 0xFF,	/* 1000 0000 */
	T2	= ((1<<(Bit2+1))-1) ^ 0xFF,	/* 1100 0000 */
	T3	= ((1<<(Bit3+1))-1) ^ 0xFF,	/* 1110 0000 */
	T4	= ((1<<(Bit4+1))-1) ^ 0xFF,	/* 1111 0000 */
	T5	= ((1<<(Bit5+1))-1) ^ 0xFF,	/* 1111 1000 */

	Rune1	= (1<<(Bit1+0*Bitx))-1,		/* 0000 0000 0111 1111 */
	Rune2	= (1<<(Bit2+1*Bitx))-1,		/* 0000 0111 1111 1111 */
	Rune3	= (1<<(Bit3+2*Bitx))-1,		/* 1111 1111 1111 1111 */
	Rune4	= (1<<(Bit4+3*Bitx))-1,
                                        /* 0001 1111 1111 1111 1111 1111 */

	Maskx	= (1<<Bitx)-1,			/* 0011 1111 */
	Testx	= Maskx ^ 0xFF,			/* 1100 0000 */

	Bad	= Runeerror,
};

int
chartorune(Rune *rune, const char *str)
{
	int c, c1, c2, c3;
	long l;

	/*
	 * one character sequence
	 *	00000-0007F => T1
	 */
	c = *(unsigned char*)str;
	if(c < Tx) {
		*rune = c;
		return 1;
	}

	/*
	 * two character sequence
	 *	0080-07FF => T2 Tx
	 */
	c1 = *(unsigned char*)(str+1) ^ Tx;
	if(c1 & Testx)
		goto bad;
	if(c < T3) {
		if(c < T2)
			goto bad;
		l = ((c << Bitx) | c1) & Rune2;
		if(l <= Rune1)
			goto bad;
		*rune = l;
		return 2;
	}

	/*
	 * three character sequence
	 *	0800-FFFF => T3 Tx Tx
	 */
	c2 = *(unsigned char*)(str+2) ^ Tx;
	if(c2 & Testx)
		goto bad;
	if(c < T4) {
		l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
		if(l <= Rune2)
			goto bad;
		*rune = l;
		return 3;
	}

	/*
	 * four character sequence (21-bit value)
	 *	10000-1FFFFF => T4 Tx Tx Tx
	 */
	c3 = *(unsigned char*)(str+3) ^ Tx;
	if (c3 & Testx)
		goto bad;
	if (c < T5) {
		l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
		if (l <= Rune3)
			goto bad;
		*rune = l;
		return 4;
	}

	/*
	 * Support for 5-byte or longer UTF-8 would go here, but
	 * since we don't have that, we'll just fall through to bad.
	 */

	/*
	 * bad decoding
	 */
bad:
	*rune = Bad;
	return 1;
}

int
runetochar(char *str, const Rune *rune)
{
	/* Runes are signed, so convert to unsigned for range check. */
	unsigned long c;

	/*
	 * one character sequence
	 *	00000-0007F => 00-7F
	 */
	c = *rune;
	if(c <= Rune1) {
		str[0] = static_cast<char>(c);
		return 1;
	}

	/*
	 * two character sequence
	 *	0080-07FF => T2 Tx
	 */
	if(c <= Rune2) {
		str[0] = T2 | static_cast<char>(c >> 1*Bitx);
		str[1] = Tx | (c & Maskx);
		return 2;
	}

	/*
	 * If the Rune is out of range, convert it to the error rune.
	 * Do this test here because the error rune encodes to three bytes.
	 * Doing it earlier would duplicate work, since an out of range
	 * Rune wouldn't have fit in one or two bytes.
	 */
	if (c > Runemax)
		c = Runeerror;

	/*
	 * three character sequence
	 *	0800-FFFF => T3 Tx Tx
	 */
	if (c <= Rune3) {
		str[0] = T3 | static_cast<char>(c >> 2*Bitx);
		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
		str[2] = Tx | (c & Maskx);
		return 3;
	}

	/*
	 * four character sequence (21-bit value)
	 *     10000-1FFFFF => T4 Tx Tx Tx
	 */
	str[0] = T4 | static_cast<char>(c >> 3*Bitx);
	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
	str[3] = Tx | (c & Maskx);
	return 4;
}

int
runelen(Rune rune)
{
	char str[10];

	return runetochar(str, &rune);
}

int
fullrune(const char *str, int n)
{
	if (n > 0) {
		int c = *(unsigned char*)str;
		if (c < Tx)
			return 1;
		if (n > 1) {
			if (c < T3)
				return 1;
			if (n > 2) {
				if (c < T4 || n > 3)
					return 1;
			}
		}
	}
	return 0;
}


int
utflen(const char *s)
{
	int c;
	long n;
	Rune rune;

	n = 0;
	for(;;) {
		c = *(unsigned char*)s;
		if(c < Runeself) {
			if(c == 0)
				return n;
			s++;
		} else
			s += chartorune(&rune, s);
		n++;
	}
	return 0;
}

char*
utfrune(const char *s, Rune c)
{
	long c1;
	Rune r;
	int n;

	if(c < Runesync)		/* not part of utf sequence */
		return strchr((char*)s, c);

	for(;;) {
		c1 = *(unsigned char*)s;
		if(c1 < Runeself) {	/* one byte rune */
			if(c1 == 0)
				return 0;
			if(c1 == c)
				return (char*)s;
			s++;
			continue;
		}
		n = chartorune(&r, s);
		if(r == c)
			return (char*)s;
		s += n;
	}
	return 0;
}

}  // namespace re2
// Copyright 1999-2005 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stdarg.h>
#include <stdio.h>



#ifdef _WIN32
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif

namespace re2 {

// ----------------------------------------------------------------------
// CEscapeString()
//    Copies 'src' to 'dest', escaping dangerous characters using
//    C-style escape sequences.  'src' and 'dest' should not overlap.
//    Returns the number of bytes written to 'dest' (not including the \0)
//    or (size_t)-1 if there was insufficient space.
// ----------------------------------------------------------------------
static size_t CEscapeString(const char* src, size_t src_len,
                            char* dest, size_t dest_len) {
  const char* src_end = src + src_len;
  size_t used = 0;

  for (; src < src_end; src++) {
    if (dest_len - used < 2)   // space for two-character escape
      return (size_t)-1;

    unsigned char c = *src;
    switch (c) {
      case '\n': dest[used++] = '\\'; dest[used++] = 'n';  break;
      case '\r': dest[used++] = '\\'; dest[used++] = 'r';  break;
      case '\t': dest[used++] = '\\'; dest[used++] = 't';  break;
      case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
      case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
      case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
      default:
        // Note that if we emit \xNN and the src character after that is a hex
        // digit then that digit must be escaped too to prevent it being
        // interpreted as part of the character code by C.
        if (c < ' ' || c > '~') {
          if (dest_len - used < 5)   // space for four-character escape + \0
            return (size_t)-1;
          snprintf(dest + used, 5, "\\%03o", c);
          used += 4;
        } else {
          dest[used++] = c; break;
        }
    }
  }

  if (dest_len - used < 1)   // make sure that there is room for \0
    return (size_t)-1;

  dest[used] = '\0';   // doesn't count towards return value though
  return used;
}

// ----------------------------------------------------------------------
// CEscape()
//    Copies 'src' to result, escaping dangerous characters using
//    C-style escape sequences.  'src' and 'dest' should not overlap.
// ----------------------------------------------------------------------
std::string CEscape(const StringPiece& src) {
  const size_t dest_len = src.size() * 4 + 1; // Maximum possible expansion
  char* dest = new char[dest_len];
  const size_t used = CEscapeString(src.data(), src.size(),
                                    dest, dest_len);
  std::string s = std::string(dest, used);
  delete[] dest;
  return s;
}

void PrefixSuccessor(std::string* prefix) {
  // We can increment the last character in the string and be done
  // unless that character is 255, in which case we have to erase the
  // last character and increment the previous character, unless that
  // is 255, etc. If the string is empty or consists entirely of
  // 255's, we just return the empty string.
  while (!prefix->empty()) {
    char& c = prefix->back();
    if (c == '\xff') {  // char literal avoids signed/unsigned.
      prefix->pop_back();
    } else {
      ++c;
      break;
    }
  }
}

static void StringAppendV(std::string* dst, const char* format, va_list ap) {
  // First try with a small fixed size buffer
  char space[1024];

  // It's possible for methods that use a va_list to invalidate
  // the data in it upon use.  The fix is to make a copy
  // of the structure before using it and use that copy instead.
  va_list backup_ap;
  va_copy(backup_ap, ap);
  int result = vsnprintf(space, sizeof(space), format, backup_ap);
  va_end(backup_ap);

  if ((result >= 0) && (static_cast<size_t>(result) < sizeof(space))) {
    // It fit
    dst->append(space, result);
    return;
  }

  // Repeatedly increase buffer size until it fits
  int length = sizeof(space);
  while (true) {
    if (result < 0) {
      // Older behavior: just try doubling the buffer size
      length *= 2;
    } else {
      // We need exactly "result+1" characters
      length = result+1;
    }
    char* buf = new char[length];

    // Restore the va_list before we use it again
    va_copy(backup_ap, ap);
    result = vsnprintf(buf, length, format, backup_ap);
    va_end(backup_ap);

    if ((result >= 0) && (result < length)) {
      // It fit
      dst->append(buf, result);
      delete[] buf;
      return;
    }
    delete[] buf;
  }
}

std::string StringPrintf(const char* format, ...) {
  va_list ap;
  va_start(ap, format);
  std::string result;
  StringAppendV(&result, format, ap);
  va_end(ap);
  return result;
}

void SStringPrintf(std::string* dst, const char* format, ...) {
  va_list ap;
  va_start(ap, format);
  dst->clear();
  StringAppendV(dst, format, ap);
  va_end(ap);
}

void StringAppendF(std::string* dst, const char* format, ...) {
  va_list ap;
  va_start(ap, format);
  StringAppendV(dst, format, ap);
  va_end(ap);
}

}  // namespace re2
/* -*- mode: c; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil -*- */
/*
 *  Copyright (c) 2014-2019 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contributors.
 *  Copyright (c) 2009 Public Software Group e. V., Berlin, Germany
 *
 *  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.
 */

/*
 *  This library contains derived data from a modified version of the
 *  Unicode data files.
 *
 *  The original data files are available at
 *  http://www.unicode.org/Public/UNIDATA/
 *
 *  Please notice the copyright statement in the file "utf8proc_data.c".
 */


/*
 *  File name:    utf8proc.c
 *
 *  Description:
 *  Implementation of libutf8proc.
 */


/*
 * Copyright (c) 2014-2019 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contributors.
 * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany
 *
 * 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.
 */


/**
 * @mainpage
 *
 * utf8proc is a free/open-source (MIT/expat licensed) C library
 * providing Unicode normalization, case-folding, and other operations
 * for strings in the UTF-8 encoding, supporting up-to-date Unicode versions.
 * See the utf8proc home page (http://julialang.org/utf8proc/)
 * for downloads and other information, or the source code on github
 * (https://github.com/JuliaLang/utf8proc).
 *
 * For the utf8proc API documentation, see: @ref utf8proc.h
 *
 * The features of utf8proc include:
 *
 * - Transformation of strings (@ref utf8proc_map) to:
 *    - decompose (@ref UTF8PROC_DECOMPOSE) or compose (@ref UTF8PROC_COMPOSE) Unicode combining characters (http://en.wikipedia.org/wiki/Combining_character)
 *    - canonicalize Unicode compatibility characters (@ref UTF8PROC_COMPAT)
 *    - strip "ignorable" (@ref UTF8PROC_IGNORE) characters, control characters (@ref UTF8PROC_STRIPCC), or combining characters such as accents (@ref UTF8PROC_STRIPMARK)
 *    - case-folding (@ref UTF8PROC_CASEFOLD)
 * - Unicode normalization: @ref utf8proc_NFD, @ref utf8proc_NFC, @ref utf8proc_NFKD, @ref utf8proc_NFKC
 * - Detecting grapheme boundaries (@ref utf8proc_grapheme_break and @ref UTF8PROC_CHARBOUND)
 * - Character-width computation: @ref utf8proc_charwidth
 * - Classification of characters by Unicode category: @ref utf8proc_category and @ref utf8proc_category_string
 * - Encode (@ref utf8proc_encode_char) and decode (@ref utf8proc_iterate) Unicode codepoints to/from UTF-8.
 */

/** @file */

#ifndef UTF8PROC_H
#define UTF8PROC_H

// DuckDB change:
#define UTF8PROC_STATIC

/** @name API version
 *
 * The utf8proc API version MAJOR.MINOR.PATCH, following
 * semantic-versioning rules (http://semver.org) based on API
 * compatibility.
 *
 * This is also returned at runtime by @ref utf8proc_version; however, the
 * runtime version may append a string like "-dev" to the version number
 * for prerelease versions.
 *
 * @note The shared-library version number in the Makefile
 *       (and CMakeLists.txt, and MANIFEST) may be different,
 *       being based on ABI compatibility rather than API compatibility.
 */
/** @{ */
/** The MAJOR version number (increased when backwards API compatibility is broken). */
#define UTF8PROC_VERSION_MAJOR 2
/** The MINOR version number (increased when new functionality is added in a backwards-compatible manner). */
#define UTF8PROC_VERSION_MINOR 4
/** The PATCH version (increased for fixes that do not change the API). */
#define UTF8PROC_VERSION_PATCH 0
/** @} */

#include <stdlib.h>

#if defined(_MSC_VER) && _MSC_VER < 1800
// MSVC prior to 2013 lacked stdbool.h and inttypes.h
typedef signed char utf8proc_int8_t;
typedef unsigned char utf8proc_uint8_t;
typedef short utf8proc_int16_t;
typedef unsigned short utf8proc_uint16_t;
typedef int utf8proc_int32_t;
typedef unsigned int utf8proc_uint32_t;
#  ifdef _WIN64
typedef __int64 utf8proc_ssize_t;
typedef unsigned __int64 utf8proc_size_t;
#  else
typedef int utf8proc_ssize_t;
typedef unsigned int utf8proc_size_t;
#  endif
#  ifndef __cplusplus
// emulate C99 bool
typedef unsigned char utf8proc_bool;
#    ifndef __bool_true_false_are_defined
#      define false 0
#      define true 1
#      define __bool_true_false_are_defined 1
#    endif
#  else
typedef bool utf8proc_bool;
#  endif
#else
#  include <stddef.h>
#  include <stdbool.h>
#  include <inttypes.h>
typedef int8_t utf8proc_int8_t;
typedef uint8_t utf8proc_uint8_t;
typedef int16_t utf8proc_int16_t;
typedef uint16_t utf8proc_uint16_t;
typedef int32_t utf8proc_int32_t;
typedef uint32_t utf8proc_uint32_t;
typedef size_t utf8proc_size_t;
typedef ptrdiff_t utf8proc_ssize_t;
typedef bool utf8proc_bool;
#endif
#include <limits.h>

#ifdef UTF8PROC_STATIC
#  define UTF8PROC_DLLEXPORT
#else
#  ifdef _WIN32
#    ifdef UTF8PROC_EXPORTS
#      define UTF8PROC_DLLEXPORT __declspec(dllexport)
#    else
#      define UTF8PROC_DLLEXPORT __declspec(dllimport)
#    endif
#  elif __GNUC__ >= 4
#    define UTF8PROC_DLLEXPORT __attribute__ ((visibility("default")))
#  else
#    define UTF8PROC_DLLEXPORT
#  endif
#endif

//#ifdef __cplusplus
//extern "C" {
//#endif

/**
 * Option flags used by several functions in the library.
 */
typedef enum {
  /** The given UTF-8 input is NULL terminated. */
  UTF8PROC_NULLTERM  = (1<<0),
  /** Unicode Versioning Stability has to be respected. */
  UTF8PROC_STABLE    = (1<<1),
  /** Compatibility decomposition (i.e. formatting information is lost). */
  UTF8PROC_COMPAT    = (1<<2),
  /** Return a result with decomposed characters. */
  UTF8PROC_COMPOSE   = (1<<3),
  /** Return a result with decomposed characters. */
  UTF8PROC_DECOMPOSE = (1<<4),
  /** Strip "default ignorable characters" such as SOFT-HYPHEN or ZERO-WIDTH-SPACE. */
  UTF8PROC_IGNORE    = (1<<5),
  /** Return an error, if the input contains unassigned codepoints. */
  UTF8PROC_REJECTNA  = (1<<6),
  /**
   * Indicating that NLF-sequences (LF, CRLF, CR, NEL) are representing a
   * line break, and should be converted to the codepoint for line
   * separation (LS).
   */
  UTF8PROC_NLF2LS    = (1<<7),
  /**
   * Indicating that NLF-sequences are representing a paragraph break, and
   * should be converted to the codepoint for paragraph separation
   * (PS).
   */
  UTF8PROC_NLF2PS    = (1<<8),
  /** Indicating that the meaning of NLF-sequences is unknown. */
  UTF8PROC_NLF2LF    = (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS),
  /** Strips and/or convers control characters.
   *
   * NLF-sequences are transformed into space, except if one of the
   * NLF2LS/PS/LF options is given. HorizontalTab (HT) and FormFeed (FF)
   * are treated as a NLF-sequence in this case.  All other control
   * characters are simply removed.
   */
  UTF8PROC_STRIPCC   = (1<<9),
  /**
   * Performs unicode case folding, to be able to do a case-insensitive
   * string comparison.
   */
  UTF8PROC_CASEFOLD  = (1<<10),
  /**
   * Inserts 0xFF bytes at the beginning of each sequence which is
   * representing a single grapheme cluster (see UAX#29).
   */
  UTF8PROC_CHARBOUND = (1<<11),
  /** Lumps certain characters together.
   *
   * E.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-". See lump.md for details.
   *
   * If NLF2LF is set, this includes a transformation of paragraph and
   * line separators to ASCII line-feed (LF).
   */
  UTF8PROC_LUMP      = (1<<12),
  /** Strips all character markings.
   *
   * This includes non-spacing, spacing and enclosing (i.e. accents).
   * @note This option works only with @ref UTF8PROC_COMPOSE or
   *       @ref UTF8PROC_DECOMPOSE
   */
  UTF8PROC_STRIPMARK = (1<<13),
  /**
   * Strip unassigned codepoints.
   */
  UTF8PROC_STRIPNA    = (1<<14),
} utf8proc_option_t;

/** @name Error codes
 * Error codes being returned by almost all functions.
 */
/** @{ */
/** Memory could not be allocated. */
#define UTF8PROC_ERROR_NOMEM -1
/** The given string is too long to be processed. */
#define UTF8PROC_ERROR_OVERFLOW -2
/** The given string is not a legal UTF-8 string. */
#define UTF8PROC_ERROR_INVALIDUTF8 -3
/** The @ref UTF8PROC_REJECTNA flag was set and an unassigned codepoint was found. */
#define UTF8PROC_ERROR_NOTASSIGNED -4
/** Invalid options have been used. */
#define UTF8PROC_ERROR_INVALIDOPTS -5
/** @} */

/* @name Types */

/** Holds the value of a property. */
typedef utf8proc_int16_t utf8proc_propval_t;

/** Struct containing information about a codepoint. */
typedef struct utf8proc_property_struct {
  /**
   * Unicode category.
   * @see utf8proc_category_t.
   */
  utf8proc_propval_t category;
  utf8proc_propval_t combining_class;
  /**
   * Bidirectional class.
   * @see utf8proc_bidi_class_t.
   */
  utf8proc_propval_t bidi_class;
  /**
   * @anchor Decomposition type.
   * @see utf8proc_decomp_type_t.
   */
  utf8proc_propval_t decomp_type;
  utf8proc_uint16_t decomp_seqindex;
  utf8proc_uint16_t casefold_seqindex;
  utf8proc_uint16_t uppercase_seqindex;
  utf8proc_uint16_t lowercase_seqindex;
  utf8proc_uint16_t titlecase_seqindex;
  utf8proc_uint16_t comb_index;
  unsigned bidi_mirrored:1;
  unsigned comp_exclusion:1;
  /**
   * Can this codepoint be ignored?
   *
   * Used by @ref utf8proc_decompose_char when @ref UTF8PROC_IGNORE is
   * passed as an option.
   */
  unsigned ignorable:1;
  unsigned control_boundary:1;
  /** The width of the codepoint. */
  unsigned charwidth:2;
  unsigned pad:2;
  /**
   * Boundclass.
   * @see utf8proc_boundclass_t.
   */
  unsigned boundclass:8;
} utf8proc_property_t;

/** Unicode categories. */
typedef enum {
  UTF8PROC_CATEGORY_CN  = 0, /**< Other, not assigned */
  UTF8PROC_CATEGORY_LU  = 1, /**< Letter, uppercase */
  UTF8PROC_CATEGORY_LL  = 2, /**< Letter, lowercase */
  UTF8PROC_CATEGORY_LT  = 3, /**< Letter, titlecase */
  UTF8PROC_CATEGORY_LM  = 4, /**< Letter, modifier */
  UTF8PROC_CATEGORY_LO  = 5, /**< Letter, other */
  UTF8PROC_CATEGORY_MN  = 6, /**< Mark, nonspacing */
  UTF8PROC_CATEGORY_MC  = 7, /**< Mark, spacing combining */
  UTF8PROC_CATEGORY_ME  = 8, /**< Mark, enclosing */
  UTF8PROC_CATEGORY_ND  = 9, /**< Number, decimal digit */
  UTF8PROC_CATEGORY_NL = 10, /**< Number, letter */
  UTF8PROC_CATEGORY_NO = 11, /**< Number, other */
  UTF8PROC_CATEGORY_PC = 12, /**< Punctuation, connector */
  UTF8PROC_CATEGORY_PD = 13, /**< Punctuation, dash */
  UTF8PROC_CATEGORY_PS = 14, /**< Punctuation, open */
  UTF8PROC_CATEGORY_PE = 15, /**< Punctuation, close */
  UTF8PROC_CATEGORY_PI = 16, /**< Punctuation, initial quote */
  UTF8PROC_CATEGORY_PF = 17, /**< Punctuation, final quote */
  UTF8PROC_CATEGORY_PO = 18, /**< Punctuation, other */
  UTF8PROC_CATEGORY_SM = 19, /**< Symbol, math */
  UTF8PROC_CATEGORY_SC = 20, /**< Symbol, currency */
  UTF8PROC_CATEGORY_SK = 21, /**< Symbol, modifier */
  UTF8PROC_CATEGORY_SO = 22, /**< Symbol, other */
  UTF8PROC_CATEGORY_ZS = 23, /**< Separator, space */
  UTF8PROC_CATEGORY_ZL = 24, /**< Separator, line */
  UTF8PROC_CATEGORY_ZP = 25, /**< Separator, paragraph */
  UTF8PROC_CATEGORY_CC = 26, /**< Other, control */
  UTF8PROC_CATEGORY_CF = 27, /**< Other, format */
  UTF8PROC_CATEGORY_CS = 28, /**< Other, surrogate */
  UTF8PROC_CATEGORY_CO = 29, /**< Other, private use */
} utf8proc_category_t;

/** Bidirectional character classes. */
typedef enum {
  UTF8PROC_BIDI_CLASS_L     = 1, /**< Left-to-Right */
  UTF8PROC_BIDI_CLASS_LRE   = 2, /**< Left-to-Right Embedding */
  UTF8PROC_BIDI_CLASS_LRO   = 3, /**< Left-to-Right Override */
  UTF8PROC_BIDI_CLASS_R     = 4, /**< Right-to-Left */
  UTF8PROC_BIDI_CLASS_AL    = 5, /**< Right-to-Left Arabic */
  UTF8PROC_BIDI_CLASS_RLE   = 6, /**< Right-to-Left Embedding */
  UTF8PROC_BIDI_CLASS_RLO   = 7, /**< Right-to-Left Override */
  UTF8PROC_BIDI_CLASS_PDF   = 8, /**< Pop Directional Format */
  UTF8PROC_BIDI_CLASS_EN    = 9, /**< European Number */
  UTF8PROC_BIDI_CLASS_ES   = 10, /**< European Separator */
  UTF8PROC_BIDI_CLASS_ET   = 11, /**< European Number Terminator */
  UTF8PROC_BIDI_CLASS_AN   = 12, /**< Arabic Number */
  UTF8PROC_BIDI_CLASS_CS   = 13, /**< Common Number Separator */
  UTF8PROC_BIDI_CLASS_NSM  = 14, /**< Nonspacing Mark */
  UTF8PROC_BIDI_CLASS_BN   = 15, /**< Boundary Neutral */
  UTF8PROC_BIDI_CLASS_B    = 16, /**< Paragraph Separator */
  UTF8PROC_BIDI_CLASS_S    = 17, /**< Segment Separator */
  UTF8PROC_BIDI_CLASS_WS   = 18, /**< Whitespace */
  UTF8PROC_BIDI_CLASS_ON   = 19, /**< Other Neutrals */
  UTF8PROC_BIDI_CLASS_LRI  = 20, /**< Left-to-Right Isolate */
  UTF8PROC_BIDI_CLASS_RLI  = 21, /**< Right-to-Left Isolate */
  UTF8PROC_BIDI_CLASS_FSI  = 22, /**< First Strong Isolate */
  UTF8PROC_BIDI_CLASS_PDI  = 23, /**< Pop Directional Isolate */
} utf8proc_bidi_class_t;

/** Decomposition type. */
typedef enum {
  UTF8PROC_DECOMP_TYPE_FONT      = 1, /**< Font */
  UTF8PROC_DECOMP_TYPE_NOBREAK   = 2, /**< Nobreak */
  UTF8PROC_DECOMP_TYPE_INITIAL   = 3, /**< Initial */
  UTF8PROC_DECOMP_TYPE_MEDIAL    = 4, /**< Medial */
  UTF8PROC_DECOMP_TYPE_FINAL     = 5, /**< Final */
  UTF8PROC_DECOMP_TYPE_ISOLATED  = 6, /**< Isolated */
  UTF8PROC_DECOMP_TYPE_CIRCLE    = 7, /**< Circle */
  UTF8PROC_DECOMP_TYPE_SUPER     = 8, /**< Super */
  UTF8PROC_DECOMP_TYPE_SUB       = 9, /**< Sub */
  UTF8PROC_DECOMP_TYPE_VERTICAL = 10, /**< Vertical */
  UTF8PROC_DECOMP_TYPE_WIDE     = 11, /**< Wide */
  UTF8PROC_DECOMP_TYPE_NARROW   = 12, /**< Narrow */
  UTF8PROC_DECOMP_TYPE_SMALL    = 13, /**< Small */
  UTF8PROC_DECOMP_TYPE_SQUARE   = 14, /**< Square */
  UTF8PROC_DECOMP_TYPE_FRACTION = 15, /**< Fraction */
  UTF8PROC_DECOMP_TYPE_COMPAT   = 16, /**< Compat */
} utf8proc_decomp_type_t;

/** Boundclass property. (TR29) */
typedef enum {
  UTF8PROC_BOUNDCLASS_START              =  0, /**< Start */
  UTF8PROC_BOUNDCLASS_OTHER              =  1, /**< Other */
  UTF8PROC_BOUNDCLASS_CR                 =  2, /**< Cr */
  UTF8PROC_BOUNDCLASS_LF                 =  3, /**< Lf */
  UTF8PROC_BOUNDCLASS_CONTROL            =  4, /**< Control */
  UTF8PROC_BOUNDCLASS_EXTEND             =  5, /**< Extend */
  UTF8PROC_BOUNDCLASS_L                  =  6, /**< L */
  UTF8PROC_BOUNDCLASS_V                  =  7, /**< V */
  UTF8PROC_BOUNDCLASS_T                  =  8, /**< T */
  UTF8PROC_BOUNDCLASS_LV                 =  9, /**< Lv */
  UTF8PROC_BOUNDCLASS_LVT                = 10, /**< Lvt */
  UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR = 11, /**< Regional indicator */
  UTF8PROC_BOUNDCLASS_SPACINGMARK        = 12, /**< Spacingmark */
  UTF8PROC_BOUNDCLASS_PREPEND            = 13, /**< Prepend */
  UTF8PROC_BOUNDCLASS_ZWJ                = 14, /**< Zero Width Joiner */

  /* the following are no longer used in Unicode 11, but we keep
     the constants here for backward compatibility */
  UTF8PROC_BOUNDCLASS_E_BASE             = 15, /**< Emoji Base */
  UTF8PROC_BOUNDCLASS_E_MODIFIER         = 16, /**< Emoji Modifier */
  UTF8PROC_BOUNDCLASS_GLUE_AFTER_ZWJ     = 17, /**< Glue_After_ZWJ */
  UTF8PROC_BOUNDCLASS_E_BASE_GAZ         = 18, /**< E_BASE + GLUE_AFTER_ZJW */

  /* the Extended_Pictographic property is used in the Unicode 11
     grapheme-boundary rules, so we store it in the boundclass field */
  UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC = 19,
  UTF8PROC_BOUNDCLASS_E_ZWG = 20, /* UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC + ZWJ */
} utf8proc_boundclass_t;

/**
 * Function pointer type passed to @ref utf8proc_map_custom and
 * @ref utf8proc_decompose_custom, which is used to specify a user-defined
 * mapping of codepoints to be applied in conjunction with other mappings.
 */
typedef utf8proc_int32_t (*utf8proc_custom_func)(utf8proc_int32_t codepoint, void *data);

/**
 * Array containing the byte lengths of a UTF-8 encoded codepoint based
 * on the first byte.
 */
UTF8PROC_DLLEXPORT extern const utf8proc_int8_t utf8proc_utf8class[256];

/**
 * Returns the utf8proc API version as a string MAJOR.MINOR.PATCH
 * (http://semver.org format), possibly with a "-dev" suffix for
 * development versions.
 */
UTF8PROC_DLLEXPORT const char *utf8proc_version(void);

/**
 * Returns the utf8proc supported Unicode version as a string MAJOR.MINOR.PATCH.
 */
UTF8PROC_DLLEXPORT const char *utf8proc_unicode_version(void);

/**
 * Returns an informative error string for the given utf8proc error code
 * (e.g. the error codes returned by @ref utf8proc_map).
 */
UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode);

/**
 * Reads a single codepoint from the UTF-8 sequence being pointed to by `str`.
 * The maximum number of bytes read is `strlen`, unless `strlen` is
 * negative (in which case up to 4 bytes are read).
 *
 * If a valid codepoint could be read, it is stored in the variable
 * pointed to by `codepoint_ref`, otherwise that variable will be set to -1.
 * In case of success, the number of bytes read is returned; otherwise, a
 * negative error code is returned.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_int32_t *codepoint_ref);

/**
 * Check if a codepoint is valid (regardless of whether it has been
 * assigned a value by the current Unicode standard).
 *
 * @return 1 if the given `codepoint` is valid and otherwise return 0.
 */
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t codepoint);

/**
 * Encodes the codepoint as an UTF-8 string in the byte array pointed
 * to by `dst`. This array must be at least 4 bytes long.
 *
 * In case of success the number of bytes written is returned, and
 * otherwise 0 is returned.
 *
 * This function does not check whether `codepoint` is valid Unicode.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t codepoint, utf8proc_uint8_t *dst);

/**
 * Look up the properties for a given codepoint.
 *
 * @param codepoint The Unicode codepoint.
 *
 * @returns
 * A pointer to a (constant) struct containing information about
 * the codepoint.
 * @par
 * If the codepoint is unassigned or invalid, a pointer to a special struct is
 * returned in which `category` is 0 (@ref UTF8PROC_CATEGORY_CN).
 */
UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8proc_int32_t codepoint);

/** Decompose a codepoint into an array of codepoints.
 *
 * @param codepoint the codepoint.
 * @param dst the destination buffer.
 * @param bufsize the size of the destination buffer.
 * @param options one or more of the following flags:
 * - @ref UTF8PROC_REJECTNA  - return an error `codepoint` is unassigned
 * - @ref UTF8PROC_IGNORE    - strip "default ignorable" codepoints
 * - @ref UTF8PROC_CASEFOLD  - apply Unicode casefolding
 * - @ref UTF8PROC_COMPAT    - replace certain codepoints with their
 *                             compatibility decomposition
 * - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster
 * - @ref UTF8PROC_LUMP      - lump certain different codepoints together
 * - @ref UTF8PROC_STRIPMARK - remove all character marks
 * - @ref UTF8PROC_STRIPNA   - remove unassigned codepoints
 * @param last_boundclass
 * Pointer to an integer variable containing
 * the previous codepoint's boundary class if the @ref UTF8PROC_CHARBOUND
 * option is used.  Otherwise, this parameter is ignored.
 *
 * @return
 * In case of success, the number of codepoints written is returned; in case
 * of an error, a negative error code is returned (@ref utf8proc_errmsg).
 * @par
 * If the number of written codepoints would be bigger than `bufsize`, the
 * required buffer size is returned, while the buffer will be overwritten with
 * undefined data.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(
  utf8proc_int32_t codepoint, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize,
  utf8proc_option_t options, int *last_boundclass
);

/**
 * The same as @ref utf8proc_decompose_char, but acts on a whole UTF-8
 * string and orders the decomposed sequences correctly.
 *
 * If the @ref UTF8PROC_NULLTERM flag in `options` is set, processing
 * will be stopped, when a NULL byte is encounted, otherwise `strlen`
 * bytes are processed.  The result (in the form of 32-bit unicode
 * codepoints) is written into the buffer being pointed to by
 * `buffer` (which must contain at least `bufsize` entries).  In case of
 * success, the number of codepoints written is returned; in case of an
 * error, a negative error code is returned (@ref utf8proc_errmsg).
 * See @ref utf8proc_decompose_custom to supply additional transformations.
 *
 * If the number of written codepoints would be bigger than `bufsize`, the
 * required buffer size is returned, while the buffer will be overwritten with
 * undefined data.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
  utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options
);

/**
 * The same as @ref utf8proc_decompose, but also takes a `custom_func` mapping function
 * that is called on each codepoint in `str` before any other transformations
 * (along with a `custom_data` pointer that is passed through to `custom_func`).
 * The `custom_func` argument is ignored if it is `NULL`.  See also @ref utf8proc_map_custom.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
  utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options,
  utf8proc_custom_func custom_func, void *custom_data
);

/**
 * Normalizes the sequence of `length` codepoints pointed to by `buffer`
 * in-place (i.e., the result is also stored in `buffer`).
 *
 * @param buffer the (native-endian UTF-32) unicode codepoints to re-encode.
 * @param length the length (in codepoints) of the buffer.
 * @param options a bitwise or (`|`) of one or more of the following flags:
 * - @ref UTF8PROC_NLF2LS  - convert LF, CRLF, CR and NEL into LS
 * - @ref UTF8PROC_NLF2PS  - convert LF, CRLF, CR and NEL into PS
 * - @ref UTF8PROC_NLF2LF  - convert LF, CRLF, CR and NEL into LF
 * - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control characters
 * - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite
 *                           codepoints
 * - @ref UTF8PROC_STABLE  - prohibit combining characters that would violate
 *                           the unicode versioning stability
 *
 * @return
 * In case of success, the length (in codepoints) of the normalized UTF-32 string is
 * returned; otherwise, a negative error code is returned (@ref utf8proc_errmsg).
 *
 * @warning The entries of the array pointed to by `str` have to be in the
 *          range `0x0000` to `0x10FFFF`. Otherwise, the program might crash!
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options);

/**
 * Reencodes the sequence of `length` codepoints pointed to by `buffer`
 * UTF-8 data in-place (i.e., the result is also stored in `buffer`).
 * Can optionally normalize the UTF-32 sequence prior to UTF-8 conversion.
 *
 * @param buffer the (native-endian UTF-32) unicode codepoints to re-encode.
 * @param length the length (in codepoints) of the buffer.
 * @param options a bitwise or (`|`) of one or more of the following flags:
 * - @ref UTF8PROC_NLF2LS  - convert LF, CRLF, CR and NEL into LS
 * - @ref UTF8PROC_NLF2PS  - convert LF, CRLF, CR and NEL into PS
 * - @ref UTF8PROC_NLF2LF  - convert LF, CRLF, CR and NEL into LF
 * - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control characters
 * - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite
 *                           codepoints
 * - @ref UTF8PROC_STABLE  - prohibit combining characters that would violate
 *                           the unicode versioning stability
 * - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster
 *
 * @return
 * In case of success, the length (in bytes) of the resulting nul-terminated
 * UTF-8 string is returned; otherwise, a negative error code is returned
 * (@ref utf8proc_errmsg).
 *
 * @warning The amount of free space pointed to by `buffer` must
 *          exceed the amount of the input data by one byte, and the
 *          entries of the array pointed to by `str` have to be in the
 *          range `0x0000` to `0x10FFFF`. Otherwise, the program might crash!
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options);

/**
 * Given a pair of consecutive codepoints, return whether a grapheme break is
 * permitted between them (as defined by the extended grapheme clusters in UAX#29).
 *
 * @param codepoint1 The first codepoint.
 * @param codepoint2 The second codepoint, occurring consecutively after `codepoint1`.
 * @param state Beginning with Version 29 (Unicode 9.0.0), this algorithm requires
 *              state to break graphemes. This state can be passed in as a pointer
 *              in the `state` argument and should initially be set to 0. If the
 *              state is not passed in (i.e. a null pointer is passed), UAX#29 rules
 *              GB10/12/13 which require this state will not be applied, essentially
 *              matching the rules in Unicode 8.0.0.
 *
 * @warning If the state parameter is used, `utf8proc_grapheme_break_stateful` must
 *          be called IN ORDER on ALL potential breaks in a string.  However, it
 *          is safe to reset the state to zero after a grapheme break.
 */
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful(
    utf8proc_int32_t codepoint1, utf8proc_int32_t codepoint2, utf8proc_int32_t *state);

/**
 * Same as @ref utf8proc_grapheme_break_stateful, except without support for the
 * Unicode 9 additions to the algorithm. Supported for legacy reasons.
 */
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break(
    utf8proc_int32_t codepoint1, utf8proc_int32_t codepoint2);


/**
 * Given a codepoint `c`, return the codepoint of the corresponding
 * lower-case character, if any; otherwise (if there is no lower-case
 * variant, or if `c` is not a valid codepoint) return `c`.
 */
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c);

/**
 * Given a codepoint `c`, return the codepoint of the corresponding
 * upper-case character, if any; otherwise (if there is no upper-case
 * variant, or if `c` is not a valid codepoint) return `c`.
 */
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c);

/**
 * Given a codepoint `c`, return the codepoint of the corresponding
 * title-case character, if any; otherwise (if there is no title-case
 * variant, or if `c` is not a valid codepoint) return `c`.
 */
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c);

/**
 * Given a codepoint, return a character width analogous to `wcwidth(codepoint)`,
 * except that a width of 0 is returned for non-printable codepoints
 * instead of -1 as in `wcwidth`.
 *
 * @note
 * If you want to check for particular types of non-printable characters,
 * (analogous to `isprint` or `iscntrl`), use @ref utf8proc_category. */
UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t codepoint);

/**
 * Return the Unicode category for the codepoint (one of the
 * @ref utf8proc_category_t constants.)
 */
UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t codepoint);

/**
 * Return the two-letter (nul-terminated) Unicode category string for
 * the codepoint (e.g. `"Lu"` or `"Co"`).
 */
UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t codepoint);

/**
 * Maps the given UTF-8 string pointed to by `str` to a new UTF-8
 * string, allocated dynamically by `malloc` and returned via `dstptr`.
 *
 * If the @ref UTF8PROC_NULLTERM flag in the `options` field is set,
 * the length is determined by a NULL terminator, otherwise the
 * parameter `strlen` is evaluated to determine the string length, but
 * in any case the result will be NULL terminated (though it might
 * contain NULL characters with the string if `str` contained NULL
 * characters). Other flags in the `options` field are passed to the
 * functions defined above, and regarded as described.  See also
 * @ref utf8proc_map_custom to supply a custom codepoint transformation.
 *
 * In case of success the length of the new string is returned,
 * otherwise a negative error code is returned.
 *
 * @note The memory of the new UTF-8 string will have been allocated
 * with `malloc`, and should therefore be deallocated with `free`.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options
);

/**
 * Like @ref utf8proc_map, but also takes a `custom_func` mapping function
 * that is called on each codepoint in `str` before any other transformations
 * (along with a `custom_data` pointer that is passed through to `custom_func`).
 * The `custom_func` argument is ignored if it is `NULL`.
 */
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options,
  utf8proc_custom_func custom_func, void *custom_data
);

/** @name Unicode normalization
 *
 * Returns a pointer to newly allocated memory of a NFD, NFC, NFKD, NFKC or
 * NFKC_Casefold normalized version of the null-terminated string `str`.  These
 * are shortcuts to calling @ref utf8proc_map with @ref UTF8PROC_NULLTERM
 * combined with @ref UTF8PROC_STABLE and flags indicating the normalization.
 */
/** @{ */
/** NFD normalization (@ref UTF8PROC_DECOMPOSE). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str);
/** NFC normalization (@ref UTF8PROC_COMPOSE). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str);
/** NFKD normalization (@ref UTF8PROC_DECOMPOSE and @ref UTF8PROC_COMPAT). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str);
/** NFKC normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str);
/**
 * NFKC_Casefold normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT
 * and @ref UTF8PROC_CASEFOLD and @ref UTF8PROC_IGNORE).
 **/
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8_t *str);
/** @} */

//#ifdef __cplusplus
//}
//#endif

#endif


#ifndef SSIZE_MAX
#define SSIZE_MAX ((size_t)SIZE_MAX/2)
#endif
#ifndef UINT16_MAX
#  define UINT16_MAX 65535U
#endif

static const utf8proc_uint16_t utf8proc_sequences[] = {
  97, 98, 99, 100, 101, 102, 103, 
  104, 105, 106, 107, 108, 109, 110, 111, 
  112, 113, 114, 115, 116, 117, 118, 119, 
  120, 121, 122, 32, 32, 776, 32, 772, 
  50, 51, 32, 769, 956, 32, 807, 49, 
  49, 8260, 52, 49, 8260, 50, 51, 8260, 
  52, 65, 768, 224, 65, 769, 225, 65, 
  770, 226, 65, 771, 227, 65, 776, 228, 
  65, 778, 229, 230, 67, 807, 231, 69, 
  768, 232, 69, 769, 233, 69, 770, 234, 
  69, 776, 235, 73, 768, 236, 73, 769, 
  237, 73, 770, 238, 73, 776, 239, 240, 
  78, 771, 241, 79, 768, 242, 79, 769, 
  243, 79, 770, 244, 79, 771, 245, 79, 
  776, 246, 248, 85, 768, 249, 85, 769, 
  250, 85, 770, 251, 85, 776, 252, 89, 
  769, 253, 254, 115, 115, 97, 768, 97, 
  769, 97, 770, 97, 771, 97, 776, 97, 
  778, 99, 807, 101, 768, 101, 769, 101, 
  770, 101, 776, 105, 768, 105, 769, 105, 
  770, 105, 776, 110, 771, 111, 768, 111, 
  769, 111, 770, 111, 771, 111, 776, 117, 
  768, 117, 769, 117, 770, 117, 776, 121, 
  769, 121, 776, 65, 772, 257, 97, 772, 
  65, 774, 259, 97, 774, 65, 808, 261, 
  97, 808, 67, 769, 263, 99, 769, 67, 
  770, 265, 99, 770, 67, 775, 267, 99, 
  775, 67, 780, 269, 99, 780, 68, 780, 
  271, 100, 780, 273, 69, 772, 275, 101, 
  772, 69, 774, 277, 101, 774, 69, 775, 
  279, 101, 775, 69, 808, 281, 101, 808, 
  69, 780, 283, 101, 780, 71, 770, 285, 
  103, 770, 71, 774, 287, 103, 774, 71, 
  775, 289, 103, 775, 71, 807, 291, 103, 
  807, 72, 770, 293, 104, 770, 295, 73, 
  771, 297, 105, 771, 73, 772, 299, 105, 
  772, 73, 774, 301, 105, 774, 73, 808, 
  303, 105, 808, 73, 775, 105, 775, 73, 
  74, 307, 105, 106, 74, 770, 309, 106, 
  770, 75, 807, 311, 107, 807, 76, 769, 
  314, 108, 769, 76, 807, 316, 108, 807, 
  76, 780, 318, 108, 780, 76, 183, 320, 
  108, 183, 322, 78, 769, 324, 110, 769, 
  78, 807, 326, 110, 807, 78, 780, 328, 
  110, 780, 700, 110, 331, 79, 772, 333, 
  111, 772, 79, 774, 335, 111, 774, 79, 
  779, 337, 111, 779, 339, 82, 769, 341, 
  114, 769, 82, 807, 343, 114, 807, 82, 
  780, 345, 114, 780, 83, 769, 347, 115, 
  769, 83, 770, 349, 115, 770, 83, 807, 
  351, 115, 807, 83, 780, 353, 115, 780, 
  84, 807, 355, 116, 807, 84, 780, 357, 
  116, 780, 359, 85, 771, 361, 117, 771, 
  85, 772, 363, 117, 772, 85, 774, 365, 
  117, 774, 85, 778, 367, 117, 778, 85, 
  779, 369, 117, 779, 85, 808, 371, 117, 
  808, 87, 770, 373, 119, 770, 89, 770, 
  375, 121, 770, 89, 776, 255, 90, 769, 
  378, 122, 769, 90, 775, 380, 122, 775, 
  90, 780, 382, 122, 780, 595, 387, 389, 
  596, 392, 598, 599, 396, 477, 601, 603, 
  402, 608, 611, 617, 616, 409, 623, 626, 
  629, 79, 795, 417, 111, 795, 419, 421, 
  640, 424, 643, 429, 648, 85, 795, 432, 
  117, 795, 650, 651, 436, 438, 658, 441, 
  445, 68, 381, 454, 68, 382, 100, 382, 
  76, 74, 457, 76, 106, 108, 106, 78, 
  74, 460, 78, 106, 110, 106, 65, 780, 
  462, 97, 780, 73, 780, 464, 105, 780, 
  79, 780, 466, 111, 780, 85, 780, 468, 
  117, 780, 220, 772, 470, 252, 772, 220, 
  769, 472, 252, 769, 220, 780, 474, 252, 
  780, 220, 768, 476, 252, 768, 196, 772, 
  479, 228, 772, 550, 772, 481, 551, 772, 
  198, 772, 483, 230, 772, 485, 71, 780, 
  487, 103, 780, 75, 780, 489, 107, 780, 
  79, 808, 491, 111, 808, 490, 772, 493, 
  491, 772, 439, 780, 495, 658, 780, 106, 
  780, 68, 90, 499, 68, 122, 100, 122, 
  71, 769, 501, 103, 769, 405, 447, 78, 
  768, 505, 110, 768, 197, 769, 507, 229, 
  769, 198, 769, 509, 230, 769, 216, 769, 
  511, 248, 769, 65, 783, 513, 97, 783, 
  65, 785, 515, 97, 785, 69, 783, 517, 
  101, 783, 69, 785, 519, 101, 785, 73, 
  783, 521, 105, 783, 73, 785, 523, 105, 
  785, 79, 783, 525, 111, 783, 79, 785, 
  527, 111, 785, 82, 783, 529, 114, 783, 
  82, 785, 531, 114, 785, 85, 783, 533, 
  117, 783, 85, 785, 535, 117, 785, 83, 
  806, 537, 115, 806, 84, 806, 539, 116, 
  806, 541, 72, 780, 543, 104, 780, 414, 
  547, 549, 65, 775, 551, 97, 775, 69, 
  807, 553, 101, 807, 214, 772, 555, 246, 
  772, 213, 772, 557, 245, 772, 79, 775, 
  559, 111, 775, 558, 772, 561, 559, 772, 
  89, 772, 563, 121, 772, 11365, 572, 410, 
  11366, 578, 384, 649, 652, 583, 585, 587, 
  589, 591, 614, 633, 635, 641, 32, 774, 
  32, 775, 32, 778, 32, 808, 32, 771, 
  32, 779, 661, 768, 769, 787, 776, 769, 
  953, 881, 883, 697, 887, 32, 837, 59, 
  1011, 168, 769, 913, 769, 940, 183, 917, 
  769, 941, 919, 769, 942, 921, 769, 943, 
  927, 769, 972, 933, 769, 973, 937, 769, 
  974, 970, 769, 953, 776, 769, 945, 946, 
  947, 948, 949, 950, 951, 952, 954, 955, 
  957, 958, 959, 960, 961, 963, 964, 965, 
  966, 967, 968, 969, 921, 776, 970, 933, 
  776, 971, 945, 769, 949, 769, 951, 769, 
  953, 769, 971, 769, 965, 776, 769, 953, 
  776, 965, 776, 959, 769, 965, 769, 969, 
  769, 983, 933, 978, 769, 978, 776, 985, 
  987, 989, 991, 993, 995, 997, 999, 1001, 
  1003, 1005, 1007, 962, 920, 1016, 931, 1010, 
  1019, 891, 892, 893, 1045, 768, 1104, 1045, 
  776, 1105, 1106, 1043, 769, 1107, 1108, 1109, 
  1110, 1030, 776, 1111, 1112, 1113, 1114, 1115, 
  1050, 769, 1116, 1048, 768, 1117, 1059, 774, 
  1118, 1119, 1072, 1073, 1074, 1075, 1076, 1077, 
  1078, 1079, 1080, 1048, 774, 1081, 1082, 1083, 
  1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 
  1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 
  1100, 1101, 1102, 1103, 1080, 774, 1077, 768, 
  1077, 776, 1075, 769, 1110, 776, 1082, 769, 
  1080, 768, 1091, 774, 1121, 1123, 1125, 1127, 
  1129, 1131, 1133, 1135, 1137, 1139, 1141, 1140, 
  783, 1143, 1141, 783, 1145, 1147, 1149, 1151, 
  1153, 1163, 1165, 1167, 1169, 1171, 1173, 1175, 
  1177, 1179, 1181, 1183, 1185, 1187, 1189, 1191, 
  1193, 1195, 1197, 1199, 1201, 1203, 1205, 1207, 
  1209, 1211, 1213, 1215, 1231, 1046, 774, 1218, 
  1078, 774, 1220, 1222, 1224, 1226, 1228, 1230, 
  1040, 774, 1233, 1072, 774, 1040, 776, 1235, 
  1072, 776, 1237, 1045, 774, 1239, 1077, 774, 
  1241, 1240, 776, 1243, 1241, 776, 1046, 776, 
  1245, 1078, 776, 1047, 776, 1247, 1079, 776, 
  1249, 1048, 772, 1251, 1080, 772, 1048, 776, 
  1253, 1080, 776, 1054, 776, 1255, 1086, 776, 
  1257, 1256, 776, 1259, 1257, 776, 1069, 776, 
  1261, 1101, 776, 1059, 772, 1263, 1091, 772, 
  1059, 776, 1265, 1091, 776, 1059, 779, 1267, 
  1091, 779, 1063, 776, 1269, 1095, 776, 1271, 
  1067, 776, 1273, 1099, 776, 1275, 1277, 1279, 
  1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, 
  1297, 1299, 1301, 1303, 1305, 1307, 1309, 1311, 
  1313, 1315, 1317, 1319, 1321, 1323, 1325, 1327, 
  1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 
  1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 
  1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 
  1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 
  1409, 1410, 1411, 1412, 1413, 1414, 1381, 1410, 
  1575, 1619, 1575, 1620, 1608, 1620, 1575, 1621, 
  1610, 1620, 1575, 1652, 1608, 1652, 1735, 1652, 
  1610, 1652, 1749, 1620, 1729, 1620, 1746, 1620, 
  2344, 2364, 2352, 2364, 2355, 2364, 2325, 2364, 
  2326, 2364, 2327, 2364, 2332, 2364, 2337, 2364, 
  2338, 2364, 2347, 2364, 2351, 2364, 2503, 2494, 
  2503, 2519, 2465, 2492, 2466, 2492, 2479, 2492, 
  2610, 2620, 2616, 2620, 2582, 2620, 2583, 2620, 
  2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878, 
  2887, 2903, 2849, 2876, 2850, 2876, 2962, 3031, 
  3014, 3006, 3015, 3006, 3014, 3031, 3142, 3158, 
  3263, 3285, 3270, 3285, 3270, 3286, 3270, 3266, 
  3274, 3285, 3398, 3390, 3399, 3390, 3398, 3415, 
  3545, 3530, 3545, 3535, 3548, 3530, 3545, 3551, 
  3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 
  3851, 3906, 4023, 3916, 4023, 3921, 4023, 3926, 
  4023, 3931, 4023, 3904, 4021, 3953, 3954, 3953, 
  3956, 4018, 3968, 4018, 3969, 4019, 3968, 4019, 
  3969, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 
  4023, 4006, 4023, 4011, 4023, 3984, 4021, 4133, 
  4142, 11520, 11521, 11522, 11523, 11524, 11525, 11526, 
  11527, 11528, 11529, 11530, 11531, 11532, 11533, 11534, 
  11535, 11536, 11537, 11538, 11539, 11540, 11541, 11542, 
  11543, 11544, 11545, 11546, 11547, 11548, 11549, 11550, 
  11551, 11552, 11553, 11554, 11555, 11556, 11557, 11559, 
  11565, 4316, 5104, 5105, 5106, 5107, 5108, 5109, 
  6917, 6965, 6919, 6965, 6921, 6965, 6923, 6965, 
  6925, 6965, 6929, 6965, 6970, 6965, 6972, 6965, 
  6974, 6965, 6975, 6965, 6978, 6965, 42571, 4304, 
  4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 
  4313, 4314, 4315, 4317, 4318, 4319, 4320, 4321, 
  4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 
  4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 
  4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 
  4346, 4349, 4350, 4351, 65, 198, 66, 68, 
  69, 398, 71, 72, 73, 74, 75, 76, 
  77, 78, 79, 546, 80, 82, 84, 85, 
  87, 592, 593, 7426, 604, 7446, 7447, 7453, 
  7461, 594, 597, 607, 609, 613, 618, 7547, 
  669, 621, 7557, 671, 625, 624, 627, 628, 
  632, 642, 427, 7452, 656, 657, 65, 805, 
  7681, 97, 805, 66, 775, 7683, 98, 775, 
  66, 803, 7685, 98, 803, 66, 817, 7687, 
  98, 817, 199, 769, 7689, 231, 769, 68, 
  775, 7691, 100, 775, 68, 803, 7693, 100, 
  803, 68, 817, 7695, 100, 817, 68, 807, 
  7697, 100, 807, 68, 813, 7699, 100, 813, 
  274, 768, 7701, 275, 768, 274, 769, 7703, 
  275, 769, 69, 813, 7705, 101, 813, 69, 
  816, 7707, 101, 816, 552, 774, 7709, 553, 
  774, 70, 775, 7711, 102, 775, 71, 772, 
  7713, 103, 772, 72, 775, 7715, 104, 775, 
  72, 803, 7717, 104, 803, 72, 776, 7719, 
  104, 776, 72, 807, 7721, 104, 807, 72, 
  814, 7723, 104, 814, 73, 816, 7725, 105, 
  816, 207, 769, 7727, 239, 769, 75, 769, 
  7729, 107, 769, 75, 803, 7731, 107, 803, 
  75, 817, 7733, 107, 817, 76, 803, 7735, 
  108, 803, 7734, 772, 7737, 7735, 772, 76, 
  817, 7739, 108, 817, 76, 813, 7741, 108, 
  813, 77, 769, 7743, 109, 769, 77, 775, 
  7745, 109, 775, 77, 803, 7747, 109, 803, 
  78, 775, 7749, 110, 775, 78, 803, 7751, 
  110, 803, 78, 817, 7753, 110, 817, 78, 
  813, 7755, 110, 813, 213, 769, 7757, 245, 
  769, 213, 776, 7759, 245, 776, 332, 768, 
  7761, 333, 768, 332, 769, 7763, 333, 769, 
  80, 769, 7765, 112, 769, 80, 775, 7767, 
  112, 775, 82, 775, 7769, 114, 775, 82, 
  803, 7771, 114, 803, 7770, 772, 7773, 7771, 
  772, 82, 817, 7775, 114, 817, 83, 775, 
  7777, 115, 775, 83, 803, 7779, 115, 803, 
  346, 775, 7781, 347, 775, 352, 775, 7783, 
  353, 775, 7778, 775, 7785, 7779, 775, 84, 
  775, 7787, 116, 775, 84, 803, 7789, 116, 
  803, 84, 817, 7791, 116, 817, 84, 813, 
  7793, 116, 813, 85, 804, 7795, 117, 804, 
  85, 816, 7797, 117, 816, 85, 813, 7799, 
  117, 813, 360, 769, 7801, 361, 769, 362, 
  776, 7803, 363, 776, 86, 771, 7805, 118, 
  771, 86, 803, 7807, 118, 803, 87, 768, 
  7809, 119, 768, 87, 769, 7811, 119, 769, 
  87, 776, 7813, 119, 776, 87, 775, 7815, 
  119, 775, 87, 803, 7817, 119, 803, 88, 
  775, 7819, 120, 775, 88, 776, 7821, 120, 
  776, 89, 775, 7823, 121, 775, 90, 770, 
  7825, 122, 770, 90, 803, 7827, 122, 803, 
  90, 817, 7829, 122, 817, 104, 817, 116, 
  776, 119, 778, 121, 778, 97, 702, 383, 
  775, 65, 803, 7841, 97, 803, 65, 777, 
  7843, 97, 777, 194, 769, 7845, 226, 769, 
  194, 768, 7847, 226, 768, 194, 777, 7849, 
  226, 777, 194, 771, 7851, 226, 771, 7840, 
  770, 7853, 7841, 770, 258, 769, 7855, 259, 
  769, 258, 768, 7857, 259, 768, 258, 777, 
  7859, 259, 777, 258, 771, 7861, 259, 771, 
  7840, 774, 7863, 7841, 774, 69, 803, 7865, 
  101, 803, 69, 777, 7867, 101, 777, 69, 
  771, 7869, 101, 771, 202, 769, 7871, 234, 
  769, 202, 768, 7873, 234, 768, 202, 777, 
  7875, 234, 777, 202, 771, 7877, 234, 771, 
  7864, 770, 7879, 7865, 770, 73, 777, 7881, 
  105, 777, 73, 803, 7883, 105, 803, 79, 
  803, 7885, 111, 803, 79, 777, 7887, 111, 
  777, 212, 769, 7889, 244, 769, 212, 768, 
  7891, 244, 768, 212, 777, 7893, 244, 777, 
  212, 771, 7895, 244, 771, 7884, 770, 7897, 
  7885, 770, 416, 769, 7899, 417, 769, 416, 
  768, 7901, 417, 768, 416, 777, 7903, 417, 
  777, 416, 771, 7905, 417, 771, 416, 803, 
  7907, 417, 803, 85, 803, 7909, 117, 803, 
  85, 777, 7911, 117, 777, 431, 769, 7913, 
  432, 769, 431, 768, 7915, 432, 768, 431, 
  777, 7917, 432, 777, 431, 771, 7919, 432, 
  771, 431, 803, 7921, 432, 803, 89, 768, 
  7923, 121, 768, 89, 803, 7925, 121, 803, 
  89, 777, 7927, 121, 777, 89, 771, 7929, 
  121, 771, 7931, 7933, 7935, 945, 787, 945, 
  788, 7936, 768, 7937, 768, 7936, 769, 7937, 
  769, 7936, 834, 7937, 834, 913, 787, 7936, 
  913, 788, 7937, 7944, 768, 7938, 7945, 768, 
  7939, 7944, 769, 7940, 7945, 769, 7941, 7944, 
  834, 7942, 7945, 834, 7943, 949, 787, 949, 
  788, 7952, 768, 7953, 768, 7952, 769, 7953, 
  769, 917, 787, 7952, 917, 788, 7953, 7960, 
  768, 7954, 7961, 768, 7955, 7960, 769, 7956, 
  7961, 769, 7957, 951, 787, 951, 788, 7968, 
  768, 7969, 768, 7968, 769, 7969, 769, 7968, 
  834, 7969, 834, 919, 787, 7968, 919, 788, 
  7969, 7976, 768, 7970, 7977, 768, 7971, 7976, 
  769, 7972, 7977, 769, 7973, 7976, 834, 7974, 
  7977, 834, 7975, 953, 787, 953, 788, 7984, 
  768, 7985, 768, 7984, 769, 7985, 769, 7984, 
  834, 7985, 834, 921, 787, 7984, 921, 788, 
  7985, 7992, 768, 7986, 7993, 768, 7987, 7992, 
  769, 7988, 7993, 769, 7989, 7992, 834, 7990, 
  7993, 834, 7991, 959, 787, 959, 788, 8000, 
  768, 8001, 768, 8000, 769, 8001, 769, 927, 
  787, 8000, 927, 788, 8001, 8008, 768, 8002, 
  8009, 768, 8003, 8008, 769, 8004, 8009, 769, 
  8005, 965, 787, 965, 788, 8016, 768, 965, 
  787, 768, 8017, 768, 8016, 769, 965, 787, 
  769, 8017, 769, 8016, 834, 965, 787, 834, 
  8017, 834, 933, 788, 8017, 8025, 768, 8019, 
  8025, 769, 8021, 8025, 834, 8023, 969, 787, 
  969, 788, 8032, 768, 8033, 768, 8032, 769, 
  8033, 769, 8032, 834, 8033, 834, 937, 787, 
  8032, 937, 788, 8033, 8040, 768, 8034, 8041, 
  768, 8035, 8040, 769, 8036, 8041, 769, 8037, 
  8040, 834, 8038, 8041, 834, 8039, 945, 768, 
  949, 768, 951, 768, 953, 768, 959, 768, 
  965, 768, 969, 768, 7936, 837, 7936, 953, 
  7937, 837, 7937, 953, 7938, 837, 7938, 953, 
  7939, 837, 7939, 953, 7940, 837, 7940, 953, 
  7941, 837, 7941, 953, 7942, 837, 7942, 953, 
  7943, 837, 7943, 953, 7944, 837, 7945, 837, 
  7946, 837, 7947, 837, 7948, 837, 7949, 837, 
  7950, 837, 7951, 837, 7968, 837, 7968, 953, 
  7969, 837, 7969, 953, 7970, 837, 7970, 953, 
  7971, 837, 7971, 953, 7972, 837, 7972, 953, 
  7973, 837, 7973, 953, 7974, 837, 7974, 953, 
  7975, 837, 7975, 953, 7976, 837, 7977, 837, 
  7978, 837, 7979, 837, 7980, 837, 7981, 837, 
  7982, 837, 7983, 837, 8032, 837, 8032, 953, 
  8033, 837, 8033, 953, 8034, 837, 8034, 953, 
  8035, 837, 8035, 953, 8036, 837, 8036, 953, 
  8037, 837, 8037, 953, 8038, 837, 8038, 953, 
  8039, 837, 8039, 953, 8040, 837, 8041, 837, 
  8042, 837, 8043, 837, 8044, 837, 8045, 837, 
  8046, 837, 8047, 837, 945, 774, 945, 772, 
  8048, 837, 8048, 953, 945, 837, 945, 953, 
  940, 837, 940, 953, 945, 834, 8118, 837, 
  945, 834, 953, 913, 774, 8112, 913, 772, 
  8113, 913, 768, 8048, 902, 8049, 913, 837, 
  32, 787, 32, 834, 168, 834, 8052, 837, 
  8052, 953, 951, 837, 951, 953, 942, 837, 
  942, 953, 951, 834, 8134, 837, 951, 834, 
  953, 917, 768, 8050, 904, 8051, 919, 768, 
  8052, 905, 8053, 919, 837, 8127, 768, 8127, 
  769, 8127, 834, 953, 774, 953, 772, 970, 
  768, 953, 776, 768, 912, 953, 834, 970, 
  834, 953, 776, 834, 921, 774, 8144, 921, 
  772, 8145, 921, 768, 8054, 906, 8055, 8190, 
  768, 8190, 769, 8190, 834, 965, 774, 965, 
  772, 971, 768, 965, 776, 768, 944, 961, 
  787, 961, 788, 965, 834, 971, 834, 965, 
  776, 834, 933, 774, 8160, 933, 772, 8161, 
  933, 768, 8058, 910, 8059, 929, 788, 8165, 
  168, 768, 901, 96, 8060, 837, 8060, 953, 
  969, 837, 969, 953, 974, 837, 974, 953, 
  969, 834, 8182, 837, 969, 834, 953, 927, 
  768, 8056, 908, 8057, 937, 768, 8060, 911, 
  8061, 937, 837, 180, 32, 788, 8194, 8195, 
  8208, 32, 819, 46, 46, 46, 46, 46, 
  46, 8242, 8242, 8242, 8242, 8242, 8245, 8245, 
  8245, 8245, 8245, 33, 33, 32, 773, 63, 
  63, 63, 33, 33, 63, 8242, 8242, 8242, 
  8242, 48, 52, 53, 54, 55, 56, 57, 
  43, 8722, 61, 40, 41, 82, 115, 97, 
  47, 99, 97, 47, 115, 67, 176, 67, 
  99, 47, 111, 99, 47, 117, 400, 176, 
  70, 78, 111, 81, 83, 77, 84, 69, 
  76, 84, 77, 90, 937, 197, 70, 8526, 
  1488, 1489, 1490, 1491, 70, 65, 88, 915, 
  928, 8721, 49, 8260, 55, 49, 8260, 57, 
  49, 8260, 49, 48, 49, 8260, 51, 50, 
  8260, 51, 49, 8260, 53, 50, 8260, 53, 
  51, 8260, 53, 52, 8260, 53, 49, 8260, 
  54, 53, 8260, 54, 49, 8260, 56, 51, 
  8260, 56, 53, 8260, 56, 55, 8260, 56, 
  49, 8260, 8560, 73, 73, 8561, 73, 73, 
  73, 8562, 73, 86, 8563, 86, 8564, 86, 
  73, 8565, 86, 73, 73, 8566, 86, 73, 
  73, 73, 8567, 73, 88, 8568, 88, 8569, 
  88, 73, 8570, 88, 73, 73, 8571, 8572, 
  8573, 8574, 8575, 105, 105, 105, 105, 105, 
  105, 118, 118, 105, 118, 105, 105, 118, 
  105, 105, 105, 105, 120, 120, 105, 120, 
  105, 105, 8580, 48, 8260, 51, 8592, 824, 
  8594, 824, 8596, 824, 8656, 824, 8660, 824, 
  8658, 824, 8707, 824, 8712, 824, 8715, 824, 
  8739, 824, 8741, 824, 8747, 8747, 8747, 8747, 
  8747, 8750, 8750, 8750, 8750, 8750, 8764, 824, 
  8771, 824, 8773, 824, 8776, 824, 61, 824, 
  8801, 824, 8781, 824, 60, 824, 62, 824, 
  8804, 824, 8805, 824, 8818, 824, 8819, 824, 
  8822, 824, 8823, 824, 8826, 824, 8827, 824, 
  8834, 824, 8835, 824, 8838, 824, 8839, 824, 
  8866, 824, 8872, 824, 8873, 824, 8875, 824, 
  8828, 824, 8829, 824, 8849, 824, 8850, 824, 
  8882, 824, 8883, 824, 8884, 824, 8885, 824, 
  12296, 12297, 49, 48, 49, 49, 49, 50, 
  49, 51, 49, 52, 49, 53, 49, 54, 
  49, 55, 49, 56, 49, 57, 50, 48, 
  40, 49, 41, 40, 50, 41, 40, 51, 
  41, 40, 52, 41, 40, 53, 41, 40, 
  54, 41, 40, 55, 41, 40, 56, 41, 
  40, 57, 41, 40, 49, 48, 41, 40, 
  49, 49, 41, 40, 49, 50, 41, 40, 
  49, 51, 41, 40, 49, 52, 41, 40, 
  49, 53, 41, 40, 49, 54, 41, 40, 
  49, 55, 41, 40, 49, 56, 41, 40, 
  49, 57, 41, 40, 50, 48, 41, 49, 
  46, 50, 46, 51, 46, 52, 46, 53, 
  46, 54, 46, 55, 46, 56, 46, 57, 
  46, 49, 48, 46, 49, 49, 46, 49, 
  50, 46, 49, 51, 46, 49, 52, 46, 
  49, 53, 46, 49, 54, 46, 49, 55, 
  46, 49, 56, 46, 49, 57, 46, 50, 
  48, 46, 40, 97, 41, 40, 98, 41, 
  40, 99, 41, 40, 100, 41, 40, 101, 
  41, 40, 102, 41, 40, 103, 41, 40, 
  104, 41, 40, 105, 41, 40, 106, 41, 
  40, 107, 41, 40, 108, 41, 40, 109, 
  41, 40, 110, 41, 40, 111, 41, 40, 
  112, 41, 40, 113, 41, 40, 114, 41, 
  40, 115, 41, 40, 116, 41, 40, 117, 
  41, 40, 118, 41, 40, 119, 41, 40, 
  120, 41, 40, 121, 41, 40, 122, 41, 
  9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 
  9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 
  9440, 9441, 83, 9442, 9443, 9444, 9445, 9446, 
  9447, 89, 9448, 9449, 8747, 8747, 8747, 8747, 
  58, 58, 61, 61, 61, 61, 61, 61, 
  10973, 824, 11312, 11313, 11314, 11315, 11316, 11317, 
  11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 
  11326, 11327, 11328, 11329, 11330, 11331, 11332, 11333, 
  11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 
  11342, 11343, 11344, 11345, 11346, 11347, 11348, 11349, 
  11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 
  11358, 11361, 619, 7549, 637, 11368, 11370, 11372, 
  11379, 11382, 575, 576, 11393, 11395, 11397, 11399, 
  11401, 11403, 11405, 11407, 11409, 11411, 11413, 11415, 
  11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, 
  11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 
  11449, 11451, 11453, 11455, 11457, 11459, 11461, 11463, 
  11465, 11467, 11469, 11471, 11473, 11475, 11477, 11479, 
  11481, 11483, 11485, 11487, 11489, 11491, 11500, 11502, 
  11507, 11617, 27597, 40863, 19968, 20008, 20022, 20031, 
  20057, 20101, 20108, 20128, 20154, 20799, 20837, 20843, 
  20866, 20886, 20907, 20960, 20981, 20992, 21147, 21241, 
  21269, 21274, 21304, 21313, 21340, 21353, 21378, 21430, 
  21448, 21475, 22231, 22303, 22763, 22786, 22794, 22805, 
  22823, 22899, 23376, 23424, 23544, 23567, 23586, 23608, 
  23662, 23665, 24027, 24037, 24049, 24062, 24178, 24186, 
  24191, 24308, 24318, 24331, 24339, 24400, 24417, 24435, 
  24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007, 
  26020, 26041, 26080, 26085, 26352, 26376, 26408, 27424, 
  27490, 27513, 27571, 27595, 27604, 27611, 27663, 27668, 
  27700, 28779, 29226, 29238, 29243, 29247, 29255, 29273, 
  29275, 29356, 29572, 29577, 29916, 29926, 29976, 29983, 
  29992, 30000, 30091, 30098, 30326, 30333, 30382, 30399, 
  30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 
  31435, 31481, 31859, 31992, 32566, 32593, 32650, 32701, 
  32769, 32780, 32786, 32819, 32895, 32905, 33251, 33258, 
  33267, 33276, 33292, 33307, 33311, 33390, 33394, 33400, 
  34381, 34411, 34880, 34892, 34915, 35198, 35211, 35282, 
  35328, 35895, 35910, 35925, 35960, 35997, 36196, 36208, 
  36275, 36523, 36554, 36763, 36784, 36789, 37009, 37193, 
  37318, 37324, 37329, 38263, 38272, 38428, 38582, 38585, 
  38632, 38737, 38750, 38754, 38761, 38859, 38893, 38899, 
  38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592, 
  39640, 39647, 39717, 39727, 39730, 39740, 39770, 40165, 
  40565, 40575, 40613, 40635, 40643, 40653, 40657, 40697, 
  40701, 40718, 40723, 40736, 40763, 40778, 40786, 40845, 
  40860, 40864, 12306, 21316, 21317, 12363, 12441, 12365, 
  12441, 12367, 12441, 12369, 12441, 12371, 12441, 12373, 
  12441, 12375, 12441, 12377, 12441, 12379, 12441, 12381, 
  12441, 12383, 12441, 12385, 12441, 12388, 12441, 12390, 
  12441, 12392, 12441, 12399, 12441, 12399, 12442, 12402, 
  12441, 12402, 12442, 12405, 12441, 12405, 12442, 12408, 
  12441, 12408, 12442, 12411, 12441, 12411, 12442, 12358, 
  12441, 32, 12441, 32, 12442, 12445, 12441, 12424, 
  12426, 12459, 12441, 12461, 12441, 12463, 12441, 12465, 
  12441, 12467, 12441, 12469, 12441, 12471, 12441, 12473, 
  12441, 12475, 12441, 12477, 12441, 12479, 12441, 12481, 
  12441, 12484, 12441, 12486, 12441, 12488, 12441, 12495, 
  12441, 12495, 12442, 12498, 12441, 12498, 12442, 12501, 
  12441, 12501, 12442, 12504, 12441, 12504, 12442, 12507, 
  12441, 12507, 12442, 12454, 12441, 12527, 12441, 12528, 
  12441, 12529, 12441, 12530, 12441, 12541, 12441, 12467, 
  12488, 4352, 4353, 4522, 4354, 4524, 4525, 4355, 
  4356, 4357, 4528, 4529, 4530, 4531, 4532, 4533, 
  4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 
  4364, 4365, 4366, 4367, 4368, 4369, 4370, 4449, 
  4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 
  4458, 4459, 4460, 4461, 4462, 4463, 4464, 4465, 
  4466, 4467, 4468, 4469, 4448, 4372, 4373, 4551, 
  4552, 4556, 4558, 4563, 4567, 4569, 4380, 4573, 
  4575, 4381, 4382, 4384, 4386, 4387, 4391, 4393, 
  4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 
  4423, 4428, 4593, 4594, 4439, 4440, 4441, 4484, 
  4485, 4488, 4497, 4498, 4500, 4510, 4513, 19977, 
  22235, 19978, 20013, 19979, 30002, 19993, 19969, 22825, 
  22320, 40, 4352, 41, 40, 4354, 41, 40, 
  4355, 41, 40, 4357, 41, 40, 4358, 41, 
  40, 4359, 41, 40, 4361, 41, 40, 4363, 
  41, 40, 4364, 41, 40, 4366, 41, 40, 
  4367, 41, 40, 4368, 41, 40, 4369, 41, 
  40, 4370, 41, 40, 4352, 4449, 41, 40, 
  4354, 4449, 41, 40, 4355, 4449, 41, 40, 
  4357, 4449, 41, 40, 4358, 4449, 41, 40, 
  4359, 4449, 41, 40, 4361, 4449, 41, 40, 
  4363, 4449, 41, 40, 4364, 4449, 41, 40, 
  4366, 4449, 41, 40, 4367, 4449, 41, 40, 
  4368, 4449, 41, 40, 4369, 4449, 41, 40, 
  4370, 4449, 41, 40, 4364, 4462, 41, 40, 
  4363, 4457, 4364, 4453, 4523, 41, 40, 4363, 
  4457, 4370, 4462, 41, 40, 19968, 41, 40, 
  20108, 41, 40, 19977, 41, 40, 22235, 41, 
  40, 20116, 41, 40, 20845, 41, 40, 19971, 
  41, 40, 20843, 41, 40, 20061, 41, 40, 
  21313, 41, 40, 26376, 41, 40, 28779, 41, 
  40, 27700, 41, 40, 26408, 41, 40, 37329, 
  41, 40, 22303, 41, 40, 26085, 41, 40, 
  26666, 41, 40, 26377, 41, 40, 31038, 41, 
  40, 21517, 41, 40, 29305, 41, 40, 36001, 
  41, 40, 31069, 41, 40, 21172, 41, 40, 
  20195, 41, 40, 21628, 41, 40, 23398, 41, 
  40, 30435, 41, 40, 20225, 41, 40, 36039, 
  41, 40, 21332, 41, 40, 31085, 41, 40, 
  20241, 41, 40, 33258, 41, 40, 33267, 41, 
  21839, 24188, 31631, 80, 84, 69, 50, 49, 
  50, 50, 50, 51, 50, 52, 50, 53, 
  50, 54, 50, 55, 50, 56, 50, 57, 
  51, 48, 51, 49, 51, 50, 51, 51, 
  51, 52, 51, 53, 4352, 4449, 4354, 4449, 
  4355, 4449, 4357, 4449, 4358, 4449, 4359, 4449, 
  4361, 4449, 4363, 4449, 4364, 4449, 4366, 4449, 
  4367, 4449, 4368, 4449, 4369, 4449, 4370, 4449, 
  4366, 4449, 4535, 4352, 4457, 4364, 4462, 4363, 
  4468, 4363, 4462, 20116, 20845, 19971, 20061, 26666, 
  26377, 31038, 21517, 29305, 36001, 31069, 21172, 31192, 
  30007, 36969, 20778, 21360, 27880, 38917, 20241, 20889, 
  27491, 24038, 21491, 21307, 23447, 23398, 30435, 20225, 
  36039, 21332, 22812, 51, 54, 51, 55, 51, 
  56, 51, 57, 52, 48, 52, 49, 52, 
  50, 52, 51, 52, 52, 52, 53, 52, 
  54, 52, 55, 52, 56, 52, 57, 53, 
  48, 49, 26376, 50, 26376, 51, 26376, 52, 
  26376, 53, 26376, 54, 26376, 55, 26376, 56, 
  26376, 57, 26376, 49, 48, 26376, 49, 49, 
  26376, 49, 50, 26376, 72, 103, 101, 114, 
  103, 101, 86, 76, 84, 68, 12450, 12452, 
  12454, 12456, 12458, 12459, 12461, 12463, 12465, 12467, 
  12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484, 
  12486, 12488, 12490, 12491, 12492, 12493, 12494, 12495, 
  12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513, 
  12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524, 
  12525, 12527, 12528, 12529, 12530, 20196, 21644, 12450, 
  12497, 12540, 12488, 12450, 12523, 12501, 12449, 12450, 
  12531, 12506, 12450, 12450, 12540, 12523, 12452, 12491, 
  12531, 12464, 12452, 12531, 12481, 12454, 12457, 12531, 
  12456, 12473, 12463, 12540, 12489, 12456, 12540, 12459, 
  12540, 12458, 12531, 12473, 12458, 12540, 12512, 12459, 
  12452, 12522, 12459, 12521, 12483, 12488, 12459, 12525, 
  12522, 12540, 12460, 12525, 12531, 12460, 12531, 12510, 
  12462, 12460, 12462, 12491, 12540, 12461, 12517, 12522, 
  12540, 12462, 12523, 12480, 12540, 12461, 12525, 12461, 
  12525, 12464, 12521, 12512, 12461, 12525, 12513, 12540, 
  12488, 12523, 12461, 12525, 12527, 12483, 12488, 12464, 
  12521, 12512, 12464, 12521, 12512, 12488, 12531, 12463, 
  12523, 12476, 12452, 12525, 12463, 12525, 12540, 12493, 
  12465, 12540, 12473, 12467, 12523, 12490, 12467, 12540, 
  12509, 12469, 12452, 12463, 12523, 12469, 12531, 12481, 
  12540, 12512, 12471, 12522, 12531, 12464, 12475, 12531, 
  12481, 12475, 12531, 12488, 12480, 12540, 12473, 12487, 
  12471, 12489, 12523, 12488, 12531, 12490, 12494, 12494, 
  12483, 12488, 12495, 12452, 12484, 12497, 12540, 12475, 
  12531, 12488, 12497, 12540, 12484, 12496, 12540, 12524, 
  12523, 12500, 12450, 12473, 12488, 12523, 12500, 12463, 
  12523, 12500, 12467, 12499, 12523, 12501, 12449, 12521, 
  12483, 12489, 12501, 12451, 12540, 12488, 12502, 12483, 
  12471, 12455, 12523, 12501, 12521, 12531, 12504, 12463, 
  12479, 12540, 12523, 12506, 12477, 12506, 12491, 12498, 
  12504, 12523, 12484, 12506, 12531, 12473, 12506, 12540, 
  12472, 12505, 12540, 12479, 12509, 12452, 12531, 12488, 
  12508, 12523, 12488, 12507, 12531, 12509, 12531, 12489, 
  12507, 12540, 12523, 12507, 12540, 12531, 12510, 12452, 
  12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 
  12510, 12523, 12463, 12510, 12531, 12471, 12519, 12531, 
  12511, 12463, 12525, 12531, 12511, 12522, 12511, 12522, 
  12496, 12540, 12523, 12513, 12460, 12513, 12460, 12488, 
  12531, 12513, 12540, 12488, 12523, 12516, 12540, 12489, 
  12516, 12540, 12523, 12518, 12450, 12531, 12522, 12483, 
  12488, 12523, 12522, 12521, 12523, 12500, 12540, 12523, 
  12540, 12502, 12523, 12524, 12512, 12524, 12531, 12488, 
  12466, 12531, 12527, 12483, 12488, 48, 28857, 49, 
  28857, 50, 28857, 51, 28857, 52, 28857, 53, 
  28857, 54, 28857, 55, 28857, 56, 28857, 57, 
  28857, 49, 48, 28857, 49, 49, 28857, 49, 
  50, 28857, 49, 51, 28857, 49, 52, 28857, 
  49, 53, 28857, 49, 54, 28857, 49, 55, 
  28857, 49, 56, 28857, 49, 57, 28857, 50, 
  48, 28857, 50, 49, 28857, 50, 50, 28857, 
  50, 51, 28857, 50, 52, 28857, 104, 80, 
  97, 100, 97, 65, 85, 98, 97, 114, 
  111, 86, 112, 99, 100, 109, 100, 109, 
  178, 100, 109, 179, 73, 85, 24179, 25104, 
  26157, 21644, 22823, 27491, 26126, 27835, 26666, 24335, 
  20250, 31038, 112, 65, 110, 65, 956, 65, 
  109, 65, 107, 65, 75, 66, 77, 66, 
  71, 66, 99, 97, 108, 107, 99, 97, 
  108, 112, 70, 110, 70, 956, 70, 956, 
  103, 109, 103, 107, 103, 72, 122, 107, 
  72, 122, 77, 72, 122, 71, 72, 122, 
  84, 72, 122, 956, 8467, 109, 8467, 100, 
  8467, 107, 8467, 102, 109, 110, 109, 956, 
  109, 109, 109, 99, 109, 107, 109, 109, 
  109, 178, 99, 109, 178, 109, 178, 107, 
  109, 178, 109, 109, 179, 99, 109, 179, 
  109, 179, 107, 109, 179, 109, 8725, 115, 
  109, 8725, 115, 178, 80, 97, 107, 80, 
  97, 77, 80, 97, 71, 80, 97, 114, 
  97, 100, 114, 97, 100, 8725, 115, 114, 
  97, 100, 8725, 115, 178, 112, 115, 110, 
  115, 956, 115, 109, 115, 112, 86, 110, 
  86, 956, 86, 109, 86, 107, 86, 77, 
  86, 112, 87, 110, 87, 956, 87, 109, 
  87, 107, 87, 77, 87, 107, 937, 77, 
  937, 97, 46, 109, 46, 66, 113, 99, 
  99, 99, 100, 67, 8725, 107, 103, 67, 
  111, 46, 100, 66, 71, 121, 104, 97, 
  72, 80, 105, 110, 75, 75, 75, 77, 
  107, 116, 108, 109, 108, 110, 108, 111, 
  103, 108, 120, 109, 98, 109, 105, 108, 
  109, 111, 108, 80, 72, 112, 46, 109, 
  46, 80, 80, 77, 80, 82, 115, 114, 
  83, 118, 87, 98, 86, 8725, 109, 65, 
  8725, 109, 49, 26085, 50, 26085, 51, 26085, 
  52, 26085, 53, 26085, 54, 26085, 55, 26085, 
  56, 26085, 57, 26085, 49, 48, 26085, 49, 
  49, 26085, 49, 50, 26085, 49, 51, 26085, 
  49, 52, 26085, 49, 53, 26085, 49, 54, 
  26085, 49, 55, 26085, 49, 56, 26085, 49, 
  57, 26085, 50, 48, 26085, 50, 49, 26085, 
  50, 50, 26085, 50, 51, 26085, 50, 52, 
  26085, 50, 53, 26085, 50, 54, 26085, 50, 
  55, 26085, 50, 56, 26085, 50, 57, 26085, 
  51, 48, 26085, 51, 49, 26085, 103, 97, 
  108, 42561, 42563, 42565, 42567, 42569, 42573, 42575, 
  42577, 42579, 42581, 42583, 42585, 42587, 42589, 42591, 
  42593, 42595, 42597, 42599, 42601, 42603, 42605, 42625, 
  42627, 42629, 42631, 42633, 42635, 42637, 42639, 42641, 
  42643, 42645, 42647, 42649, 42651, 42787, 42789, 42791, 
  42793, 42795, 42797, 42799, 42803, 42805, 42807, 42809, 
  42811, 42813, 42815, 42817, 42819, 42821, 42823, 42825, 
  42827, 42829, 42831, 42833, 42835, 42837, 42839, 42841, 
  42843, 42845, 42847, 42849, 42851, 42853, 42855, 42857, 
  42859, 42861, 42863, 42874, 42876, 7545, 42879, 42881, 
  42883, 42885, 42887, 42892, 42897, 42899, 42903, 42905, 
  42907, 42909, 42911, 42913, 42915, 42917, 42919, 42921, 
  620, 670, 647, 43859, 42933, 42935, 42937, 42939, 
  42941, 42943, 42947, 42900, 7566, 294, 43831, 43858, 
  5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 
  5032, 5033, 5034, 5035, 5036, 5037, 5038, 5039, 
  5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, 
  5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055, 
  5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, 
  5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, 
  5072, 5073, 5074, 5075, 5076, 5077, 5078, 5079, 
  5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, 
  5088, 5089, 5090, 5091, 5092, 5093, 5094, 5095, 
  5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 
  35912, 26356, 36040, 28369, 20018, 21477, 22865, 21895, 
  22856, 25078, 30313, 32645, 34367, 34746, 35064, 37007, 
  27138, 27931, 28889, 29662, 33853, 37226, 39409, 20098, 
  21365, 27396, 29211, 34349, 40478, 23888, 28651, 34253, 
  35172, 25289, 33240, 34847, 24266, 26391, 28010, 29436, 
  37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 
  34310, 34396, 36335, 38706, 39791, 40442, 30860, 31103, 
  32160, 33737, 37636, 35542, 22751, 24324, 31840, 32894, 
  29282, 30922, 36034, 38647, 22744, 23650, 27155, 28122, 
  28431, 32047, 32311, 38475, 21202, 32907, 20956, 20940, 
  31260, 32190, 33777, 38517, 35712, 25295, 35582, 20025, 
  23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489, 
  19981, 27852, 25976, 32034, 21443, 22622, 30465, 33865, 
  35498, 27578, 27784, 25342, 33509, 25504, 30053, 20142, 
  20841, 20937, 26753, 31975, 33391, 35538, 37327, 21237, 
  21570, 24300, 26053, 28670, 31018, 38317, 39530, 40599, 
  40654, 26310, 27511, 36706, 24180, 24976, 25088, 25754, 
  28451, 29001, 29833, 31178, 32244, 32879, 36646, 34030, 
  36899, 37706, 21015, 21155, 21693, 28872, 35010, 24265, 
  24565, 25467, 27566, 31806, 29557, 20196, 22265, 23994, 
  24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 
  38936, 20363, 31150, 37300, 38584, 24801, 20102, 20698, 
  23534, 23615, 26009, 29134, 30274, 34044, 36988, 26248, 
  38446, 21129, 26491, 26611, 27969, 28316, 29705, 30041, 
  30827, 32016, 39006, 25134, 38520, 20523, 23833, 28138, 
  36650, 24459, 24900, 26647, 38534, 21033, 21519, 23653, 
  26131, 26446, 26792, 27877, 29702, 30178, 32633, 35023, 
  35041, 38626, 21311, 28346, 21533, 29136, 29848, 34298, 
  38563, 40023, 40607, 26519, 28107, 33256, 31520, 31890, 
  29376, 28825, 35672, 20160, 33590, 21050, 20999, 24230, 
  25299, 31958, 23429, 27934, 26292, 36667, 38477, 24275, 
  20800, 21952, 22618, 26228, 20958, 29482, 30410, 31036, 
  31070, 31077, 31119, 38742, 31934, 34322, 35576, 36920, 
  37117, 39151, 39164, 39208, 40372, 37086, 38583, 20398, 
  20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120, 
  22592, 22696, 23652, 24724, 24936, 24974, 25074, 25935, 
  26082, 26257, 26757, 28023, 28186, 28450, 29038, 29227, 
  29730, 30865, 31049, 31048, 31056, 31062, 31117, 31118, 
  31296, 31361, 31680, 32265, 32321, 32626, 32773, 33261, 
  33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104, 
  36790, 38627, 38911, 38971, 24693, 55376, 57070, 33304, 
  20006, 20917, 20840, 20352, 20805, 20864, 21191, 21242, 
  21845, 21913, 21986, 22707, 22852, 22868, 23138, 23336, 
  24274, 24281, 24425, 24493, 24792, 24910, 24840, 24928, 
  25140, 25540, 25628, 25682, 25942, 26395, 26454, 28379, 
  28363, 28702, 30631, 29237, 29359, 29809, 29958, 30011, 
  30237, 30239, 30427, 30452, 30538, 30528, 30924, 31409, 
  31867, 32091, 32574, 33618, 33775, 34681, 35137, 35206, 
  35519, 35531, 35565, 35722, 36664, 36978, 37273, 37494, 
  38524, 38875, 38923, 39698, 55370, 56394, 55370, 56388, 
  55372, 57301, 15261, 16408, 16441, 55380, 56905, 55383, 
  56528, 55391, 57043, 40771, 40846, 102, 102, 102, 
  105, 102, 108, 102, 102, 105, 102, 102, 
  108, 383, 116, 115, 116, 1396, 1398, 1396, 
  1381, 1396, 1387, 1406, 1398, 1396, 1389, 1497, 
  1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 
  1512, 1514, 1513, 1473, 1513, 1474, 64329, 1473, 
  64329, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 
  1489, 1468, 1490, 1468, 1491, 1468, 1492, 1468, 
  1493, 1468, 1494, 1468, 1496, 1468, 1497, 1468, 
  1498, 1468, 1499, 1468, 1500, 1468, 1502, 1468, 
  1504, 1468, 1505, 1468, 1507, 1468, 1508, 1468, 
  1510, 1468, 1511, 1468, 1512, 1468, 1513, 1468, 
  1514, 1468, 1493, 1465, 1489, 1471, 1499, 1471, 
  1508, 1471, 1488, 1500, 1649, 1659, 1662, 1664, 
  1658, 1663, 1657, 1700, 1702, 1668, 1667, 1670, 
  1671, 1677, 1676, 1678, 1672, 1688, 1681, 1705, 
  1711, 1715, 1713, 1722, 1723, 1728, 1729, 1726, 
  1746, 1747, 1709, 1735, 1734, 1736, 1655, 1739, 
  1733, 1737, 1744, 1609, 1574, 1575, 1574, 1749, 
  1574, 1608, 1574, 1735, 1574, 1734, 1574, 1736, 
  1574, 1744, 1574, 1609, 1740, 1574, 1580, 1574, 
  1581, 1574, 1605, 1574, 1610, 1576, 1580, 1576, 
  1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 
  1610, 1578, 1580, 1578, 1581, 1578, 1582, 1578, 
  1605, 1578, 1609, 1578, 1610, 1579, 1580, 1579, 
  1605, 1579, 1609, 1579, 1610, 1580, 1581, 1580, 
  1605, 1581, 1580, 1581, 1605, 1582, 1580, 1582, 
  1581, 1582, 1605, 1587, 1580, 1587, 1581, 1587, 
  1582, 1587, 1605, 1589, 1581, 1589, 1605, 1590, 
  1580, 1590, 1581, 1590, 1582, 1590, 1605, 1591, 
  1581, 1591, 1605, 1592, 1605, 1593, 1580, 1593, 
  1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 
  1581, 1601, 1582, 1601, 1605, 1601, 1609, 1601, 
  1610, 1602, 1581, 1602, 1605, 1602, 1609, 1602, 
  1610, 1603, 1575, 1603, 1580, 1603, 1581, 1603, 
  1582, 1603, 1604, 1603, 1605, 1603, 1609, 1603, 
  1610, 1604, 1580, 1604, 1581, 1604, 1582, 1604, 
  1605, 1604, 1609, 1604, 1610, 1605, 1580, 1605, 
  1581, 1605, 1582, 1605, 1605, 1605, 1609, 1605, 
  1610, 1606, 1580, 1606, 1581, 1606, 1582, 1606, 
  1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 
  1605, 1607, 1609, 1607, 1610, 1610, 1580, 1610, 
  1581, 1610, 1582, 1610, 1605, 1610, 1609, 1610, 
  1610, 1584, 1648, 1585, 1648, 1609, 1648, 32, 
  1612, 1617, 32, 1613, 1617, 32, 1614, 1617, 
  32, 1615, 1617, 32, 1616, 1617, 32, 1617, 
  1648, 1574, 1585, 1574, 1586, 1574, 1606, 1576, 
  1585, 1576, 1586, 1576, 1606, 1578, 1585, 1578, 
  1586, 1578, 1606, 1579, 1585, 1579, 1586, 1579, 
  1606, 1605, 1575, 1606, 1585, 1606, 1586, 1606, 
  1606, 1610, 1585, 1610, 1586, 1610, 1606, 1574, 
  1582, 1574, 1607, 1576, 1607, 1578, 1607, 1589, 
  1582, 1604, 1607, 1606, 1607, 1607, 1648, 1610, 
  1607, 1579, 1607, 1587, 1607, 1588, 1605, 1588, 
  1607, 1600, 1614, 1617, 1600, 1615, 1617, 1600, 
  1616, 1617, 1591, 1609, 1591, 1610, 1593, 1609, 
  1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609, 
  1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609, 
  1581, 1610, 1580, 1609, 1580, 1610, 1582, 1609, 
  1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609, 
  1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582, 
  1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585, 
  1575, 1611, 1578, 1580, 1605, 1578, 1581, 1580, 
  1578, 1581, 1605, 1578, 1582, 1605, 1578, 1605, 
  1580, 1578, 1605, 1581, 1578, 1605, 1582, 1580, 
  1605, 1581, 1581, 1605, 1610, 1581, 1605, 1609, 
  1587, 1581, 1580, 1587, 1580, 1581, 1587, 1580, 
  1609, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 
  1605, 1605, 1589, 1581, 1581, 1589, 1605, 1605, 
  1588, 1581, 1605, 1588, 1580, 1610, 1588, 1605, 
  1582, 1588, 1605, 1605, 1590, 1581, 1609, 1590, 
  1582, 1605, 1591, 1605, 1581, 1591, 1605, 1605, 
  1591, 1605, 1610, 1593, 1580, 1605, 1593, 1605, 
  1605, 1593, 1605, 1609, 1594, 1605, 1605, 1594, 
  1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 
  1602, 1605, 1581, 1602, 1605, 1605, 1604, 1581, 
  1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 
  1580, 1580, 1604, 1582, 1605, 1604, 1605, 1581, 
  1605, 1581, 1580, 1605, 1581, 1605, 1605, 1581, 
  1610, 1605, 1580, 1581, 1605, 1580, 1605, 1605, 
  1582, 1580, 1605, 1582, 1605, 1605, 1580, 1582, 
  1607, 1605, 1580, 1607, 1605, 1605, 1606, 1581, 
  1605, 1606, 1581, 1609, 1606, 1580, 1605, 1606, 
  1580, 1609, 1606, 1605, 1610, 1606, 1605, 1609, 
  1610, 1605, 1605, 1576, 1582, 1610, 1578, 1580, 
  1610, 1578, 1580, 1609, 1578, 1582, 1610, 1578, 
  1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609, 
  1580, 1605, 1610, 1580, 1581, 1609, 1580, 1605, 
  1609, 1587, 1582, 1609, 1589, 1581, 1610, 1588, 
  1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 
  1604, 1605, 1610, 1610, 1581, 1610, 1610, 1580, 
  1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 
  1605, 1610, 1606, 1581, 1610, 1593, 1605, 1610, 
  1603, 1605, 1610, 1606, 1580, 1581, 1605, 1582, 
  1610, 1604, 1580, 1605, 1603, 1605, 1605, 1580, 
  1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 
  1601, 1605, 1610, 1576, 1581, 1610, 1587, 1582, 
  1610, 1606, 1580, 1610, 1589, 1604, 1746, 1602, 
  1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 
  1576, 1585, 1605, 1581, 1605, 1583, 1589, 1604, 
  1593, 1605, 1585, 1587, 1608, 1604, 1593, 1604, 
  1610, 1607, 1608, 1587, 1604, 1605, 1589, 1604, 
  1609, 17, 1589, 1604, 1609, 32, 1575, 1604, 
  1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 
  1608, 1587, 1604, 1605, 7, 1580, 1604, 32, 
  1580, 1604, 1575, 1604, 1607, 1585, 1740, 1575, 
  1604, 44, 12289, 12290, 58, 33, 63, 12310, 
  12311, 8230, 8229, 8212, 8211, 95, 123, 125, 
  12308, 12309, 12304, 12305, 12298, 12299, 12300, 12301, 
  12302, 12303, 91, 93, 8254, 35, 38, 42, 
  45, 60, 62, 92, 36, 37, 64, 32, 
  1611, 1600, 1611, 32, 1612, 32, 1613, 32, 
  1614, 1600, 1614, 32, 1615, 1600, 1615, 32, 
  1616, 1600, 1616, 32, 1617, 1600, 1617, 32, 
  1618, 1600, 1618, 1569, 1570, 1571, 1572, 1573, 
  1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 
  1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 
  1590, 1591, 1592, 1593, 1594, 1601, 1602, 1603, 
  1604, 1605, 1606, 1607, 1608, 1610, 1604, 1570, 
  1604, 1571, 1604, 1573, 1604, 1575, 34, 39, 
  47, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 
  65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 
  65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 
  65368, 65369, 65370, 94, 124, 126, 10629, 10630, 
  12539, 12449, 12451, 12453, 12455, 12457, 12515, 12517, 
  12519, 12483, 12540, 12531, 12441, 12442, 12644, 12593, 
  12594, 12595, 12596, 12597, 12598, 12599, 12600, 12601, 
  12602, 12603, 12604, 12605, 12606, 12607, 12608, 12609, 
  12610, 12611, 12612, 12613, 12614, 12615, 12616, 12617, 
  12618, 12619, 12620, 12621, 12622, 12623, 12624, 12625, 
  12626, 12627, 12628, 12629, 12630, 12631, 12632, 12633, 
  12634, 12635, 12636, 12637, 12638, 12639, 12640, 12641, 
  12642, 12643, 162, 163, 172, 175, 166, 165, 
  8361, 9474, 8592, 8593, 8594, 8595, 9632, 9675, 
  55297, 56360, 55297, 56361, 55297, 56362, 55297, 56363, 
  55297, 56364, 55297, 56365, 55297, 56366, 55297, 56367, 
  55297, 56368, 55297, 56369, 55297, 56370, 55297, 56371, 
  55297, 56372, 55297, 56373, 55297, 56374, 55297, 56375, 
  55297, 56376, 55297, 56377, 55297, 56378, 55297, 56379, 
  55297, 56380, 55297, 56381, 55297, 56382, 55297, 56383, 
  55297, 56384, 55297, 56385, 55297, 56386, 55297, 56387, 
  55297, 56388, 55297, 56389, 55297, 56390, 55297, 56391, 
  55297, 56392, 55297, 56393, 55297, 56394, 55297, 56395, 
  55297, 56396, 55297, 56397, 55297, 56398, 55297, 56399, 
  55297, 56536, 55297, 56537, 55297, 56538, 55297, 56539, 
  55297, 56540, 55297, 56541, 55297, 56542, 55297, 56543, 
  55297, 56544, 55297, 56545, 55297, 56546, 55297, 56547, 
  55297, 56548, 55297, 56549, 55297, 56550, 55297, 56551, 
  55297, 56552, 55297, 56553, 55297, 56554, 55297, 56555, 
  55297, 56556, 55297, 56557, 55297, 56558, 55297, 56559, 
  55297, 56560, 55297, 56561, 55297, 56562, 55297, 56563, 
  55297, 56564, 55297, 56565, 55297, 56566, 55297, 56567, 
  55297, 56568, 55297, 56569, 55297, 56570, 55297, 56571, 
  55299, 56512, 55299, 56513, 55299, 56514, 55299, 56515, 
  55299, 56516, 55299, 56517, 55299, 56518, 55299, 56519, 
  55299, 56520, 55299, 56521, 55299, 56522, 55299, 56523, 
  55299, 56524, 55299, 56525, 55299, 56526, 55299, 56527, 
  55299, 56528, 55299, 56529, 55299, 56530, 55299, 56531, 
  55299, 56532, 55299, 56533, 55299, 56534, 55299, 56535, 
  55299, 56536, 55299, 56537, 55299, 56538, 55299, 56539, 
  55299, 56540, 55299, 56541, 55299, 56542, 55299, 56543, 
  55299, 56544, 55299, 56545, 55299, 56546, 55299, 56547, 
  55299, 56548, 55299, 56549, 55299, 56550, 55299, 56551, 
  55299, 56552, 55299, 56553, 55299, 56554, 55299, 56555, 
  55299, 56556, 55299, 56557, 55299, 56558, 55299, 56559, 
  55299, 56560, 55299, 56561, 55299, 56562, 55300, 56473, 
  55300, 56506, 55300, 56475, 55300, 56506, 55300, 56485, 
  55300, 56506, 55300, 56625, 55300, 56615, 55300, 56626, 
  55300, 56615, 55300, 57159, 55300, 57150, 55300, 57159, 
  55300, 57175, 55301, 56505, 55301, 56506, 55301, 56505, 
  55301, 56496, 55301, 56505, 55301, 56509, 55301, 56760, 
  55301, 56751, 55301, 56761, 55301, 56751, 55302, 56512, 
  55302, 56513, 55302, 56514, 55302, 56515, 55302, 56516, 
  55302, 56517, 55302, 56518, 55302, 56519, 55302, 56520, 
  55302, 56521, 55302, 56522, 55302, 56523, 55302, 56524, 
  55302, 56525, 55302, 56526, 55302, 56527, 55302, 56528, 
  55302, 56529, 55302, 56530, 55302, 56531, 55302, 56532, 
  55302, 56533, 55302, 56534, 55302, 56535, 55302, 56536, 
  55302, 56537, 55302, 56538, 55302, 56539, 55302, 56540, 
  55302, 56541, 55302, 56542, 55302, 56543, 55323, 56928, 
  55323, 56929, 55323, 56930, 55323, 56931, 55323, 56932, 
  55323, 56933, 55323, 56934, 55323, 56935, 55323, 56936, 
  55323, 56937, 55323, 56938, 55323, 56939, 55323, 56940, 
  55323, 56941, 55323, 56942, 55323, 56943, 55323, 56944, 
  55323, 56945, 55323, 56946, 55323, 56947, 55323, 56948, 
  55323, 56949, 55323, 56950, 55323, 56951, 55323, 56952, 
  55323, 56953, 55323, 56954, 55323, 56955, 55323, 56956, 
  55323, 56957, 55323, 56958, 55323, 56959, 55348, 56663, 
  55348, 56677, 55348, 56664, 55348, 56677, 55348, 56671, 
  55348, 56686, 55348, 56671, 55348, 56687, 55348, 56671, 
  55348, 56688, 55348, 56671, 55348, 56689, 55348, 56671, 
  55348, 56690, 55348, 56761, 55348, 56677, 55348, 56762, 
  55348, 56677, 55348, 56763, 55348, 56686, 55348, 56764, 
  55348, 56686, 55348, 56763, 55348, 56687, 55348, 56764, 
  55348, 56687, 305, 567, 913, 914, 916, 917, 
  918, 919, 921, 922, 923, 924, 925, 926, 
  927, 929, 1012, 932, 934, 935, 936, 8711, 
  8706, 1013, 977, 1008, 981, 1009, 982, 988, 
  55354, 56610, 55354, 56611, 55354, 56612, 55354, 56613, 
  55354, 56614, 55354, 56615, 55354, 56616, 55354, 56617, 
  55354, 56618, 55354, 56619, 55354, 56620, 55354, 56621, 
  55354, 56622, 55354, 56623, 55354, 56624, 55354, 56625, 
  55354, 56626, 55354, 56627, 55354, 56628, 55354, 56629, 
  55354, 56630, 55354, 56631, 55354, 56632, 55354, 56633, 
  55354, 56634, 55354, 56635, 55354, 56636, 55354, 56637, 
  55354, 56638, 55354, 56639, 55354, 56640, 55354, 56641, 
  55354, 56642, 55354, 56643, 1646, 1697, 1647, 48, 
  46, 48, 44, 49, 44, 50, 44, 51, 
  44, 52, 44, 53, 44, 54, 44, 55, 
  44, 56, 44, 57, 44, 40, 65, 41, 
  40, 66, 41, 40, 67, 41, 40, 68, 
  41, 40, 69, 41, 40, 70, 41, 40, 
  71, 41, 40, 72, 41, 40, 73, 41, 
  40, 74, 41, 40, 75, 41, 40, 76, 
  41, 40, 77, 41, 40, 78, 41, 40, 
  79, 41, 40, 80, 41, 40, 81, 41, 
  40, 82, 41, 40, 83, 41, 40, 84, 
  41, 40, 85, 41, 40, 86, 41, 40, 
  87, 41, 40, 88, 41, 40, 89, 41, 
  40, 90, 41, 12308, 83, 12309, 67, 68, 
  87, 90, 72, 86, 83, 68, 83, 83, 
  80, 80, 86, 87, 67, 77, 67, 77, 
  68, 77, 82, 68, 74, 12411, 12363, 12467, 
  12467, 23383, 21452, 12487, 22810, 35299, 20132, 26144, 
  28961, 21069, 24460, 20877, 26032, 21021, 32066, 36009, 
  22768, 21561, 28436, 25237, 25429, 36938, 25351, 25171, 
  31105, 31354, 21512, 28288, 30003, 21106, 21942, 37197, 
  12308, 26412, 12309, 12308, 19977, 12309, 12308, 20108, 
  12309, 12308, 23433, 12309, 12308, 28857, 12309, 12308, 
  25171, 12309, 12308, 30423, 12309, 12308, 21213, 12309, 
  12308, 25943, 12309, 24471, 21487, 20029, 20024, 20033, 
  55360, 56610, 20320, 20411, 20482, 20602, 20633, 20687, 
  13470, 55361, 56890, 20820, 20836, 20855, 55361, 56604, 
  13497, 20839, 55361, 56651, 20887, 20900, 20172, 20908, 
  55396, 56799, 20995, 13535, 21051, 21062, 21111, 13589, 
  21253, 21254, 21321, 21338, 21363, 21373, 21375, 55362, 
  56876, 28784, 21450, 21471, 55362, 57187, 21483, 21489, 
  21510, 21662, 21560, 21576, 21608, 21666, 21750, 21776, 
  21843, 21859, 21892, 21931, 21939, 21954, 22294, 22295, 
  22097, 22132, 22766, 22478, 22516, 22541, 22411, 22578, 
  22577, 22700, 55365, 56548, 22770, 22775, 22790, 22818, 
  22882, 55365, 57000, 55365, 57066, 23020, 23067, 23079, 
  23000, 23142, 14062, 14076, 23304, 23358, 55366, 56776, 
  23491, 23512, 23539, 55366, 57112, 23551, 23558, 24403, 
  14209, 23648, 23744, 23693, 55367, 56804, 23875, 55367, 
  56806, 23918, 23915, 23932, 24033, 24034, 14383, 24061, 
  24104, 24125, 24169, 14434, 55368, 56707, 14460, 24240, 
  24243, 24246, 55400, 57234, 55368, 57137, 33281, 24354, 
  14535, 55372, 57016, 55384, 56794, 24418, 24427, 14563, 
  24474, 24525, 24535, 24569, 24705, 14650, 14620, 55369, 
  57044, 24775, 24904, 24908, 24954, 25010, 24996, 25007, 
  25054, 25104, 25115, 25181, 25265, 25300, 25424, 55370, 
  57100, 25405, 25340, 25448, 25475, 25572, 55370, 57329, 
  25634, 25541, 25513, 14894, 25705, 25726, 25757, 25719, 
  14956, 25964, 55372, 56330, 26083, 26360, 26185, 15129, 
  15112, 15076, 20882, 20885, 26368, 26268, 32941, 17369, 
  26401, 26462, 26451, 55372, 57283, 15177, 26618, 26501, 
  26706, 55373, 56429, 26766, 26655, 26900, 26946, 27043, 
  27114, 27304, 55373, 56995, 27355, 15384, 27425, 55374, 
  56487, 27476, 15438, 27506, 27551, 27579, 55374, 56973, 
  55367, 56587, 55374, 57082, 27726, 55375, 56508, 27839, 
  27853, 27751, 27926, 27966, 28009, 28024, 28037, 55375, 
  56606, 27956, 28207, 28270, 15667, 28359, 55375, 57041, 
  28153, 28526, 55375, 57182, 55375, 57230, 28614, 28729, 
  28699, 15766, 28746, 28797, 28791, 28845, 55361, 56613, 
  28997, 55376, 56931, 29084, 55376, 57259, 29224, 29264, 
  55377, 56840, 29312, 29333, 55377, 57141, 55378, 56340, 
  29562, 29579, 16044, 29605, 16056, 29767, 29788, 29829, 
  29898, 16155, 29988, 55379, 56374, 30014, 55379, 56466, 
  55368, 56735, 30224, 55379, 57249, 55379, 57272, 55380, 
  56388, 16380, 16392, 55380, 56563, 55380, 56562, 55380, 
  56601, 55380, 56627, 30494, 30495, 30603, 16454, 16534, 
  55381, 56349, 30798, 16611, 55381, 56870, 55381, 56986, 
  55381, 57029, 31211, 16687, 31306, 31311, 55382, 56700, 
  55382, 56999, 31470, 16898, 55382, 57259, 31686, 31689, 
  16935, 55383, 56448, 31954, 17056, 31976, 31971, 32000, 
  55383, 57222, 32099, 17153, 32199, 32258, 32325, 17204, 
  55384, 56872, 55384, 56903, 17241, 55384, 57049, 32634, 
  55384, 57150, 32661, 32762, 55385, 56538, 55385, 56611, 
  32864, 55385, 56744, 32880, 55372, 57183, 17365, 32946, 
  33027, 17419, 33086, 23221, 55385, 57255, 55385, 57269, 
  55372, 57235, 55372, 57244, 33284, 36766, 17515, 33425, 
  33419, 33437, 21171, 33457, 33459, 33469, 33510, 55386, 
  57148, 33565, 33635, 33709, 33571, 33725, 33767, 33619, 
  33738, 33740, 33756, 55387, 56374, 55387, 56683, 55387, 
  56533, 17707, 34033, 34035, 34070, 55388, 57290, 34148, 
  55387, 57132, 17757, 17761, 55387, 57265, 55388, 56530, 
  17771, 34384, 34407, 34409, 34473, 34440, 34574, 34530, 
  34600, 34667, 34694, 17879, 34785, 34817, 17913, 34912, 
  55389, 56935, 35031, 35038, 17973, 35066, 13499, 55390, 
  56494, 55390, 56678, 18110, 18119, 35488, 55391, 56488, 
  36011, 36033, 36123, 36215, 55391, 57135, 55362, 56324, 
  36299, 36284, 36336, 55362, 56542, 36564, 55393, 56786, 
  55393, 56813, 37012, 37105, 37137, 55393, 57134, 37147, 
  37432, 37591, 37592, 37500, 37881, 37909, 55394, 57338, 
  38283, 18837, 38327, 55395, 56695, 18918, 38595, 23986, 
  38691, 55396, 56645, 55396, 56858, 19054, 19062, 38880, 
  55397, 56330, 19122, 55397, 56470, 38953, 55397, 56758, 
  39138, 19251, 39209, 39335, 39362, 39422, 19406, 55398, 
  57136, 40000, 40189, 19662, 19693, 40295, 55400, 56526, 
  19704, 55400, 56581, 55400, 56846, 55400, 56977, 19798, 
  40702, 40709, 40719, 40726, 55401, 56832, 7838, 192, 
  193, 194, 195, 196, 199, 200, 201, 202, 
  203, 204, 205, 206, 207, 208, 209, 210, 
  211, 212, 213, 214, 216, 217, 218, 219, 
  220, 221, 222, 376, 256, 258, 260, 262, 
  264, 266, 268, 270, 272, 274, 276, 278, 
  280, 282, 284, 286, 288, 290, 292, 296, 
  298, 300, 302, 306, 308, 310, 313, 315, 
  317, 319, 321, 323, 325, 327, 330, 332, 
  334, 336, 338, 340, 342, 344, 346, 348, 
  350, 352, 354, 356, 358, 360, 362, 364, 
  366, 368, 370, 372, 374, 377, 379, 381, 
  579, 386, 388, 391, 395, 401, 502, 408, 
  573, 544, 416, 418, 420, 423, 428, 431, 
  435, 437, 440, 444, 503, 453, 452, 456, 
  455, 459, 458, 461, 463, 465, 467, 469, 
  471, 473, 475, 478, 480, 482, 484, 486, 
  488, 490, 492, 494, 498, 497, 500, 504, 
  506, 508, 510, 512, 514, 516, 518, 520, 
  522, 524, 526, 528, 530, 532, 534, 536, 
  538, 540, 542, 548, 550, 552, 554, 556, 
  558, 560, 562, 571, 11390, 11391, 577, 582, 
  584, 586, 588, 590, 11375, 11373, 11376, 385, 
  390, 393, 394, 399, 42923, 403, 42924, 404, 
  42893, 42922, 407, 406, 42926, 11362, 42925, 412, 
  11374, 413, 415, 11364, 422, 42949, 425, 42929, 
  430, 580, 433, 434, 581, 439, 42930, 42928, 
  880, 882, 886, 1021, 1022, 1023, 938, 939, 
  975, 984, 986, 990, 992, 994, 996, 998, 
  1000, 1002, 1004, 1006, 1017, 895, 1015, 1018, 
  1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 
  1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 
  1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 
  1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 
  1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 
  1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 
  1120, 1122, 1124, 1126, 1128, 1130, 1132, 1134, 
  1136, 1138, 1140, 1142, 1144, 1146, 1148, 1150, 
  1152, 1162, 1164, 1166, 1168, 1170, 1172, 1174, 
  1176, 1178, 1180, 1182, 1184, 1186, 1188, 1190, 
  1192, 1194, 1196, 1198, 1200, 1202, 1204, 1206, 
  1208, 1210, 1212, 1214, 1217, 1219, 1221, 1223, 
  1225, 1227, 1229, 1216, 1232, 1234, 1236, 1238, 
  1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, 
  1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 
  1272, 1274, 1276, 1278, 1280, 1282, 1284, 1286, 
  1288, 1290, 1292, 1294, 1296, 1298, 1300, 1302, 
  1304, 1306, 1308, 1310, 1312, 1314, 1316, 1318, 
  1320, 1322, 1324, 1326, 1329, 1330, 1331, 1332, 
  1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 
  1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 
  1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 
  1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 
  1365, 1366, 7312, 7313, 7314, 7315, 7316, 7317, 
  7318, 7319, 7320, 7321, 7322, 7323, 7324, 7325, 
  7326, 7327, 7328, 7329, 7330, 7331, 7332, 7333, 
  7334, 7335, 7336, 7337, 7338, 7339, 7340, 7341, 
  7342, 7343, 7344, 7345, 7346, 7347, 7348, 7349, 
  7350, 7351, 7352, 7353, 7354, 7357, 7358, 7359, 
  43888, 43889, 43890, 43891, 43892, 43893, 43894, 43895, 
  43896, 43897, 43898, 43899, 43900, 43901, 43902, 43903, 
  43904, 43905, 43906, 43907, 43908, 43909, 43910, 43911, 
  43912, 43913, 43914, 43915, 43916, 43917, 43918, 43919, 
  43920, 43921, 43922, 43923, 43924, 43925, 43926, 43927, 
  43928, 43929, 43930, 43931, 43932, 43933, 43934, 43935, 
  43936, 43937, 43938, 43939, 43940, 43941, 43942, 43943, 
  43944, 43945, 43946, 43947, 43948, 43949, 43950, 43951, 
  43952, 43953, 43954, 43955, 43956, 43957, 43958, 43959, 
  43960, 43961, 43962, 43963, 43964, 43965, 43966, 43967, 
  5112, 5113, 5114, 5115, 5116, 5117, 42570, 42877, 
  11363, 42950, 7680, 7682, 7684, 7686, 7688, 7690, 
  7692, 7694, 7696, 7698, 7700, 7702, 7704, 7706, 
  7708, 7710, 7712, 7714, 7716, 7718, 7720, 7722, 
  7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, 
  7740, 7742, 7744, 7746, 7748, 7750, 7752, 7754, 
  7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 
  7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786, 
  7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 
  7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 
  7820, 7822, 7824, 7826, 7828, 223, 7840, 7842, 
  7844, 7846, 7848, 7850, 7852, 7854, 7856, 7858, 
  7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 
  7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 
  7892, 7894, 7896, 7898, 7900, 7902, 7904, 7906, 
  7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 
  7924, 7926, 7928, 7930, 7932, 7934, 7944, 7945, 
  7946, 7947, 7948, 7949, 7950, 7951, 7960, 7961, 
  7962, 7963, 7964, 7965, 7976, 7977, 7978, 7979, 
  7980, 7981, 7982, 7983, 7992, 7993, 7994, 7995, 
  7996, 7997, 7998, 7999, 8008, 8009, 8010, 8011, 
  8012, 8013, 8025, 8027, 8029, 8031, 8040, 8041, 
  8042, 8043, 8044, 8045, 8046, 8047, 8122, 8123, 
  8136, 8137, 8138, 8139, 8154, 8155, 8184, 8185, 
  8170, 8171, 8186, 8187, 8072, 8073, 8074, 8075, 
  8076, 8077, 8078, 8079, 8064, 8065, 8066, 8067, 
  8068, 8069, 8070, 8071, 8088, 8089, 8090, 8091, 
  8092, 8093, 8094, 8095, 8080, 8081, 8082, 8083, 
  8084, 8085, 8086, 8087, 8104, 8105, 8106, 8107, 
  8108, 8109, 8110, 8111, 8096, 8097, 8098, 8099, 
  8100, 8101, 8102, 8103, 8120, 8121, 8124, 8115, 
  8140, 8131, 8152, 8153, 8168, 8169, 8172, 8188, 
  8179, 8498, 8544, 8545, 8546, 8547, 8548, 8549, 
  8550, 8551, 8552, 8553, 8554, 8555, 8556, 8557, 
  8558, 8559, 8579, 9398, 9399, 9400, 9401, 9402, 
  9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 
  9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 
  9419, 9420, 9421, 9422, 9423, 11264, 11265, 11266, 
  11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 
  11275, 11276, 11277, 11278, 11279, 11280, 11281, 11282, 
  11283, 11284, 11285, 11286, 11287, 11288, 11289, 11290, 
  11291, 11292, 11293, 11294, 11295, 11296, 11297, 11298, 
  11299, 11300, 11301, 11302, 11303, 11304, 11305, 11306, 
  11307, 11308, 11309, 11310, 11360, 570, 574, 11367, 
  11369, 11371, 11378, 11381, 11392, 11394, 11396, 11398, 
  11400, 11402, 11404, 11406, 11408, 11410, 11412, 11414, 
  11416, 11418, 11420, 11422, 11424, 11426, 11428, 11430, 
  11432, 11434, 11436, 11438, 11440, 11442, 11444, 11446, 
  11448, 11450, 11452, 11454, 11456, 11458, 11460, 11462, 
  11464, 11466, 11468, 11470, 11472, 11474, 11476, 11478, 
  11480, 11482, 11484, 11486, 11488, 11490, 11499, 11501, 
  11506, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 
  4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 
  4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 
  4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 
  4287, 4288, 4289, 4290, 4291, 4292, 4293, 4295, 
  4301, 42560, 42562, 42564, 42566, 42568, 42572, 42574, 
  42576, 42578, 42580, 42582, 42584, 42586, 42588, 42590, 
  42592, 42594, 42596, 42598, 42600, 42602, 42604, 42624, 
  42626, 42628, 42630, 42632, 42634, 42636, 42638, 42640, 
  42642, 42644, 42646, 42648, 42650, 42786, 42788, 42790, 
  42792, 42794, 42796, 42798, 42802, 42804, 42806, 42808, 
  42810, 42812, 42814, 42816, 42818, 42820, 42822, 42824, 
  42826, 42828, 42830, 42832, 42834, 42836, 42838, 42840, 
  42842, 42844, 42846, 42848, 42850, 42852, 42854, 42856, 
  42858, 42860, 42862, 42873, 42875, 42878, 42880, 42882, 
  42884, 42886, 42891, 42896, 42898, 42948, 42902, 42904, 
  42906, 42908, 42910, 42912, 42914, 42916, 42918, 42920, 
  42932, 42934, 42936, 42938, 42940, 42942, 42946, 42931, 
  65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 
  65321, 65322, 65323, 65324, 65325, 65326, 65327, 65328, 
  65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336, 
  65337, 65338, 55297, 56320, 55297, 56321, 55297, 56322, 
  55297, 56323, 55297, 56324, 55297, 56325, 55297, 56326, 
  55297, 56327, 55297, 56328, 55297, 56329, 55297, 56330, 
  55297, 56331, 55297, 56332, 55297, 56333, 55297, 56334, 
  55297, 56335, 55297, 56336, 55297, 56337, 55297, 56338, 
  55297, 56339, 55297, 56340, 55297, 56341, 55297, 56342, 
  55297, 56343, 55297, 56344, 55297, 56345, 55297, 56346, 
  55297, 56347, 55297, 56348, 55297, 56349, 55297, 56350, 
  55297, 56351, 55297, 56352, 55297, 56353, 55297, 56354, 
  55297, 56355, 55297, 56356, 55297, 56357, 55297, 56358, 
  55297, 56359, 55297, 56496, 55297, 56497, 55297, 56498, 
  55297, 56499, 55297, 56500, 55297, 56501, 55297, 56502, 
  55297, 56503, 55297, 56504, 55297, 56505, 55297, 56506, 
  55297, 56507, 55297, 56508, 55297, 56509, 55297, 56510, 
  55297, 56511, 55297, 56512, 55297, 56513, 55297, 56514, 
  55297, 56515, 55297, 56516, 55297, 56517, 55297, 56518, 
  55297, 56519, 55297, 56520, 55297, 56521, 55297, 56522, 
  55297, 56523, 55297, 56524, 55297, 56525, 55297, 56526, 
  55297, 56527, 55297, 56528, 55297, 56529, 55297, 56530, 
  55297, 56531, 55299, 56448, 55299, 56449, 55299, 56450, 
  55299, 56451, 55299, 56452, 55299, 56453, 55299, 56454, 
  55299, 56455, 55299, 56456, 55299, 56457, 55299, 56458, 
  55299, 56459, 55299, 56460, 55299, 56461, 55299, 56462, 
  55299, 56463, 55299, 56464, 55299, 56465, 55299, 56466, 
  55299, 56467, 55299, 56468, 55299, 56469, 55299, 56470, 
  55299, 56471, 55299, 56472, 55299, 56473, 55299, 56474, 
  55299, 56475, 55299, 56476, 55299, 56477, 55299, 56478, 
  55299, 56479, 55299, 56480, 55299, 56481, 55299, 56482, 
  55299, 56483, 55299, 56484, 55299, 56485, 55299, 56486, 
  55299, 56487, 55299, 56488, 55299, 56489, 55299, 56490, 
  55299, 56491, 55299, 56492, 55299, 56493, 55299, 56494, 
  55299, 56495, 55299, 56496, 55299, 56497, 55299, 56498, 
  55302, 56480, 55302, 56481, 55302, 56482, 55302, 56483, 
  55302, 56484, 55302, 56485, 55302, 56486, 55302, 56487, 
  55302, 56488, 55302, 56489, 55302, 56490, 55302, 56491, 
  55302, 56492, 55302, 56493, 55302, 56494, 55302, 56495, 
  55302, 56496, 55302, 56497, 55302, 56498, 55302, 56499, 
  55302, 56500, 55302, 56501, 55302, 56502, 55302, 56503, 
  55302, 56504, 55302, 56505, 55302, 56506, 55302, 56507, 
  55302, 56508, 55302, 56509, 55302, 56510, 55302, 56511, 
  55323, 56896, 55323, 56897, 55323, 56898, 55323, 56899, 
  55323, 56900, 55323, 56901, 55323, 56902, 55323, 56903, 
  55323, 56904, 55323, 56905, 55323, 56906, 55323, 56907, 
  55323, 56908, 55323, 56909, 55323, 56910, 55323, 56911, 
  55323, 56912, 55323, 56913, 55323, 56914, 55323, 56915, 
  55323, 56916, 55323, 56917, 55323, 56918, 55323, 56919, 
  55323, 56920, 55323, 56921, 55323, 56922, 55323, 56923, 
  55323, 56924, 55323, 56925, 55323, 56926, 55323, 56927, 
  55354, 56576, 55354, 56577, 55354, 56578, 55354, 56579, 
  55354, 56580, 55354, 56581, 55354, 56582, 55354, 56583, 
  55354, 56584, 55354, 56585, 55354, 56586, 55354, 56587, 
  55354, 56588, 55354, 56589, 55354, 56590, 55354, 56591, 
  55354, 56592, 55354, 56593, 55354, 56594, 55354, 56595, 
  55354, 56596, 55354, 56597, 55354, 56598, 55354, 56599, 
  55354, 56600, 55354, 56601, 55354, 56602, 55354, 56603, 
  55354, 56604, 55354, 56605, 55354, 56606, 55354, 56607, 
  55354, 56608, 55354, 56609, };

static const utf8proc_uint16_t utf8proc_stage1table[] = {
  0, 256, 512, 768, 1024, 1280, 1536, 
  1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 
  3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632, 
  5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 
  7936, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 
  9984, 10240, 10496, 10752, 11008, 11264, 11520, 11776, 
  12032, 12288, 12544, 12800, 13056, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13568, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13824, 14080, 13312, 13312, 13312, 14336, 5376, 14592, 
  14848, 15104, 15360, 15616, 15872, 16128, 16384, 16640, 
  16896, 17152, 17408, 17664, 16128, 16384, 16640, 16896, 
  17152, 17408, 17664, 16128, 16384, 16640, 16896, 17152, 
  17408, 17664, 16128, 16384, 16640, 16896, 17152, 17408, 
  17664, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 
  16128, 16384, 16640, 16896, 17152, 17408, 17664, 16128, 
  17920, 18176, 18176, 18176, 18176, 18176, 18176, 18176, 
  18176, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 
  20224, 20480, 20736, 20992, 21248, 21504, 21760, 5376, 
  22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 
  24064, 24320, 24576, 24832, 25088, 25344, 25600, 25856, 
  26112, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 
  28160, 5376, 5376, 5376, 28416, 28672, 28928, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 5376, 5376, 5376, 5376, 29184, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 5376, 5376, 29440, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 5376, 5376, 29696, 29952, 27136, 27136, 30208, 
  30464, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  30720, 13312, 13312, 30976, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 13312, 31232, 31488, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 31744, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 
  33792, 10240, 10240, 34048, 27136, 27136, 27136, 27136, 
  27136, 34304, 34560, 34816, 27136, 27136, 27136, 27136, 
  27136, 35072, 35328, 27136, 27136, 35584, 35840, 36096, 
  27136, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 
  38144, 38400, 38656, 38912, 27136, 27136, 27136, 27136, 
  27136, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 39168, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  39424, 39680, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 39936, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, 
  13312, 13312, 13312, 13312, 40192, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 40448, 40704, 40960, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 41216, 41472, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 27136, 27136, 27136, 27136, 27136, 27136, 27136, 
  27136, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  41728, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 
  41728, };

static const utf8proc_uint16_t utf8proc_stage2table[] = {
  1, 2, 2, 2, 2, 2, 2, 
  2, 2, 3, 4, 3, 5, 6, 2, 
  2, 2, 2, 2, 2, 2, 2, 2, 
  2, 2, 2, 2, 2, 7, 7, 7, 
  3, 8, 9, 9, 10, 11, 10, 9, 
  9, 12, 13, 9, 14, 15, 16, 15, 
  15, 17, 17, 17, 17, 17, 17, 17, 
  17, 17, 17, 15, 9, 18, 19, 20, 
  9, 9, 21, 22, 23, 24, 25, 26, 
  27, 28, 29, 30, 31, 32, 33, 34, 
  35, 36, 37, 38, 39, 40, 41, 42, 
  43, 44, 45, 46, 12, 9, 13, 47, 
  48, 47, 49, 50, 51, 52, 53, 54, 
  55, 56, 57, 58, 59, 60, 61, 62, 
  63, 64, 65, 66, 67, 68, 69, 70, 
  71, 72, 73, 74, 12, 75, 13, 75, 
  2, 2, 2, 2, 2, 2, 7, 2, 
  2, 2, 2, 2, 2, 2, 2, 2, 
  2, 2, 2, 2, 2, 2, 2, 2, 
  2, 2, 2, 2, 2, 2, 2, 2, 
  2, 76, 9, 11, 11, 11, 11, 77, 
  9, 78, 79, 80, 81, 75, 82, 79, 
  83, 84, 85, 86, 87, 88, 89, 9, 
  9, 90, 91, 92, 93, 94, 95, 96, 
  9, 97, 98, 99, 100, 101, 102, 103, 
  104, 105, 106, 107, 108, 109, 110, 111, 
  112, 113, 114, 115, 116, 117, 118, 119, 
  75, 120, 121, 122, 123, 124, 125, 126, 
  127, 128, 129, 130, 131, 132, 133, 134, 
  135, 136, 137, 138, 139, 140, 141, 142, 
  143, 144, 145, 146, 147, 148, 149, 150, 
  75, 151, 152, 153, 154, 155, 156, 157, 
  158, 159, 160, 161, 162, 163, 164, 165, 
  166, 167, 168, 169, 170, 171, 172, 173, 
  174, 175, 176, 177, 178, 179, 180, 181, 
  182, 183, 184, 185, 186, 187, 188, 189, 
  190, 191, 192, 193, 194, 195, 196, 197, 
  198, 199, 200, 201, 202, 203, 204, 205, 
  206, 207, 208, 209, 210, 211, 212, 213, 
  214, 215, 216, 217, 218, 219, 220, 221, 
  222, 223, 224, 225, 226, 227, 228, 229, 
  230, 231, 232, 233, 234, 235, 236, 237, 
  238, 239, 240, 241, 242, 243, 244, 245, 
  246, 247, 248, 249, 250, 251, 252, 253, 
  254, 255, 256, 257, 258, 259, 260, 261, 
  262, 263, 264, 265, 266, 267, 268, 269, 
  270, 271, 272, 273, 274, 275, 276, 277, 
  278, 279, 280, 281, 282, 283, 284, 285, 
  286, 287, 288, 289, 290, 291, 292, 293, 
  294, 295, 296, 297, 298, 299, 215, 300, 
  301, 302, 303, 304, 305, 306, 307, 308, 
  309, 310, 311, 312, 215, 313, 314, 315, 
  316, 317, 318, 319, 320, 321, 322, 323, 
  324, 325, 326, 215, 215, 327, 328, 329, 
  330, 331, 332, 333, 334, 335, 336, 337, 
  338, 339, 340, 215, 341, 342, 343, 215, 
  344, 341, 341, 341, 341, 345, 346, 347, 
  348, 349, 350, 351, 352, 353, 354, 355, 
  356, 357, 358, 359, 360, 361, 362, 363, 
  364, 365, 366, 367, 368, 369, 370, 371, 
  372, 373, 374, 375, 376, 377, 378, 379, 
  380, 381, 382, 383, 384, 385, 386, 387, 
  388, 389, 390, 391, 392, 393, 394, 395, 
  396, 397, 398, 399, 400, 401, 402, 403, 
  404, 405, 406, 407, 408, 409, 410, 411, 
  412, 413, 414, 415, 416, 417, 418, 419, 
  420, 421, 422, 423, 424, 425, 426, 427, 
  428, 429, 430, 431, 432, 433, 434, 435, 
  436, 437, 215, 438, 439, 440, 441, 442, 
  443, 444, 445, 446, 447, 448, 449, 450, 
  451, 452, 453, 454, 455, 215, 215, 215, 
  215, 215, 215, 456, 457, 458, 459, 460, 
  461, 462, 463, 464, 465, 466, 467, 468, 
  469, 470, 471, 472, 473, 474, 475, 476, 
  477, 478, 479, 480, 481, 482, 215, 483, 
  484, 215, 485, 215, 486, 487, 215, 215, 
  215, 488, 489, 215, 490, 215, 491, 492, 
  215, 493, 494, 495, 496, 497, 215, 215, 
  498, 215, 499, 500, 215, 215, 501, 215, 
  215, 215, 215, 215, 215, 215, 502, 215, 
  215, 503, 215, 504, 505, 215, 215, 215, 
  506, 507, 508, 509, 510, 511, 215, 215, 
  215, 215, 215, 512, 215, 341, 215, 215, 
  215, 215, 215, 215, 215, 215, 513, 514, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 515, 516, 517, 518, 519, 520, 521, 
  522, 523, 524, 524, 525, 525, 525, 525, 
  525, 525, 525, 526, 526, 526, 526, 524, 
  524, 524, 524, 524, 524, 524, 524, 524, 
  524, 525, 525, 526, 526, 526, 526, 526, 
  526, 527, 528, 529, 530, 531, 532, 526, 
  526, 533, 534, 535, 536, 537, 526, 526, 
  526, 526, 526, 526, 526, 524, 526, 525, 
  526, 526, 526, 526, 526, 526, 526, 526, 
  526, 526, 526, 526, 526, 526, 526, 526, 
  526, 538, 539, 540, 541, 542, 543, 544, 
  545, 546, 547, 548, 549, 550, 543, 543, 
  551, 543, 552, 543, 553, 554, 555, 556, 
  556, 556, 556, 555, 557, 556, 556, 556, 
  556, 556, 558, 558, 559, 560, 561, 562, 
  563, 564, 556, 556, 556, 556, 565, 566, 
  556, 567, 568, 556, 556, 569, 569, 569, 
  569, 570, 556, 556, 556, 556, 543, 543, 
  543, 571, 572, 573, 574, 575, 576, 543, 
  556, 556, 556, 543, 543, 543, 556, 556, 
  577, 543, 543, 543, 556, 556, 556, 556, 
  543, 555, 556, 556, 543, 578, 579, 579, 
  578, 579, 579, 578, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 580, 581, 582, 583, 584, 526, 585, 
  586, 0, 0, 587, 588, 589, 590, 591, 
  592, 0, 0, 0, 0, 88, 593, 594, 
  595, 596, 597, 598, 0, 599, 0, 600, 
  601, 602, 603, 604, 605, 606, 607, 608, 
  609, 610, 611, 612, 613, 614, 615, 616, 
  617, 618, 619, 0, 620, 621, 622, 623, 
  624, 625, 626, 627, 628, 629, 630, 631, 
  632, 633, 634, 635, 636, 637, 638, 639, 
  640, 641, 642, 643, 644, 645, 646, 647, 
  648, 649, 650, 651, 652, 653, 654, 655, 
  656, 657, 658, 659, 660, 661, 662, 663, 
  664, 665, 666, 667, 668, 669, 670, 671, 
  672, 673, 674, 675, 676, 677, 678, 679, 
  680, 681, 682, 683, 684, 685, 686, 687, 
  688, 689, 690, 691, 692, 693, 694, 695, 
  696, 697, 698, 699, 700, 701, 702, 75, 
  703, 704, 705, 706, 707, 215, 708, 709, 
  710, 711, 712, 713, 714, 715, 716, 717, 
  718, 719, 720, 721, 722, 723, 724, 725, 
  726, 727, 728, 729, 730, 731, 732, 733, 
  734, 735, 736, 737, 738, 739, 740, 741, 
  742, 743, 744, 745, 746, 747, 748, 749, 
  750, 751, 752, 753, 754, 755, 756, 757, 
  758, 759, 760, 761, 762, 763, 764, 765, 
  766, 767, 768, 769, 770, 771, 772, 773, 
  774, 775, 776, 777, 778, 779, 780, 781, 
  782, 783, 784, 785, 786, 787, 788, 789, 
  790, 791, 792, 793, 794, 795, 796, 797, 
  798, 799, 800, 801, 802, 803, 804, 805, 
  806, 807, 808, 809, 810, 811, 812, 813, 
  814, 815, 816, 817, 818, 819, 820, 821, 
  822, 823, 824, 825, 826, 827, 828, 829, 
  830, 831, 832, 833, 834, 835, 836, 837, 
  838, 839, 840, 841, 543, 543, 543, 543, 
  543, 842, 842, 843, 844, 845, 846, 847, 
  848, 849, 850, 851, 852, 853, 854, 855, 
  856, 857, 858, 859, 860, 861, 862, 863, 
  864, 865, 866, 867, 868, 869, 870, 871, 
  872, 873, 874, 875, 876, 877, 878, 879, 
  880, 881, 882, 883, 884, 885, 886, 887, 
  888, 889, 890, 891, 892, 893, 894, 895, 
  896, 897, 898, 899, 900, 901, 902, 903, 
  904, 905, 906, 907, 908, 909, 910, 911, 
  912, 913, 914, 915, 916, 917, 918, 919, 
  920, 921, 922, 923, 924, 925, 926, 927, 
  928, 929, 930, 931, 932, 933, 934, 935, 
  936, 937, 938, 939, 940, 941, 942, 943, 
  944, 945, 946, 947, 948, 949, 950, 951, 
  952, 953, 954, 955, 956, 957, 958, 959, 
  960, 961, 962, 963, 964, 965, 966, 967, 
  968, 969, 970, 971, 972, 973, 974, 975, 
  976, 977, 978, 979, 980, 981, 982, 983, 
  984, 985, 986, 987, 988, 989, 990, 991, 
  992, 993, 994, 995, 996, 997, 998, 999, 
  1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 
  1008, 0, 1009, 1010, 1011, 1012, 1013, 1014, 
  1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 
  1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 
  1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 
  1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 
  0, 0, 525, 1047, 1047, 1047, 1047, 1047, 
  1047, 215, 1048, 1049, 1050, 1051, 1052, 1053, 
  1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 
  1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 
  1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 
  1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 
  1086, 215, 1047, 1087, 0, 0, 77, 77, 
  11, 0, 556, 543, 543, 543, 543, 556, 
  543, 543, 543, 1088, 556, 543, 543, 543, 
  543, 543, 543, 556, 556, 556, 556, 556, 
  556, 543, 543, 556, 543, 543, 1088, 1089, 
  543, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 
  1097, 1098, 1099, 1099, 1100, 1101, 1102, 1103, 
  1104, 1105, 1106, 1107, 1105, 543, 556, 1105, 
  1098, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 0, 0, 0, 0, 
  1108, 1108, 1108, 1108, 1105, 1105, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1109, 1109, 1109, 1109, 1109, 1109, 75, 
  75, 1110, 10, 10, 1111, 15, 1112, 77, 
  77, 543, 543, 543, 543, 543, 543, 543, 
  543, 1113, 1114, 1115, 1112, 1116, 0, 1112, 
  1112, 1117, 1117, 1118, 1119, 1120, 1121, 1122, 
  1123, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1124, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1125, 1117, 1126, 1127, 1128, 1129, 1113, 
  1114, 1115, 1130, 1131, 1132, 1133, 1134, 556, 
  543, 543, 543, 543, 543, 556, 543, 543, 
  556, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 
  1135, 1135, 1135, 10, 1136, 1136, 1112, 1117, 
  1117, 1137, 1117, 1117, 1117, 1117, 1138, 1139, 
  1140, 1141, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1142, 1143, 1144, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1145, 1146, 1112, 1147, 543, 
  543, 543, 543, 543, 543, 543, 1109, 77, 
  543, 543, 543, 543, 556, 543, 1124, 1124, 
  543, 543, 77, 556, 543, 543, 556, 1117, 
  1117, 17, 17, 17, 17, 17, 17, 17, 
  17, 17, 17, 1117, 1117, 1117, 1148, 1148, 
  1117, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 
  1112, 1112, 1112, 1112, 1112, 1112, 1112, 0, 
  1149, 1117, 1150, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 543, 556, 543, 543, 556, 543, 543, 
  556, 556, 556, 543, 556, 556, 543, 556, 
  543, 543, 543, 556, 543, 556, 543, 556, 
  543, 556, 543, 543, 0, 0, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1117, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 
  1152, 1152, 1152, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 543, 543, 543, 543, 
  543, 543, 543, 556, 543, 1153, 1153, 77, 
  9, 9, 9, 1153, 0, 0, 556, 1154, 
  1154, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 543, 
  543, 543, 543, 1153, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 1153, 543, 543, 
  543, 1153, 543, 543, 543, 543, 543, 0, 
  0, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 
  1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 556, 556, 556, 0, 0, 1105, 
  0, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 0, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 556, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 1109, 556, 543, 543, 556, 
  543, 543, 556, 543, 543, 543, 556, 556, 
  556, 1127, 1128, 1129, 543, 543, 543, 556, 
  543, 543, 556, 556, 543, 543, 543, 543, 
  543, 1151, 1151, 1151, 1155, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 1156, 1157, 341, 341, 341, 341, 341, 
  341, 1158, 1159, 341, 1160, 1161, 341, 341, 
  341, 341, 341, 1151, 1155, 1162, 341, 1155, 
  1155, 1155, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1155, 1155, 1155, 1155, 1163, 1155, 
  1155, 341, 543, 556, 543, 543, 1151, 1151, 
  1151, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 
  1171, 341, 341, 1151, 1151, 1047, 1047, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1047, 525, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1151, 1155, 1155, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 0, 
  341, 341, 0, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 0, 0, 0, 341, 
  341, 341, 341, 0, 0, 1173, 341, 1174, 
  1155, 1155, 1151, 1151, 1151, 1151, 0, 0, 
  1175, 1155, 0, 0, 1176, 1177, 1163, 341, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  1178, 0, 0, 0, 0, 1179, 1180, 0, 
  1181, 341, 341, 1151, 1151, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 341, 341, 11, 11, 1182, 1182, 1182, 
  1182, 1182, 1182, 841, 11, 341, 1047, 543, 
  0, 0, 1151, 1151, 1155, 0, 341, 341, 
  341, 341, 341, 341, 0, 0, 0, 0, 
  341, 341, 0, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 1183, 0, 341, 1184, 
  0, 341, 341, 0, 0, 1173, 0, 1155, 
  1155, 1155, 1151, 1151, 0, 0, 0, 0, 
  1151, 1151, 0, 0, 1151, 1151, 1163, 0, 
  0, 0, 1151, 0, 0, 0, 0, 0, 
  0, 0, 1185, 1186, 1187, 341, 0, 1188, 
  0, 0, 0, 0, 0, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1151, 1151, 341, 341, 341, 1151, 1047, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 1151, 1151, 1155, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  341, 341, 341, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 0, 341, 341, 
  341, 341, 341, 0, 0, 1173, 341, 1155, 
  1155, 1155, 1151, 1151, 1151, 1151, 1151, 0, 
  1151, 1151, 1155, 0, 1155, 1155, 1163, 0, 
  0, 341, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 1151, 1151, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1047, 11, 0, 0, 0, 0, 0, 
  0, 0, 341, 1151, 1151, 1151, 1151, 1151, 
  1151, 0, 1151, 1155, 1155, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 0, 
  341, 341, 0, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 0, 341, 341, 
  341, 341, 341, 0, 0, 1173, 341, 1189, 
  1151, 1155, 1151, 1151, 1151, 1151, 0, 0, 
  1190, 1191, 0, 0, 1192, 1193, 1163, 0, 
  0, 0, 0, 0, 0, 0, 0, 1194, 
  1195, 0, 0, 0, 0, 1196, 1197, 0, 
  341, 341, 341, 1151, 1151, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 841, 341, 1182, 1182, 1182, 1182, 1182, 
  1182, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 1151, 341, 0, 341, 341, 
  341, 341, 341, 341, 0, 0, 0, 341, 
  341, 341, 0, 1198, 341, 1199, 341, 0, 
  0, 0, 341, 341, 0, 341, 0, 341, 
  341, 0, 0, 0, 341, 341, 0, 0, 
  0, 341, 341, 341, 0, 0, 0, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 0, 0, 0, 1200, 
  1155, 1151, 1155, 1155, 0, 0, 0, 1201, 
  1202, 1155, 0, 1203, 1204, 1205, 1163, 0, 
  0, 341, 0, 0, 0, 0, 0, 0, 
  1206, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1182, 1182, 1182, 77, 77, 77, 77, 
  77, 77, 11, 77, 0, 0, 0, 0, 
  0, 1151, 1155, 1155, 1155, 1151, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 0, 0, 341, 1151, 
  1151, 1151, 1155, 1155, 1155, 1155, 0, 1207, 
  1151, 1208, 0, 1151, 1151, 1151, 1163, 0, 
  0, 0, 0, 0, 0, 0, 1209, 1210, 
  0, 341, 341, 341, 0, 0, 0, 0, 
  0, 341, 341, 1151, 1151, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 0, 0, 0, 0, 0, 0, 0, 
  1047, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  841, 341, 1151, 1155, 1155, 1047, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 341, 341, 
  341, 341, 341, 0, 0, 1173, 341, 1155, 
  1212, 1213, 1155, 1214, 1155, 1155, 0, 1215, 
  1216, 1217, 0, 1218, 1219, 1151, 1163, 0, 
  0, 0, 0, 0, 0, 0, 1220, 1221, 
  0, 0, 0, 0, 0, 0, 0, 341, 
  0, 341, 341, 1151, 1151, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 0, 341, 341, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1151, 1151, 1155, 1155, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1163, 1163, 341, 1222, 
  1155, 1155, 1151, 1151, 1151, 1151, 0, 1223, 
  1224, 1155, 0, 1225, 1226, 1227, 1163, 1228, 
  841, 0, 0, 0, 0, 341, 341, 341, 
  1229, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  341, 341, 341, 1151, 1151, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 841, 341, 341, 341, 341, 341, 
  341, 0, 0, 1155, 1155, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 0, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 0, 0, 1230, 0, 0, 0, 0, 
  1231, 1155, 1155, 1151, 1151, 1151, 0, 1151, 
  0, 1155, 1232, 1233, 1155, 1234, 1235, 1236, 
  1237, 0, 0, 0, 0, 0, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 0, 0, 1155, 1155, 1047, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1151, 341, 1238, 1151, 1151, 1151, 
  1151, 1239, 1239, 1163, 0, 0, 0, 0, 
  11, 341, 341, 341, 341, 341, 341, 525, 
  1151, 1240, 1240, 1240, 1240, 1151, 1151, 1151, 
  1047, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1047, 1047, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 341, 341, 0, 341, 0, 341, 
  341, 341, 341, 341, 0, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 341, 0, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1151, 341, 1241, 1151, 1151, 1151, 
  1151, 1242, 1242, 1163, 1151, 1151, 341, 0, 
  0, 341, 341, 341, 341, 341, 0, 525, 
  0, 1243, 1243, 1243, 1243, 1151, 1151, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 1244, 1245, 341, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 841, 841, 841, 1047, 1047, 1047, 
  1047, 1047, 1047, 1047, 1047, 1246, 1047, 1047, 
  1047, 1047, 1047, 1047, 841, 1047, 841, 841, 
  841, 556, 556, 841, 841, 841, 841, 841, 
  841, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 841, 556, 841, 
  556, 841, 1247, 12, 13, 12, 13, 1155, 
  1155, 341, 341, 341, 1248, 341, 341, 341, 
  341, 0, 341, 341, 341, 341, 1249, 341, 
  341, 341, 341, 1250, 341, 341, 341, 341, 
  1251, 341, 341, 341, 341, 1252, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1253, 341, 341, 341, 0, 0, 
  0, 0, 1254, 1255, 1256, 1257, 1258, 1259, 
  1260, 1261, 1262, 1255, 1255, 1255, 1255, 1151, 
  1155, 1255, 1263, 543, 543, 1163, 1047, 543, 
  543, 341, 341, 341, 341, 341, 1151, 1151, 
  1151, 1151, 1151, 1151, 1264, 1151, 1151, 1151, 
  1151, 0, 1151, 1151, 1151, 1151, 1265, 1151, 
  1151, 1151, 1151, 1266, 1151, 1151, 1151, 1151, 
  1267, 1151, 1151, 1151, 1151, 1268, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1269, 1151, 1151, 1151, 0, 841, 
  841, 841, 841, 841, 841, 841, 841, 556, 
  841, 841, 841, 841, 841, 841, 0, 841, 
  841, 1047, 1047, 1047, 1047, 1047, 841, 841, 
  841, 841, 1047, 1047, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 1270, 1271, 
  341, 341, 341, 341, 1272, 1272, 1151, 1273, 
  1151, 1151, 1155, 1151, 1151, 1151, 1151, 1151, 
  1173, 1272, 1163, 1163, 1155, 1155, 1151, 1151, 
  341, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1047, 1047, 1047, 1047, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 1155, 
  1155, 1151, 1151, 341, 341, 341, 341, 1151, 
  1151, 1151, 341, 1272, 1272, 1272, 341, 341, 
  1272, 1272, 1272, 1272, 1272, 1272, 1272, 341, 
  341, 341, 1151, 1151, 1151, 1151, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 1151, 1272, 1155, 1151, 1151, 
  1272, 1272, 1272, 1272, 1272, 1272, 556, 341, 
  1272, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1272, 1272, 1272, 1151, 841, 
  841, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 
  1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 
  1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 
  1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 
  1305, 1306, 1307, 1308, 1309, 1310, 1311, 0, 
  1312, 0, 0, 0, 0, 0, 1313, 0, 
  0, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 
  1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 
  1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 
  1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 
  1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 
  1353, 1354, 1355, 1356, 1047, 1357, 1358, 1359, 
  1360, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1362, 1363, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 0, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 0, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 0, 0, 543, 543, 
  543, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 
  1047, 1047, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 0, 0, 0, 0, 0, 
  0, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 
  1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 
  1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 
  1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 
  1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 
  1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 
  1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 
  1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 
  1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 
  1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 
  1445, 1446, 1447, 1448, 1449, 1450, 1451, 0, 
  0, 1452, 1453, 1454, 1455, 1456, 1457, 0, 
  0, 1087, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 841, 1047, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 8, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 12, 13, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1047, 1047, 1047, 1458, 
  1458, 1458, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 341, 
  341, 341, 341, 1151, 1151, 1163, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 1151, 1151, 1163, 1047, 1047, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 1151, 1151, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 341, 
  341, 341, 0, 1151, 1151, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 577, 577, 1155, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1151, 
  1155, 1155, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1163, 1151, 1047, 1047, 1047, 
  525, 1047, 1047, 1047, 11, 341, 543, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 0, 0, 0, 0, 0, 
  0, 9, 9, 9, 9, 9, 9, 1087, 
  9, 9, 9, 9, 577, 577, 577, 1459, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 525, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 1151, 1151, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1089, 341, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 1151, 1151, 1151, 1155, 1155, 1155, 1155, 
  1151, 1151, 1155, 1155, 1155, 0, 0, 0, 
  0, 1155, 1155, 1151, 1155, 1155, 1155, 1155, 
  1155, 1155, 1088, 543, 556, 0, 0, 0, 
  0, 77, 0, 0, 0, 9, 9, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1182, 0, 0, 0, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  543, 556, 1155, 1155, 1151, 0, 0, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 1155, 1151, 
  1155, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  0, 1163, 1272, 1151, 1272, 1272, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1155, 1155, 
  1155, 1155, 1155, 1155, 1151, 1151, 543, 543, 
  543, 543, 543, 543, 543, 543, 0, 0, 
  556, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 
  525, 1047, 1047, 1047, 1047, 1047, 1047, 0, 
  0, 543, 543, 543, 543, 543, 556, 556, 
  556, 556, 556, 556, 543, 543, 556, 842, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1151, 1151, 1151, 1151, 1155, 1460, 1461, 
  1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 
  341, 341, 1470, 1471, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 1173, 1472, 1151, 
  1151, 1151, 1151, 1473, 1474, 1475, 1476, 1477, 
  1478, 1479, 1480, 1481, 1482, 1483, 341, 341, 
  341, 341, 341, 341, 341, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1047, 1047, 1047, 1047, 1047, 
  1047, 1047, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 543, 556, 543, 543, 
  543, 543, 543, 543, 543, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 0, 0, 
  0, 1151, 1151, 1155, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1155, 1151, 1151, 1151, 1151, 1155, 
  1155, 1151, 1151, 1483, 1163, 1151, 1151, 341, 
  341, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 1173, 
  1155, 1151, 1151, 1155, 1155, 1155, 1151, 1155, 
  1151, 1151, 1151, 1483, 1483, 0, 0, 0, 
  0, 0, 0, 0, 0, 1047, 1047, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1155, 1155, 1151, 
  1173, 0, 0, 0, 1047, 1047, 1047, 1047, 
  1047, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 341, 341, 
  341, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 525, 525, 525, 525, 525, 525, 1047, 
  1047, 1484, 1485, 1486, 1487, 1488, 1488, 1489, 
  1490, 1491, 0, 0, 0, 0, 0, 0, 
  0, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 
  1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 
  1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 
  1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 
  1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 
  1531, 1532, 1533, 1534, 0, 0, 1535, 1536, 
  1537, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 
  1047, 0, 0, 0, 0, 0, 0, 0, 
  0, 543, 543, 543, 1047, 569, 556, 556, 
  556, 556, 556, 543, 543, 556, 556, 556, 
  556, 543, 1155, 569, 569, 569, 569, 569, 
  569, 569, 341, 341, 341, 341, 556, 341, 
  341, 341, 341, 341, 341, 543, 341, 341, 
  1155, 543, 543, 341, 0, 0, 0, 0, 
  0, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 1538, 1539, 1540, 
  525, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 
  1548, 1549, 1550, 1551, 525, 1552, 1553, 1554, 
  1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 
  1563, 1564, 1565, 1566, 1567, 1568, 1569, 525, 
  1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 
  1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 
  1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 
  1594, 1595, 1596, 1597, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 1598, 1599, 215, 215, 215, 1600, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 1601, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 1602, 1603, 1604, 1605, 
  1568, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 
  1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 
  1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 
  1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 
  1637, 543, 543, 556, 543, 543, 543, 543, 
  543, 543, 543, 556, 543, 543, 579, 1638, 
  556, 558, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 555, 
  1089, 1089, 556, 0, 543, 578, 556, 543, 
  556, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 
  1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 
  1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 
  1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 
  1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 
  1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 
  1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 
  1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 
  1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 
  1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 
  1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 
  1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 
  1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 
  1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 
  1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 
  1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 
  1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 
  1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 
  1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 
  1790, 1791, 1792, 1793, 1794, 215, 215, 1795, 
  215, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 
  1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 
  1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 
  1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 
  1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 
  1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 
  1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 
  1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 
  1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 
  1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 
  1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 
  1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 
  1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 
  1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 
  1907, 1908, 1909, 1910, 1911, 1912, 1913, 0, 
  0, 1914, 1915, 1916, 1917, 1918, 1919, 0, 
  0, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 
  1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 
  1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 
  1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 
  1951, 1952, 1953, 1954, 1955, 1956, 1957, 0, 
  0, 1958, 1959, 1960, 1961, 1962, 1963, 0, 
  0, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 
  1971, 0, 1972, 0, 1973, 0, 1974, 0, 
  1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 
  1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 
  1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 
  1999, 2000, 2001, 2002, 2003, 2004, 2005, 0, 
  0, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 
  2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 
  2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 
  2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 
  2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 
  2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 
  2053, 2054, 2055, 2056, 2057, 2058, 0, 2059, 
  2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 
  2068, 2069, 2070, 2071, 2072, 2073, 0, 2074, 
  2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 
  2083, 2084, 2085, 2086, 2087, 0, 0, 2088, 
  2089, 2090, 2091, 2092, 2093, 0, 2094, 2095, 
  2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 
  2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 
  2112, 0, 0, 2113, 2114, 2115, 0, 2116, 
  2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 
  0, 2125, 2126, 2127, 2127, 2127, 2127, 2127, 
  2128, 2127, 2127, 2127, 1459, 2129, 2130, 2131, 
  2132, 1087, 2133, 1087, 1087, 1087, 1087, 9, 
  2134, 2135, 2136, 2137, 2135, 2135, 2136, 2137, 
  2135, 9, 9, 9, 9, 2138, 2139, 2140, 
  9, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 
  76, 10, 10, 10, 2148, 2149, 9, 2150, 
  2151, 9, 81, 93, 9, 2152, 9, 2153, 
  48, 48, 9, 9, 9, 2154, 12, 13, 
  2155, 2156, 2157, 9, 9, 9, 9, 9, 
  9, 9, 9, 75, 9, 48, 9, 9, 
  2158, 9, 9, 9, 9, 9, 9, 9, 
  2127, 1459, 1459, 1459, 1459, 1459, 0, 2159, 
  2160, 2161, 2162, 1459, 1459, 1459, 1459, 1459, 
  1459, 2163, 2164, 0, 0, 2165, 2166, 2167, 
  2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 
  2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 
  2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 
  0, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 
  2199, 2200, 2201, 2202, 2203, 2204, 0, 0, 
  0, 11, 11, 11, 11, 11, 11, 11, 
  11, 2205, 11, 11, 11, 11, 11, 11, 
  11, 11, 11, 11, 11, 11, 11, 11, 
  11, 11, 11, 11, 11, 11, 11, 11, 
  11, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 543, 543, 569, 569, 543, 543, 543, 
  543, 569, 569, 569, 543, 543, 842, 842, 
  842, 842, 543, 842, 842, 842, 569, 569, 
  543, 556, 543, 569, 569, 556, 556, 556, 
  556, 543, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2206, 2207, 2208, 2209, 77, 2210, 2211, 
  2212, 77, 2213, 2214, 2215, 2215, 2215, 2216, 
  2217, 2218, 2218, 2219, 2220, 77, 2221, 2222, 
  77, 75, 2223, 2224, 2225, 2225, 2225, 77, 
  77, 2226, 2227, 2228, 77, 2229, 77, 2230, 
  77, 2229, 77, 2231, 2232, 2233, 2208, 84, 
  2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 
  2242, 2243, 2244, 77, 2245, 2246, 2247, 2248, 
  2249, 2250, 75, 75, 75, 75, 2251, 2252, 
  2234, 2253, 2254, 77, 75, 77, 77, 2255, 
  841, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 
  2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 
  2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 
  2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 
  2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 
  2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 
  2303, 1458, 1458, 1458, 2304, 2305, 1458, 1458, 
  1458, 1458, 2306, 77, 77, 0, 0, 0, 
  0, 2307, 75, 2308, 75, 2309, 79, 79, 
  79, 79, 79, 2310, 2311, 77, 77, 77, 
  77, 75, 77, 77, 75, 77, 77, 75, 
  77, 77, 79, 79, 77, 77, 77, 2312, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 2313, 2314, 
  2315, 2316, 77, 2317, 77, 2318, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 2319, 2319, 2320, 2321, 75, 75, 
  75, 2322, 2323, 2319, 2324, 2325, 2319, 75, 
  75, 75, 2319, 14, 85, 75, 2319, 2319, 
  75, 75, 75, 2319, 2319, 2319, 2319, 75, 
  2319, 2319, 2319, 2319, 2326, 2327, 2328, 2329, 
  75, 75, 75, 75, 2319, 2330, 2331, 2319, 
  2332, 2333, 2319, 2319, 2319, 75, 75, 75, 
  75, 75, 2319, 75, 2319, 2334, 2319, 2319, 
  2319, 2319, 2335, 2319, 2336, 2337, 2338, 2319, 
  2339, 2340, 2341, 2319, 2319, 2319, 2342, 75, 
  75, 75, 75, 2319, 2319, 2319, 2319, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  2319, 2343, 2344, 2345, 75, 2346, 2347, 2319, 
  2319, 2319, 2319, 2319, 2319, 75, 2348, 2349, 
  2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 
  2358, 2359, 2360, 2361, 2362, 2363, 2364, 2319, 
  2319, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 
  2372, 2373, 2374, 2319, 2319, 2319, 75, 75, 
  2319, 2319, 2375, 2376, 75, 75, 75, 75, 
  75, 2319, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 2377, 2319, 75, 75, 2319, 
  2319, 2378, 2379, 2319, 2380, 2381, 2382, 2383, 
  2384, 2319, 2319, 2385, 2386, 2387, 2388, 2319, 
  2319, 2319, 75, 75, 75, 75, 75, 2319, 
  2319, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 2319, 2319, 2319, 2319, 2319, 75, 
  75, 2319, 2319, 75, 75, 75, 75, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2389, 2390, 2391, 2392, 2319, 2319, 2319, 
  2319, 2319, 2319, 2393, 2394, 2395, 2396, 75, 
  75, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 77, 77, 77, 77, 77, 77, 77, 
  77, 12, 13, 12, 13, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 2397, 2397, 77, 77, 77, 
  77, 2319, 2319, 77, 77, 77, 77, 77, 
  77, 79, 2398, 2399, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 77, 75, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 79, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 841, 77, 
  77, 77, 77, 77, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  79, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 75, 75, 75, 
  75, 75, 75, 77, 77, 77, 77, 77, 
  77, 77, 2397, 2397, 2397, 2397, 79, 79, 
  79, 2397, 79, 79, 2397, 77, 77, 77, 
  77, 79, 79, 79, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 
  2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 
  2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 
  2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 
  2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 
  2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 
  2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, 
  2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 
  2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 
  2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 
  2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 
  2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 
  2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 
  2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 
  2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 
  2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 
  2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 
  2535, 2536, 2537, 2538, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 79, 79, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 79, 
  75, 77, 77, 77, 77, 77, 77, 77, 
  77, 79, 75, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 75, 75, 75, 2539, 2539, 2540, 2540, 
  75, 79, 79, 79, 79, 79, 79, 77, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 77, 2397, 2397, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  2539, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  2397, 79, 79, 79, 79, 79, 79, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 79, 79, 79, 2397, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 2397, 79, 79, 79, 79, 79, 
  79, 79, 79, 2397, 2397, 2541, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 2397, 2397, 
  79, 79, 79, 79, 79, 2397, 2397, 79, 
  79, 79, 79, 79, 79, 79, 79, 2397, 
  79, 79, 79, 79, 79, 2397, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 2397, 79, 79, 79, 79, 
  79, 79, 79, 2397, 2397, 79, 2397, 79, 
  79, 79, 79, 2397, 79, 79, 2397, 79, 
  79, 79, 79, 79, 79, 79, 2397, 77, 
  77, 79, 79, 2397, 2397, 79, 79, 79, 
  79, 79, 79, 79, 77, 79, 77, 79, 
  77, 77, 77, 77, 77, 77, 79, 77, 
  77, 77, 79, 77, 77, 77, 77, 77, 
  77, 2397, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 79, 79, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 79, 77, 77, 
  79, 77, 77, 77, 77, 2397, 77, 2397, 
  77, 77, 77, 77, 2397, 2397, 2397, 77, 
  2397, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 79, 79, 79, 79, 
  79, 12, 13, 12, 13, 12, 13, 12, 
  13, 12, 13, 12, 13, 12, 13, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 77, 2397, 2397, 
  2397, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 79, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 2397, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  2397, 2319, 75, 75, 2319, 2319, 12, 13, 
  75, 2319, 2319, 75, 2319, 2319, 2319, 75, 
  75, 75, 75, 75, 2319, 2319, 2319, 2319, 
  75, 75, 75, 75, 75, 2319, 2319, 2319, 
  75, 75, 75, 2319, 2319, 2319, 2319, 12, 
  13, 12, 13, 12, 13, 12, 13, 12, 
  13, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 2539, 2539, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 12, 13, 12, 13, 
  12, 13, 12, 13, 12, 13, 12, 13, 
  12, 13, 12, 13, 12, 13, 12, 13, 
  12, 13, 75, 75, 2319, 2319, 2319, 2319, 
  2319, 2319, 75, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 75, 75, 75, 75, 75, 75, 75, 
  75, 2319, 75, 75, 75, 75, 75, 75, 
  75, 2319, 2319, 2319, 2319, 2319, 2319, 75, 
  75, 75, 2319, 75, 75, 75, 75, 2319, 
  2319, 2319, 2319, 2319, 75, 2319, 2319, 75, 
  75, 12, 13, 12, 13, 2319, 75, 75, 
  75, 75, 2319, 75, 2319, 2319, 2319, 75, 
  75, 2319, 2319, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 2319, 2319, 2319, 
  2319, 2319, 2319, 75, 75, 12, 13, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 2319, 2319, 2542, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 75, 2319, 
  2319, 2319, 2319, 75, 75, 2319, 75, 2319, 
  75, 75, 2319, 75, 2319, 2319, 2319, 2319, 
  75, 75, 75, 75, 75, 2319, 2319, 75, 
  75, 75, 75, 75, 75, 2319, 2319, 2319, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  2319, 2319, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 2319, 2319, 75, 
  75, 75, 75, 2319, 2319, 2319, 2319, 75, 
  2319, 2319, 75, 75, 2319, 2543, 2544, 2545, 
  75, 75, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 75, 75, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 75, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 
  75, 75, 75, 75, 75, 2546, 2547, 2319, 
  75, 75, 75, 2319, 2319, 2319, 2319, 2319, 
  75, 75, 75, 75, 75, 2319, 2319, 2319, 
  75, 75, 75, 75, 2319, 75, 75, 75, 
  2319, 2319, 2319, 2319, 2319, 75, 2319, 75, 
  75, 77, 77, 77, 77, 77, 79, 79, 
  79, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 2397, 2397, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 75, 75, 
  75, 75, 75, 75, 75, 75, 77, 77, 
  75, 75, 75, 75, 75, 75, 77, 77, 
  77, 2397, 77, 77, 77, 77, 2397, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 0, 0, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 2548, 
  77, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 
  2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 
  2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 
  2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 
  2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587, 
  2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 
  0, 2596, 2597, 2598, 2599, 2600, 2601, 2602, 
  2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 
  2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 
  2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 
  2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 
  2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 
  0, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 
  2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 
  2658, 2659, 215, 2660, 2661, 215, 2662, 2663, 
  215, 215, 215, 215, 215, 2664, 2665, 2666, 
  2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 
  2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 
  2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 
  2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 
  2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 
  2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 
  2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 
  2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 
  2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 
  2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 
  2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 
  2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 
  2763, 2764, 2765, 2766, 2767, 215, 77, 77, 
  77, 77, 77, 77, 2768, 2769, 2770, 2771, 
  543, 543, 543, 2772, 2773, 0, 0, 0, 
  0, 0, 9, 9, 9, 9, 1211, 9, 
  9, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 
  2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 
  2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 
  2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 
  2805, 2806, 2807, 2808, 2809, 2810, 2811, 0, 
  2812, 0, 0, 0, 0, 0, 2813, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  2814, 1047, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  1163, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 9, 9, 81, 93, 81, 93, 9, 
  9, 9, 81, 93, 9, 81, 93, 9, 
  9, 9, 9, 9, 9, 9, 9, 9, 
  1087, 9, 9, 1087, 9, 81, 93, 9, 
  9, 81, 93, 12, 13, 12, 13, 12, 
  13, 12, 13, 9, 9, 9, 9, 9, 
  524, 9, 9, 9, 9, 9, 9, 9, 
  9, 9, 9, 1087, 1087, 9, 9, 9, 
  9, 1087, 9, 2137, 9, 9, 9, 9, 
  9, 9, 9, 9, 9, 9, 9, 9, 
  9, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 0, 2815, 2815, 2815, 2815, 
  2816, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2817, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 
  2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 
  2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 
  2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 
  2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 
  2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 
  2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 
  2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 
  2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 
  2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 
  2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 
  2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 
  2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 
  2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 
  2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 
  2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, 
  2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 
  2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 
  2961, 2962, 2963, 2964, 2965, 2966, 2967, 2968, 
  2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 
  2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 
  2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 
  2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 
  3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 
  3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 
  3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 
  3025, 3026, 3027, 3028, 3029, 3030, 3031, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 0, 0, 0, 
  0, 3032, 3033, 3033, 3033, 2815, 3034, 3035, 
  3036, 3037, 3038, 3037, 3038, 3037, 3038, 3037, 
  3038, 3037, 3038, 2815, 2815, 3037, 3038, 3037, 
  3038, 3037, 3038, 3037, 3038, 3039, 3040, 3041, 
  3041, 2815, 3036, 3036, 3036, 3036, 3036, 3036, 
  3036, 3036, 3036, 3042, 1089, 555, 1088, 3043, 
  3043, 3044, 3034, 3034, 3034, 3034, 3034, 3045, 
  2815, 3046, 3047, 3048, 3034, 3035, 3049, 2815, 
  77, 0, 3035, 3035, 3035, 3035, 3035, 3050, 
  3035, 3035, 3035, 3035, 3051, 3052, 3053, 3054, 
  3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 
  3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 
  3071, 3072, 3073, 3074, 3035, 3075, 3076, 3077, 
  3078, 3079, 3080, 3035, 3035, 3035, 3035, 3035, 
  3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 
  3089, 3090, 3091, 3092, 3093, 3094, 3095, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3096, 3035, 3035, 
  0, 0, 3097, 3098, 3099, 3100, 3101, 3102, 
  3103, 3039, 3035, 3035, 3035, 3035, 3035, 3104, 
  3035, 3035, 3035, 3035, 3105, 3106, 3107, 3108, 
  3109, 3110, 3111, 3112, 3113, 3114, 3115, 3116, 
  3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 
  3125, 3126, 3127, 3128, 3035, 3129, 3130, 3131, 
  3132, 3133, 3134, 3035, 3035, 3035, 3035, 3035, 
  3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 
  3143, 3144, 3145, 3146, 3147, 3148, 3149, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3150, 3151, 3152, 3153, 3035, 3154, 3035, 3035, 
  3155, 3156, 3157, 3158, 3033, 3034, 3159, 3160, 
  3161, 0, 0, 0, 0, 0, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 0, 3162, 3163, 3164, 3165, 3166, 3167, 
  3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 
  3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 
  3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 
  3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 
  3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 
  3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 
  3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 
  3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 
  3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 
  3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 
  3248, 3249, 3250, 3251, 3252, 3253, 3254, 3255, 
  0, 3256, 3256, 3257, 3258, 3259, 3260, 3261, 
  3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 
  3270, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 0, 0, 0, 0, 
  0, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 
  3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 
  3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 
  3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 
  0, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 
  3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 
  3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 
  3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 
  3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 
  3341, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 
  3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 
  3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, 
  3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 
  3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 
  3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 
  3256, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 
  3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 
  3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 
  3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419, 
  3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 
  3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 
  3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 
  3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 
  3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, 
  3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 
  3468, 3469, 3470, 3471, 3472, 3473, 3474, 3475, 
  3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 
  3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 
  3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 
  3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 
  3508, 3509, 3510, 3511, 3512, 3513, 3514, 3515, 
  3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 
  3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 
  3532, 3533, 3534, 3535, 3536, 3537, 3538, 3539, 
  3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 
  3548, 3549, 3550, 3551, 3552, 3553, 3554, 3555, 
  3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 
  3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 
  3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 
  3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 
  3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 
  3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 
  3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 
  3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 
  3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 
  3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 
  3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 
  3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 
  3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 
  3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 
  3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 
  3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 
  3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691, 
  3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 
  3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 
  3708, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 
  3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 
  3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 
  3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 
  3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 
  3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 
  3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 
  3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 
  3772, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3034, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 0, 0, 
  0, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 525, 525, 525, 525, 525, 525, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 525, 9, 9, 
  9, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 341, 341, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 
  3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 
  3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 
  3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 
  3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 
  3812, 3813, 3814, 3815, 3816, 3817, 3818, 341, 
  543, 842, 842, 842, 9, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 9, 
  524, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 
  3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 
  3834, 3835, 3836, 3837, 3838, 3839, 3840, 3841, 
  3842, 3843, 3844, 3845, 3846, 3847, 3848, 543, 
  543, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 543, 543, 1047, 1047, 1047, 1047, 1047, 
  1047, 0, 0, 0, 0, 0, 0, 0, 
  0, 526, 526, 526, 526, 526, 526, 526, 
  526, 526, 526, 526, 526, 526, 526, 526, 
  526, 526, 526, 526, 526, 526, 526, 526, 
  524, 524, 524, 524, 524, 524, 524, 524, 
  524, 526, 526, 3849, 3850, 3851, 3852, 3853, 
  3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 
  3862, 215, 215, 3863, 3864, 3865, 3866, 3867, 
  3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 
  3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 
  3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 
  3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 
  3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 
  3908, 3909, 3910, 3911, 3912, 3913, 3914, 3915, 
  3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 
  3924, 3925, 215, 215, 215, 215, 215, 215, 
  215, 215, 3926, 3927, 3928, 3929, 3930, 3931, 
  3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, 
  3940, 524, 3941, 3941, 3942, 3943, 3944, 215, 
  341, 3945, 3946, 3947, 3948, 3949, 215, 3950, 
  3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 
  3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 
  3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, 
  215, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 
  3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 
  3990, 0, 0, 3991, 3992, 3993, 3994, 3995, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  341, 3996, 3997, 215, 341, 341, 341, 341, 
  341, 341, 341, 1151, 341, 341, 341, 1163, 
  341, 341, 341, 341, 1151, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1155, 1155, 1151, 1151, 
  1155, 77, 77, 77, 77, 0, 0, 0, 
  0, 1182, 1182, 1182, 1182, 1182, 1182, 841, 
  841, 11, 84, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 9, 9, 9, 
  9, 0, 0, 0, 0, 0, 0, 0, 
  0, 1155, 1155, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1163, 1151, 0, 
  0, 0, 0, 0, 0, 0, 0, 1047, 
  1047, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 341, 341, 341, 341, 341, 
  341, 1047, 1047, 1047, 341, 1047, 341, 341, 
  1151, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 1151, 
  1151, 1151, 1151, 1151, 556, 556, 556, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1155, 1483, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  1047, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
  1361, 1361, 1361, 1361, 1361, 1361, 0, 0, 
  0, 1151, 1151, 1151, 1155, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1173, 1155, 1155, 1151, 
  1151, 1151, 1151, 1155, 1155, 1151, 1151, 1155, 
  1155, 1483, 1047, 1047, 1047, 1047, 1047, 1047, 
  1047, 1047, 1047, 1047, 1047, 1047, 1047, 0, 
  525, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 1047, 
  1047, 341, 341, 341, 341, 341, 1151, 525, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1151, 1151, 1151, 1151, 1151, 1151, 
  1155, 1155, 1151, 1151, 1155, 1155, 1151, 1151, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 1151, 341, 341, 341, 
  341, 341, 341, 341, 341, 1151, 1155, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 1047, 1047, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 525, 341, 341, 341, 341, 341, 341, 
  841, 841, 841, 341, 1272, 1151, 1272, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 543, 341, 543, 543, 556, 341, 341, 
  543, 543, 341, 341, 341, 341, 341, 543, 
  543, 341, 543, 341, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 341, 341, 525, 1047, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1155, 1151, 1151, 1155, 
  1155, 1047, 1047, 341, 525, 525, 1155, 1163, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 341, 341, 341, 341, 341, 341, 
  0, 0, 341, 341, 341, 341, 341, 341, 
  0, 0, 341, 341, 341, 341, 341, 341, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 215, 215, 215, 215, 
  215, 215, 215, 215, 3998, 215, 215, 215, 
  215, 215, 215, 215, 3941, 3999, 4000, 4001, 
  4002, 215, 215, 215, 215, 215, 215, 215, 
  215, 0, 0, 0, 0, 0, 0, 0, 
  0, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 
  4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 
  4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 
  4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 
  4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 
  4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 
  4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 
  4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 
  4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 
  4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 
  4082, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1155, 1155, 1151, 1155, 
  1155, 1151, 1155, 1155, 1047, 1155, 1163, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4083, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 
  4084, 4084, 4084, 4084, 4084, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 
  0, 0, 0, 0, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 
  1365, 1365, 1365, 1365, 1365, 0, 0, 0, 
  0, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 
  4085, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 
  4094, 4094, 4095, 4096, 4097, 4098, 4099, 4100, 
  4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 
  4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116, 
  4117, 4118, 4119, 4120, 4121, 4122, 4123, 4124, 
  4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 
  4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 
  4141, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 
  4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 
  4157, 4158, 4159, 4160, 4161, 4162, 4163, 4164, 
  4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 
  4173, 4174, 4175, 4176, 4177, 4106, 4178, 4179, 
  4180, 4181, 4182, 4183, 4184, 4185, 4186, 4187, 
  4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 
  4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 
  4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 
  4212, 4213, 4214, 4215, 4216, 4217, 4218, 4219, 
  4220, 4221, 4222, 4223, 4224, 4225, 4226, 4227, 
  4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 
  4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 
  4244, 4245, 4196, 4246, 4247, 4248, 4249, 4250, 
  4251, 4252, 4253, 4180, 4254, 4255, 4256, 4257, 
  4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 
  4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 
  4106, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 
  4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 
  4289, 4290, 4291, 4292, 4293, 4294, 4295, 4296, 
  4297, 4298, 4299, 4300, 4182, 4301, 4302, 4303, 
  4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 
  4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 
  4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 
  4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 
  4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 
  4344, 4345, 4346, 4347, 4348, 4349, 4350, 3035, 
  3035, 4351, 3035, 4352, 3035, 3035, 4353, 4354, 
  4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 
  3035, 4363, 3035, 4364, 3035, 3035, 4365, 4366, 
  3035, 3035, 3035, 4367, 4368, 4369, 4370, 4371, 
  4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, 
  4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 
  4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 
  4396, 4397, 4398, 4399, 4400, 4401, 4402, 4403, 
  4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 
  4235, 4412, 4413, 4414, 4415, 4416, 4417, 4417, 
  4418, 4419, 4420, 4421, 4422, 4423, 4424, 4425, 
  4365, 4426, 4427, 4428, 4429, 4430, 4431, 0, 
  0, 4432, 4433, 4434, 4435, 4436, 4437, 4438, 
  4439, 4379, 4440, 4441, 4442, 4351, 4443, 4444, 
  4445, 4446, 4447, 4448, 4449, 4450, 4451, 4452, 
  4453, 4454, 4388, 4455, 4389, 4456, 4457, 4458, 
  4459, 4460, 4352, 4127, 4461, 4462, 4463, 4197, 
  4284, 4464, 4465, 4396, 4466, 4397, 4467, 4468, 
  4469, 4354, 4470, 4471, 4472, 4473, 4474, 4355, 
  4475, 4476, 4477, 4478, 4479, 4480, 4411, 4481, 
  4482, 4235, 4483, 4415, 4484, 4485, 4486, 4487, 
  4488, 4420, 4489, 4364, 4490, 4421, 4178, 4491, 
  4422, 4492, 4424, 4493, 4494, 4495, 4496, 4497, 
  4426, 4360, 4498, 4427, 4499, 4428, 4500, 4094, 
  4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, 
  4509, 4510, 4511, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 4519, 4520, 4521, 4522, 
  4523, 0, 0, 0, 0, 0, 4524, 4525, 
  4526, 4527, 4528, 4529, 4530, 4531, 4532, 4533, 
  4534, 4535, 4536, 4537, 4538, 4539, 4540, 4541, 
  4542, 4543, 4544, 4545, 4546, 4547, 4548, 4549, 
  0, 4550, 4551, 4552, 4553, 4554, 0, 4555, 
  0, 4556, 4557, 0, 4558, 4559, 0, 4560, 
  4561, 4562, 4563, 4564, 4565, 4566, 4567, 4568, 
  4569, 4570, 4571, 4572, 4573, 4574, 4575, 4576, 
  4577, 4578, 4579, 4580, 4581, 4582, 4583, 4584, 
  4585, 4586, 4587, 4588, 4589, 4590, 4591, 4592, 
  4593, 4594, 4595, 4596, 4597, 4598, 4599, 4600, 
  4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, 
  4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 
  4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 
  4625, 4626, 4627, 4628, 4629, 4630, 4631, 4632, 
  4633, 4634, 4635, 4636, 4637, 4638, 4639, 4640, 
  4641, 4642, 4643, 4644, 4645, 4646, 4647, 4648, 
  4649, 4650, 4651, 4652, 4653, 4654, 4655, 4656, 
  4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 
  4665, 4666, 4667, 4668, 4668, 4668, 4668, 4668, 
  4668, 4668, 4668, 4668, 4668, 4668, 4668, 4668, 
  4668, 4668, 4668, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 4669, 4670, 4671, 4672, 
  4673, 4674, 4675, 4676, 4677, 4678, 4679, 4680, 
  4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 
  4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 
  4697, 4698, 4699, 4700, 4701, 4702, 4703, 4704, 
  4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 
  4713, 4714, 4715, 4716, 4707, 4717, 4718, 4719, 
  4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 
  4728, 4729, 4730, 4731, 4732, 4733, 4734, 4735, 
  4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, 
  4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 
  4752, 4753, 4754, 4755, 4756, 4757, 4758, 4759, 
  4760, 4761, 4762, 4763, 4764, 4765, 4766, 4767, 
  4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, 
  4776, 4777, 4778, 4779, 4780, 4781, 4782, 4783, 
  4784, 4785, 4786, 4787, 4788, 4789, 4790, 4791, 
  4792, 4793, 4794, 4795, 4796, 4797, 4798, 4799, 
  4800, 4801, 4802, 4803, 4804, 4805, 4806, 4807, 
  4808, 4809, 4810, 4811, 4812, 4813, 4814, 4815, 
  4816, 4708, 4817, 4818, 4819, 4820, 4821, 4822, 
  4823, 4824, 4825, 4826, 4827, 4828, 4829, 4830, 
  4831, 4832, 4833, 4834, 4835, 4836, 4837, 4838, 
  4839, 4840, 4841, 4842, 4843, 4844, 4845, 4846, 
  4847, 4848, 4849, 4850, 4851, 4852, 4853, 4854, 
  4855, 4856, 4857, 4858, 4859, 4860, 4861, 4862, 
  4863, 4864, 4865, 4866, 4867, 4868, 4869, 4870, 
  4871, 4872, 4873, 4874, 4875, 4876, 4877, 4878, 
  4879, 4880, 4881, 4882, 4883, 4884, 4885, 4886, 
  4887, 4888, 4889, 4890, 4891, 4892, 4893, 4894, 
  4895, 4896, 4897, 4898, 4899, 4900, 4901, 4902, 
  4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 
  4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 
  4919, 4920, 4921, 4922, 4923, 4924, 4925, 4926, 
  4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 
  4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 
  4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 
  4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 
  4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 
  4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 
  4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 
  4983, 4984, 4985, 4986, 4987, 4988, 4989, 4990, 
  4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998, 
  4999, 5000, 5001, 5002, 5003, 5004, 5005, 5006, 
  5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, 
  5015, 5016, 5017, 5018, 5019, 5020, 5021, 5022, 
  5023, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 
  2137, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5031, 5032, 5033, 5034, 5035, 5036, 5037, 
  5038, 5039, 5040, 5041, 5042, 5043, 5044, 5045, 
  5046, 5047, 5048, 5049, 5050, 5051, 5052, 5053, 
  5054, 5055, 5056, 5057, 5058, 5059, 5060, 5061, 
  5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, 
  5070, 5071, 5072, 5073, 5074, 5075, 5076, 5077, 
  5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 
  5086, 5087, 5088, 5089, 5090, 5091, 5092, 5093, 
  5094, 0, 0, 5095, 5096, 5097, 5098, 5099, 
  5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 
  5108, 5109, 5110, 5111, 5112, 5113, 5114, 5115, 
  5116, 5117, 5118, 5119, 5120, 5121, 5122, 5123, 
  5124, 5125, 5126, 5127, 5128, 5129, 5130, 5131, 
  5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139, 
  5140, 5141, 5142, 5143, 5144, 5145, 5146, 5147, 
  5148, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5149, 5150, 5151, 5152, 5153, 5154, 5155, 
  5156, 5157, 5158, 5159, 5160, 5161, 77, 0, 
  0, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 5162, 5163, 5164, 5165, 5166, 5167, 5168, 
  5169, 5170, 5171, 0, 0, 0, 0, 0, 
  0, 543, 543, 543, 543, 543, 543, 543, 
  556, 556, 556, 556, 556, 556, 556, 543, 
  543, 5172, 5173, 5174, 5175, 5175, 5176, 5177, 
  5178, 5179, 5180, 5181, 5182, 5183, 5184, 5185, 
  5186, 5187, 5188, 5189, 5190, 5191, 3033, 3033, 
  5192, 5193, 5194, 5194, 5194, 5194, 5195, 5195, 
  5195, 5196, 5197, 5198, 0, 5199, 5200, 5201, 
  5202, 5203, 5204, 5205, 5206, 5207, 5208, 5209, 
  5210, 5211, 5212, 5213, 5214, 5215, 5216, 5217, 
  0, 5218, 5219, 5220, 5221, 0, 0, 0, 
  0, 5222, 5223, 5224, 1117, 5225, 0, 5226, 
  5227, 5228, 5229, 5230, 5231, 5232, 5233, 5234, 
  5235, 5236, 5237, 5238, 5239, 5240, 5241, 5242, 
  5243, 5244, 5245, 5246, 5247, 5248, 5249, 5250, 
  5251, 5252, 5253, 5254, 5255, 5256, 5257, 5258, 
  5259, 5260, 5261, 5262, 5263, 5264, 5265, 5266, 
  5267, 5268, 5269, 5270, 5271, 5272, 5273, 5274, 
  5275, 5276, 5277, 5278, 5279, 5280, 5281, 5282, 
  5283, 5284, 5285, 5286, 5287, 5288, 5289, 5290, 
  5291, 5292, 5293, 5294, 5295, 5296, 5297, 5298, 
  5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, 
  5307, 5308, 5309, 5310, 5311, 5312, 5313, 5314, 
  5315, 5316, 5317, 5318, 5319, 5320, 5321, 5322, 
  5323, 5324, 5325, 5326, 5327, 5328, 5329, 5330, 
  5331, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 
  5339, 5340, 5341, 5342, 5343, 5344, 5345, 5346, 
  5347, 5348, 5349, 5350, 5351, 5352, 5353, 5354, 
  5355, 5356, 5357, 5358, 5359, 5360, 0, 0, 
  1459, 0, 5361, 5362, 5363, 5364, 5365, 5366, 
  5367, 5368, 5369, 5370, 5371, 5372, 5373, 5374, 
  5375, 5376, 5377, 5378, 5379, 5380, 5381, 5382, 
  5383, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 
  5391, 5392, 5393, 5394, 5395, 5396, 5397, 5398, 
  5399, 5400, 5401, 5402, 5403, 5404, 5405, 5406, 
  5407, 5408, 5409, 5410, 5411, 5412, 5413, 5414, 
  5415, 5416, 5417, 5418, 5419, 5420, 5421, 5422, 
  5423, 5424, 5425, 5426, 5427, 5428, 5429, 5430, 
  5431, 5432, 5433, 5434, 5435, 5436, 5437, 5438, 
  5439, 5440, 5441, 5442, 5443, 5444, 5445, 5446, 
  5447, 5448, 5449, 5450, 5451, 5452, 5453, 5454, 
  5455, 5456, 5457, 5458, 5459, 5460, 5461, 5462, 
  5463, 5464, 5465, 5466, 5467, 5468, 5469, 5470, 
  5471, 5472, 5473, 5474, 5475, 5476, 5477, 5478, 
  5479, 5480, 5481, 5482, 5483, 5484, 5485, 5486, 
  5487, 5488, 5489, 5490, 5491, 5492, 5493, 5494, 
  5495, 5496, 5497, 5498, 5499, 5500, 5501, 5502, 
  5503, 5504, 5505, 5506, 5507, 5508, 5509, 5510, 
  5511, 5512, 5513, 5514, 5515, 5516, 5517, 5518, 
  5519, 5520, 5521, 5522, 5523, 5524, 5525, 5526, 
  5527, 5528, 5529, 5530, 5531, 5532, 5533, 5534, 
  5535, 5536, 5537, 5538, 5539, 5540, 5541, 5542, 
  5543, 5544, 5545, 5546, 5547, 5548, 5549, 5550, 
  0, 0, 0, 5551, 5552, 5553, 5554, 5555, 
  5556, 0, 0, 5557, 5558, 5559, 5560, 5561, 
  5562, 0, 0, 5563, 5564, 5565, 5566, 5567, 
  5568, 0, 0, 5569, 5570, 5571, 0, 0, 
  0, 5572, 5573, 5574, 5575, 5576, 5577, 5578, 
  0, 5579, 5580, 5581, 5582, 5583, 5584, 5585, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 5586, 5586, 5586, 77, 77, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 0, 341, 341, 0, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 0, 0, 0, 0, 
  0, 1047, 9, 1047, 0, 0, 0, 0, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 0, 0, 0, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 5587, 5587, 5587, 5587, 5587, 5587, 5587, 
  5587, 5587, 5587, 5587, 5587, 5587, 5587, 5587, 
  5587, 5587, 5587, 5587, 5587, 5587, 5587, 5587, 
  5587, 5587, 5587, 5587, 5587, 5587, 5587, 5587, 
  5587, 5587, 5587, 5587, 5587, 5587, 5587, 5587, 
  5587, 5587, 5587, 5587, 5587, 5587, 5587, 5587, 
  5587, 5587, 5587, 5587, 5587, 5587, 1211, 1211, 
  1211, 1211, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 1211, 1211, 77, 841, 841, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 0, 0, 0, 
  0, 77, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 556, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 556, 5588, 5588, 5588, 5588, 5588, 5588, 
  5588, 5588, 5588, 5588, 5588, 5588, 5588, 5588, 
  5588, 5588, 5588, 5588, 5588, 5588, 5588, 5588, 
  5588, 5588, 5588, 5588, 5588, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 1182, 1182, 1182, 1182, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1458, 341, 341, 341, 341, 341, 
  341, 341, 341, 1458, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 543, 
  543, 543, 543, 543, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 1047, 1458, 1458, 1458, 1458, 1458, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5589, 5590, 5591, 5592, 5593, 5594, 5595, 
  5596, 5597, 5598, 5599, 5600, 5601, 5602, 5603, 
  5604, 5605, 5606, 5607, 5608, 5609, 5610, 5611, 
  5612, 5613, 5614, 5615, 5616, 5617, 5618, 5619, 
  5620, 5621, 5622, 5623, 5624, 5625, 5626, 5627, 
  5628, 5629, 5630, 5631, 5632, 5633, 5634, 5635, 
  5636, 5637, 5638, 5639, 5640, 5641, 5642, 5643, 
  5644, 5645, 5646, 5647, 5648, 5649, 5650, 5651, 
  5652, 5653, 5654, 5655, 5656, 5657, 5658, 5659, 
  5660, 5661, 5662, 5663, 5664, 5665, 5666, 5667, 
  5668, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 5669, 5670, 5671, 5672, 5673, 5674, 5675, 
  5676, 5677, 5678, 5679, 5680, 5681, 5682, 5683, 
  5684, 5685, 5686, 5687, 5688, 5689, 5690, 5691, 
  5692, 5693, 5694, 5695, 5696, 5697, 5698, 5699, 
  5700, 5701, 5702, 5703, 5704, 0, 0, 0, 
  0, 5705, 5706, 5707, 5708, 5709, 5710, 5711, 
  5712, 5713, 5714, 5715, 5716, 5717, 5718, 5719, 
  5720, 5721, 5722, 5723, 5724, 5725, 5726, 5727, 
  5728, 5729, 5730, 5731, 5732, 5733, 5734, 5735, 
  5736, 5737, 5738, 5739, 5740, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  1047, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 0, 
  0, 1108, 0, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 0, 
  1108, 1108, 0, 0, 0, 1108, 0, 0, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 0, 
  1105, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  5742, 5742, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 0, 1108, 1108, 0, 
  0, 0, 0, 0, 5741, 5741, 5741, 5741, 
  5741, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 5741, 
  5741, 5741, 5741, 5741, 5741, 0, 0, 0, 
  9, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 0, 0, 0, 0, 0, 
  1105, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 0, 0, 0, 0, 5741, 5741, 1108, 
  1108, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 0, 0, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 1108, 1151, 1151, 1151, 0, 1151, 1151, 
  0, 0, 0, 0, 0, 1151, 556, 1151, 
  543, 1108, 1108, 1108, 1108, 0, 1108, 1108, 
  1108, 0, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 0, 
  0, 543, 569, 556, 0, 0, 0, 0, 
  1163, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 5741, 0, 0, 0, 0, 0, 0, 
  0, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 
  1105, 1105, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 5741, 5741, 
  1105, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 5741, 5741, 
  5741, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 5742, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 543, 556, 
  0, 0, 0, 0, 5741, 5741, 5741, 5741, 
  5741, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 0, 
  0, 0, 9, 9, 9, 9, 9, 9, 
  9, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 0, 
  0, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 0, 0, 0, 0, 
  0, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 0, 0, 0, 0, 0, 
  0, 0, 1105, 1105, 1105, 1105, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5743, 5744, 5745, 5746, 5747, 5748, 5749, 
  5750, 5751, 5752, 5753, 5754, 5755, 5756, 5757, 
  5758, 5759, 5760, 5761, 5762, 5763, 5764, 5765, 
  5766, 5767, 5768, 5769, 5770, 5771, 5772, 5773, 
  5774, 5775, 5776, 5777, 5778, 5779, 5780, 5781, 
  5782, 5783, 5784, 5785, 5786, 5787, 5788, 5789, 
  5790, 5791, 5792, 5793, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5794, 5795, 5796, 5797, 5798, 5799, 5800, 
  5801, 5802, 5803, 5804, 5805, 5806, 5807, 5808, 
  5809, 5810, 5811, 5812, 5813, 5814, 5815, 5816, 
  5817, 5818, 5819, 5820, 5821, 5822, 5823, 5824, 
  5825, 5826, 5827, 5828, 5829, 5830, 5831, 5832, 
  5833, 5834, 5835, 5836, 5837, 5838, 5839, 5840, 
  5841, 5842, 5843, 5844, 0, 0, 0, 0, 
  0, 0, 0, 5741, 5741, 5741, 5741, 5741, 
  5741, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 543, 543, 543, 
  543, 0, 0, 0, 0, 0, 0, 0, 
  0, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 
  1135, 1135, 1135, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5845, 5845, 5845, 5845, 5845, 5845, 5845, 
  5845, 5845, 5845, 5845, 5845, 5845, 5845, 5845, 
  5845, 5845, 5845, 5845, 5845, 5845, 5845, 5845, 
  5845, 5845, 5845, 5845, 5845, 5845, 5845, 5845, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 5741, 5741, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  1108, 0, 0, 0, 0, 0, 0, 0, 
  0, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 
  1117, 1117, 1117, 1117, 1117, 1117, 1117, 556, 
  556, 543, 543, 543, 556, 543, 556, 556, 
  556, 556, 5846, 5846, 5846, 5846, 1112, 1112, 
  1112, 1112, 1112, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1155, 1151, 1155, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1163, 
  1047, 1047, 1047, 1047, 1047, 1047, 1047, 0, 
  0, 0, 0, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 
  1211, 1211, 1211, 1211, 1211, 1211, 1211, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  1163, 1151, 1151, 1155, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 5847, 5848, 5849, 5850, 341, 341, 
  341, 341, 341, 341, 341, 341, 5851, 341, 
  341, 341, 341, 341, 5852, 341, 341, 341, 
  341, 1155, 1155, 1155, 1151, 1151, 1151, 1151, 
  1155, 1155, 1163, 5853, 1047, 1047, 5854, 1047, 
  1047, 1047, 1047, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 5854, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 543, 543, 543, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  5855, 1151, 1151, 1151, 1151, 1155, 1151, 5856, 
  5857, 1151, 5858, 5859, 1163, 1163, 0, 1172, 
  1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1047, 1047, 1047, 1047, 341, 1155, 1155, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1173, 1047, 1047, 341, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1151, 1151, 1155, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1155, 1155, 1155, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1155, 1483, 341, 1228, 1228, 341, 1047, 1047, 
  1047, 1047, 1151, 1173, 1151, 1151, 1047, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 341, 1047, 341, 1047, 1047, 
  1047, 0, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 1155, 1155, 1155, 
  1151, 1151, 1151, 1155, 1155, 1151, 1483, 1173, 
  1151, 1047, 1047, 1047, 1047, 1047, 1047, 1151, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 0, 341, 341, 341, 341, 0, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1047, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  1151, 1155, 1155, 1155, 1151, 1151, 1151, 1151, 
  1151, 1151, 1173, 1163, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 1151, 1151, 1155, 1155, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 0, 
  341, 341, 0, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 0, 341, 341, 
  341, 341, 341, 0, 1173, 1173, 341, 5860, 
  1155, 1151, 1155, 1155, 1155, 1155, 0, 0, 
  5861, 1155, 0, 0, 5862, 5863, 1483, 0, 
  0, 341, 0, 0, 0, 0, 0, 0, 
  5864, 0, 0, 0, 0, 0, 341, 341, 
  341, 341, 341, 1155, 1155, 0, 0, 543, 
  543, 543, 543, 543, 543, 543, 0, 0, 
  0, 543, 543, 543, 543, 543, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 1155, 1155, 
  1155, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1155, 1155, 1163, 1151, 1151, 1155, 1173, 
  341, 341, 341, 341, 1047, 1047, 1047, 1047, 
  1047, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 1047, 0, 1047, 543, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 5865, 1155, 1155, 1151, 1151, 1151, 1151, 
  1151, 1151, 5866, 5867, 5868, 5869, 5870, 5871, 
  1151, 1151, 1155, 1163, 1173, 341, 341, 1047, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  5872, 1155, 1155, 1151, 1151, 1151, 1151, 0, 
  0, 5873, 5874, 5875, 5876, 1151, 1151, 1155, 
  1163, 1173, 1047, 1047, 1047, 1047, 1047, 1047, 
  1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 
  1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 
  1047, 341, 341, 341, 341, 1151, 1151, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 1155, 1155, 1155, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1155, 1155, 1151, 1155, 
  1163, 1151, 1047, 1047, 1047, 341, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 9, 9, 9, 9, 9, 9, 9, 
  9, 9, 9, 9, 9, 9, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1151, 1155, 1151, 1155, 
  1155, 1151, 1151, 1151, 1151, 1151, 1151, 1483, 
  1173, 341, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 0, 0, 1151, 1151, 
  1151, 1155, 1155, 1151, 1151, 1151, 1151, 1155, 
  1151, 1151, 1151, 1151, 1163, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1182, 1182, 1047, 1047, 1047, 
  841, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 1155, 1155, 1155, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1155, 1163, 1173, 1047, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5877, 5878, 5879, 5880, 5881, 5882, 5883, 
  5884, 5885, 5886, 5887, 5888, 5889, 5890, 5891, 
  5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 
  5900, 5901, 5902, 5903, 5904, 5905, 5906, 5907, 
  5908, 5909, 5910, 5911, 5912, 5913, 5914, 5915, 
  5916, 5917, 5918, 5919, 5920, 5921, 5922, 5923, 
  5924, 5925, 5926, 5927, 5928, 5929, 5930, 5931, 
  5932, 5933, 5934, 5935, 5936, 5937, 5938, 5939, 
  5940, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1155, 1155, 1155, 1151, 1151, 1151, 
  1151, 0, 0, 1151, 1151, 1155, 1155, 1155, 
  1155, 1163, 341, 1047, 341, 1155, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 1151, 1151, 1151, 1151, 1151, 1151, 
  5941, 5941, 1151, 1151, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1151, 1163, 1151, 1151, 
  1151, 1151, 1155, 1228, 1151, 1151, 1151, 1151, 
  1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 
  1163, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 1151, 1151, 1151, 1151, 1151, 1151, 
  1155, 1155, 1151, 1151, 1151, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 1228, 1228, 1228, 
  1228, 1228, 1228, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1155, 1151, 1163, 1047, 1047, 1047, 341, 1047, 
  1047, 1047, 1047, 1047, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  1155, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  0, 1151, 1151, 1151, 1151, 1151, 1151, 1155, 
  5942, 341, 1047, 1047, 1047, 1047, 1047, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 0, 0, 
  0, 1047, 1047, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 0, 1155, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1155, 1151, 1151, 1155, 1151, 1151, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  0, 341, 341, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 1151, 1151, 1151, 1151, 1151, 1151, 
  0, 0, 0, 1151, 0, 1151, 1151, 0, 
  1151, 1151, 1151, 1173, 1151, 1163, 1163, 1228, 
  1151, 0, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 0, 
  341, 341, 0, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 1155, 1155, 1155, 1155, 1155, 
  0, 1151, 1151, 0, 1155, 1155, 1151, 1155, 
  1163, 341, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 1151, 1151, 1155, 1155, 
  1047, 1047, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 77, 77, 
  77, 77, 77, 77, 77, 77, 11, 11, 
  11, 11, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  1047, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 
  0, 1047, 1047, 1047, 1047, 1047, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 5943, 5943, 5943, 5943, 5943, 5943, 5943, 
  5943, 5943, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 1047, 
  1047, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 0, 
  0, 569, 569, 569, 569, 569, 1047, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 543, 543, 543, 543, 543, 543, 543, 
  1047, 1047, 1047, 1047, 1047, 841, 841, 841, 
  841, 525, 525, 525, 525, 1047, 841, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 0, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 0, 0, 0, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 5944, 5945, 5946, 5947, 5948, 5949, 5950, 
  5951, 5952, 5953, 5954, 5955, 5956, 5957, 5958, 
  5959, 5960, 5961, 5962, 5963, 5964, 5965, 5966, 
  5967, 5968, 5969, 5970, 5971, 5972, 5973, 5974, 
  5975, 5976, 5977, 5978, 5979, 5980, 5981, 5982, 
  5983, 5984, 5985, 5986, 5987, 5988, 5989, 5990, 
  5991, 5992, 5993, 5994, 5995, 5996, 5997, 5998, 
  5999, 6000, 6001, 6002, 6003, 6004, 6005, 6006, 
  6007, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1047, 1047, 1047, 1047, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 0, 0, 0, 0, 
  1151, 341, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 
  1155, 0, 0, 0, 0, 0, 0, 0, 
  1151, 1151, 1151, 1151, 525, 525, 525, 525, 
  525, 525, 525, 525, 525, 525, 525, 525, 
  525, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3034, 3034, 3033, 3034, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 3035, 3035, 3035, 
  3035, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 0, 0, 841, 1151, 569, 
  1047, 1459, 1459, 1459, 1459, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  0, 0, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  6008, 6009, 841, 841, 841, 841, 841, 6010, 
  6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 
  569, 569, 569, 841, 841, 841, 6019, 6020, 
  6021, 6022, 6023, 6024, 1459, 1459, 1459, 1459, 
  1459, 1459, 1459, 1459, 556, 556, 556, 556, 
  556, 556, 556, 556, 841, 841, 543, 543, 
  543, 543, 543, 556, 556, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 543, 543, 543, 543, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 6025, 6026, 6027, 6028, 6029, 6030, 
  6031, 6032, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 543, 543, 543, 77, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 
  1182, 1182, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 6033, 2233, 2208, 2251, 2235, 2236, 6034, 
  2215, 2218, 6035, 6036, 2219, 2238, 2221, 6037, 
  2223, 2224, 2225, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 2229, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6033, 2233, 2208, 
  2251, 2235, 2236, 6034, 2215, 2218, 6035, 6036, 
  2219, 2238, 2221, 6037, 2223, 2224, 2225, 6038, 
  6039, 6040, 6041, 6042, 6043, 6044, 2229, 6045, 
  6046, 6047, 2252, 2234, 6048, 2214, 0, 2253, 
  2254, 6049, 2220, 6050, 6051, 2239, 6052, 6053, 
  6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 
  6062, 6033, 2233, 2208, 2251, 2235, 2236, 6034, 
  2215, 2218, 6035, 6036, 2219, 2238, 2221, 6037, 
  2223, 2224, 2225, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 2229, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6033, 0, 2208, 
  2251, 0, 0, 6034, 0, 0, 6035, 6036, 
  0, 0, 2221, 6037, 2223, 2224, 0, 6038, 
  6039, 6040, 6041, 6042, 6043, 6044, 2229, 6045, 
  6046, 6047, 2252, 0, 6048, 0, 2216, 2253, 
  2254, 6049, 2220, 6050, 6051, 0, 6052, 6053, 
  6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 
  6062, 6033, 2233, 2208, 2251, 2235, 2236, 6034, 
  2215, 2218, 6035, 6036, 2219, 2238, 2221, 6037, 
  2223, 2224, 2225, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 2229, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6033, 2233, 0, 
  2251, 2235, 2236, 6034, 0, 0, 6035, 6036, 
  2219, 2238, 2221, 6037, 2223, 2224, 0, 6038, 
  6039, 6040, 6041, 6042, 6043, 6044, 0, 6045, 
  6046, 6047, 2252, 2234, 6048, 2214, 2216, 2253, 
  2254, 6049, 2220, 6050, 6051, 2239, 6052, 6053, 
  6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 
  6062, 6033, 2233, 0, 2251, 2235, 2236, 6034, 
  0, 2218, 6035, 6036, 2219, 2238, 0, 6037, 
  0, 0, 0, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 0, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6033, 2233, 2208, 
  2251, 2235, 2236, 6034, 2215, 2218, 6035, 6036, 
  2219, 2238, 2221, 6037, 2223, 2224, 2225, 6038, 
  6039, 6040, 6041, 6042, 6043, 6044, 2229, 6045, 
  6046, 6047, 2252, 2234, 6048, 2214, 2216, 2253, 
  2254, 6049, 2220, 6050, 6051, 2239, 6052, 6053, 
  6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 
  6062, 6033, 2233, 2208, 2251, 2235, 2236, 6034, 
  2215, 2218, 6035, 6036, 2219, 2238, 2221, 6037, 
  2223, 2224, 2225, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 2229, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6033, 2233, 2208, 
  2251, 2235, 2236, 6034, 2215, 2218, 6035, 6036, 
  2219, 2238, 2221, 6037, 2223, 2224, 2225, 6038, 
  6039, 6040, 6041, 6042, 6043, 6044, 2229, 6045, 
  6046, 6047, 2252, 2234, 6048, 2214, 2216, 2253, 
  2254, 6049, 2220, 6050, 6051, 2239, 6052, 6053, 
  6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 
  6062, 6033, 2233, 2208, 2251, 2235, 2236, 6034, 
  2215, 2218, 6035, 6036, 2219, 2238, 2221, 6037, 
  2223, 2224, 2225, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 2229, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6033, 2233, 2208, 
  2251, 2235, 2236, 6034, 2215, 2218, 6035, 6036, 
  2219, 2238, 2221, 6037, 2223, 2224, 2225, 6038, 
  6039, 6040, 6041, 6042, 6043, 6044, 2229, 6045, 
  6046, 6047, 2252, 2234, 6048, 2214, 2216, 2253, 
  2254, 6049, 2220, 6050, 6051, 2239, 6052, 6053, 
  6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 
  6062, 6033, 2233, 2208, 2251, 2235, 2236, 6034, 
  2215, 2218, 6035, 6036, 2219, 2238, 2221, 6037, 
  2223, 2224, 2225, 6038, 6039, 6040, 6041, 6042, 
  6043, 6044, 2229, 6045, 6046, 6047, 2252, 2234, 
  6048, 2214, 2216, 2253, 2254, 6049, 2220, 6050, 
  6051, 2239, 6052, 6053, 6054, 6055, 6056, 6057, 
  6058, 6059, 6060, 6061, 6062, 6063, 6064, 0, 
  0, 6065, 6066, 2248, 6067, 6068, 6069, 6070, 
  6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 
  2249, 6079, 6080, 6081, 6082, 6083, 6084, 6085, 
  6086, 6087, 6088, 6089, 6090, 2247, 6091, 6092, 
  6093, 6094, 6095, 6096, 6097, 6098, 6099, 6100, 
  6101, 6102, 2246, 6103, 6104, 6105, 6106, 6107, 
  6108, 6109, 6110, 6111, 6112, 6113, 6114, 6115, 
  6116, 6117, 6118, 6065, 6066, 2248, 6067, 6068, 
  6069, 6070, 6071, 6072, 6073, 6074, 6075, 6076, 
  6077, 6078, 2249, 6079, 6080, 6081, 6082, 6083, 
  6084, 6085, 6086, 6087, 6088, 6089, 6090, 2247, 
  6091, 6092, 6093, 6094, 6095, 6096, 6097, 6098, 
  6099, 6100, 6101, 6102, 2246, 6103, 6104, 6105, 
  6106, 6107, 6108, 6109, 6110, 6111, 6112, 6113, 
  6114, 6115, 6116, 6117, 6118, 6065, 6066, 2248, 
  6067, 6068, 6069, 6070, 6071, 6072, 6073, 6074, 
  6075, 6076, 6077, 6078, 2249, 6079, 6080, 6081, 
  6082, 6083, 6084, 6085, 6086, 6087, 6088, 6089, 
  6090, 2247, 6091, 6092, 6093, 6094, 6095, 6096, 
  6097, 6098, 6099, 6100, 6101, 6102, 2246, 6103, 
  6104, 6105, 6106, 6107, 6108, 6109, 6110, 6111, 
  6112, 6113, 6114, 6115, 6116, 6117, 6118, 6065, 
  6066, 2248, 6067, 6068, 6069, 6070, 6071, 6072, 
  6073, 6074, 6075, 6076, 6077, 6078, 2249, 6079, 
  6080, 6081, 6082, 6083, 6084, 6085, 6086, 6087, 
  6088, 6089, 6090, 2247, 6091, 6092, 6093, 6094, 
  6095, 6096, 6097, 6098, 6099, 6100, 6101, 6102, 
  2246, 6103, 6104, 6105, 6106, 6107, 6108, 6109, 
  6110, 6111, 6112, 6113, 6114, 6115, 6116, 6117, 
  6118, 6065, 6066, 2248, 6067, 6068, 6069, 6070, 
  6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 
  2249, 6079, 6080, 6081, 6082, 6083, 6084, 6085, 
  6086, 6087, 6088, 6089, 6090, 2247, 6091, 6092, 
  6093, 6094, 6095, 6096, 6097, 6098, 6099, 6100, 
  6101, 6102, 2246, 6103, 6104, 6105, 6106, 6107, 
  6108, 6109, 6110, 6111, 6112, 6113, 6114, 6115, 
  6116, 6117, 6118, 6119, 6120, 0, 0, 6121, 
  6122, 6123, 6124, 6125, 6126, 6127, 6128, 6129, 
  6130, 6121, 6122, 6123, 6124, 6125, 6126, 6127, 
  6128, 6129, 6130, 6121, 6122, 6123, 6124, 6125, 
  6126, 6127, 6128, 6129, 6130, 6121, 6122, 6123, 
  6124, 6125, 6126, 6127, 6128, 6129, 6130, 6121, 
  6122, 6123, 6124, 6125, 6126, 6127, 6128, 6129, 
  6130, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  841, 841, 841, 841, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 841, 841, 
  841, 841, 841, 841, 841, 841, 1151, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 1151, 841, 841, 
  1047, 1047, 1047, 1047, 1047, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 1151, 1151, 1151, 1151, 
  1151, 0, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 
  1151, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 543, 543, 543, 543, 543, 543, 543, 
  0, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 543, 543, 543, 543, 543, 543, 
  543, 543, 0, 0, 543, 543, 543, 543, 
  543, 543, 543, 0, 543, 543, 0, 543, 
  543, 543, 543, 543, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 0, 0, 
  0, 543, 543, 543, 543, 543, 543, 543, 
  525, 525, 525, 525, 525, 525, 525, 0, 
  0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 341, 
  841, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 341, 341, 341, 
  341, 341, 341, 341, 341, 543, 543, 543, 
  543, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 
  1172, 1172, 1172, 0, 0, 0, 0, 0, 
  11, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 
  1108, 1108, 1108, 1108, 1108, 1108, 0, 0, 
  5741, 5741, 5741, 5741, 5741, 5741, 5741, 5741, 
  5741, 556, 556, 556, 556, 556, 556, 556, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 6131, 6132, 6133, 6134, 6135, 6136, 6137, 
  6138, 6139, 6140, 6141, 6142, 6143, 6144, 6145, 
  6146, 6147, 6148, 6149, 6150, 6151, 6152, 6153, 
  6154, 6155, 6156, 6157, 6158, 6159, 6160, 6161, 
  6162, 6163, 6164, 6165, 6166, 6167, 6168, 6169, 
  6170, 6171, 6172, 6173, 6174, 6175, 6176, 6177, 
  6178, 6179, 6180, 6181, 6182, 6183, 6184, 6185, 
  6186, 6187, 6188, 6189, 6190, 6191, 6192, 6193, 
  6194, 6195, 6196, 6197, 6198, 543, 543, 543, 
  543, 543, 543, 1173, 1153, 0, 0, 0, 
  0, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 
  1152, 1152, 1152, 0, 0, 0, 0, 1105, 
  1105, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 1148, 5846, 5846, 
  5846, 1111, 5846, 5846, 5846, 5846, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 1148, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 5846, 
  5846, 5846, 5846, 5846, 5846, 5846, 5846, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 6199, 6200, 6201, 6202, 0, 6203, 6204, 
  6205, 6206, 6207, 6208, 6209, 6210, 6211, 6212, 
  6213, 6214, 6215, 6216, 6217, 6218, 6219, 6220, 
  6221, 6222, 6223, 6224, 6225, 6226, 6227, 6228, 
  6229, 0, 6200, 6201, 0, 6230, 0, 0, 
  6205, 0, 6207, 6208, 6209, 6210, 6211, 6212, 
  6213, 6214, 6215, 6216, 0, 6218, 6219, 6220, 
  6221, 0, 6223, 0, 6225, 0, 0, 0, 
  0, 0, 0, 6201, 0, 0, 0, 0, 
  6205, 0, 6207, 0, 6209, 0, 6211, 6212, 
  6213, 0, 6215, 6216, 0, 6218, 0, 0, 
  6221, 0, 6223, 0, 6225, 0, 6227, 0, 
  6229, 0, 6200, 6201, 0, 6230, 0, 0, 
  6205, 6206, 6207, 6208, 0, 6210, 6211, 6212, 
  6213, 6214, 6215, 6216, 0, 6218, 6219, 6220, 
  6221, 0, 6223, 6224, 6225, 6226, 0, 6228, 
  0, 6199, 6200, 6201, 6202, 6230, 6203, 6204, 
  6205, 6206, 6207, 0, 6209, 6210, 6211, 6212, 
  6213, 6214, 6215, 6216, 6217, 6218, 6219, 6220, 
  6221, 6222, 6223, 6224, 6225, 0, 0, 0, 
  0, 0, 6200, 6201, 6202, 0, 6203, 6204, 
  6205, 6206, 6207, 0, 6209, 6210, 6211, 6212, 
  6213, 6214, 6215, 6216, 6217, 6218, 6219, 6220, 
  6221, 6222, 6223, 6224, 6225, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 75, 75, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 79, 79, 79, 79, 2397, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 0, 0, 0, 
  0, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  0, 0, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 0, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  2397, 0, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 6231, 6232, 6233, 6234, 6235, 6236, 6237, 
  6238, 6239, 6240, 6241, 1211, 1211, 0, 0, 
  0, 6242, 6243, 6244, 6245, 6246, 6247, 6248, 
  6249, 6250, 6251, 6252, 6253, 6254, 6255, 6256, 
  6257, 6258, 6259, 6260, 6261, 6262, 6263, 6264, 
  6265, 6266, 6267, 6268, 6269, 6270, 6271, 6272, 
  79, 6273, 6274, 6275, 6276, 6277, 6278, 6279, 
  6280, 6281, 6282, 6283, 6284, 6285, 6286, 6287, 
  6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 
  6296, 6297, 6298, 6299, 6300, 6301, 6302, 6303, 
  6304, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 6305, 6306, 6307, 0, 0, 
  0, 2541, 2541, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 2541, 
  2541, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 6308, 
  841, 6309, 6308, 6308, 6308, 6308, 6308, 6308, 
  6308, 6308, 6308, 6308, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 841, 841, 
  841, 841, 841, 841, 841, 841, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 6310, 
  6310, 6310, 6310, 6310, 6310, 6310, 6310, 6310, 
  6310, 6310, 6310, 6310, 6310, 6310, 6310, 6310, 
  6310, 6310, 6310, 6310, 6310, 6310, 6310, 6310, 
  6310, 6311, 6312, 6313, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 6314, 6315, 6316, 6317, 6318, 6319, 6320, 
  6321, 6322, 6323, 6324, 6325, 6326, 6327, 6328, 
  6329, 6330, 6331, 6332, 6333, 6334, 6335, 6336, 
  6337, 6338, 6339, 6340, 6341, 6342, 6343, 6344, 
  6345, 6346, 6347, 6348, 6349, 6350, 6351, 6352, 
  6353, 6354, 6355, 6356, 6357, 0, 0, 0, 
  0, 6358, 6359, 6360, 6361, 6362, 6363, 6364, 
  6365, 6366, 0, 0, 0, 0, 0, 0, 
  0, 6367, 6368, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2397, 2397, 2397, 2397, 2397, 2397, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 79, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 79, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 79, 79, 79, 79, 
  2397, 2397, 2397, 2397, 2397, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 79, 79, 79, 2397, 79, 79, 
  79, 2397, 2397, 2397, 6369, 6369, 6369, 6369, 
  6369, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  79, 2397, 79, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 79, 79, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 77, 
  77, 77, 77, 77, 77, 77, 77, 79, 
  79, 79, 79, 79, 2397, 2397, 2397, 2397, 
  79, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 2397, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 2397, 2397, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 2397, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 79, 
  79, 79, 79, 79, 79, 2397, 79, 79, 
  79, 2397, 2397, 2397, 79, 79, 2397, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 2397, 2397, 0, 0, 
  0, 79, 79, 79, 79, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 79, 79, 
  79, 79, 0, 0, 0, 0, 0, 0, 
  0, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 77, 77, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 77, 77, 77, 77, 77, 77, 77, 
  77, 77, 77, 77, 77, 0, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2815, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2815, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 0, 2397, 2397, 2397, 2397, 
  0, 0, 0, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 0, 0, 2397, 2397, 
  2397, 2397, 2397, 2397, 0, 0, 0, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 0, 0, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 2397, 2397, 2397, 2397, 2397, 2397, 2397, 
  2397, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 79, 79, 79, 79, 79, 79, 79, 
  79, 79, 79, 79, 79, 79, 79, 0, 
  0, 2397, 2397, 2397, 2397, 0, 0, 0, 
  0, 2397, 2397, 2397, 0, 0, 0, 0, 
  0, 2397, 2397, 2397, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2397, 2397, 2397, 2397, 2397, 2397, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 3035, 3035, 3035, 3035, 3035, 3035, 
  3035, 3035, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 6370, 6371, 6372, 6373, 6374, 4373, 6375, 
  6376, 6377, 6378, 4374, 6379, 6380, 6381, 4375, 
  6382, 6383, 6384, 6385, 6386, 6387, 6388, 6389, 
  6390, 6391, 6392, 6393, 4433, 6394, 6395, 6396, 
  6397, 6398, 6399, 6400, 6401, 6402, 4438, 4376, 
  4377, 4439, 6403, 6404, 4184, 6405, 4378, 6406, 
  6407, 6408, 6409, 6409, 6409, 6410, 6411, 6412, 
  6413, 6414, 6415, 6416, 6417, 6418, 6419, 6420, 
  6421, 6422, 6423, 6424, 6425, 6426, 6427, 6427, 
  4441, 6428, 6429, 6430, 6431, 4380, 6432, 6433, 
  6434, 4337, 6435, 6436, 6437, 6438, 6439, 6440, 
  6441, 6442, 6443, 6444, 6445, 6446, 6447, 6448, 
  6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 
  6457, 6458, 6459, 6460, 6460, 6461, 6462, 6463, 
  4180, 6464, 6465, 6466, 6467, 6468, 6469, 6470, 
  6471, 4385, 6472, 6473, 6474, 6475, 6476, 6477, 
  6478, 6479, 6480, 6481, 6482, 6483, 6484, 6485, 
  6486, 6487, 6488, 6489, 6490, 6491, 6492, 4126, 
  6493, 6494, 6495, 6495, 6496, 6497, 6497, 6498, 
  6499, 6500, 6501, 6502, 6503, 6504, 6505, 6506, 
  6507, 6508, 6509, 6510, 4386, 6511, 6512, 6513, 
  6514, 4453, 6514, 6515, 4388, 6516, 6517, 6518, 
  6519, 4389, 4099, 6520, 6521, 6522, 6523, 6524, 
  6525, 6526, 6527, 6528, 6529, 6530, 6531, 6532, 
  6533, 6534, 6535, 6536, 6537, 6538, 6539, 6540, 
  6541, 4390, 6542, 6543, 6544, 6545, 6546, 6547, 
  4392, 6548, 6549, 6550, 6551, 6552, 6553, 6554, 
  6555, 4127, 4461, 6556, 6557, 6558, 6559, 6560, 
  6561, 6562, 6563, 4393, 6564, 6565, 6566, 6567, 
  4504, 6568, 6569, 6570, 6571, 6572, 6573, 6574, 
  6575, 6576, 6577, 6578, 6579, 6580, 4197, 6581, 
  6582, 6583, 6584, 6585, 6586, 6587, 6588, 6589, 
  6590, 6591, 4394, 4284, 6592, 6593, 6594, 6595, 
  6596, 6597, 6598, 6599, 4465, 6600, 6601, 6602, 
  6603, 6604, 6605, 6606, 6607, 4466, 6608, 6609, 
  6610, 6611, 6612, 6613, 6614, 6615, 6616, 6617, 
  6618, 6619, 4468, 6620, 6621, 6622, 6623, 6624, 
  6625, 6626, 6627, 6628, 6629, 6630, 6630, 6631, 
  6632, 4470, 6633, 6634, 6635, 6636, 6637, 6638, 
  6639, 4183, 6640, 6641, 6642, 6643, 6644, 6645, 
  6646, 4476, 6647, 6648, 6649, 6650, 6651, 6652, 
  6652, 4477, 4506, 6653, 6654, 6655, 6656, 6657, 
  4145, 4479, 6658, 6659, 4405, 6660, 6661, 4359, 
  6662, 6663, 4409, 6664, 6665, 6666, 6667, 6667, 
  6668, 6669, 6670, 6671, 6672, 6673, 6674, 6675, 
  6676, 6677, 6678, 6679, 6680, 6681, 6682, 6683, 
  6684, 6685, 6686, 6687, 6688, 6689, 6690, 6691, 
  6692, 6693, 6694, 4415, 6695, 6696, 6697, 6698, 
  6699, 6700, 6701, 6702, 6703, 6704, 6705, 6706, 
  6707, 6708, 6709, 6710, 6496, 6711, 6712, 6713, 
  6714, 6715, 6716, 6717, 6718, 6719, 6720, 6721, 
  6722, 4201, 6723, 6724, 6725, 6726, 6727, 6728, 
  4418, 6729, 6730, 6731, 6732, 6733, 6734, 6735, 
  6736, 6737, 6738, 6739, 6740, 6741, 6742, 6743, 
  6744, 6745, 6746, 6747, 6748, 4140, 6749, 6750, 
  6751, 6752, 6753, 6754, 4486, 6755, 6756, 6757, 
  6758, 6759, 6760, 6761, 6762, 6763, 6764, 6765, 
  6766, 6767, 6768, 6769, 6770, 6771, 6772, 6773, 
  6774, 4491, 4492, 6775, 6776, 6777, 6778, 6779, 
  6780, 6781, 6782, 6783, 6784, 6785, 6786, 6787, 
  4493, 6788, 6789, 6790, 6791, 6792, 6793, 6794, 
  6795, 6796, 6797, 6798, 6799, 6800, 6801, 6802, 
  6803, 6804, 6805, 6806, 6807, 6808, 6809, 6810, 
  6811, 6812, 6813, 6814, 6815, 6816, 6817, 4499, 
  4499, 6818, 6819, 6820, 6821, 6822, 6823, 6824, 
  6825, 6826, 6827, 4500, 6828, 6829, 6830, 6831, 
  6832, 6833, 6834, 6835, 6836, 6837, 6838, 6839, 
  6840, 6841, 6842, 6843, 6844, 6845, 6846, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 1459, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 
  2129, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 577, 577, 577, 577, 577, 577, 577, 
  577, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 
  4086, 4086, 4086, 4086, 4086, 4086, 4086, 0, 
  0, };

static const utf8proc_property_t utf8proc_properties[] = {
  {0, 0, 0, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX,  false,false,false,false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_S, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_LF},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_WS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CR},
  {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5093, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5084, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5096, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1, UINT16_MAX, 1, UINT16_MAX, 2784, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2, UINT16_MAX, 2, UINT16_MAX, 49, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3, UINT16_MAX, 3, UINT16_MAX, 704, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 4, UINT16_MAX, 4, UINT16_MAX, 62, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5, UINT16_MAX, 5, UINT16_MAX, 2872, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6, UINT16_MAX, 6, UINT16_MAX, 782, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7, UINT16_MAX, 7, UINT16_MAX, 808, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 8, UINT16_MAX, 8, UINT16_MAX, 111, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 9, UINT16_MAX, 9, UINT16_MAX, 898, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 10, UINT16_MAX, 10, UINT16_MAX, 913, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 11, UINT16_MAX, 11, UINT16_MAX, 999, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 12, UINT16_MAX, 12, UINT16_MAX, 2890, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 13, UINT16_MAX, 13, UINT16_MAX, 160, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 14, UINT16_MAX, 14, UINT16_MAX, 205, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 15, UINT16_MAX, 15, UINT16_MAX, 2982, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 16, UINT16_MAX, 16, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 17, UINT16_MAX, 17, UINT16_MAX, 1087, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 18, UINT16_MAX, 18, UINT16_MAX, 1173, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 19, UINT16_MAX, 19, UINT16_MAX, 1257, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 20, UINT16_MAX, 20, UINT16_MAX, 254, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 21, UINT16_MAX, 21, UINT16_MAX, 3042, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 22, UINT16_MAX, 22, UINT16_MAX, 1337, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 23, UINT16_MAX, 23, UINT16_MAX, 3122, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 24, UINT16_MAX, 24, UINT16_MAX, 303, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 25, UINT16_MAX, 25, UINT16_MAX, 1423, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1491, UINT16_MAX, 1491, 352, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1493, UINT16_MAX, 1493, 2818, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2812, UINT16_MAX, 2812, 401, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1494, UINT16_MAX, 1494, 743, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1495, UINT16_MAX, 1495, 414, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2837, UINT16_MAX, 2837, 2875, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1497, UINT16_MAX, 1497, 795, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1498, UINT16_MAX, 1498, 853, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1499, UINT16_MAX, 1499, 463, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1500, UINT16_MAX, 1500, 901, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1501, UINT16_MAX, 1501, 956, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1502, UINT16_MAX, 1502, 1043, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1503, UINT16_MAX, 1503, 2932, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1504, UINT16_MAX, 1504, 512, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1505, UINT16_MAX, 1505, 557, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1507, UINT16_MAX, 1507, 2994, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2826, UINT16_MAX, 2826, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1508, UINT16_MAX, 1508, 1130, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 3305, UINT16_MAX, 3305, 1215, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1509, UINT16_MAX, 1509, 1296, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1510, UINT16_MAX, 1510, 606, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2908, UINT16_MAX, 2908, 3082, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1511, UINT16_MAX, 1511, 1380, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2925, UINT16_MAX, 2925, 3131, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 3312, UINT16_MAX, 3312, 655, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2834, UINT16_MAX, 2834, 1466, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_NOBREAK, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8219, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 1621, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PI, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 1, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8221, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8225, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35, 35, 7220, UINT16_MAX, 7220, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 14, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PF, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 16423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 16426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 16429, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8240, 50, UINT16_MAX, 50, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8243, 53, UINT16_MAX, 53, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8246, 56, UINT16_MAX, 56, UINT16_MAX, 3143, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8249, 59, UINT16_MAX, 59, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8252, 62, UINT16_MAX, 62, UINT16_MAX, 1537, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8255, 65, UINT16_MAX, 65, UINT16_MAX, 1579, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 66, UINT16_MAX, 66, UINT16_MAX, 1549, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8259, 69, UINT16_MAX, 69, UINT16_MAX, 2852, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8262, 72, UINT16_MAX, 72, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8265, 75, UINT16_MAX, 75, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8268, 78, UINT16_MAX, 78, UINT16_MAX, 3357, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8271, 81, UINT16_MAX, 81, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8274, 84, UINT16_MAX, 84, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8277, 87, UINT16_MAX, 87, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8280, 90, UINT16_MAX, 90, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8283, 93, UINT16_MAX, 93, UINT16_MAX, 2878, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 94, UINT16_MAX, 94, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8287, 97, UINT16_MAX, 97, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8290, 100, UINT16_MAX, 100, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8293, 103, UINT16_MAX, 103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8296, 106, UINT16_MAX, 106, UINT16_MAX, 3461, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8299, 109, UINT16_MAX, 109, UINT16_MAX, 1597, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8302, 112, UINT16_MAX, 112, UINT16_MAX, 1591, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 113, UINT16_MAX, 113, UINT16_MAX, 1585, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8306, 116, UINT16_MAX, 116, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8309, 119, UINT16_MAX, 119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8312, 122, UINT16_MAX, 122, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8315, 125, UINT16_MAX, 125, UINT16_MAX, 1509, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8318, 128, UINT16_MAX, 128, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 129, UINT16_MAX, 129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 8322, 8069, UINT16_MAX, 8069, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8324, UINT16_MAX, 8070, UINT16_MAX, 8070, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8326, UINT16_MAX, 8071, UINT16_MAX, 8071, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8328, UINT16_MAX, 8072, UINT16_MAX, 8072, 3192, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8330, UINT16_MAX, 8073, UINT16_MAX, 8073, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8332, UINT16_MAX, 8074, UINT16_MAX, 8074, 1540, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8334, UINT16_MAX, 2836, UINT16_MAX, 2836, 1582, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1492, UINT16_MAX, 1492, 1558, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8336, UINT16_MAX, 8075, UINT16_MAX, 8075, 2855, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8338, UINT16_MAX, 8076, UINT16_MAX, 8076, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8340, UINT16_MAX, 8077, UINT16_MAX, 8077, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8342, UINT16_MAX, 8078, UINT16_MAX, 8078, 3406, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8344, UINT16_MAX, 8079, UINT16_MAX, 8079, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8346, UINT16_MAX, 8080, UINT16_MAX, 8080, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8348, UINT16_MAX, 8081, UINT16_MAX, 8081, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8350, UINT16_MAX, 8082, UINT16_MAX, 8082, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8352, UINT16_MAX, 8083, UINT16_MAX, 8083, 2881, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8084, UINT16_MAX, 8084, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8354, UINT16_MAX, 8085, UINT16_MAX, 8085, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8356, UINT16_MAX, 8086, UINT16_MAX, 8086, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8358, UINT16_MAX, 8087, UINT16_MAX, 8087, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8360, UINT16_MAX, 8088, UINT16_MAX, 8088, 3510, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8362, UINT16_MAX, 8089, UINT16_MAX, 8089, 1606, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8364, UINT16_MAX, 8090, UINT16_MAX, 8090, 1594, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8091, UINT16_MAX, 8091, 1588, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8366, UINT16_MAX, 8092, UINT16_MAX, 8092, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8368, UINT16_MAX, 8093, UINT16_MAX, 8093, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8370, UINT16_MAX, 8094, UINT16_MAX, 8094, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8372, UINT16_MAX, 8095, UINT16_MAX, 8095, 1523, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8374, UINT16_MAX, 8096, UINT16_MAX, 8096, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8097, UINT16_MAX, 8097, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8376, UINT16_MAX, 8098, UINT16_MAX, 8098, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8378, 188, UINT16_MAX, 188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8381, UINT16_MAX, 8099, UINT16_MAX, 8099, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8383, 193, UINT16_MAX, 193, UINT16_MAX, 3259, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8386, UINT16_MAX, 8100, UINT16_MAX, 8100, 3308, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8388, 198, UINT16_MAX, 198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8391, UINT16_MAX, 8101, UINT16_MAX, 8101, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8393, 203, UINT16_MAX, 203, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8396, UINT16_MAX, 8102, UINT16_MAX, 8102, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8398, 208, UINT16_MAX, 208, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8401, UINT16_MAX, 8103, UINT16_MAX, 8103, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8403, 213, UINT16_MAX, 213, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8406, UINT16_MAX, 8104, UINT16_MAX, 8104, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8408, 218, UINT16_MAX, 218, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8411, UINT16_MAX, 8105, UINT16_MAX, 8105, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8413, 223, UINT16_MAX, 223, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8416, UINT16_MAX, 8106, UINT16_MAX, 8106, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 226, UINT16_MAX, 226, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8107, UINT16_MAX, 8107, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8419, 229, UINT16_MAX, 229, UINT16_MAX, 2858, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8422, UINT16_MAX, 8108, UINT16_MAX, 8108, 2862, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8424, 234, UINT16_MAX, 234, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8427, UINT16_MAX, 8109, UINT16_MAX, 8109, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8429, 239, UINT16_MAX, 239, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8432, UINT16_MAX, 8110, UINT16_MAX, 8110, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8434, 244, UINT16_MAX, 244, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8437, UINT16_MAX, 8111, UINT16_MAX, 8111, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8439, 249, UINT16_MAX, 249, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8442, UINT16_MAX, 8112, UINT16_MAX, 8112, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8444, 254, UINT16_MAX, 254, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8447, UINT16_MAX, 8113, UINT16_MAX, 8113, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8449, 259, UINT16_MAX, 259, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8452, UINT16_MAX, 8114, UINT16_MAX, 8114, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8454, 264, UINT16_MAX, 264, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8457, UINT16_MAX, 8115, UINT16_MAX, 8115, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8459, 269, UINT16_MAX, 269, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8462, UINT16_MAX, 8116, UINT16_MAX, 8116, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8464, 274, UINT16_MAX, 274, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8467, UINT16_MAX, 8117, UINT16_MAX, 8117, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 277, UINT16_MAX, 277, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 5164, UINT16_MAX, 5164, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8470, 280, UINT16_MAX, 280, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8473, UINT16_MAX, 8118, UINT16_MAX, 8118, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8475, 285, UINT16_MAX, 285, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8478, UINT16_MAX, 8119, UINT16_MAX, 8119, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8480, 290, UINT16_MAX, 290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8483, UINT16_MAX, 8120, UINT16_MAX, 8120, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8485, 295, UINT16_MAX, 295, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8488, UINT16_MAX, 8121, UINT16_MAX, 8121, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8490, 8492, UINT16_MAX, 8, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1499, UINT16_MAX, 1499, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8494, 304, UINT16_MAX, 304, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8497, UINT16_MAX, 8122, UINT16_MAX, 8122, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8499, 309, UINT16_MAX, 309, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8502, UINT16_MAX, 8123, UINT16_MAX, 8123, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8504, 314, UINT16_MAX, 314, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8507, UINT16_MAX, 8124, UINT16_MAX, 8124, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8509, 319, UINT16_MAX, 319, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8512, UINT16_MAX, 8125, UINT16_MAX, 8125, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8514, 324, UINT16_MAX, 324, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8517, UINT16_MAX, 8126, UINT16_MAX, 8126, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8519, 329, UINT16_MAX, 329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8522, UINT16_MAX, 8127, UINT16_MAX, 8127, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8524, 334, UINT16_MAX, 334, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8527, UINT16_MAX, 8128, UINT16_MAX, 8128, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 337, UINT16_MAX, 337, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8129, UINT16_MAX, 8129, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8530, 340, UINT16_MAX, 340, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8533, UINT16_MAX, 8130, UINT16_MAX, 8130, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8535, 345, UINT16_MAX, 345, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8538, UINT16_MAX, 8131, UINT16_MAX, 8131, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8540, 350, UINT16_MAX, 350, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8543, UINT16_MAX, 8132, UINT16_MAX, 8132, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8545, 8545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 355, UINT16_MAX, 355, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8133, UINT16_MAX, 8133, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8548, 358, UINT16_MAX, 358, UINT16_MAX, 2974, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8551, UINT16_MAX, 8134, UINT16_MAX, 8134, 2978, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8553, 363, UINT16_MAX, 363, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8556, UINT16_MAX, 8135, UINT16_MAX, 8135, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8558, 368, UINT16_MAX, 368, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8561, UINT16_MAX, 8136, UINT16_MAX, 8136, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 371, UINT16_MAX, 371, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8137, UINT16_MAX, 8137, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8564, 374, UINT16_MAX, 374, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8567, UINT16_MAX, 8138, UINT16_MAX, 8138, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8569, 379, UINT16_MAX, 379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8572, UINT16_MAX, 8139, UINT16_MAX, 8139, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8574, 384, UINT16_MAX, 384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8577, UINT16_MAX, 8140, UINT16_MAX, 8140, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8579, 389, UINT16_MAX, 389, UINT16_MAX, 3012, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8582, UINT16_MAX, 8141, UINT16_MAX, 8141, 3015, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8584, 394, UINT16_MAX, 394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8587, UINT16_MAX, 8142, UINT16_MAX, 8142, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8589, 399, UINT16_MAX, 399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8592, UINT16_MAX, 8143, UINT16_MAX, 8143, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8594, 404, UINT16_MAX, 404, UINT16_MAX, 3018, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8597, UINT16_MAX, 8144, UINT16_MAX, 8144, 3021, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8599, 409, UINT16_MAX, 409, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8602, UINT16_MAX, 8145, UINT16_MAX, 8145, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8604, 414, UINT16_MAX, 414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8607, UINT16_MAX, 8146, UINT16_MAX, 8146, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 417, UINT16_MAX, 417, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8147, UINT16_MAX, 8147, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8610, 420, UINT16_MAX, 420, UINT16_MAX, 3030, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8613, UINT16_MAX, 8148, UINT16_MAX, 8148, 3033, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8615, 425, UINT16_MAX, 425, UINT16_MAX, 3036, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8618, UINT16_MAX, 8149, UINT16_MAX, 8149, 3039, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8620, 430, UINT16_MAX, 430, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8623, UINT16_MAX, 8150, UINT16_MAX, 8150, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8625, 435, UINT16_MAX, 435, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8628, UINT16_MAX, 8151, UINT16_MAX, 8151, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8630, 440, UINT16_MAX, 440, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8633, UINT16_MAX, 8152, UINT16_MAX, 8152, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8635, 445, UINT16_MAX, 445, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8638, UINT16_MAX, 8153, UINT16_MAX, 8153, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8640, 450, UINT16_MAX, 450, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8643, UINT16_MAX, 8154, UINT16_MAX, 8154, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8645, 455, UINT16_MAX, 455, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8648, UINT16_MAX, 8155, UINT16_MAX, 8155, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8650, 460, UINT16_MAX, 460, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8653, 463, UINT16_MAX, 463, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8656, UINT16_MAX, 8156, UINT16_MAX, 8156, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8658, 468, UINT16_MAX, 468, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8661, UINT16_MAX, 8157, UINT16_MAX, 8157, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8663, 473, UINT16_MAX, 473, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8666, UINT16_MAX, 8158, UINT16_MAX, 8158, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 18, 18, 3305, UINT16_MAX, 3305, 3140, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8159, UINT16_MAX, 8159, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 476, UINT16_MAX, 476, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 477, UINT16_MAX, 477, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8160, UINT16_MAX, 8160, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 478, UINT16_MAX, 478, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8161, UINT16_MAX, 8161, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 479, UINT16_MAX, 479, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 480, UINT16_MAX, 480, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8162, UINT16_MAX, 8162, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 481, UINT16_MAX, 481, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 482, UINT16_MAX, 482, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 483, UINT16_MAX, 483, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8163, UINT16_MAX, 8163, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 484, UINT16_MAX, 484, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 485, UINT16_MAX, 485, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 486, UINT16_MAX, 486, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 487, UINT16_MAX, 487, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8164, UINT16_MAX, 8164, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 488, UINT16_MAX, 488, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 489, UINT16_MAX, 489, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8165, UINT16_MAX, 8165, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 490, UINT16_MAX, 490, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 491, UINT16_MAX, 491, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 492, UINT16_MAX, 492, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8166, UINT16_MAX, 8166, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8167, UINT16_MAX, 8167, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 493, UINT16_MAX, 493, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 494, UINT16_MAX, 494, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8168, UINT16_MAX, 8168, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 495, UINT16_MAX, 495, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8688, 498, UINT16_MAX, 498, UINT16_MAX, 3565, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8691, UINT16_MAX, 8169, UINT16_MAX, 8169, 3614, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 501, UINT16_MAX, 501, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8170, UINT16_MAX, 8170, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 502, UINT16_MAX, 502, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8171, UINT16_MAX, 8171, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 503, UINT16_MAX, 503, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 504, UINT16_MAX, 504, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8172, UINT16_MAX, 8172, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 505, UINT16_MAX, 505, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 506, UINT16_MAX, 506, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8173, UINT16_MAX, 8173, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 507, UINT16_MAX, 507, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8700, 510, UINT16_MAX, 510, UINT16_MAX, 3663, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8703, UINT16_MAX, 8174, UINT16_MAX, 8174, 3712, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 513, UINT16_MAX, 513, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 514, UINT16_MAX, 514, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 515, UINT16_MAX, 515, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8175, UINT16_MAX, 8175, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 516, UINT16_MAX, 516, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8176, UINT16_MAX, 8176, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 517, UINT16_MAX, 517, UINT16_MAX, 1573, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 518, UINT16_MAX, 518, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8177, UINT16_MAX, 8177, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 519, UINT16_MAX, 519, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8178, UINT16_MAX, 8178, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8179, UINT16_MAX, 8179, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8712, 522, UINT16_MAX, 522, 8180, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8715, 522, 8181, 522, 8180, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8717, UINT16_MAX, 8181, UINT16_MAX, 8180, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8719, 529, UINT16_MAX, 529, 8182, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8722, 529, 8183, 529, 8182, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8724, UINT16_MAX, 8183, UINT16_MAX, 8182, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8726, 536, UINT16_MAX, 536, 8184, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8729, 536, 8185, 536, 8184, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8731, UINT16_MAX, 8185, UINT16_MAX, 8184, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8733, 543, UINT16_MAX, 543, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8736, UINT16_MAX, 8186, UINT16_MAX, 8186, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8738, 548, UINT16_MAX, 548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8741, UINT16_MAX, 8187, UINT16_MAX, 8187, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8743, 553, UINT16_MAX, 553, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8746, UINT16_MAX, 8188, UINT16_MAX, 8188, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8748, 558, UINT16_MAX, 558, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8751, UINT16_MAX, 8189, UINT16_MAX, 8189, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8753, 563, UINT16_MAX, 563, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8756, UINT16_MAX, 8190, UINT16_MAX, 8190, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8758, 568, UINT16_MAX, 568, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8761, UINT16_MAX, 8191, UINT16_MAX, 8191, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8763, 573, UINT16_MAX, 573, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8766, UINT16_MAX, 8192, UINT16_MAX, 8192, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8768, 578, UINT16_MAX, 578, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8771, UINT16_MAX, 8193, UINT16_MAX, 8193, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1496, UINT16_MAX, 1496, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8773, 583, UINT16_MAX, 583, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8776, UINT16_MAX, 8194, UINT16_MAX, 8194, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8778, 588, UINT16_MAX, 588, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8781, UINT16_MAX, 8195, UINT16_MAX, 8195, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8783, 593, UINT16_MAX, 593, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8786, UINT16_MAX, 8196, UINT16_MAX, 8196, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 596, UINT16_MAX, 596, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8197, UINT16_MAX, 8197, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8789, 599, UINT16_MAX, 599, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8792, UINT16_MAX, 8198, UINT16_MAX, 8198, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8794, 604, UINT16_MAX, 604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8797, UINT16_MAX, 8199, UINT16_MAX, 8199, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8799, 609, UINT16_MAX, 609, UINT16_MAX, 1567, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8802, UINT16_MAX, 8200, UINT16_MAX, 8200, 1570, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8804, 614, UINT16_MAX, 614, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8807, UINT16_MAX, 8201, UINT16_MAX, 8201, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8809, 619, UINT16_MAX, 619, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8812, UINT16_MAX, 8202, UINT16_MAX, 8202, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8814, 8814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8816, 626, UINT16_MAX, 626, 8203, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8819, 626, 8204, 626, 8203, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8821, UINT16_MAX, 8204, UINT16_MAX, 8203, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8823, 633, UINT16_MAX, 633, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8826, UINT16_MAX, 8205, UINT16_MAX, 8205, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 636, UINT16_MAX, 636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 637, UINT16_MAX, 637, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8830, 640, UINT16_MAX, 640, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8833, UINT16_MAX, 8206, UINT16_MAX, 8206, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8835, 645, UINT16_MAX, 645, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8838, UINT16_MAX, 8207, UINT16_MAX, 8207, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8840, 650, UINT16_MAX, 650, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8843, UINT16_MAX, 8208, UINT16_MAX, 8208, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8845, 655, UINT16_MAX, 655, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8848, UINT16_MAX, 8209, UINT16_MAX, 8209, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8850, 660, UINT16_MAX, 660, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8853, UINT16_MAX, 8210, UINT16_MAX, 8210, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8855, 665, UINT16_MAX, 665, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8858, UINT16_MAX, 8211, UINT16_MAX, 8211, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8860, 670, UINT16_MAX, 670, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8863, UINT16_MAX, 8212, UINT16_MAX, 8212, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8865, 675, UINT16_MAX, 675, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8868, UINT16_MAX, 8213, UINT16_MAX, 8213, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8870, 680, UINT16_MAX, 680, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8873, UINT16_MAX, 8214, UINT16_MAX, 8214, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8875, 685, UINT16_MAX, 685, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8878, UINT16_MAX, 8215, UINT16_MAX, 8215, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8880, 690, UINT16_MAX, 690, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8883, UINT16_MAX, 8216, UINT16_MAX, 8216, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8885, 695, UINT16_MAX, 695, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8888, UINT16_MAX, 8217, UINT16_MAX, 8217, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8890, 700, UINT16_MAX, 700, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8893, UINT16_MAX, 8218, UINT16_MAX, 8218, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8895, 705, UINT16_MAX, 705, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8898, UINT16_MAX, 8219, UINT16_MAX, 8219, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8900, 710, UINT16_MAX, 710, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8903, UINT16_MAX, 8220, UINT16_MAX, 8220, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8905, 715, UINT16_MAX, 715, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8908, UINT16_MAX, 8221, UINT16_MAX, 8221, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8910, 720, UINT16_MAX, 720, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8913, UINT16_MAX, 8222, UINT16_MAX, 8222, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8915, 725, UINT16_MAX, 725, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8918, UINT16_MAX, 8223, UINT16_MAX, 8223, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 728, UINT16_MAX, 728, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8224, UINT16_MAX, 8224, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8921, 731, UINT16_MAX, 731, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8924, UINT16_MAX, 8225, UINT16_MAX, 8225, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 734, UINT16_MAX, 734, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 735, UINT16_MAX, 735, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1506, UINT16_MAX, 1506, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 736, UINT16_MAX, 736, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8226, UINT16_MAX, 8226, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8929, 739, UINT16_MAX, 739, UINT16_MAX, 1543, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8932, UINT16_MAX, 8227, UINT16_MAX, 8227, 1546, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8934, 744, UINT16_MAX, 744, UINT16_MAX, 2866, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8937, UINT16_MAX, 8228, UINT16_MAX, 8228, 2869, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8939, 749, UINT16_MAX, 749, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8942, UINT16_MAX, 8229, UINT16_MAX, 8229, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8944, 754, UINT16_MAX, 754, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8947, UINT16_MAX, 8230, UINT16_MAX, 8230, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8949, 759, UINT16_MAX, 759, UINT16_MAX, 1615, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8952, UINT16_MAX, 8231, UINT16_MAX, 8231, 1618, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8954, 764, UINT16_MAX, 764, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8957, UINT16_MAX, 8232, UINT16_MAX, 8232, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 8959, 769, UINT16_MAX, 769, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 8962, UINT16_MAX, 8233, UINT16_MAX, 8233, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 772, UINT16_MAX, 772, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 773, UINT16_MAX, 773, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8234, UINT16_MAX, 8234, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 774, UINT16_MAX, 774, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 775, UINT16_MAX, 775, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8235, UINT16_MAX, 8235, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8236, UINT16_MAX, 8236, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 776, UINT16_MAX, 776, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8237, UINT16_MAX, 8237, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 777, UINT16_MAX, 777, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 778, UINT16_MAX, 778, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 779, UINT16_MAX, 779, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 780, UINT16_MAX, 780, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8238, UINT16_MAX, 8238, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 781, UINT16_MAX, 781, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8239, UINT16_MAX, 8239, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 782, UINT16_MAX, 782, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8240, UINT16_MAX, 8240, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 783, UINT16_MAX, 783, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8241, UINT16_MAX, 8241, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 784, UINT16_MAX, 784, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8242, UINT16_MAX, 8242, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8243, UINT16_MAX, 8243, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8244, UINT16_MAX, 8244, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8245, UINT16_MAX, 8245, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8246, UINT16_MAX, 8246, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8247, UINT16_MAX, 8247, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8248, UINT16_MAX, 8248, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8249, UINT16_MAX, 8249, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8250, UINT16_MAX, 8250, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2821, UINT16_MAX, 2821, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8251, UINT16_MAX, 8251, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8252, UINT16_MAX, 8252, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8253, UINT16_MAX, 8253, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8254, UINT16_MAX, 8254, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8255, UINT16_MAX, 8255, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8256, UINT16_MAX, 8256, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8257, UINT16_MAX, 8257, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8258, UINT16_MAX, 8258, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8259, UINT16_MAX, 8259, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8260, UINT16_MAX, 8260, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8261, UINT16_MAX, 8261, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8262, UINT16_MAX, 8262, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8263, UINT16_MAX, 8263, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8264, UINT16_MAX, 8264, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8265, UINT16_MAX, 8265, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8266, UINT16_MAX, 8266, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8267, UINT16_MAX, 8267, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8268, UINT16_MAX, 8268, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8269, UINT16_MAX, 8269, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8270, UINT16_MAX, 8270, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8271, UINT16_MAX, 8271, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8272, UINT16_MAX, 8272, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8273, UINT16_MAX, 8273, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8274, UINT16_MAX, 8274, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8275, UINT16_MAX, 8275, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8276, UINT16_MAX, 8276, 1576, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8277, UINT16_MAX, 8277, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8278, UINT16_MAX, 8278, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 9, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 17, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 22, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 24, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8981, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8983, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8985, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8987, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8989, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 8991, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 11, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 18, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 23, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32768, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32769, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32770, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32771, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32775, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32776, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32778, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32772, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32814, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32773, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32780, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32779, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32782, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32783, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32815, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32816, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 232, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32781, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32808, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32813, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32807, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32784, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32774, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32777, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32810, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32812, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32811, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32809, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32819, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32817, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 8997, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 240, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, 807, 7217, UINT16_MAX, 7217, 32818, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 233, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 234, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 808, UINT16_MAX, 808, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8279, UINT16_MAX, 8279, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 809, UINT16_MAX, 809, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8280, UINT16_MAX, 8280, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 811, UINT16_MAX, 811, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8281, UINT16_MAX, 8281, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 9004, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8282, UINT16_MAX, 8282, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8283, UINT16_MAX, 8283, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8284, UINT16_MAX, 8284, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 815, UINT16_MAX, 815, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 9008, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9010, 820, UINT16_MAX, 820, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, 821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9014, 824, UINT16_MAX, 824, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9017, 827, UINT16_MAX, 827, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9020, 830, UINT16_MAX, 830, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9023, 833, UINT16_MAX, 833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9026, 836, UINT16_MAX, 836, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9029, 839, UINT16_MAX, 839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9032, 17226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 845, UINT16_MAX, 845, UINT16_MAX, 1673, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 846, UINT16_MAX, 846, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 847, UINT16_MAX, 847, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 848, UINT16_MAX, 848, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 849, UINT16_MAX, 849, UINT16_MAX, 1726, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 850, UINT16_MAX, 850, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 851, UINT16_MAX, 851, UINT16_MAX, 1777, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 852, UINT16_MAX, 852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 807, UINT16_MAX, 807, UINT16_MAX, 1830, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 853, UINT16_MAX, 853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 854, UINT16_MAX, 854, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 35, UINT16_MAX, 35, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 855, UINT16_MAX, 855, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 856, UINT16_MAX, 856, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 857, UINT16_MAX, 857, UINT16_MAX, 1881, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 858, UINT16_MAX, 858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 859, UINT16_MAX, 859, UINT16_MAX, 5027, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 860, UINT16_MAX, 860, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 861, UINT16_MAX, 861, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 862, UINT16_MAX, 862, UINT16_MAX, 1932, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 863, UINT16_MAX, 863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 864, UINT16_MAX, 864, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 865, UINT16_MAX, 865, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 866, UINT16_MAX, 866, UINT16_MAX, 1983, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9059, 869, UINT16_MAX, 869, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9062, 872, UINT16_MAX, 872, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9065, UINT16_MAX, 2603, UINT16_MAX, 2603, 4904, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9067, UINT16_MAX, 2635, UINT16_MAX, 2635, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9069, UINT16_MAX, 2640, UINT16_MAX, 2640, 4913, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9071, UINT16_MAX, 2676, UINT16_MAX, 2676, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9073, 17267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7211, UINT16_MAX, 7211, 2088, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7212, UINT16_MAX, 7212, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2846, UINT16_MAX, 2846, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7213, UINT16_MAX, 7213, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7214, UINT16_MAX, 7214, 2141, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7215, UINT16_MAX, 7215, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7216, UINT16_MAX, 7216, 2192, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 915, UINT16_MAX, 915, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7217, UINT16_MAX, 7217, 2245, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7218, UINT16_MAX, 7218, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7219, UINT16_MAX, 7219, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7220, UINT16_MAX, 7220, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7221, UINT16_MAX, 7221, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7222, UINT16_MAX, 7222, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7223, UINT16_MAX, 7223, 2401, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2847, UINT16_MAX, 2847, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7224, UINT16_MAX, 7224, 5023, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 860, 917, UINT16_MAX, 917, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 917, UINT16_MAX, 917, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7226, UINT16_MAX, 7226, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 897, UINT16_MAX, 897, 2349, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7227, UINT16_MAX, 7227, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7228, UINT16_MAX, 7228, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7229, UINT16_MAX, 7229, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2835, UINT16_MAX, 2835, 2452, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9078, UINT16_MAX, 8285, UINT16_MAX, 8285, 2036, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9080, UINT16_MAX, 8286, UINT16_MAX, 8286, 2297, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9082, UINT16_MAX, 2745, UINT16_MAX, 2745, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9084, UINT16_MAX, 2714, UINT16_MAX, 2714, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9086, UINT16_MAX, 2750, UINT16_MAX, 2750, 5033, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 896, UINT16_MAX, 896, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 846, 846, 7212, UINT16_MAX, 7212, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 852, 852, 915, UINT16_MAX, 915, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2505, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9092, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 863, 863, 7227, UINT16_MAX, 7227, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 858, 858, 2847, UINT16_MAX, 2847, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8287, UINT16_MAX, 8287, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 902, UINT16_MAX, 902, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8288, UINT16_MAX, 8288, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 903, UINT16_MAX, 903, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8289, UINT16_MAX, 8289, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 904, UINT16_MAX, 904, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7238, UINT16_MAX, 7238, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 905, UINT16_MAX, 905, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8290, UINT16_MAX, 8290, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 906, UINT16_MAX, 906, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8291, UINT16_MAX, 8291, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 907, UINT16_MAX, 907, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8292, UINT16_MAX, 8292, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 908, UINT16_MAX, 908, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8293, UINT16_MAX, 8293, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 909, UINT16_MAX, 909, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8294, UINT16_MAX, 8294, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 910, UINT16_MAX, 910, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8295, UINT16_MAX, 8295, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 911, UINT16_MAX, 911, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8296, UINT16_MAX, 8296, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 912, UINT16_MAX, 912, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8297, UINT16_MAX, 8297, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 913, UINT16_MAX, 913, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8298, UINT16_MAX, 8298, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 853, 853, 7218, UINT16_MAX, 7218, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 859, 859, 7224, UINT16_MAX, 7224, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 914, UINT16_MAX, 8299, UINT16_MAX, 8299, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8300, UINT16_MAX, 8300, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 915, 852, UINT16_MAX, 852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 849, 849, 7214, UINT16_MAX, 7214, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 916, UINT16_MAX, 916, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8301, UINT16_MAX, 8301, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 917, 918, UINT16_MAX, 918, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 919, UINT16_MAX, 919, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8302, UINT16_MAX, 8302, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 920, UINT16_MAX, 920, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 921, UINT16_MAX, 921, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 922, UINT16_MAX, 922, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9115, 925, UINT16_MAX, 925, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9118, 928, UINT16_MAX, 928, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 929, UINT16_MAX, 929, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9122, 932, UINT16_MAX, 932, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 933, UINT16_MAX, 933, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 934, UINT16_MAX, 934, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 935, UINT16_MAX, 935, UINT16_MAX, 2525, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9128, 938, UINT16_MAX, 938, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 939, UINT16_MAX, 939, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 940, UINT16_MAX, 940, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 941, UINT16_MAX, 941, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 942, UINT16_MAX, 942, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9135, 945, UINT16_MAX, 945, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9138, 948, UINT16_MAX, 948, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9141, 951, UINT16_MAX, 951, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 952, UINT16_MAX, 952, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 953, UINT16_MAX, 953, UINT16_MAX, 2615, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 954, UINT16_MAX, 954, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 955, UINT16_MAX, 955, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 956, UINT16_MAX, 956, UINT16_MAX, 2522, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 957, UINT16_MAX, 957, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 958, UINT16_MAX, 958, UINT16_MAX, 2511, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 959, UINT16_MAX, 959, UINT16_MAX, 2601, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 960, UINT16_MAX, 960, UINT16_MAX, 2635, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 961, UINT16_MAX, 961, UINT16_MAX, 2531, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9154, 964, UINT16_MAX, 964, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 965, UINT16_MAX, 965, UINT16_MAX, 2528, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 966, UINT16_MAX, 966, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 967, UINT16_MAX, 967, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 968, UINT16_MAX, 968, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 969, UINT16_MAX, 969, UINT16_MAX, 2641, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 970, UINT16_MAX, 970, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 971, UINT16_MAX, 971, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 972, UINT16_MAX, 972, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 973, UINT16_MAX, 973, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 974, UINT16_MAX, 974, UINT16_MAX, 2542, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 975, UINT16_MAX, 975, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 976, UINT16_MAX, 976, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 977, UINT16_MAX, 977, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 978, UINT16_MAX, 978, UINT16_MAX, 2659, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 979, UINT16_MAX, 979, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 980, UINT16_MAX, 980, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 981, UINT16_MAX, 981, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 982, UINT16_MAX, 982, UINT16_MAX, 2665, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 983, UINT16_MAX, 983, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 984, UINT16_MAX, 984, UINT16_MAX, 2653, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 985, UINT16_MAX, 985, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 986, UINT16_MAX, 986, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8303, UINT16_MAX, 8303, 2622, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8304, UINT16_MAX, 8304, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8305, UINT16_MAX, 8305, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8306, UINT16_MAX, 8306, 2575, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8307, UINT16_MAX, 8307, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8308, UINT16_MAX, 8308, 2564, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8309, UINT16_MAX, 8309, 2608, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8310, UINT16_MAX, 8310, 2638, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8311, UINT16_MAX, 8311, 2553, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9179, UINT16_MAX, 8312, UINT16_MAX, 8312, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8313, UINT16_MAX, 8313, 2581, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8314, UINT16_MAX, 8314, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8315, UINT16_MAX, 8315, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8316, UINT16_MAX, 8316, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8317, UINT16_MAX, 8317, 2644, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8318, UINT16_MAX, 8318, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8319, UINT16_MAX, 8319, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8320, UINT16_MAX, 8320, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8321, UINT16_MAX, 8321, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8322, UINT16_MAX, 8322, 2584, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8323, UINT16_MAX, 8323, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8324, UINT16_MAX, 8324, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8325, UINT16_MAX, 8325, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8326, UINT16_MAX, 8326, 2662, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8327, UINT16_MAX, 8327, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8328, UINT16_MAX, 8328, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8329, UINT16_MAX, 8329, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8330, UINT16_MAX, 8330, 2668, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8331, UINT16_MAX, 8331, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8332, UINT16_MAX, 8332, 2656, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8333, UINT16_MAX, 8333, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8334, UINT16_MAX, 8334, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9181, UINT16_MAX, 8335, UINT16_MAX, 8335, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9183, UINT16_MAX, 8336, UINT16_MAX, 8336, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8337, UINT16_MAX, 8337, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9185, UINT16_MAX, 8338, UINT16_MAX, 8338, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8339, UINT16_MAX, 8339, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8340, UINT16_MAX, 8340, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8341, UINT16_MAX, 8341, 2578, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9187, UINT16_MAX, 8342, UINT16_MAX, 8342, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8343, UINT16_MAX, 8343, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8344, UINT16_MAX, 8344, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8345, UINT16_MAX, 8345, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8346, UINT16_MAX, 8346, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9189, UINT16_MAX, 8347, UINT16_MAX, 8347, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9191, UINT16_MAX, 8348, UINT16_MAX, 8348, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9193, UINT16_MAX, 8349, UINT16_MAX, 8349, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8350, UINT16_MAX, 8350, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1003, UINT16_MAX, 1003, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8351, UINT16_MAX, 8351, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1004, UINT16_MAX, 1004, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8352, UINT16_MAX, 8352, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1005, UINT16_MAX, 1005, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8353, UINT16_MAX, 8353, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1006, UINT16_MAX, 1006, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8354, UINT16_MAX, 8354, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1007, UINT16_MAX, 1007, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8355, UINT16_MAX, 8355, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1008, UINT16_MAX, 1008, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8356, UINT16_MAX, 8356, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1009, UINT16_MAX, 1009, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8357, UINT16_MAX, 8357, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1010, UINT16_MAX, 1010, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8358, UINT16_MAX, 8358, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1011, UINT16_MAX, 1011, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8359, UINT16_MAX, 8359, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1012, UINT16_MAX, 1012, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8360, UINT16_MAX, 8360, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1013, UINT16_MAX, 1013, UINT16_MAX, 2595, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8361, UINT16_MAX, 8361, 2598, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9206, 1016, UINT16_MAX, 1016, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9209, UINT16_MAX, 8362, UINT16_MAX, 8362, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1019, UINT16_MAX, 1019, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8363, UINT16_MAX, 8363, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1020, UINT16_MAX, 1020, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8364, UINT16_MAX, 8364, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1021, UINT16_MAX, 1021, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8365, UINT16_MAX, 8365, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1022, UINT16_MAX, 1022, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8366, UINT16_MAX, 8366, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1023, UINT16_MAX, 1023, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8367, UINT16_MAX, 8367, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ME, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1024, UINT16_MAX, 1024, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8368, UINT16_MAX, 8368, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1025, UINT16_MAX, 1025, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8369, UINT16_MAX, 8369, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1026, UINT16_MAX, 1026, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8370, UINT16_MAX, 8370, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1027, UINT16_MAX, 1027, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8371, UINT16_MAX, 8371, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1028, UINT16_MAX, 1028, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8372, UINT16_MAX, 8372, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1029, UINT16_MAX, 1029, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8373, UINT16_MAX, 8373, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1030, UINT16_MAX, 1030, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8374, UINT16_MAX, 8374, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1031, UINT16_MAX, 1031, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8375, UINT16_MAX, 8375, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1032, UINT16_MAX, 1032, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8376, UINT16_MAX, 8376, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1033, UINT16_MAX, 1033, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8377, UINT16_MAX, 8377, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1034, UINT16_MAX, 1034, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8378, UINT16_MAX, 8378, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1035, UINT16_MAX, 1035, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8379, UINT16_MAX, 8379, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1036, UINT16_MAX, 1036, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8380, UINT16_MAX, 8380, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1037, UINT16_MAX, 1037, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8381, UINT16_MAX, 8381, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1038, UINT16_MAX, 1038, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8382, UINT16_MAX, 8382, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1039, UINT16_MAX, 1039, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8383, UINT16_MAX, 8383, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1040, UINT16_MAX, 1040, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8384, UINT16_MAX, 8384, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1041, UINT16_MAX, 1041, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8385, UINT16_MAX, 8385, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1042, UINT16_MAX, 1042, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8386, UINT16_MAX, 8386, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1043, UINT16_MAX, 1043, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8387, UINT16_MAX, 8387, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1044, UINT16_MAX, 1044, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8388, UINT16_MAX, 8388, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1045, UINT16_MAX, 1045, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8389, UINT16_MAX, 8389, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1046, UINT16_MAX, 1046, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8390, UINT16_MAX, 8390, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1047, UINT16_MAX, 1047, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8391, UINT16_MAX, 8391, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1048, UINT16_MAX, 1048, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8392, UINT16_MAX, 8392, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1049, UINT16_MAX, 1049, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8393, UINT16_MAX, 8393, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1050, UINT16_MAX, 1050, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8394, UINT16_MAX, 8394, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1051, UINT16_MAX, 1051, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9244, 1054, UINT16_MAX, 1054, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9247, UINT16_MAX, 8395, UINT16_MAX, 8395, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1057, UINT16_MAX, 1057, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8396, UINT16_MAX, 8396, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1058, UINT16_MAX, 1058, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8397, UINT16_MAX, 8397, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1059, UINT16_MAX, 1059, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8398, UINT16_MAX, 8398, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1060, UINT16_MAX, 1060, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8399, UINT16_MAX, 8399, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1061, UINT16_MAX, 1061, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8400, UINT16_MAX, 8400, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1062, UINT16_MAX, 1062, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8401, UINT16_MAX, 8401, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8402, UINT16_MAX, 8402, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9255, 1065, UINT16_MAX, 1065, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9258, UINT16_MAX, 8403, UINT16_MAX, 8403, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9260, 1070, UINT16_MAX, 1070, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9263, UINT16_MAX, 8404, UINT16_MAX, 8404, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1073, UINT16_MAX, 1073, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8405, UINT16_MAX, 8405, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9266, 1076, UINT16_MAX, 1076, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9269, UINT16_MAX, 8406, UINT16_MAX, 8406, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1079, UINT16_MAX, 1079, UINT16_MAX, 2629, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8407, UINT16_MAX, 8407, 2632, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9272, 1082, UINT16_MAX, 1082, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9275, UINT16_MAX, 8408, UINT16_MAX, 8408, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9277, 1087, UINT16_MAX, 1087, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9280, UINT16_MAX, 8409, UINT16_MAX, 8409, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9282, 1092, UINT16_MAX, 1092, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9285, UINT16_MAX, 8410, UINT16_MAX, 8410, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1095, UINT16_MAX, 1095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8411, UINT16_MAX, 8411, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9288, 1098, UINT16_MAX, 1098, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9291, UINT16_MAX, 8412, UINT16_MAX, 8412, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9293, 1103, UINT16_MAX, 1103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9296, UINT16_MAX, 8413, UINT16_MAX, 8413, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9298, 1108, UINT16_MAX, 1108, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9301, UINT16_MAX, 8414, UINT16_MAX, 8414, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1111, UINT16_MAX, 1111, UINT16_MAX, 2647, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8415, UINT16_MAX, 8415, 2650, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9304, 1114, UINT16_MAX, 1114, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9307, UINT16_MAX, 8416, UINT16_MAX, 8416, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9309, 1119, UINT16_MAX, 1119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9312, UINT16_MAX, 8417, UINT16_MAX, 8417, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9314, 1124, UINT16_MAX, 1124, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9317, UINT16_MAX, 8418, UINT16_MAX, 8418, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9319, 1129, UINT16_MAX, 1129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9322, UINT16_MAX, 8419, UINT16_MAX, 8419, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9324, 1134, UINT16_MAX, 1134, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9327, UINT16_MAX, 8420, UINT16_MAX, 8420, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9329, 1139, UINT16_MAX, 1139, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9332, UINT16_MAX, 8421, UINT16_MAX, 8421, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1142, UINT16_MAX, 1142, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8422, UINT16_MAX, 8422, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9335, 1145, UINT16_MAX, 1145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9338, UINT16_MAX, 8423, UINT16_MAX, 8423, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1148, UINT16_MAX, 1148, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8424, UINT16_MAX, 8424, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1149, UINT16_MAX, 1149, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8425, UINT16_MAX, 8425, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1150, UINT16_MAX, 1150, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8426, UINT16_MAX, 8426, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1151, UINT16_MAX, 1151, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8427, UINT16_MAX, 8427, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1152, UINT16_MAX, 1152, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8428, UINT16_MAX, 8428, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1153, UINT16_MAX, 1153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8429, UINT16_MAX, 8429, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1154, UINT16_MAX, 1154, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8430, UINT16_MAX, 8430, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1155, UINT16_MAX, 1155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8431, UINT16_MAX, 8431, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1156, UINT16_MAX, 1156, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8432, UINT16_MAX, 8432, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1157, UINT16_MAX, 1157, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8433, UINT16_MAX, 8433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1158, UINT16_MAX, 1158, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8434, UINT16_MAX, 8434, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1159, UINT16_MAX, 1159, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8435, UINT16_MAX, 8435, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1160, UINT16_MAX, 1160, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8436, UINT16_MAX, 8436, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1161, UINT16_MAX, 1161, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8437, UINT16_MAX, 8437, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1162, UINT16_MAX, 1162, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8438, UINT16_MAX, 8438, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1163, UINT16_MAX, 1163, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8439, UINT16_MAX, 8439, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1164, UINT16_MAX, 1164, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8440, UINT16_MAX, 8440, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1165, UINT16_MAX, 1165, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8441, UINT16_MAX, 8441, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1166, UINT16_MAX, 1166, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8442, UINT16_MAX, 8442, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1167, UINT16_MAX, 1167, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8443, UINT16_MAX, 8443, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1168, UINT16_MAX, 1168, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8444, UINT16_MAX, 8444, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1169, UINT16_MAX, 1169, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8445, UINT16_MAX, 8445, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1170, UINT16_MAX, 1170, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8446, UINT16_MAX, 8446, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1171, UINT16_MAX, 1171, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8447, UINT16_MAX, 8447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1172, UINT16_MAX, 1172, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8448, UINT16_MAX, 8448, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1173, UINT16_MAX, 1173, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8449, UINT16_MAX, 8449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1174, UINT16_MAX, 1174, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8450, UINT16_MAX, 8450, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1175, UINT16_MAX, 1175, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1176, UINT16_MAX, 1176, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1177, UINT16_MAX, 1177, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1178, UINT16_MAX, 1178, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1179, UINT16_MAX, 1179, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1180, UINT16_MAX, 1180, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1181, UINT16_MAX, 1181, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1182, UINT16_MAX, 1182, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1183, UINT16_MAX, 1183, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1184, UINT16_MAX, 1184, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1185, UINT16_MAX, 1185, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1186, UINT16_MAX, 1186, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1187, UINT16_MAX, 1187, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1188, UINT16_MAX, 1188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1189, UINT16_MAX, 1189, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1190, UINT16_MAX, 1190, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1191, UINT16_MAX, 1191, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1192, UINT16_MAX, 1192, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1193, UINT16_MAX, 1193, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1194, UINT16_MAX, 1194, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1195, UINT16_MAX, 1195, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1196, UINT16_MAX, 1196, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1197, UINT16_MAX, 1197, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1198, UINT16_MAX, 1198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1199, UINT16_MAX, 1199, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1200, UINT16_MAX, 1200, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1201, UINT16_MAX, 1201, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1202, UINT16_MAX, 1202, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1203, UINT16_MAX, 1203, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1204, UINT16_MAX, 1204, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1205, UINT16_MAX, 1205, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1206, UINT16_MAX, 1206, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1207, UINT16_MAX, 1207, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1208, UINT16_MAX, 1208, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1209, UINT16_MAX, 1209, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1210, UINT16_MAX, 1210, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1211, UINT16_MAX, 1211, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1212, UINT16_MAX, 1212, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8451, UINT16_MAX, 8451, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8452, UINT16_MAX, 8452, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8453, UINT16_MAX, 8453, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8454, UINT16_MAX, 8454, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8455, UINT16_MAX, 8455, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8456, UINT16_MAX, 8456, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8457, UINT16_MAX, 8457, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8458, UINT16_MAX, 8458, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8459, UINT16_MAX, 8459, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8460, UINT16_MAX, 8460, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8461, UINT16_MAX, 8461, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8462, UINT16_MAX, 8462, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8463, UINT16_MAX, 8463, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8464, UINT16_MAX, 8464, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8465, UINT16_MAX, 8465, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8466, UINT16_MAX, 8466, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8467, UINT16_MAX, 8467, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8468, UINT16_MAX, 8468, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8469, UINT16_MAX, 8469, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8470, UINT16_MAX, 8470, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8471, UINT16_MAX, 8471, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8472, UINT16_MAX, 8472, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8473, UINT16_MAX, 8473, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8474, UINT16_MAX, 8474, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8475, UINT16_MAX, 8475, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8476, UINT16_MAX, 8476, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8477, UINT16_MAX, 8477, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8478, UINT16_MAX, 8478, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8479, UINT16_MAX, 8479, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8480, UINT16_MAX, 8480, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8481, UINT16_MAX, 8481, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8482, UINT16_MAX, 8482, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8483, UINT16_MAX, 8483, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8484, UINT16_MAX, 8484, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8485, UINT16_MAX, 8485, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8486, UINT16_MAX, 8486, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8487, UINT16_MAX, 8487, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8488, UINT16_MAX, 8488, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 9405, 9405, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 222, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 228, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 10, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 11, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 12, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 13, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 14, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 15, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 16, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 17, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 18, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 19, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 20, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 21, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 22, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 23, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 24, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 25, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_PREPEND},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 30, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 31, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 32, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9409, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9413, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9415, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2671, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2676, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2679, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 27, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 28, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 29, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 33, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 34, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32785, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32786, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32787, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 35, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 9417, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 9419, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 9421, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 9423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2685, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9427, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2688, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 9429, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2682, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_PREPEND},
  {UTF8PROC_CATEGORY_MN, 36, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2691, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9431, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2694, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9433, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2697, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9435, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32788, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9437, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9439, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32789, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2700, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9455, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32790, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32792, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2704, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9475, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9479, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32791, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32793, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9481, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2709, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32795, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2712, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2716, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9487, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32794, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2719, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 84, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 91, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32796, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2722, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32799, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2725, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2730, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32797, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32798, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32800, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2733, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2737, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_PREPEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32801, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32802, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32803, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2740, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2745, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32804, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 9519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MN, 103, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 107, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 9521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MN, 118, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 122, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 9523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 9525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NOBREAK, 1335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 129, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 130, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 132, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, 9546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, 9550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 9564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2748, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32805, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1376, UINT16_MAX, 1376, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1377, UINT16_MAX, 1377, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1378, UINT16_MAX, 1378, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1379, UINT16_MAX, 1379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1380, UINT16_MAX, 1380, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1381, UINT16_MAX, 1381, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1382, UINT16_MAX, 1382, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1383, UINT16_MAX, 1383, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1384, UINT16_MAX, 1384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1385, UINT16_MAX, 1385, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1386, UINT16_MAX, 1386, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1387, UINT16_MAX, 1387, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1388, UINT16_MAX, 1388, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1389, UINT16_MAX, 1389, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1390, UINT16_MAX, 1390, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1391, UINT16_MAX, 1391, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1392, UINT16_MAX, 1392, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1393, UINT16_MAX, 1393, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1394, UINT16_MAX, 1394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1395, UINT16_MAX, 1395, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1396, UINT16_MAX, 1396, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1397, UINT16_MAX, 1397, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1398, UINT16_MAX, 1398, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1399, UINT16_MAX, 1399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1400, UINT16_MAX, 1400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1401, UINT16_MAX, 1401, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1402, UINT16_MAX, 1402, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1403, UINT16_MAX, 1403, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1404, UINT16_MAX, 1404, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1405, UINT16_MAX, 1405, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1406, UINT16_MAX, 1406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1407, UINT16_MAX, 1407, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1408, UINT16_MAX, 1408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1409, UINT16_MAX, 1409, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1410, UINT16_MAX, 1410, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1411, UINT16_MAX, 1411, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1412, UINT16_MAX, 1412, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1413, UINT16_MAX, 1413, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1414, UINT16_MAX, 1414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1415, UINT16_MAX, 1415, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8489, UINT16_MAX, 1446, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8490, UINT16_MAX, 1447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8491, UINT16_MAX, 1448, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8492, UINT16_MAX, 1449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8493, UINT16_MAX, 1450, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8494, UINT16_MAX, 1451, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8495, UINT16_MAX, 1452, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8496, UINT16_MAX, 1453, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8497, UINT16_MAX, 1454, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8498, UINT16_MAX, 1455, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8499, UINT16_MAX, 1456, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8500, UINT16_MAX, 1457, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8501, UINT16_MAX, 1416, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8502, UINT16_MAX, 1458, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8503, UINT16_MAX, 1459, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8504, UINT16_MAX, 1460, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8505, UINT16_MAX, 1461, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8506, UINT16_MAX, 1462, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8507, UINT16_MAX, 1463, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8508, UINT16_MAX, 1464, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8509, UINT16_MAX, 1465, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8510, UINT16_MAX, 1466, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8511, UINT16_MAX, 1467, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8512, UINT16_MAX, 1468, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8513, UINT16_MAX, 1469, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8514, UINT16_MAX, 1470, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8515, UINT16_MAX, 1471, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8516, UINT16_MAX, 1472, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8517, UINT16_MAX, 1473, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8518, UINT16_MAX, 1474, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8519, UINT16_MAX, 1475, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8520, UINT16_MAX, 1476, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8521, UINT16_MAX, 1477, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8522, UINT16_MAX, 1478, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8523, UINT16_MAX, 1479, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8524, UINT16_MAX, 1480, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8525, UINT16_MAX, 1481, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8526, UINT16_MAX, 1482, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8527, UINT16_MAX, 1483, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8528, UINT16_MAX, 1484, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8529, UINT16_MAX, 1485, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8530, UINT16_MAX, 1486, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8531, UINT16_MAX, 1487, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8532, UINT16_MAX, 1488, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8533, UINT16_MAX, 1489, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8534, UINT16_MAX, 1490, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_L},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 2, 0, UTF8PROC_BOUNDCLASS_L},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 1, 0, UTF8PROC_BOUNDCLASS_V},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_V},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_T},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8535, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8536, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8537, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8538, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8539, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8540, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8541, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8542, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8543, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8544, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8545, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8546, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8547, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8549, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8550, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8551, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8552, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8553, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8554, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8555, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8556, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8557, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8558, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8559, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8560, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8561, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8562, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8563, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8564, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8565, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8566, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8567, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8568, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8569, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8570, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8571, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8572, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8573, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8574, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8575, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8576, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8577, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8578, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8579, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8580, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8581, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8582, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8583, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8584, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8585, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8586, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8587, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8588, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8589, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8590, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8591, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8592, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8593, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8594, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8595, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8596, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8597, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8598, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8599, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8600, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8601, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8602, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8603, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8605, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8606, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8607, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8608, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8609, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8610, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8611, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8612, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8613, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8614, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8615, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8616, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8617, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8618, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8619, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8620, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1417, 1417, UINT16_MAX, 1417, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1418, 1418, UINT16_MAX, 1418, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1419, 1419, UINT16_MAX, 1419, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1420, 1420, UINT16_MAX, 1420, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1421, 1421, UINT16_MAX, 1421, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1422, 1422, UINT16_MAX, 1422, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2751, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2754, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2757, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2760, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2763, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2766, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 9625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32806, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2769, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2772, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2775, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2778, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2781, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 9635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 9, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 955, 8305, UINT16_MAX, 8305, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 957, 8307, UINT16_MAX, 8307, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 969, 8317, UINT16_MAX, 8317, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 972, 8320, UINT16_MAX, 8320, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 973, 8321, UINT16_MAX, 8321, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 981, 8329, UINT16_MAX, 8329, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1004, 8352, UINT16_MAX, 8352, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1445, 8621, UINT16_MAX, 8621, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1446, UINT16_MAX, 1446, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1447, UINT16_MAX, 1447, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1448, UINT16_MAX, 1448, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1449, UINT16_MAX, 1449, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1450, UINT16_MAX, 1450, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1451, UINT16_MAX, 1451, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1452, UINT16_MAX, 1452, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1453, UINT16_MAX, 1453, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1454, UINT16_MAX, 1454, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1455, UINT16_MAX, 1455, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1456, UINT16_MAX, 1456, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1457, UINT16_MAX, 1457, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1416, UINT16_MAX, 1416, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1458, UINT16_MAX, 1458, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1459, UINT16_MAX, 1459, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1460, UINT16_MAX, 1460, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1461, UINT16_MAX, 1461, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1462, UINT16_MAX, 1462, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1463, UINT16_MAX, 1463, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1464, UINT16_MAX, 1464, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1465, UINT16_MAX, 1465, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1466, UINT16_MAX, 1466, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1467, UINT16_MAX, 1467, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1468, UINT16_MAX, 1468, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1469, UINT16_MAX, 1469, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1470, UINT16_MAX, 1470, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1471, UINT16_MAX, 1471, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1472, UINT16_MAX, 1472, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1473, UINT16_MAX, 1473, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1474, UINT16_MAX, 1474, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1475, UINT16_MAX, 1475, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1476, UINT16_MAX, 1476, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1477, UINT16_MAX, 1477, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1478, UINT16_MAX, 1478, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1479, UINT16_MAX, 1479, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1480, UINT16_MAX, 1480, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1481, UINT16_MAX, 1481, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1482, UINT16_MAX, 1482, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1483, UINT16_MAX, 1483, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1484, UINT16_MAX, 1484, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1485, UINT16_MAX, 1485, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1486, UINT16_MAX, 1486, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1487, UINT16_MAX, 1487, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1488, UINT16_MAX, 1488, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1489, UINT16_MAX, 1489, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1490, UINT16_MAX, 1490, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 4, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 6, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 10, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 12, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 14, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 479, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 15, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 19, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 20, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 21, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 848, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 8, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 17, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 20, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 21, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 968, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8622, UINT16_MAX, 8622, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8623, UINT16_MAX, 8623, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8624, UINT16_MAX, 8624, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 94, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 490, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 25, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 214, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9733, 1543, UINT16_MAX, 1543, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9736, UINT16_MAX, 8625, UINT16_MAX, 8625, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9738, 1548, UINT16_MAX, 1548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9741, UINT16_MAX, 8626, UINT16_MAX, 8626, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9743, 1553, UINT16_MAX, 1553, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9746, UINT16_MAX, 8627, UINT16_MAX, 8627, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9748, 1558, UINT16_MAX, 1558, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9751, UINT16_MAX, 8628, UINT16_MAX, 8628, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9753, 1563, UINT16_MAX, 1563, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9756, UINT16_MAX, 8629, UINT16_MAX, 8629, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9758, 1568, UINT16_MAX, 1568, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9761, UINT16_MAX, 8630, UINT16_MAX, 8630, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9763, 1573, UINT16_MAX, 1573, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9766, UINT16_MAX, 8631, UINT16_MAX, 8631, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9768, 1578, UINT16_MAX, 1578, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9771, UINT16_MAX, 8632, UINT16_MAX, 8632, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9773, 1583, UINT16_MAX, 1583, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9776, UINT16_MAX, 8633, UINT16_MAX, 8633, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9778, 1588, UINT16_MAX, 1588, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9781, UINT16_MAX, 8634, UINT16_MAX, 8634, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9783, 1593, UINT16_MAX, 1593, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9786, UINT16_MAX, 8635, UINT16_MAX, 8635, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9788, 1598, UINT16_MAX, 1598, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9791, UINT16_MAX, 8636, UINT16_MAX, 8636, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9793, 1603, UINT16_MAX, 1603, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9796, UINT16_MAX, 8637, UINT16_MAX, 8637, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9798, 1608, UINT16_MAX, 1608, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9801, UINT16_MAX, 8638, UINT16_MAX, 8638, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9803, 1613, UINT16_MAX, 1613, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9806, UINT16_MAX, 8639, UINT16_MAX, 8639, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9808, 1618, UINT16_MAX, 1618, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9811, UINT16_MAX, 8640, UINT16_MAX, 8640, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9813, 1623, UINT16_MAX, 1623, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9816, UINT16_MAX, 8641, UINT16_MAX, 8641, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9818, 1628, UINT16_MAX, 1628, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9821, UINT16_MAX, 8642, UINT16_MAX, 8642, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9823, 1633, UINT16_MAX, 1633, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9826, UINT16_MAX, 8643, UINT16_MAX, 8643, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9828, 1638, UINT16_MAX, 1638, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9831, UINT16_MAX, 8644, UINT16_MAX, 8644, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9833, 1643, UINT16_MAX, 1643, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9836, UINT16_MAX, 8645, UINT16_MAX, 8645, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9838, 1648, UINT16_MAX, 1648, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9841, UINT16_MAX, 8646, UINT16_MAX, 8646, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9843, 1653, UINT16_MAX, 1653, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9846, UINT16_MAX, 8647, UINT16_MAX, 8647, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9848, 1658, UINT16_MAX, 1658, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9851, UINT16_MAX, 8648, UINT16_MAX, 8648, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9853, 1663, UINT16_MAX, 1663, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9856, UINT16_MAX, 8649, UINT16_MAX, 8649, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9858, 1668, UINT16_MAX, 1668, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9861, UINT16_MAX, 8650, UINT16_MAX, 8650, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9863, 1673, UINT16_MAX, 1673, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9866, UINT16_MAX, 8651, UINT16_MAX, 8651, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9868, 1678, UINT16_MAX, 1678, UINT16_MAX, 2884, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9871, UINT16_MAX, 8652, UINT16_MAX, 8652, 2887, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9873, 1683, UINT16_MAX, 1683, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9876, UINT16_MAX, 8653, UINT16_MAX, 8653, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9878, 1688, UINT16_MAX, 1688, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9881, UINT16_MAX, 8654, UINT16_MAX, 8654, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9883, 1693, UINT16_MAX, 1693, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9886, UINT16_MAX, 8655, UINT16_MAX, 8655, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9888, 1698, UINT16_MAX, 1698, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9891, UINT16_MAX, 8656, UINT16_MAX, 8656, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9893, 1703, UINT16_MAX, 1703, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9896, UINT16_MAX, 8657, UINT16_MAX, 8657, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9898, 1708, UINT16_MAX, 1708, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9901, UINT16_MAX, 8658, UINT16_MAX, 8658, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9903, 1713, UINT16_MAX, 1713, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9906, UINT16_MAX, 8659, UINT16_MAX, 8659, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9908, 1718, UINT16_MAX, 1718, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9911, UINT16_MAX, 8660, UINT16_MAX, 8660, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9913, 1723, UINT16_MAX, 1723, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9916, UINT16_MAX, 8661, UINT16_MAX, 8661, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9918, 1728, UINT16_MAX, 1728, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9921, UINT16_MAX, 8662, UINT16_MAX, 8662, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9923, 1733, UINT16_MAX, 1733, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9926, UINT16_MAX, 8663, UINT16_MAX, 8663, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9928, 1738, UINT16_MAX, 1738, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9931, UINT16_MAX, 8664, UINT16_MAX, 8664, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9933, 1743, UINT16_MAX, 1743, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9936, UINT16_MAX, 8665, UINT16_MAX, 8665, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9938, 1748, UINT16_MAX, 1748, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9941, UINT16_MAX, 8666, UINT16_MAX, 8666, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9943, 1753, UINT16_MAX, 1753, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9946, UINT16_MAX, 8667, UINT16_MAX, 8667, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9948, 1758, UINT16_MAX, 1758, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9951, UINT16_MAX, 8668, UINT16_MAX, 8668, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9953, 1763, UINT16_MAX, 1763, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9956, UINT16_MAX, 8669, UINT16_MAX, 8669, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9958, 1768, UINT16_MAX, 1768, UINT16_MAX, 3006, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9961, UINT16_MAX, 8670, UINT16_MAX, 8670, 3009, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9963, 1773, UINT16_MAX, 1773, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9966, UINT16_MAX, 8671, UINT16_MAX, 8671, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9968, 1778, UINT16_MAX, 1778, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9971, UINT16_MAX, 8672, UINT16_MAX, 8672, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9973, 1783, UINT16_MAX, 1783, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9976, UINT16_MAX, 8673, UINT16_MAX, 8673, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9978, 1788, UINT16_MAX, 1788, UINT16_MAX, 3024, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9981, UINT16_MAX, 8674, UINT16_MAX, 8674, 3027, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9983, 1793, UINT16_MAX, 1793, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9986, UINT16_MAX, 8675, UINT16_MAX, 8675, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9988, 1798, UINT16_MAX, 1798, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9991, UINT16_MAX, 8676, UINT16_MAX, 8676, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9993, 1803, UINT16_MAX, 1803, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 9996, UINT16_MAX, 8677, UINT16_MAX, 8677, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 9998, 1808, UINT16_MAX, 1808, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10001, UINT16_MAX, 8678, UINT16_MAX, 8678, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10003, 1813, UINT16_MAX, 1813, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10006, UINT16_MAX, 8679, UINT16_MAX, 8679, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10008, 1818, UINT16_MAX, 1818, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10011, UINT16_MAX, 8680, UINT16_MAX, 8680, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10013, 1823, UINT16_MAX, 1823, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10016, UINT16_MAX, 8681, UINT16_MAX, 8681, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10018, 1828, UINT16_MAX, 1828, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10021, UINT16_MAX, 8682, UINT16_MAX, 8682, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10023, 1833, UINT16_MAX, 1833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10026, UINT16_MAX, 8683, UINT16_MAX, 8683, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10028, 1838, UINT16_MAX, 1838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10031, UINT16_MAX, 8684, UINT16_MAX, 8684, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10033, 1843, UINT16_MAX, 1843, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10036, UINT16_MAX, 8685, UINT16_MAX, 8685, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10038, 1848, UINT16_MAX, 1848, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10041, UINT16_MAX, 8686, UINT16_MAX, 8686, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10043, 1853, UINT16_MAX, 1853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10046, UINT16_MAX, 8687, UINT16_MAX, 8687, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10048, 1858, UINT16_MAX, 1858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10051, UINT16_MAX, 8688, UINT16_MAX, 8688, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10053, 1863, UINT16_MAX, 1863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10056, UINT16_MAX, 8689, UINT16_MAX, 8689, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10058, 1868, UINT16_MAX, 1868, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10061, UINT16_MAX, 8690, UINT16_MAX, 8690, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10063, 1873, UINT16_MAX, 1873, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10066, UINT16_MAX, 8691, UINT16_MAX, 8691, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10068, 1878, UINT16_MAX, 1878, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10071, UINT16_MAX, 8692, UINT16_MAX, 8692, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10073, 1883, UINT16_MAX, 1883, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10076, UINT16_MAX, 8693, UINT16_MAX, 8693, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10078, 1888, UINT16_MAX, 1888, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10081, UINT16_MAX, 8694, UINT16_MAX, 8694, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10083, 1893, UINT16_MAX, 1893, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10086, UINT16_MAX, 8695, UINT16_MAX, 8695, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10088, 1898, UINT16_MAX, 1898, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10091, UINT16_MAX, 8696, UINT16_MAX, 8696, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10093, 1903, UINT16_MAX, 1903, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10096, UINT16_MAX, 8697, UINT16_MAX, 8697, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10098, 1908, UINT16_MAX, 1908, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10101, UINT16_MAX, 8698, UINT16_MAX, 8698, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10103, 1913, UINT16_MAX, 1913, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10106, UINT16_MAX, 8699, UINT16_MAX, 8699, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10108, 10108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10110, 10110, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10112, 10112, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10114, 10114, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 10116, 10116, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10118, 1783, 8673, UINT16_MAX, 8673, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 8322, UINT16_MAX, 8700, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10120, 1930, UINT16_MAX, 1930, UINT16_MAX, 3241, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10123, UINT16_MAX, 8701, UINT16_MAX, 8701, 3250, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10125, 1935, UINT16_MAX, 1935, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10128, UINT16_MAX, 8702, UINT16_MAX, 8702, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10130, 1940, UINT16_MAX, 1940, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10133, UINT16_MAX, 8703, UINT16_MAX, 8703, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10135, 1945, UINT16_MAX, 1945, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10138, UINT16_MAX, 8704, UINT16_MAX, 8704, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10140, 1950, UINT16_MAX, 1950, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10143, UINT16_MAX, 8705, UINT16_MAX, 8705, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10145, 1955, UINT16_MAX, 1955, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10148, UINT16_MAX, 8706, UINT16_MAX, 8706, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10150, 1960, UINT16_MAX, 1960, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10153, UINT16_MAX, 8707, UINT16_MAX, 8707, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10155, 1965, UINT16_MAX, 1965, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10158, UINT16_MAX, 8708, UINT16_MAX, 8708, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10160, 1970, UINT16_MAX, 1970, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10163, UINT16_MAX, 8709, UINT16_MAX, 8709, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10165, 1975, UINT16_MAX, 1975, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10168, UINT16_MAX, 8710, UINT16_MAX, 8710, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10170, 1980, UINT16_MAX, 1980, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10173, UINT16_MAX, 8711, UINT16_MAX, 8711, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10175, 1985, UINT16_MAX, 1985, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10178, UINT16_MAX, 8712, UINT16_MAX, 8712, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10180, 1990, UINT16_MAX, 1990, UINT16_MAX, 3455, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10183, UINT16_MAX, 8713, UINT16_MAX, 8713, 3458, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10185, 1995, UINT16_MAX, 1995, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10188, UINT16_MAX, 8714, UINT16_MAX, 8714, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10190, 2000, UINT16_MAX, 2000, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10193, UINT16_MAX, 8715, UINT16_MAX, 8715, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10195, 2005, UINT16_MAX, 2005, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10198, UINT16_MAX, 8716, UINT16_MAX, 8716, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10200, 2010, UINT16_MAX, 2010, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10203, UINT16_MAX, 8717, UINT16_MAX, 8717, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10205, 2015, UINT16_MAX, 2015, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10208, UINT16_MAX, 8718, UINT16_MAX, 8718, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10210, 2020, UINT16_MAX, 2020, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10213, UINT16_MAX, 8719, UINT16_MAX, 8719, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10215, 2025, UINT16_MAX, 2025, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10218, UINT16_MAX, 8720, UINT16_MAX, 8720, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10220, 2030, UINT16_MAX, 2030, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10223, UINT16_MAX, 8721, UINT16_MAX, 8721, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10225, 2035, UINT16_MAX, 2035, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10228, UINT16_MAX, 8722, UINT16_MAX, 8722, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10230, 2040, UINT16_MAX, 2040, UINT16_MAX, 3559, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10233, UINT16_MAX, 8723, UINT16_MAX, 8723, 3562, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10235, 2045, UINT16_MAX, 2045, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10238, UINT16_MAX, 8724, UINT16_MAX, 8724, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10240, 2050, UINT16_MAX, 2050, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10243, UINT16_MAX, 8725, UINT16_MAX, 8725, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10245, 2055, UINT16_MAX, 2055, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10248, UINT16_MAX, 8726, UINT16_MAX, 8726, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10250, 2060, UINT16_MAX, 2060, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10253, UINT16_MAX, 8727, UINT16_MAX, 8727, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10255, 2065, UINT16_MAX, 2065, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10258, UINT16_MAX, 8728, UINT16_MAX, 8728, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10260, 2070, UINT16_MAX, 2070, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10263, UINT16_MAX, 8729, UINT16_MAX, 8729, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10265, 2075, UINT16_MAX, 2075, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10268, UINT16_MAX, 8730, UINT16_MAX, 8730, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10270, 2080, UINT16_MAX, 2080, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10273, UINT16_MAX, 8731, UINT16_MAX, 8731, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10275, 2085, UINT16_MAX, 2085, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10278, UINT16_MAX, 8732, UINT16_MAX, 8732, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10280, 2090, UINT16_MAX, 2090, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10283, UINT16_MAX, 8733, UINT16_MAX, 8733, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10285, 2095, UINT16_MAX, 2095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10288, UINT16_MAX, 8734, UINT16_MAX, 8734, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10290, 2100, UINT16_MAX, 2100, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10293, UINT16_MAX, 8735, UINT16_MAX, 8735, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10295, 2105, UINT16_MAX, 2105, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10298, UINT16_MAX, 8736, UINT16_MAX, 8736, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10300, 2110, UINT16_MAX, 2110, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10303, UINT16_MAX, 8737, UINT16_MAX, 8737, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10305, 2115, UINT16_MAX, 2115, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10308, UINT16_MAX, 8738, UINT16_MAX, 8738, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10310, 2120, UINT16_MAX, 2120, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10313, UINT16_MAX, 8739, UINT16_MAX, 8739, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10315, 2125, UINT16_MAX, 2125, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10318, UINT16_MAX, 8740, UINT16_MAX, 8740, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10320, 2130, UINT16_MAX, 2130, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10323, UINT16_MAX, 8741, UINT16_MAX, 8741, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10325, 2135, UINT16_MAX, 2135, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10328, UINT16_MAX, 8742, UINT16_MAX, 8742, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10330, 2140, UINT16_MAX, 2140, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10333, UINT16_MAX, 8743, UINT16_MAX, 8743, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10335, 2145, UINT16_MAX, 2145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10338, UINT16_MAX, 8744, UINT16_MAX, 8744, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10340, 2150, UINT16_MAX, 2150, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10343, UINT16_MAX, 8745, UINT16_MAX, 8745, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2153, UINT16_MAX, 2153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8746, UINT16_MAX, 8746, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2154, UINT16_MAX, 2154, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8747, UINT16_MAX, 8747, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2155, UINT16_MAX, 2155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8748, UINT16_MAX, 8748, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10348, UINT16_MAX, 8749, UINT16_MAX, 8749, 3761, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10350, UINT16_MAX, 8750, UINT16_MAX, 8750, 3814, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10352, UINT16_MAX, 8751, UINT16_MAX, 8751, 4793, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10354, UINT16_MAX, 8752, UINT16_MAX, 8752, 4796, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10356, UINT16_MAX, 8753, UINT16_MAX, 8753, 4799, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10358, UINT16_MAX, 8754, UINT16_MAX, 8754, 4802, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10360, UINT16_MAX, 8755, UINT16_MAX, 8755, 4805, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10362, UINT16_MAX, 8756, UINT16_MAX, 8756, 4808, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10364, 2174, UINT16_MAX, 2174, UINT16_MAX, 3867, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10367, 2177, UINT16_MAX, 2177, UINT16_MAX, 3920, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10370, 2180, UINT16_MAX, 2180, UINT16_MAX, 4811, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10373, 2183, UINT16_MAX, 2183, UINT16_MAX, 4814, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10376, 2186, UINT16_MAX, 2186, UINT16_MAX, 4817, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10379, 2189, UINT16_MAX, 2189, UINT16_MAX, 4820, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10382, 2192, UINT16_MAX, 2192, UINT16_MAX, 4823, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10385, 2195, UINT16_MAX, 2195, UINT16_MAX, 4826, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10388, UINT16_MAX, 8757, UINT16_MAX, 8757, 3973, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10390, UINT16_MAX, 8758, UINT16_MAX, 8758, 3977, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10392, UINT16_MAX, 8759, UINT16_MAX, 8759, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10394, UINT16_MAX, 8760, UINT16_MAX, 8760, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10396, UINT16_MAX, 8761, UINT16_MAX, 8761, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10398, UINT16_MAX, 8762, UINT16_MAX, 8762, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10400, 2210, UINT16_MAX, 2210, UINT16_MAX, 3981, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10403, 2213, UINT16_MAX, 2213, UINT16_MAX, 3985, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10406, 2216, UINT16_MAX, 2216, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10409, 2219, UINT16_MAX, 2219, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10412, 2222, UINT16_MAX, 2222, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10415, 2225, UINT16_MAX, 2225, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10418, UINT16_MAX, 8763, UINT16_MAX, 8763, 3989, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10420, UINT16_MAX, 8764, UINT16_MAX, 8764, 4042, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10422, UINT16_MAX, 8765, UINT16_MAX, 8765, 4829, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10424, UINT16_MAX, 8766, UINT16_MAX, 8766, 4832, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10426, UINT16_MAX, 8767, UINT16_MAX, 8767, 4835, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10428, UINT16_MAX, 8768, UINT16_MAX, 8768, 4838, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10430, UINT16_MAX, 8769, UINT16_MAX, 8769, 4841, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10432, UINT16_MAX, 8770, UINT16_MAX, 8770, 4844, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10434, 2244, UINT16_MAX, 2244, UINT16_MAX, 4095, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10437, 2247, UINT16_MAX, 2247, UINT16_MAX, 4148, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10440, 2250, UINT16_MAX, 2250, UINT16_MAX, 4847, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10443, 2253, UINT16_MAX, 2253, UINT16_MAX, 4850, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10446, 2256, UINT16_MAX, 2256, UINT16_MAX, 4853, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10449, 2259, UINT16_MAX, 2259, UINT16_MAX, 4856, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10452, 2262, UINT16_MAX, 2262, UINT16_MAX, 4859, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10455, 2265, UINT16_MAX, 2265, UINT16_MAX, 4862, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10458, UINT16_MAX, 8771, UINT16_MAX, 8771, 4201, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10460, UINT16_MAX, 8772, UINT16_MAX, 8772, 4253, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10462, UINT16_MAX, 8773, UINT16_MAX, 8773, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10464, UINT16_MAX, 8774, UINT16_MAX, 8774, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10466, UINT16_MAX, 8775, UINT16_MAX, 8775, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10468, UINT16_MAX, 8776, UINT16_MAX, 8776, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10470, UINT16_MAX, 8777, UINT16_MAX, 8777, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10472, UINT16_MAX, 8778, UINT16_MAX, 8778, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10474, 2284, UINT16_MAX, 2284, UINT16_MAX, 4305, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10477, 2287, UINT16_MAX, 2287, UINT16_MAX, 4357, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10480, 2290, UINT16_MAX, 2290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10483, 2293, UINT16_MAX, 2293, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10486, 2296, UINT16_MAX, 2296, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10489, 2299, UINT16_MAX, 2299, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10492, 2302, UINT16_MAX, 2302, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10495, 2305, UINT16_MAX, 2305, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10498, UINT16_MAX, 8779, UINT16_MAX, 8779, 4409, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10500, UINT16_MAX, 8780, UINT16_MAX, 8780, 4413, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10502, UINT16_MAX, 8781, UINT16_MAX, 8781, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10504, UINT16_MAX, 8782, UINT16_MAX, 8782, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10506, UINT16_MAX, 8783, UINT16_MAX, 8783, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10508, UINT16_MAX, 8784, UINT16_MAX, 8784, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10510, 2320, UINT16_MAX, 2320, UINT16_MAX, 4417, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10513, 2323, UINT16_MAX, 2323, UINT16_MAX, 4421, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10516, 2326, UINT16_MAX, 2326, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10519, 2329, UINT16_MAX, 2329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10522, 2332, UINT16_MAX, 2332, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10525, 2335, UINT16_MAX, 2335, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10528, 10528, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4425, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10530, UINT16_MAX, 8785, UINT16_MAX, 8785, 4477, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10532, 18726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10537, UINT16_MAX, 8786, UINT16_MAX, 8786, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10539, 18733, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10544, UINT16_MAX, 8787, UINT16_MAX, 8787, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10546, 18740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10551, UINT16_MAX, 8788, UINT16_MAX, 8788, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10553, 2363, UINT16_MAX, 2363, UINT16_MAX, 4529, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10556, 2366, UINT16_MAX, 2366, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10559, 2369, UINT16_MAX, 2369, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10562, 2372, UINT16_MAX, 2372, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10565, UINT16_MAX, 8789, UINT16_MAX, 8789, 4581, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10567, UINT16_MAX, 8790, UINT16_MAX, 8790, 4634, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10569, UINT16_MAX, 8791, UINT16_MAX, 8791, 4865, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10571, UINT16_MAX, 8792, UINT16_MAX, 8792, 4868, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10573, UINT16_MAX, 8793, UINT16_MAX, 8793, 4871, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10575, UINT16_MAX, 8794, UINT16_MAX, 8794, 4874, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10577, UINT16_MAX, 8795, UINT16_MAX, 8795, 4877, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10579, UINT16_MAX, 8796, UINT16_MAX, 8796, 4880, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10581, 2391, UINT16_MAX, 2391, UINT16_MAX, 4687, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10584, 2394, UINT16_MAX, 2394, UINT16_MAX, 4740, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10587, 2397, UINT16_MAX, 2397, UINT16_MAX, 4883, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10590, 2400, UINT16_MAX, 2400, UINT16_MAX, 4886, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10593, 2403, UINT16_MAX, 2403, UINT16_MAX, 4889, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10596, 2406, UINT16_MAX, 2406, UINT16_MAX, 4892, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10599, 2409, UINT16_MAX, 2409, UINT16_MAX, 4895, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10602, 2412, UINT16_MAX, 2412, UINT16_MAX, 4898, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10605, UINT16_MAX, 8797, UINT16_MAX, 8797, 4901, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 820, UINT16_MAX, 8798, UINT16_MAX, 8798, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10607, UINT16_MAX, 8799, UINT16_MAX, 8799, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 824, UINT16_MAX, 8800, UINT16_MAX, 8800, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10609, UINT16_MAX, 8801, UINT16_MAX, 8801, 4910, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 827, UINT16_MAX, 8802, UINT16_MAX, 8802, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10611, UINT16_MAX, 8803, UINT16_MAX, 8803, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 830, UINT16_MAX, 8804, UINT16_MAX, 8804, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10613, UINT16_MAX, 8805, UINT16_MAX, 8805, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 833, UINT16_MAX, 8806, UINT16_MAX, 8806, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10615, UINT16_MAX, 8807, UINT16_MAX, 8807, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 836, UINT16_MAX, 8808, UINT16_MAX, 8808, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10617, UINT16_MAX, 8809, UINT16_MAX, 8809, 5030, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 839, UINT16_MAX, 8810, UINT16_MAX, 8810, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10619, 10621, 8811, UINT16_MAX, 8811, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10623, 10625, 8812, UINT16_MAX, 8812, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10627, 10629, 8813, UINT16_MAX, 8813, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10631, 10633, 8814, UINT16_MAX, 8814, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10635, 10637, 8815, UINT16_MAX, 8815, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10639, 10641, 8816, UINT16_MAX, 8816, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10643, 10645, 8817, UINT16_MAX, 8817, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10647, 10649, 8818, UINT16_MAX, 8818, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10651, 10621, UINT16_MAX, 8819, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10653, 10625, UINT16_MAX, 8820, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10655, 10629, UINT16_MAX, 8821, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10657, 10633, UINT16_MAX, 8822, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10659, 10637, UINT16_MAX, 8823, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10661, 10641, UINT16_MAX, 8824, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10663, 10645, UINT16_MAX, 8825, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10665, 10649, UINT16_MAX, 8826, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10667, 10669, 8827, UINT16_MAX, 8827, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10671, 10673, 8828, UINT16_MAX, 8828, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10675, 10677, 8829, UINT16_MAX, 8829, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10679, 10681, 8830, UINT16_MAX, 8830, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10683, 10685, 8831, UINT16_MAX, 8831, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10687, 10689, 8832, UINT16_MAX, 8832, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10691, 10693, 8833, UINT16_MAX, 8833, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10695, 10697, 8834, UINT16_MAX, 8834, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10699, 10669, UINT16_MAX, 8835, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10701, 10673, UINT16_MAX, 8836, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10703, 10677, UINT16_MAX, 8837, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10705, 10681, UINT16_MAX, 8838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10707, 10685, UINT16_MAX, 8839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10709, 10689, UINT16_MAX, 8840, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10711, 10693, UINT16_MAX, 8841, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10713, 10697, UINT16_MAX, 8842, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10715, 10717, 8843, UINT16_MAX, 8843, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10719, 10721, 8844, UINT16_MAX, 8844, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10723, 10725, 8845, UINT16_MAX, 8845, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10727, 10729, 8846, UINT16_MAX, 8846, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10731, 10733, 8847, UINT16_MAX, 8847, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10735, 10737, 8848, UINT16_MAX, 8848, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10739, 10741, 8849, UINT16_MAX, 8849, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10743, 10745, 8850, UINT16_MAX, 8850, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10747, 10717, UINT16_MAX, 8851, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10749, 10721, UINT16_MAX, 8852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10751, 10725, UINT16_MAX, 8853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10753, 10729, UINT16_MAX, 8854, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10755, 10733, UINT16_MAX, 8855, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10757, 10737, UINT16_MAX, 8856, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10759, 10741, UINT16_MAX, 8857, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10761, 10745, UINT16_MAX, 8858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10763, UINT16_MAX, 8859, UINT16_MAX, 8859, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10765, UINT16_MAX, 8860, UINT16_MAX, 8860, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10767, 10769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10771, 10773, 8861, UINT16_MAX, 8861, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10775, 10777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10779, 10779, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4907, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10781, 18975, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10786, 2596, UINT16_MAX, 2596, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10789, 2599, UINT16_MAX, 2599, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10792, 2602, UINT16_MAX, 2602, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2603, 2604, UINT16_MAX, 2604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10797, 10773, UINT16_MAX, 8862, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 807, 807, 7217, UINT16_MAX, 7217, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4919, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10805, 10807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10809, 10811, 8863, UINT16_MAX, 8863, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10813, 10815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10817, 10817, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4916, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10819, 19013, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10824, 2634, UINT16_MAX, 2634, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2635, 2636, UINT16_MAX, 2636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10829, 2639, UINT16_MAX, 2639, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2640, 2641, UINT16_MAX, 2641, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10834, 10811, UINT16_MAX, 8864, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10836, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10842, UINT16_MAX, 8865, UINT16_MAX, 8865, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10844, UINT16_MAX, 8866, UINT16_MAX, 8866, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10846, 19040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 2659, 17226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10852, 10852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10854, 19048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10859, 2669, UINT16_MAX, 2669, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10862, 2672, UINT16_MAX, 2672, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10865, 2675, UINT16_MAX, 2675, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2676, 2677, UINT16_MAX, 2677, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10876, UINT16_MAX, 8867, UINT16_MAX, 8867, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10878, UINT16_MAX, 8868, UINT16_MAX, 8868, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10880, 19074, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 2693, 17267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10886, 10886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10888, UINT16_MAX, 8869, UINT16_MAX, 8869, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10890, 10890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10892, 19086, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10897, 2707, UINT16_MAX, 2707, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10900, 2710, UINT16_MAX, 2710, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10903, 2713, UINT16_MAX, 2713, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2714, 2715, UINT16_MAX, 2715, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10908, 2718, UINT16_MAX, 2718, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 10911, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 2721, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 2722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10915, 10917, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10919, 10921, 8870, UINT16_MAX, 8870, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10923, 10925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10927, 10927, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5036, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 10929, 19123, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10934, 2744, UINT16_MAX, 2744, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2745, 2746, UINT16_MAX, 2746, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 10939, 2749, UINT16_MAX, 2749, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2750, 2751, UINT16_MAX, 2751, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 10944, 10921, UINT16_MAX, 8871, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 2754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10947, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4971, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, 2757, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, 2758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_COMPAT, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_NOBREAK, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_ZWJ},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NOBREAK, 2759, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10952, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PI, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PF, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 2762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10955, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19149, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZL, 0, UTF8PROC_BIDI_CLASS_WS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_ZP, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRE, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLE, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_PDF, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRO, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLO, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, 10960, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, 19154, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10965, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10970, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10972, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_CS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10974, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10976, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 10978, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_FSI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_PDI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 8, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 2801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 13, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, 2801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 4, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 14, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 23, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 7, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 10, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 11, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 12, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 13, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 15, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 18, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 19, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, 10996, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19190, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11005, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19199, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19202, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11014, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 277, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 11019, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 11024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2835, 866, UINT16_MAX, 866, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 1501, 10, UINT16_MAX, 10, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2836, 65, UINT16_MAX, 65, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2837, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2838, UINT16_MAX, 2838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2839, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8872, UINT16_MAX, 8872, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19233, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19236, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 27431, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19243, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19246, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19249, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19255, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19261, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19273, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 11087, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1499, 2897, UINT16_MAX, 2897, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11090, 2900, UINT16_MAX, 2900, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19285, 2904, UINT16_MAX, 2904, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11097, 2907, UINT16_MAX, 2907, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2908, 2909, UINT16_MAX, 2909, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11102, 2912, UINT16_MAX, 2912, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19297, 2916, UINT16_MAX, 2916, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 27493, 2921, UINT16_MAX, 2921, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11114, 2924, UINT16_MAX, 2924, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2925, 2926, UINT16_MAX, 2926, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11119, 2929, UINT16_MAX, 2929, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19314, 2933, UINT16_MAX, 2933, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1502, 2934, UINT16_MAX, 2934, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2812, 2935, UINT16_MAX, 2935, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1494, 2936, UINT16_MAX, 2936, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1503, 2937, UINT16_MAX, 2937, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8, UINT16_MAX, 8873, UINT16_MAX, 8873, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11130, UINT16_MAX, 8874, UINT16_MAX, 8874, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19324, UINT16_MAX, 8875, UINT16_MAX, 8875, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11135, UINT16_MAX, 8876, UINT16_MAX, 8876, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21, UINT16_MAX, 8877, UINT16_MAX, 8877, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11137, UINT16_MAX, 8878, UINT16_MAX, 8878, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19331, UINT16_MAX, 8879, UINT16_MAX, 8879, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 27526, UINT16_MAX, 8880, UINT16_MAX, 8880, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11146, UINT16_MAX, 8881, UINT16_MAX, 8881, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23, UINT16_MAX, 8882, UINT16_MAX, 8882, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11148, UINT16_MAX, 8883, UINT16_MAX, 8883, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19342, UINT16_MAX, 8884, UINT16_MAX, 8884, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11, UINT16_MAX, 8885, UINT16_MAX, 8885, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2, UINT16_MAX, 8886, UINT16_MAX, 8886, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3, UINT16_MAX, 8887, UINT16_MAX, 8887, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12, UINT16_MAX, 8888, UINT16_MAX, 8888, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2961, UINT16_MAX, 2961, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8889, UINT16_MAX, 8889, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5039, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5042, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5045, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11157, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11161, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11163, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11165, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11167, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5048, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5054, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5051, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5057, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5060, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5063, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5066, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11175, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5069, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19373, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11184, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19378, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5072, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5075, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11191, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5078, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5081, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11195, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5090, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11197, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5087, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11199, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5099, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5102, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11203, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11205, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11207, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5105, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5108, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11211, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5111, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5114, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11215, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5117, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5120, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5147, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5150, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11219, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11221, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5123, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5126, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11223, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11225, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5129, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5132, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11229, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5153, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5156, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5135, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5138, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5141, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5144, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11231, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11233, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11235, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11237, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5159, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5162, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5165, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5168, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11239, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11241, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11243, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11245, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11247, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11249, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11251, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11253, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, 3063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, 3064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11257, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11259, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11261, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11263, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11265, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11269, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11271, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11273, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 11277, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27702, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27706, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27710, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27714, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27718, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27730, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 11366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1491, 3287, UINT16_MAX, 3287, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1493, 3288, UINT16_MAX, 3288, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2812, 3289, UINT16_MAX, 3289, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1494, 3290, UINT16_MAX, 3290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1495, 3291, UINT16_MAX, 3291, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2837, 3292, UINT16_MAX, 3292, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1497, 3293, UINT16_MAX, 3293, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1498, 3294, UINT16_MAX, 3294, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1499, 3295, UINT16_MAX, 3295, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1500, 3296, UINT16_MAX, 3296, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1501, 3297, UINT16_MAX, 3297, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1502, 3298, UINT16_MAX, 3298, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1503, 3299, UINT16_MAX, 3299, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1504, 3300, UINT16_MAX, 3300, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1505, 3301, UINT16_MAX, 3301, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1507, 3302, UINT16_MAX, 3302, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2826, 3303, UINT16_MAX, 3303, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1508, 3304, UINT16_MAX, 3304, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3305, 3306, UINT16_MAX, 3306, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1509, 3307, UINT16_MAX, 3307, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1510, 3308, UINT16_MAX, 3308, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2908, 3309, UINT16_MAX, 3309, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1511, 3310, UINT16_MAX, 3310, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2925, 3311, UINT16_MAX, 3311, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3312, 3313, UINT16_MAX, 3313, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2834, 3314, UINT16_MAX, 3314, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 0, UINT16_MAX, 8890, UINT16_MAX, 8890, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1, UINT16_MAX, 8891, UINT16_MAX, 8891, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2, UINT16_MAX, 8892, UINT16_MAX, 8892, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3, UINT16_MAX, 8893, UINT16_MAX, 8893, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4, UINT16_MAX, 8894, UINT16_MAX, 8894, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 5, UINT16_MAX, 8895, UINT16_MAX, 8895, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 6, UINT16_MAX, 8896, UINT16_MAX, 8896, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 7, UINT16_MAX, 8897, UINT16_MAX, 8897, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 8, UINT16_MAX, 8898, UINT16_MAX, 8898, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 9, UINT16_MAX, 8899, UINT16_MAX, 8899, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 10, UINT16_MAX, 8900, UINT16_MAX, 8900, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 11, UINT16_MAX, 8901, UINT16_MAX, 8901, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12, UINT16_MAX, 8902, UINT16_MAX, 8902, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 13, UINT16_MAX, 8903, UINT16_MAX, 8903, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 14, UINT16_MAX, 8904, UINT16_MAX, 8904, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 15, UINT16_MAX, 8905, UINT16_MAX, 8905, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 16, UINT16_MAX, 8906, UINT16_MAX, 8906, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 17, UINT16_MAX, 8907, UINT16_MAX, 8907, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 18, UINT16_MAX, 8908, UINT16_MAX, 8908, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 19, UINT16_MAX, 8909, UINT16_MAX, 8909, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20, UINT16_MAX, 8910, UINT16_MAX, 8910, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 21, UINT16_MAX, 8911, UINT16_MAX, 8911, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 22, UINT16_MAX, 8912, UINT16_MAX, 8912, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 23, UINT16_MAX, 8913, UINT16_MAX, 8913, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 24, UINT16_MAX, 8914, UINT16_MAX, 8914, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 25, UINT16_MAX, 8915, UINT16_MAX, 8915, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 27891, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19703, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19708, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 11519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5171, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3329, UINT16_MAX, 3329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3330, UINT16_MAX, 3330, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3331, UINT16_MAX, 3331, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3332, UINT16_MAX, 3332, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3333, UINT16_MAX, 3333, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3334, UINT16_MAX, 3334, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3335, UINT16_MAX, 3335, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3336, UINT16_MAX, 3336, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3337, UINT16_MAX, 3337, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3338, UINT16_MAX, 3338, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3339, UINT16_MAX, 3339, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3340, UINT16_MAX, 3340, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3341, UINT16_MAX, 3341, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3342, UINT16_MAX, 3342, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3343, UINT16_MAX, 3343, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3344, UINT16_MAX, 3344, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3345, UINT16_MAX, 3345, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3346, UINT16_MAX, 3346, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3347, UINT16_MAX, 3347, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3348, UINT16_MAX, 3348, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3349, UINT16_MAX, 3349, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3350, UINT16_MAX, 3350, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3351, UINT16_MAX, 3351, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3352, UINT16_MAX, 3352, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3353, UINT16_MAX, 3353, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3354, UINT16_MAX, 3354, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3355, UINT16_MAX, 3355, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3356, UINT16_MAX, 3356, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3357, UINT16_MAX, 3357, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3358, UINT16_MAX, 3358, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3359, UINT16_MAX, 3359, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3360, UINT16_MAX, 3360, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3361, UINT16_MAX, 3361, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3362, UINT16_MAX, 3362, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3363, UINT16_MAX, 3363, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3364, UINT16_MAX, 3364, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3365, UINT16_MAX, 3365, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3366, UINT16_MAX, 3366, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3367, UINT16_MAX, 3367, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3368, UINT16_MAX, 3368, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3369, UINT16_MAX, 3369, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3370, UINT16_MAX, 3370, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3371, UINT16_MAX, 3371, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3372, UINT16_MAX, 3372, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3373, UINT16_MAX, 3373, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3374, UINT16_MAX, 3374, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3375, UINT16_MAX, 3375, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8916, UINT16_MAX, 8916, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8917, UINT16_MAX, 8917, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8918, UINT16_MAX, 8918, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8919, UINT16_MAX, 8919, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8920, UINT16_MAX, 8920, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8921, UINT16_MAX, 8921, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8922, UINT16_MAX, 8922, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8923, UINT16_MAX, 8923, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8924, UINT16_MAX, 8924, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8925, UINT16_MAX, 8925, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8926, UINT16_MAX, 8926, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8927, UINT16_MAX, 8927, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8928, UINT16_MAX, 8928, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8929, UINT16_MAX, 8929, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8930, UINT16_MAX, 8930, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8931, UINT16_MAX, 8931, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8932, UINT16_MAX, 8932, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8933, UINT16_MAX, 8933, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8934, UINT16_MAX, 8934, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8935, UINT16_MAX, 8935, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8936, UINT16_MAX, 8936, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8937, UINT16_MAX, 8937, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8938, UINT16_MAX, 8938, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8939, UINT16_MAX, 8939, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8940, UINT16_MAX, 8940, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8941, UINT16_MAX, 8941, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8942, UINT16_MAX, 8942, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8943, UINT16_MAX, 8943, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8944, UINT16_MAX, 8944, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8945, UINT16_MAX, 8945, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8946, UINT16_MAX, 8946, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8947, UINT16_MAX, 8947, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8948, UINT16_MAX, 8948, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8949, UINT16_MAX, 8949, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8950, UINT16_MAX, 8950, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8951, UINT16_MAX, 8951, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8952, UINT16_MAX, 8952, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8953, UINT16_MAX, 8953, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8954, UINT16_MAX, 8954, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8955, UINT16_MAX, 8955, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8956, UINT16_MAX, 8956, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8957, UINT16_MAX, 8957, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8958, UINT16_MAX, 8958, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8959, UINT16_MAX, 8959, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8960, UINT16_MAX, 8960, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8961, UINT16_MAX, 8961, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8962, UINT16_MAX, 8962, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3376, UINT16_MAX, 3376, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8963, UINT16_MAX, 8963, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3377, UINT16_MAX, 3377, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3378, UINT16_MAX, 3378, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3379, UINT16_MAX, 3379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8964, UINT16_MAX, 8964, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8965, UINT16_MAX, 8965, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3380, UINT16_MAX, 3380, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8966, UINT16_MAX, 8966, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3381, UINT16_MAX, 3381, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8967, UINT16_MAX, 8967, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3382, UINT16_MAX, 3382, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8968, UINT16_MAX, 8968, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1513, UINT16_MAX, 1513, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1531, UINT16_MAX, 1531, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1512, UINT16_MAX, 1512, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1520, UINT16_MAX, 1520, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3383, UINT16_MAX, 3383, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8969, UINT16_MAX, 8969, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3384, UINT16_MAX, 3384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8970, UINT16_MAX, 8970, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 9, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2908, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3385, UINT16_MAX, 3385, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3386, UINT16_MAX, 3386, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3387, UINT16_MAX, 3387, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8971, UINT16_MAX, 8971, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3388, UINT16_MAX, 3388, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8972, UINT16_MAX, 8972, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3389, UINT16_MAX, 3389, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8973, UINT16_MAX, 8973, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3390, UINT16_MAX, 3390, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8974, UINT16_MAX, 8974, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3391, UINT16_MAX, 3391, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8975, UINT16_MAX, 8975, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3392, UINT16_MAX, 3392, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8976, UINT16_MAX, 8976, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3393, UINT16_MAX, 3393, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8977, UINT16_MAX, 8977, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3394, UINT16_MAX, 3394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8978, UINT16_MAX, 8978, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3395, UINT16_MAX, 3395, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8979, UINT16_MAX, 8979, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3396, UINT16_MAX, 3396, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8980, UINT16_MAX, 8980, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3397, UINT16_MAX, 3397, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8981, UINT16_MAX, 8981, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3398, UINT16_MAX, 3398, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8982, UINT16_MAX, 8982, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3399, UINT16_MAX, 3399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8983, UINT16_MAX, 8983, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3400, UINT16_MAX, 3400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8984, UINT16_MAX, 8984, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3401, UINT16_MAX, 3401, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8985, UINT16_MAX, 8985, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3402, UINT16_MAX, 3402, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8986, UINT16_MAX, 8986, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3403, UINT16_MAX, 3403, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8987, UINT16_MAX, 8987, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3404, UINT16_MAX, 3404, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8988, UINT16_MAX, 8988, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3405, UINT16_MAX, 3405, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8989, UINT16_MAX, 8989, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3406, UINT16_MAX, 3406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8990, UINT16_MAX, 8990, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3407, UINT16_MAX, 3407, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8991, UINT16_MAX, 8991, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3408, UINT16_MAX, 3408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8992, UINT16_MAX, 8992, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3409, UINT16_MAX, 3409, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8993, UINT16_MAX, 8993, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3410, UINT16_MAX, 3410, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8994, UINT16_MAX, 8994, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3411, UINT16_MAX, 3411, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8995, UINT16_MAX, 8995, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3412, UINT16_MAX, 3412, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8996, UINT16_MAX, 8996, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3413, UINT16_MAX, 3413, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8997, UINT16_MAX, 8997, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3414, UINT16_MAX, 3414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8998, UINT16_MAX, 8998, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3415, UINT16_MAX, 3415, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8999, UINT16_MAX, 8999, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3416, UINT16_MAX, 3416, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9000, UINT16_MAX, 9000, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3417, UINT16_MAX, 3417, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9001, UINT16_MAX, 9001, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3418, UINT16_MAX, 3418, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9002, UINT16_MAX, 9002, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3419, UINT16_MAX, 3419, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9003, UINT16_MAX, 9003, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3420, UINT16_MAX, 3420, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9004, UINT16_MAX, 9004, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3421, UINT16_MAX, 3421, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9005, UINT16_MAX, 9005, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3422, UINT16_MAX, 3422, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9006, UINT16_MAX, 9006, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3423, UINT16_MAX, 3423, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9007, UINT16_MAX, 9007, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3424, UINT16_MAX, 3424, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9008, UINT16_MAX, 9008, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3425, UINT16_MAX, 3425, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9009, UINT16_MAX, 9009, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3426, UINT16_MAX, 3426, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9010, UINT16_MAX, 9010, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3427, UINT16_MAX, 3427, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9011, UINT16_MAX, 9011, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3428, UINT16_MAX, 3428, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9012, UINT16_MAX, 9012, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3429, UINT16_MAX, 3429, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9013, UINT16_MAX, 9013, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3430, UINT16_MAX, 3430, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9014, UINT16_MAX, 9014, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3431, UINT16_MAX, 3431, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9015, UINT16_MAX, 9015, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3432, UINT16_MAX, 3432, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9016, UINT16_MAX, 9016, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3433, UINT16_MAX, 3433, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9017, UINT16_MAX, 9017, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3434, UINT16_MAX, 3434, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9018, UINT16_MAX, 9018, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3435, UINT16_MAX, 3435, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9019, UINT16_MAX, 9019, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3436, UINT16_MAX, 3436, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9020, UINT16_MAX, 9020, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3437, UINT16_MAX, 3437, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9021, UINT16_MAX, 9021, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3438, UINT16_MAX, 3438, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9022, UINT16_MAX, 9022, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3439, UINT16_MAX, 3439, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9023, UINT16_MAX, 9023, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9024, UINT16_MAX, 9024, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9025, UINT16_MAX, 9025, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9026, UINT16_MAX, 9026, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9027, UINT16_MAX, 9027, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9028, UINT16_MAX, 9028, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9029, UINT16_MAX, 9029, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9030, UINT16_MAX, 9030, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9031, UINT16_MAX, 9031, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9032, UINT16_MAX, 9032, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9033, UINT16_MAX, 9033, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9034, UINT16_MAX, 9034, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9035, UINT16_MAX, 9035, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9036, UINT16_MAX, 9036, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9037, UINT16_MAX, 9037, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9038, UINT16_MAX, 9038, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9039, UINT16_MAX, 9039, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9040, UINT16_MAX, 9040, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9041, UINT16_MAX, 9041, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9042, UINT16_MAX, 9042, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9043, UINT16_MAX, 9043, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9044, UINT16_MAX, 9044, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9045, UINT16_MAX, 9045, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9046, UINT16_MAX, 9046, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9047, UINT16_MAX, 9047, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9048, UINT16_MAX, 9048, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9049, UINT16_MAX, 9049, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9050, UINT16_MAX, 9050, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9051, UINT16_MAX, 9051, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9052, UINT16_MAX, 9052, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9053, UINT16_MAX, 9053, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9054, UINT16_MAX, 9054, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9055, UINT16_MAX, 9055, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9056, UINT16_MAX, 9056, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9057, UINT16_MAX, 9057, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9058, UINT16_MAX, 9058, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9059, UINT16_MAX, 9059, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9060, UINT16_MAX, 9060, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9061, UINT16_MAX, 9061, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9062, UINT16_MAX, 9062, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9063, UINT16_MAX, 9063, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3455, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3458, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3475, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3478, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3479, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3481, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3482, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3484, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3487, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3488, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3490, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3547, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3553, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3568, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3634, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3643, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3655, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_WIDE, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 218, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 224, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5239, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5174, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5177, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5180, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5183, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5186, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5189, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5192, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5195, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5198, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5201, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5204, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5207, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5210, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5213, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5216, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5219, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11884, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5223, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11888, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5227, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11892, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5231, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11894, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11896, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5235, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11900, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11902, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32820, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32821, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11904, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 11906, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5242, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, 11908, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, 11910, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5310, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5245, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11912, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5248, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11914, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5251, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11916, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5254, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11918, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5257, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11920, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5260, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11922, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5263, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11924, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5266, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11926, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5269, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11928, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5272, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11930, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5275, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11932, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5278, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11934, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5281, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11936, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5284, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11938, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5287, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11940, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5290, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11942, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11944, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5294, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11946, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11948, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5298, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11950, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11952, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5302, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11954, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11956, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5306, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11958, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11960, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5313, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5316, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5319, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5322, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11962, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11964, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11966, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11968, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 11970, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5325, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, 11972, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, 11974, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3805, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3806, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3808, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3818, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3822, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3823, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3824, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3825, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3827, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3828, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3830, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3831, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3832, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3833, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3836, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3837, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3839, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3843, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3845, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3848, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3849, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3869, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3884, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3885, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3887, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20272, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20278, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20281, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20284, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20290, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20299, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20302, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 28562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 53142, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 44957, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20387, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20399, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20402, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20405, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20414, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20417, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20429, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20432, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20435, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20438, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4111, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4112, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4113, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 20498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12319, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3806, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12345, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12363, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 36943, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 28756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12376, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4187, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4188, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4190, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4191, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4192, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4194, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4195, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4196, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4197, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4199, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4200, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4202, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4203, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4204, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4205, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4206, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4207, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4208, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4210, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4211, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4212, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4214, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4215, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4216, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12412, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12414, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12418, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12424, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12428, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12430, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12432, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12436, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 12438, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 12467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 20661, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 12472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 20666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4286, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4288, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4290, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4291, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4292, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4297, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4298, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4299, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4300, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4301, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4302, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4303, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4304, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4307, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4310, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4314, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4316, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4319, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4330, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28910, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28914, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28918, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20730, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20737, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37127, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28940, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20755, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28953, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28957, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28972, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 28976, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37174, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 45371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37185, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20806, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29011, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20823, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37220, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29033, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20845, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20848, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20885, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29089, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20906, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20916, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20919, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20922, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20928, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29123, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20935, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20940, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20943, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20946, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29141, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20953, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20956, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20959, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29172, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29176, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20988, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20991, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20994, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21003, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12818, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21017, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12828, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12830, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12832, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12836, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21043, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21049, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21052, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21055, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21058, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21061, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21073, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21079, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21082, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21085, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12896, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21092, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12903, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12905, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 12907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21101, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21104, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 12915, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12917, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12919, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12921, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12923, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12929, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12931, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12933, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12935, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12937, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12939, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12941, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12943, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21137, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12952, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12954, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12956, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12958, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12960, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12962, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12964, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21158, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21161, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21167, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12978, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12980, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12982, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12984, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12986, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12988, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12990, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12992, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12994, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 12996, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21190, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13004, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21204, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13015, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21212, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13027, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21221, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21224, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21230, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 45814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13052, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13054, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13056, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13058, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13060, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13062, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13072, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13074, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13078, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13080, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13082, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13084, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13086, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13092, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13094, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13096, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29482, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13105, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13107, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13109, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13111, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13113, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13115, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13117, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13119, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13121, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13123, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13128, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13130, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13138, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 29524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13147, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13149, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13151, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13153, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13161, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13163, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13165, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13167, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13175, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21377, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21383, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21389, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21395, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21398, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21401, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21404, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21413, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21419, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21428, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21431, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21437, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5056, UINT16_MAX, 5056, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9064, UINT16_MAX, 9064, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5057, UINT16_MAX, 5057, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9065, UINT16_MAX, 9065, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5058, UINT16_MAX, 5058, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9066, UINT16_MAX, 9066, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5059, UINT16_MAX, 5059, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9067, UINT16_MAX, 9067, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5060, UINT16_MAX, 5060, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9068, UINT16_MAX, 9068, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1445, UINT16_MAX, 1445, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8621, UINT16_MAX, 8621, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5061, UINT16_MAX, 5061, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9069, UINT16_MAX, 9069, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5062, UINT16_MAX, 5062, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9070, UINT16_MAX, 9070, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5063, UINT16_MAX, 5063, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9071, UINT16_MAX, 9071, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5064, UINT16_MAX, 5064, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9072, UINT16_MAX, 9072, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5065, UINT16_MAX, 5065, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9073, UINT16_MAX, 9073, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5066, UINT16_MAX, 5066, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9074, UINT16_MAX, 9074, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5067, UINT16_MAX, 5067, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9075, UINT16_MAX, 9075, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5068, UINT16_MAX, 5068, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9076, UINT16_MAX, 9076, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5069, UINT16_MAX, 5069, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9077, UINT16_MAX, 9077, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5070, UINT16_MAX, 5070, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9078, UINT16_MAX, 9078, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5071, UINT16_MAX, 5071, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9079, UINT16_MAX, 9079, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5072, UINT16_MAX, 5072, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9080, UINT16_MAX, 9080, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5073, UINT16_MAX, 5073, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9081, UINT16_MAX, 9081, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5074, UINT16_MAX, 5074, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9082, UINT16_MAX, 9082, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5075, UINT16_MAX, 5075, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9083, UINT16_MAX, 9083, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5076, UINT16_MAX, 5076, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9084, UINT16_MAX, 9084, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5077, UINT16_MAX, 5077, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9085, UINT16_MAX, 9085, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5078, UINT16_MAX, 5078, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9086, UINT16_MAX, 9086, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5079, UINT16_MAX, 5079, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9087, UINT16_MAX, 9087, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5080, UINT16_MAX, 5080, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9088, UINT16_MAX, 9088, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5081, UINT16_MAX, 5081, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9089, UINT16_MAX, 9089, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5082, UINT16_MAX, 5082, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9090, UINT16_MAX, 9090, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5083, UINT16_MAX, 5083, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9091, UINT16_MAX, 9091, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5084, UINT16_MAX, 5084, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9092, UINT16_MAX, 9092, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5085, UINT16_MAX, 5085, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9093, UINT16_MAX, 9093, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5086, UINT16_MAX, 5086, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9094, UINT16_MAX, 9094, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5087, UINT16_MAX, 5087, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9095, UINT16_MAX, 9095, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5088, UINT16_MAX, 5088, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9096, UINT16_MAX, 9096, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5089, UINT16_MAX, 5089, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9097, UINT16_MAX, 9097, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5090, UINT16_MAX, 5090, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9098, UINT16_MAX, 9098, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5091, UINT16_MAX, 5091, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9099, UINT16_MAX, 9099, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 981, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 983, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5092, UINT16_MAX, 5092, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9100, UINT16_MAX, 9100, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5093, UINT16_MAX, 5093, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9101, UINT16_MAX, 9101, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5094, UINT16_MAX, 5094, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9102, UINT16_MAX, 9102, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5095, UINT16_MAX, 5095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9103, UINT16_MAX, 9103, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5096, UINT16_MAX, 5096, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9104, UINT16_MAX, 9104, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5097, UINT16_MAX, 5097, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9105, UINT16_MAX, 9105, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5098, UINT16_MAX, 5098, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9106, UINT16_MAX, 9106, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5099, UINT16_MAX, 5099, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9107, UINT16_MAX, 9107, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5100, UINT16_MAX, 5100, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9108, UINT16_MAX, 9108, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5101, UINT16_MAX, 5101, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9109, UINT16_MAX, 9109, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5102, UINT16_MAX, 5102, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9110, UINT16_MAX, 9110, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5103, UINT16_MAX, 5103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9111, UINT16_MAX, 9111, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5104, UINT16_MAX, 5104, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9112, UINT16_MAX, 9112, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5105, UINT16_MAX, 5105, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9113, UINT16_MAX, 9113, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5106, UINT16_MAX, 5106, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9114, UINT16_MAX, 9114, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5107, UINT16_MAX, 5107, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9115, UINT16_MAX, 9115, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5108, UINT16_MAX, 5108, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9116, UINT16_MAX, 9116, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5109, UINT16_MAX, 5109, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9117, UINT16_MAX, 9117, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5110, UINT16_MAX, 5110, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9118, UINT16_MAX, 9118, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5111, UINT16_MAX, 5111, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9119, UINT16_MAX, 9119, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5112, UINT16_MAX, 5112, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9120, UINT16_MAX, 9120, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5113, UINT16_MAX, 5113, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9121, UINT16_MAX, 9121, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5114, UINT16_MAX, 5114, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9122, UINT16_MAX, 9122, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5115, UINT16_MAX, 5115, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9123, UINT16_MAX, 9123, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5116, UINT16_MAX, 5116, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9124, UINT16_MAX, 9124, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5117, UINT16_MAX, 5117, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9125, UINT16_MAX, 9125, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5118, UINT16_MAX, 5118, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9126, UINT16_MAX, 9126, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5119, UINT16_MAX, 5119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9127, UINT16_MAX, 9127, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5120, UINT16_MAX, 5120, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9128, UINT16_MAX, 9128, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5121, UINT16_MAX, 5121, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9129, UINT16_MAX, 9129, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5122, UINT16_MAX, 5122, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9130, UINT16_MAX, 9130, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5123, UINT16_MAX, 5123, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9131, UINT16_MAX, 9131, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5124, UINT16_MAX, 5124, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9132, UINT16_MAX, 9132, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5125, UINT16_MAX, 5125, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9133, UINT16_MAX, 9133, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5126, UINT16_MAX, 5126, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9134, UINT16_MAX, 9134, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5127, UINT16_MAX, 5127, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9135, UINT16_MAX, 9135, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5128, UINT16_MAX, 5128, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9136, UINT16_MAX, 9136, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5129, UINT16_MAX, 5129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9137, UINT16_MAX, 9137, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5129, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5130, UINT16_MAX, 5130, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9138, UINT16_MAX, 9138, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5131, UINT16_MAX, 5131, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9139, UINT16_MAX, 9139, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5132, UINT16_MAX, 5132, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5133, UINT16_MAX, 5133, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9140, UINT16_MAX, 9140, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5134, UINT16_MAX, 5134, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9141, UINT16_MAX, 9141, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5135, UINT16_MAX, 5135, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9142, UINT16_MAX, 9142, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5136, UINT16_MAX, 5136, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9143, UINT16_MAX, 9143, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5137, UINT16_MAX, 5137, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9144, UINT16_MAX, 9144, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5138, UINT16_MAX, 5138, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9145, UINT16_MAX, 9145, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1524, UINT16_MAX, 1524, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5139, UINT16_MAX, 5139, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9146, UINT16_MAX, 9146, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5140, UINT16_MAX, 5140, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9147, UINT16_MAX, 9147, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9148, UINT16_MAX, 9148, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5141, UINT16_MAX, 5141, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9149, UINT16_MAX, 9149, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5142, UINT16_MAX, 5142, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9150, UINT16_MAX, 9150, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5143, UINT16_MAX, 5143, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9151, UINT16_MAX, 9151, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5144, UINT16_MAX, 5144, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9152, UINT16_MAX, 9152, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5145, UINT16_MAX, 5145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9153, UINT16_MAX, 9153, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5146, UINT16_MAX, 5146, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9154, UINT16_MAX, 9154, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5147, UINT16_MAX, 5147, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9155, UINT16_MAX, 9155, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5148, UINT16_MAX, 5148, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9156, UINT16_MAX, 9156, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5149, UINT16_MAX, 5149, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9157, UINT16_MAX, 9157, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5150, UINT16_MAX, 5150, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9158, UINT16_MAX, 9158, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 785, UINT16_MAX, 785, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1515, UINT16_MAX, 1515, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1523, UINT16_MAX, 1523, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5151, UINT16_MAX, 5151, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1525, UINT16_MAX, 1525, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5152, UINT16_MAX, 5152, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5153, UINT16_MAX, 5153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1527, UINT16_MAX, 1527, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5154, UINT16_MAX, 5154, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5155, UINT16_MAX, 5155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9159, UINT16_MAX, 9159, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5156, UINT16_MAX, 5156, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9160, UINT16_MAX, 9160, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5157, UINT16_MAX, 5157, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9161, UINT16_MAX, 9161, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5158, UINT16_MAX, 5158, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9162, UINT16_MAX, 9162, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5159, UINT16_MAX, 5159, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9163, UINT16_MAX, 9163, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5160, UINT16_MAX, 5160, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9164, UINT16_MAX, 9164, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5161, UINT16_MAX, 5161, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9165, UINT16_MAX, 9165, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5162, UINT16_MAX, 5162, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1536, UINT16_MAX, 1536, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5163, UINT16_MAX, 5163, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9166, UINT16_MAX, 9166, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5094, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5165, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3377, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5167, 5167, UINT16_MAX, 5167, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5168, 5168, UINT16_MAX, 5168, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5169, 5169, UINT16_MAX, 5169, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5170, 5170, UINT16_MAX, 5170, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5171, 5171, UINT16_MAX, 5171, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5172, 5172, UINT16_MAX, 5172, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5173, 5173, UINT16_MAX, 5173, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5174, 5174, UINT16_MAX, 5174, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5175, 5175, UINT16_MAX, 5175, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5176, 5176, UINT16_MAX, 5176, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5177, 5177, UINT16_MAX, 5177, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5178, 5178, UINT16_MAX, 5178, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5179, 5179, UINT16_MAX, 5179, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5180, 5180, UINT16_MAX, 5180, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5181, 5181, UINT16_MAX, 5181, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5182, 5182, UINT16_MAX, 5182, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5183, 5183, UINT16_MAX, 5183, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5184, 5184, UINT16_MAX, 5184, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5185, 5185, UINT16_MAX, 5185, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5186, 5186, UINT16_MAX, 5186, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5187, 5187, UINT16_MAX, 5187, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5188, 5188, UINT16_MAX, 5188, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5189, 5189, UINT16_MAX, 5189, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5190, 5190, UINT16_MAX, 5190, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5191, 5191, UINT16_MAX, 5191, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5192, 5192, UINT16_MAX, 5192, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5193, 5193, UINT16_MAX, 5193, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5194, 5194, UINT16_MAX, 5194, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5195, 5195, UINT16_MAX, 5195, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5196, 5196, UINT16_MAX, 5196, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5197, 5197, UINT16_MAX, 5197, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5198, 5198, UINT16_MAX, 5198, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5199, 5199, UINT16_MAX, 5199, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5200, 5200, UINT16_MAX, 5200, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5201, 5201, UINT16_MAX, 5201, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5202, 5202, UINT16_MAX, 5202, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5203, 5203, UINT16_MAX, 5203, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5204, 5204, UINT16_MAX, 5204, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5205, 5205, UINT16_MAX, 5205, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5206, 5206, UINT16_MAX, 5206, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5207, 5207, UINT16_MAX, 5207, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5208, 5208, UINT16_MAX, 5208, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5209, 5209, UINT16_MAX, 5209, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5210, 5210, UINT16_MAX, 5210, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5211, 5211, UINT16_MAX, 5211, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5212, 5212, UINT16_MAX, 5212, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5213, 5213, UINT16_MAX, 5213, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5214, 5214, UINT16_MAX, 5214, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5215, 5215, UINT16_MAX, 5215, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5216, 5216, UINT16_MAX, 5216, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5217, 5217, UINT16_MAX, 5217, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5218, 5218, UINT16_MAX, 5218, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5219, 5219, UINT16_MAX, 5219, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5220, 5220, UINT16_MAX, 5220, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5221, 5221, UINT16_MAX, 5221, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5222, 5222, UINT16_MAX, 5222, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5223, 5223, UINT16_MAX, 5223, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5224, 5224, UINT16_MAX, 5224, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5225, 5225, UINT16_MAX, 5225, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5226, 5226, UINT16_MAX, 5226, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5227, 5227, UINT16_MAX, 5227, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5228, 5228, UINT16_MAX, 5228, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5229, 5229, UINT16_MAX, 5229, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5230, 5230, UINT16_MAX, 5230, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5231, 5231, UINT16_MAX, 5231, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5232, 5232, UINT16_MAX, 5232, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5233, 5233, UINT16_MAX, 5233, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5234, 5234, UINT16_MAX, 5234, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5235, 5235, UINT16_MAX, 5235, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5236, 5236, UINT16_MAX, 5236, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5237, 5237, UINT16_MAX, 5237, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5238, 5238, UINT16_MAX, 5238, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5239, 5239, UINT16_MAX, 5239, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5240, 5240, UINT16_MAX, 5240, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5241, 5241, UINT16_MAX, 5241, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5242, 5242, UINT16_MAX, 5242, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5243, 5243, UINT16_MAX, 5243, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5244, 5244, UINT16_MAX, 5244, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5245, 5245, UINT16_MAX, 5245, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5246, 5246, UINT16_MAX, 5246, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_LV},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_LVT},
  {UTF8PROC_CATEGORY_CS, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5247, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5248, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5249, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5250, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5251, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3655, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5253, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5254, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5255, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5256, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5257, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5259, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5260, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5261, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5262, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5263, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5265, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5266, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5268, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5269, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5271, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5272, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5273, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5274, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5277, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5278, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5279, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5280, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5281, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5282, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5283, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5284, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5286, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5288, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5290, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5291, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5292, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5297, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5298, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5299, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5300, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5301, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5302, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5303, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5304, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5307, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5310, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5314, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5316, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5319, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5330, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5334, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5340, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5342, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5345, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5363, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5367, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5369, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5370, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5372, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5373, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5375, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5376, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5377, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5378, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5379, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5381, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5382, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5383, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5384, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5385, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5387, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5388, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5389, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5391, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5394, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5395, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5397, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5398, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5399, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5400, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5401, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5402, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5403, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5404, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5405, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5406, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5409, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5412, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5413, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5414, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5415, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5417, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5418, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5419, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5421, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5424, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5427, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5428, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5429, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5430, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5431, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5432, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5433, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5435, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5436, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5437, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5438, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5439, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 4187, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5455, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5458, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5475, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5478, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5479, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5481, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5482, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5484, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5487, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5488, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5490, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3487, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 4192, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5547, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 4196, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5553, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5568, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5634, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5643, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13852, 13852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13854, 13854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13856, 13856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22050, 22050, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22053, 22053, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13864, 13866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13866, 13866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13868, 13868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13870, 13870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13872, 13872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13874, 13874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 13876, 13876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 26, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 2839, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 2842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_FONT, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13891, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13893, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13899, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13901, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13903, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13905, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13909, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13911, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13913, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13915, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13917, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13919, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13921, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13923, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13927, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13929, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13931, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13933, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13935, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13937, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13939, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13941, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13943, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13945, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13947, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13949, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 13951, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_COMPAT, 13953, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5763, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5763, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5776, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5776, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 13995, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 13995, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 13997, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 13997, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 13999, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 13999, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14001, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14001, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14003, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14003, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14005, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14005, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14007, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14007, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14007, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14009, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14009, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14009, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14012, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14014, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14018, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14020, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14022, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14026, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14028, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14032, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14044, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14050, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14052, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14054, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14056, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14058, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14060, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14062, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14072, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14074, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14078, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14080, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14082, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14084, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14086, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14088, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14092, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14094, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14096, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14098, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14100, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14102, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14104, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14106, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14110, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14112, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14114, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14116, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14118, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14120, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14122, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14124, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14126, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14128, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14130, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14132, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14134, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14136, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14138, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14140, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14142, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14144, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14146, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14148, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14150, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14152, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14154, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14156, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14158, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14160, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14162, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14168, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14170, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14172, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14174, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14176, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14178, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14180, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14182, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14184, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14188, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14190, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14192, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14194, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14196, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22399, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22402, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22405, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14216, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14218, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14220, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14018, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14222, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14224, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14026, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14028, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14230, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14232, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14234, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14236, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14238, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14050, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14110, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14116, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14118, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14120, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14128, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14130, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14132, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14134, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14142, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14144, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14146, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14240, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14154, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14242, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14244, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14246, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14168, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14170, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14196, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14248, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14250, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14188, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14190, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14012, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14014, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14254, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14256, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14020, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14022, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14026, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14032, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14260, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14052, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14054, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14056, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14058, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14060, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14072, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14074, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14262, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14078, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14080, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14082, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14084, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14086, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14092, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14094, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14096, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14098, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14100, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14102, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14104, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14106, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14112, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14114, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14122, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14124, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14126, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14128, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14130, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14136, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14138, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14140, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14142, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14148, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14150, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14152, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14154, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14160, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14162, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14266, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14172, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14174, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14268, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14180, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14182, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14184, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14256, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14026, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14260, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14272, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14072, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14274, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14278, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14128, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14130, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14142, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14266, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22475, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22478, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14291, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14297, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14299, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14301, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14303, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14307, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14319, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14291, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14297, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14299, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14301, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14303, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14307, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14319, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14274, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14278, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 14088, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14088, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22702, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22705, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22708, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22714, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22717, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22720, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22723, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22729, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22732, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22735, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22741, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22747, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22750, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22753, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22759, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22822, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31017, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31021, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31025, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31029, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31033, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31037, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31041, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 63816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 63835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 31076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 3063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 3064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 6531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 6516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, 6504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, 2762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, 6507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, 6532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, 6535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 2801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, 6539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, 6540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14734, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14736, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14742, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14748, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14750, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 14760, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 14803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 14803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 6504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, 6535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 2762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 6615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 6507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1491, 6616, UINT16_MAX, 6616, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1493, 6617, UINT16_MAX, 6617, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2812, 6618, UINT16_MAX, 6618, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1494, 6619, UINT16_MAX, 6619, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1495, 6620, UINT16_MAX, 6620, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2837, 6621, UINT16_MAX, 6621, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1497, 6622, UINT16_MAX, 6622, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1498, 6623, UINT16_MAX, 6623, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1499, 6624, UINT16_MAX, 6624, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1500, 6625, UINT16_MAX, 6625, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1501, 6626, UINT16_MAX, 6626, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1502, 6627, UINT16_MAX, 6627, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1503, 6628, UINT16_MAX, 6628, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1504, 6629, UINT16_MAX, 6629, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1505, 6630, UINT16_MAX, 6630, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1507, 6631, UINT16_MAX, 6631, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2826, 6632, UINT16_MAX, 6632, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1508, 6633, UINT16_MAX, 6633, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 3305, 6634, UINT16_MAX, 6634, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1509, 6635, UINT16_MAX, 6635, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1510, 6636, UINT16_MAX, 6636, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2908, 6637, UINT16_MAX, 6637, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1511, 6638, UINT16_MAX, 6638, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2925, 6639, UINT16_MAX, 6639, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 3312, 6640, UINT16_MAX, 6640, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2834, 6641, UINT16_MAX, 6641, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 0, UINT16_MAX, 9167, UINT16_MAX, 9167, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1, UINT16_MAX, 9168, UINT16_MAX, 9168, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2, UINT16_MAX, 9169, UINT16_MAX, 9169, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 3, UINT16_MAX, 9170, UINT16_MAX, 9170, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 4, UINT16_MAX, 9171, UINT16_MAX, 9171, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 5, UINT16_MAX, 9172, UINT16_MAX, 9172, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 6, UINT16_MAX, 9173, UINT16_MAX, 9173, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 7, UINT16_MAX, 9174, UINT16_MAX, 9174, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 8, UINT16_MAX, 9175, UINT16_MAX, 9175, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 9, UINT16_MAX, 9176, UINT16_MAX, 9176, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 10, UINT16_MAX, 9177, UINT16_MAX, 9177, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 11, UINT16_MAX, 9178, UINT16_MAX, 9178, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 12, UINT16_MAX, 9179, UINT16_MAX, 9179, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 13, UINT16_MAX, 9180, UINT16_MAX, 9180, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 14, UINT16_MAX, 9181, UINT16_MAX, 9181, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 15, UINT16_MAX, 9182, UINT16_MAX, 9182, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 16, UINT16_MAX, 9183, UINT16_MAX, 9183, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 17, UINT16_MAX, 9184, UINT16_MAX, 9184, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 18, UINT16_MAX, 9185, UINT16_MAX, 9185, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 19, UINT16_MAX, 9186, UINT16_MAX, 9186, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 20, UINT16_MAX, 9187, UINT16_MAX, 9187, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 21, UINT16_MAX, 9188, UINT16_MAX, 9188, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 22, UINT16_MAX, 9189, UINT16_MAX, 9189, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 23, UINT16_MAX, 9190, UINT16_MAX, 9190, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 24, UINT16_MAX, 9191, UINT16_MAX, 9191, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 25, UINT16_MAX, 9192, UINT16_MAX, 9192, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6643, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6655, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4286, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4288, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4290, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4291, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4292, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4293, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4297, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4298, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4299, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4300, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4301, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4302, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4303, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4304, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4307, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4310, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4311, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4314, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4316, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4317, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4319, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6661, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6701, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6702, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6703, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6704, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6705, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6706, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6707, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6708, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6709, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6710, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6712, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6713, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6714, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6715, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6716, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6717, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6718, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6719, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6720, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6721, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6723, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6724, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6725, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6727, UINT16_MAX, 6727, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6729, UINT16_MAX, 6729, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6731, UINT16_MAX, 6731, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6733, UINT16_MAX, 6733, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6735, UINT16_MAX, 6735, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6737, UINT16_MAX, 6737, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6739, UINT16_MAX, 6739, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6741, UINT16_MAX, 6741, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6743, UINT16_MAX, 6743, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6745, UINT16_MAX, 6745, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6747, UINT16_MAX, 6747, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6749, UINT16_MAX, 6749, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6751, UINT16_MAX, 6751, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6753, UINT16_MAX, 6753, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6755, UINT16_MAX, 6755, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6757, UINT16_MAX, 6757, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6759, UINT16_MAX, 6759, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6761, UINT16_MAX, 6761, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6763, UINT16_MAX, 6763, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6765, UINT16_MAX, 6765, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6767, UINT16_MAX, 6767, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6769, UINT16_MAX, 6769, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6771, UINT16_MAX, 6771, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6773, UINT16_MAX, 6773, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6775, UINT16_MAX, 6775, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6777, UINT16_MAX, 6777, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6779, UINT16_MAX, 6779, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6781, UINT16_MAX, 6781, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6783, UINT16_MAX, 6783, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6785, UINT16_MAX, 6785, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6787, UINT16_MAX, 6787, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6789, UINT16_MAX, 6789, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6791, UINT16_MAX, 6791, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6793, UINT16_MAX, 6793, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6795, UINT16_MAX, 6795, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6797, UINT16_MAX, 6797, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6799, UINT16_MAX, 6799, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6801, UINT16_MAX, 6801, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6803, UINT16_MAX, 6803, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6805, UINT16_MAX, 6805, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9193, UINT16_MAX, 9193, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9195, UINT16_MAX, 9195, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9197, UINT16_MAX, 9197, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9199, UINT16_MAX, 9199, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9201, UINT16_MAX, 9201, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9203, UINT16_MAX, 9203, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9205, UINT16_MAX, 9205, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9207, UINT16_MAX, 9207, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9209, UINT16_MAX, 9209, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9211, UINT16_MAX, 9211, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9213, UINT16_MAX, 9213, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9215, UINT16_MAX, 9215, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9217, UINT16_MAX, 9217, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9219, UINT16_MAX, 9219, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9221, UINT16_MAX, 9221, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9223, UINT16_MAX, 9223, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9225, UINT16_MAX, 9225, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9227, UINT16_MAX, 9227, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9229, UINT16_MAX, 9229, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9231, UINT16_MAX, 9231, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9233, UINT16_MAX, 9233, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9235, UINT16_MAX, 9235, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9237, UINT16_MAX, 9237, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9239, UINT16_MAX, 9239, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9241, UINT16_MAX, 9241, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9243, UINT16_MAX, 9243, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9245, UINT16_MAX, 9245, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9247, UINT16_MAX, 9247, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9249, UINT16_MAX, 9249, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9251, UINT16_MAX, 9251, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9253, UINT16_MAX, 9253, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9255, UINT16_MAX, 9255, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9257, UINT16_MAX, 9257, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9259, UINT16_MAX, 9259, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9261, UINT16_MAX, 9261, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9263, UINT16_MAX, 9263, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9265, UINT16_MAX, 9265, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9267, UINT16_MAX, 9267, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9269, UINT16_MAX, 9269, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9271, UINT16_MAX, 9271, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6807, UINT16_MAX, 6807, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6809, UINT16_MAX, 6809, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6811, UINT16_MAX, 6811, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6813, UINT16_MAX, 6813, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6815, UINT16_MAX, 6815, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6817, UINT16_MAX, 6817, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6819, UINT16_MAX, 6819, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6821, UINT16_MAX, 6821, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6823, UINT16_MAX, 6823, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6825, UINT16_MAX, 6825, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6827, UINT16_MAX, 6827, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6829, UINT16_MAX, 6829, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6831, UINT16_MAX, 6831, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6833, UINT16_MAX, 6833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6835, UINT16_MAX, 6835, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6837, UINT16_MAX, 6837, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6839, UINT16_MAX, 6839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6841, UINT16_MAX, 6841, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6843, UINT16_MAX, 6843, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6845, UINT16_MAX, 6845, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6847, UINT16_MAX, 6847, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6849, UINT16_MAX, 6849, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6851, UINT16_MAX, 6851, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6853, UINT16_MAX, 6853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6855, UINT16_MAX, 6855, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6857, UINT16_MAX, 6857, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6859, UINT16_MAX, 6859, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6861, UINT16_MAX, 6861, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6863, UINT16_MAX, 6863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6865, UINT16_MAX, 6865, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6867, UINT16_MAX, 6867, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6869, UINT16_MAX, 6869, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6871, UINT16_MAX, 6871, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6873, UINT16_MAX, 6873, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6875, UINT16_MAX, 6875, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6877, UINT16_MAX, 6877, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9273, UINT16_MAX, 9273, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9275, UINT16_MAX, 9275, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9277, UINT16_MAX, 9277, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9279, UINT16_MAX, 9279, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9281, UINT16_MAX, 9281, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9283, UINT16_MAX, 9283, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9285, UINT16_MAX, 9285, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9287, UINT16_MAX, 9287, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9289, UINT16_MAX, 9289, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9291, UINT16_MAX, 9291, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9293, UINT16_MAX, 9293, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9295, UINT16_MAX, 9295, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9297, UINT16_MAX, 9297, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9299, UINT16_MAX, 9299, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9301, UINT16_MAX, 9301, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9303, UINT16_MAX, 9303, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9305, UINT16_MAX, 9305, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9307, UINT16_MAX, 9307, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9309, UINT16_MAX, 9309, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9311, UINT16_MAX, 9311, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9313, UINT16_MAX, 9313, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9315, UINT16_MAX, 9315, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9317, UINT16_MAX, 9317, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9319, UINT16_MAX, 9319, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9321, UINT16_MAX, 9321, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9323, UINT16_MAX, 9323, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9325, UINT16_MAX, 9325, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9327, UINT16_MAX, 9327, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9329, UINT16_MAX, 9329, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9331, UINT16_MAX, 9331, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9333, UINT16_MAX, 9333, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9335, UINT16_MAX, 9335, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9337, UINT16_MAX, 9337, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9339, UINT16_MAX, 9339, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9341, UINT16_MAX, 9341, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9343, UINT16_MAX, 9343, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6879, UINT16_MAX, 6879, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6881, UINT16_MAX, 6881, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6883, UINT16_MAX, 6883, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6885, UINT16_MAX, 6885, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6887, UINT16_MAX, 6887, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6889, UINT16_MAX, 6889, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6891, UINT16_MAX, 6891, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6893, UINT16_MAX, 6893, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6895, UINT16_MAX, 6895, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6897, UINT16_MAX, 6897, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6899, UINT16_MAX, 6899, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6901, UINT16_MAX, 6901, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6903, UINT16_MAX, 6903, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6905, UINT16_MAX, 6905, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6907, UINT16_MAX, 6907, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6909, UINT16_MAX, 6909, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6911, UINT16_MAX, 6911, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6913, UINT16_MAX, 6913, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6915, UINT16_MAX, 6915, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6917, UINT16_MAX, 6917, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6919, UINT16_MAX, 6919, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6921, UINT16_MAX, 6921, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6923, UINT16_MAX, 6923, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6925, UINT16_MAX, 6925, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6927, UINT16_MAX, 6927, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6929, UINT16_MAX, 6929, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6931, UINT16_MAX, 6931, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6933, UINT16_MAX, 6933, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6935, UINT16_MAX, 6935, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6937, UINT16_MAX, 6937, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6939, UINT16_MAX, 6939, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6941, UINT16_MAX, 6941, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6943, UINT16_MAX, 6943, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6945, UINT16_MAX, 6945, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6947, UINT16_MAX, 6947, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6949, UINT16_MAX, 6949, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6951, UINT16_MAX, 6951, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6953, UINT16_MAX, 6953, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6955, UINT16_MAX, 6955, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6957, UINT16_MAX, 6957, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6959, UINT16_MAX, 6959, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6961, UINT16_MAX, 6961, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6963, UINT16_MAX, 6963, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6965, UINT16_MAX, 6965, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6967, UINT16_MAX, 6967, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6969, UINT16_MAX, 6969, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6971, UINT16_MAX, 6971, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6973, UINT16_MAX, 6973, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6975, UINT16_MAX, 6975, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6977, UINT16_MAX, 6977, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 6979, UINT16_MAX, 6979, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9345, UINT16_MAX, 9345, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9347, UINT16_MAX, 9347, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9349, UINT16_MAX, 9349, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9351, UINT16_MAX, 9351, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9353, UINT16_MAX, 9353, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9355, UINT16_MAX, 9355, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9357, UINT16_MAX, 9357, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9359, UINT16_MAX, 9359, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9361, UINT16_MAX, 9361, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9363, UINT16_MAX, 9363, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9365, UINT16_MAX, 9365, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9367, UINT16_MAX, 9367, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9369, UINT16_MAX, 9369, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9371, UINT16_MAX, 9371, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9373, UINT16_MAX, 9373, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9375, UINT16_MAX, 9375, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9377, UINT16_MAX, 9377, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9379, UINT16_MAX, 9379, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9381, UINT16_MAX, 9381, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9383, UINT16_MAX, 9383, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9385, UINT16_MAX, 9385, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9387, UINT16_MAX, 9387, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9389, UINT16_MAX, 9389, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9391, UINT16_MAX, 9391, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9393, UINT16_MAX, 9393, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9395, UINT16_MAX, 9395, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9397, UINT16_MAX, 9397, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9399, UINT16_MAX, 9399, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9401, UINT16_MAX, 9401, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9403, UINT16_MAX, 9403, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9405, UINT16_MAX, 9405, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9407, UINT16_MAX, 9407, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9409, UINT16_MAX, 9409, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9411, UINT16_MAX, 9411, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9413, UINT16_MAX, 9413, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9415, UINT16_MAX, 9415, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9417, UINT16_MAX, 9417, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9419, UINT16_MAX, 9419, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9421, UINT16_MAX, 9421, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9423, UINT16_MAX, 9423, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9425, UINT16_MAX, 9425, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9427, UINT16_MAX, 9427, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9429, UINT16_MAX, 9429, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9431, UINT16_MAX, 9431, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9433, UINT16_MAX, 9433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9435, UINT16_MAX, 9435, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9437, UINT16_MAX, 9437, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9439, UINT16_MAX, 9439, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9441, UINT16_MAX, 9441, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9443, UINT16_MAX, 9443, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9445, UINT16_MAX, 9445, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5328, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5332, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5336, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49206, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_PREPEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49208, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 15185, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 15189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5340, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5344, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49210, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5348, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15197, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49212, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49216, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5354, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49214, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15205, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49218, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49220, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5362, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5366, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 15217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7029, UINT16_MAX, 7029, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7031, UINT16_MAX, 7031, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7033, UINT16_MAX, 7033, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7035, UINT16_MAX, 7035, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7037, UINT16_MAX, 7037, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7039, UINT16_MAX, 7039, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7041, UINT16_MAX, 7041, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7043, UINT16_MAX, 7043, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7045, UINT16_MAX, 7045, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7047, UINT16_MAX, 7047, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7049, UINT16_MAX, 7049, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7051, UINT16_MAX, 7051, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7053, UINT16_MAX, 7053, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7055, UINT16_MAX, 7055, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7057, UINT16_MAX, 7057, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7059, UINT16_MAX, 7059, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7061, UINT16_MAX, 7061, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7063, UINT16_MAX, 7063, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7065, UINT16_MAX, 7065, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7067, UINT16_MAX, 7067, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7069, UINT16_MAX, 7069, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7071, UINT16_MAX, 7071, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7073, UINT16_MAX, 7073, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7075, UINT16_MAX, 7075, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7077, UINT16_MAX, 7077, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7079, UINT16_MAX, 7079, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7081, UINT16_MAX, 7081, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7083, UINT16_MAX, 7083, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7085, UINT16_MAX, 7085, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7087, UINT16_MAX, 7087, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7089, UINT16_MAX, 7089, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7091, UINT16_MAX, 7091, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9447, UINT16_MAX, 9447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9449, UINT16_MAX, 9449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9451, UINT16_MAX, 9451, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9453, UINT16_MAX, 9453, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9455, UINT16_MAX, 9455, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9457, UINT16_MAX, 9457, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9459, UINT16_MAX, 9459, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9461, UINT16_MAX, 9461, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9463, UINT16_MAX, 9463, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9465, UINT16_MAX, 9465, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9467, UINT16_MAX, 9467, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9469, UINT16_MAX, 9469, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9471, UINT16_MAX, 9471, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9473, UINT16_MAX, 9473, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9475, UINT16_MAX, 9475, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9477, UINT16_MAX, 9477, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9479, UINT16_MAX, 9479, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9481, UINT16_MAX, 9481, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9483, UINT16_MAX, 9483, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9485, UINT16_MAX, 9485, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9487, UINT16_MAX, 9487, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9489, UINT16_MAX, 9489, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9491, UINT16_MAX, 9491, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9493, UINT16_MAX, 9493, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9495, UINT16_MAX, 9495, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9497, UINT16_MAX, 9497, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9499, UINT16_MAX, 9499, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9501, UINT16_MAX, 9501, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9503, UINT16_MAX, 9503, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9505, UINT16_MAX, 9505, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9507, UINT16_MAX, 9507, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9509, UINT16_MAX, 9509, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7093, UINT16_MAX, 7093, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7095, UINT16_MAX, 7095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7097, UINT16_MAX, 7097, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7099, UINT16_MAX, 7099, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7101, UINT16_MAX, 7101, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7103, UINT16_MAX, 7103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7105, UINT16_MAX, 7105, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7107, UINT16_MAX, 7107, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7109, UINT16_MAX, 7109, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7111, UINT16_MAX, 7111, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7113, UINT16_MAX, 7113, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7115, UINT16_MAX, 7115, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7117, UINT16_MAX, 7117, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7119, UINT16_MAX, 7119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7121, UINT16_MAX, 7121, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7123, UINT16_MAX, 7123, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7125, UINT16_MAX, 7125, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7127, UINT16_MAX, 7127, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7129, UINT16_MAX, 7129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7131, UINT16_MAX, 7131, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7133, UINT16_MAX, 7133, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7135, UINT16_MAX, 7135, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7137, UINT16_MAX, 7137, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7139, UINT16_MAX, 7139, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7141, UINT16_MAX, 7141, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7143, UINT16_MAX, 7143, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7145, UINT16_MAX, 7145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7147, UINT16_MAX, 7147, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7149, UINT16_MAX, 7149, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7151, UINT16_MAX, 7151, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7153, UINT16_MAX, 7153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7155, UINT16_MAX, 7155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9511, UINT16_MAX, 9511, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9513, UINT16_MAX, 9513, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9515, UINT16_MAX, 9515, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9517, UINT16_MAX, 9517, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9519, UINT16_MAX, 9519, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9521, UINT16_MAX, 9521, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9523, UINT16_MAX, 9523, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9525, UINT16_MAX, 9525, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9527, UINT16_MAX, 9527, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9529, UINT16_MAX, 9529, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9531, UINT16_MAX, 9531, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9533, UINT16_MAX, 9533, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9535, UINT16_MAX, 9535, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9537, UINT16_MAX, 9537, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9539, UINT16_MAX, 9539, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9541, UINT16_MAX, 9541, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9543, UINT16_MAX, 9543, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9545, UINT16_MAX, 9545, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9547, UINT16_MAX, 9547, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9549, UINT16_MAX, 9549, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9551, UINT16_MAX, 9551, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9553, UINT16_MAX, 9553, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9555, UINT16_MAX, 9555, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9557, UINT16_MAX, 9557, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9559, UINT16_MAX, 9559, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9561, UINT16_MAX, 9561, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9563, UINT16_MAX, 9563, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9565, UINT16_MAX, 9565, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9567, UINT16_MAX, 9567, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9569, UINT16_MAX, 9569, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9571, UINT16_MAX, 9571, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9573, UINT16_MAX, 9573, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5370, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5374, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5378, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15369, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15373, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49222, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 226, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49224, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49226, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49228, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49230, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49232, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5390, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5394, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15377, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5398, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15381, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5404, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15385, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15389, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 15397, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2908, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7210, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7211, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7212, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7214, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7215, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7216, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 915, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7218, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7219, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7220, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7221, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7222, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7223, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7224, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7225, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 917, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7229, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7230, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 845, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 848, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 849, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 35, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 914, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FONT, 7231, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7232, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7233, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7234, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7235, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7236, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7237, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7238, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 904, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7239, UINT16_MAX, 7239, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7241, UINT16_MAX, 7241, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7243, UINT16_MAX, 7243, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7245, UINT16_MAX, 7245, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7247, UINT16_MAX, 7247, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7249, UINT16_MAX, 7249, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7251, UINT16_MAX, 7251, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7253, UINT16_MAX, 7253, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7255, UINT16_MAX, 7255, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7257, UINT16_MAX, 7257, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7259, UINT16_MAX, 7259, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7261, UINT16_MAX, 7261, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7263, UINT16_MAX, 7263, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7265, UINT16_MAX, 7265, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7267, UINT16_MAX, 7267, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7269, UINT16_MAX, 7269, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7271, UINT16_MAX, 7271, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7273, UINT16_MAX, 7273, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7275, UINT16_MAX, 7275, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7277, UINT16_MAX, 7277, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7279, UINT16_MAX, 7279, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7281, UINT16_MAX, 7281, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7283, UINT16_MAX, 7283, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7285, UINT16_MAX, 7285, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7287, UINT16_MAX, 7287, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7289, UINT16_MAX, 7289, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7291, UINT16_MAX, 7291, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7293, UINT16_MAX, 7293, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7295, UINT16_MAX, 7295, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7297, UINT16_MAX, 7297, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7299, UINT16_MAX, 7299, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7301, UINT16_MAX, 7301, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7303, UINT16_MAX, 7303, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7305, UINT16_MAX, 7305, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9575, UINT16_MAX, 9575, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9577, UINT16_MAX, 9577, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9579, UINT16_MAX, 9579, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9581, UINT16_MAX, 9581, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9583, UINT16_MAX, 9583, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9585, UINT16_MAX, 9585, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9587, UINT16_MAX, 9587, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9589, UINT16_MAX, 9589, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9591, UINT16_MAX, 9591, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9593, UINT16_MAX, 9593, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9595, UINT16_MAX, 9595, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9597, UINT16_MAX, 9597, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9599, UINT16_MAX, 9599, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9601, UINT16_MAX, 9601, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9603, UINT16_MAX, 9603, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9605, UINT16_MAX, 9605, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9607, UINT16_MAX, 9607, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9609, UINT16_MAX, 9609, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9611, UINT16_MAX, 9611, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9613, UINT16_MAX, 9613, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9615, UINT16_MAX, 9615, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9617, UINT16_MAX, 9617, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9619, UINT16_MAX, 9619, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9621, UINT16_MAX, 9621, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9623, UINT16_MAX, 9623, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9625, UINT16_MAX, 9625, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9627, UINT16_MAX, 9627, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9629, UINT16_MAX, 9629, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9631, UINT16_MAX, 9631, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9633, UINT16_MAX, 9633, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9635, UINT16_MAX, 9635, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9637, UINT16_MAX, 9637, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9639, UINT16_MAX, 9639, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 9641, UINT16_MAX, 9641, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 7307, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 5786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 7308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 7309, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 15522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23716, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23719, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23725, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23728, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23731, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23734, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23737, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23743, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23749, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23755, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23776, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 15605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 15607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2837, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2908, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 13070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 23807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 15620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 15622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 15624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 15630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 5425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7455, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7458, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4208, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4191, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 7498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 7499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC},
  {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTEND},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7547, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7553, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7568, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7661, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7701, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7702, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7703, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7704, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7705, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7706, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7708, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7709, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7710, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7712, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7714, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7715, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7716, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7717, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7718, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7719, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7720, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7721, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7723, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7724, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7725, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7728, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7729, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7730, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7731, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7732, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7733, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7735, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7737, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7739, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7742, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7743, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7745, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7747, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7748, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7749, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7750, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7753, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7755, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7757, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7759, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7760, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7763, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7776, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7805, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7818, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7822, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7824, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7827, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7828, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7830, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7831, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7833, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7837, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7839, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7843, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7845, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7849, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7869, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7885, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7887, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7888, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7891, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7893, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7894, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7896, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7899, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7901, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7903, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7905, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7908, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7909, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7910, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7911, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7912, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7913, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7914, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7915, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7916, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7917, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7918, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7920, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7921, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7922, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7923, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7924, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7926, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7927, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7928, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7929, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7930, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7932, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7934, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7936, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7937, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7938, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7939, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7940, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7942, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7943, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7945, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7946, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7947, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7949, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7951, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7952, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7953, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7954, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7955, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7956, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7957, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7958, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7959, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7960, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7961, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7962, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7963, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7964, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7965, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7966, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7967, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7969, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7970, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7971, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7972, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7973, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7974, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7976, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7978, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7979, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7980, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7981, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7983, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7984, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7985, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7986, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7987, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7989, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7991, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7992, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7993, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7994, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7996, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7997, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7999, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8001, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8002, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8003, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8004, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8006, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8007, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8008, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8009, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8010, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8011, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8012, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8013, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8015, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8017, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8018, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8020, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8021, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8022, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8023, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8026, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8028, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8029, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8031, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8033, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8037, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8039, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8041, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8043, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8044, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8045, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8049, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8050, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8051, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8052, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8053, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8055, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8056, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8058, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8060, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8062, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8065, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
  {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER},
};

static const utf8proc_uint16_t utf8proc_combinations[] = {
  0, 46, 192, 193, 194, 195, 196, 197, 0, 
  256, 258, 260, 550, 461, 0, 0, 512, 
  514, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7680, 7840, 0, 0, 0, 0, 0, 7842, 
1, 11, 
  262, 264, 0, 0, 0, 199, 0, 0, 
  0, 266, 268, 
0, 46, 200, 201, 202, 7868, 203, 
  0, 552, 274, 276, 280, 278, 282, 0, 
  0, 516, 518, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7864, 0, 7704, 7706, 0, 
  0, 7866, 
0, 46, 204, 205, 206, 296, 207, 0, 
  0, 298, 300, 302, 304, 463, 0, 0, 
  520, 522, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7882, 0, 0, 7724, 0, 0, 
  7880, 
0, 42, 504, 323, 0, 209, 0, 0, 325, 
  0, 0, 0, 7748, 327, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7750, 7752, 7754, 
0, 46, 210, 211, 212, 213, 
  214, 0, 0, 332, 334, 490, 558, 465, 
  336, 416, 524, 526, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 7884, 0, 0, 0, 
  0, 0, 7886, 
0, 46, 217, 218, 219, 360, 220, 
  366, 0, 362, 364, 370, 0, 467, 368, 
  431, 532, 534, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7908, 0, 7798, 7796, 0, 
  7794, 7910, 
0, 46, 7922, 221, 374, 7928, 376, 0, 
  0, 562, 0, 0, 7822, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7924, 0, 0, 0, 0, 0, 
  7926, 
0, 46, 224, 225, 226, 227, 228, 229, 0, 
  257, 259, 261, 551, 462, 0, 0, 513, 
  515, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7681, 7841, 0, 0, 0, 0, 0, 7843, 
1, 11, 
  263, 265, 0, 0, 0, 231, 0, 0, 
  0, 267, 269, 
0, 46, 232, 233, 234, 7869, 235, 
  0, 553, 275, 277, 281, 279, 283, 0, 
  0, 517, 519, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7865, 0, 7705, 7707, 0, 
  0, 7867, 
0, 46, 236, 237, 238, 297, 239, 0, 
  0, 299, 301, 303, 0, 464, 0, 0, 
  521, 523, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7883, 0, 0, 7725, 0, 0, 
  7881, 
0, 42, 505, 324, 0, 241, 0, 0, 326, 
  0, 0, 0, 7749, 328, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7751, 7753, 7755, 
0, 46, 242, 243, 244, 245, 
  246, 0, 0, 333, 335, 491, 559, 466, 
  337, 417, 525, 527, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 7885, 0, 0, 0, 
  0, 0, 7887, 
0, 46, 249, 250, 251, 361, 252, 
  367, 0, 363, 365, 371, 0, 468, 369, 
  432, 533, 535, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7909, 0, 7799, 7797, 0, 
  7795, 7911, 
0, 46, 7923, 253, 375, 7929, 255, 7833, 
  0, 563, 0, 0, 7823, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7925, 0, 0, 0, 0, 0, 
  7927, 
6, 42, 7696, 0, 0, 0, 7690, 270, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7692, 7694, 7698, 
6, 42, 7697, 0, 
  0, 0, 7691, 271, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7693, 7695, 7699, 
1, 11, 500, 284, 0, 0, 0, 
  290, 7712, 286, 0, 288, 486, 
1, 11, 501, 285, 
  0, 0, 0, 291, 7713, 287, 0, 289, 
  487, 
2, 44, 292, 0, 7718, 0, 7720, 0, 0, 
  0, 7714, 542, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7716, 
  0, 0, 0, 7722, 
2, 44, 293, 0, 7719, 0, 
  7721, 0, 0, 0, 7715, 543, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7717, 7830, 0, 0, 7723, 
2, 2, 308, 
2, 11, 
  309, 0, 0, 0, 0, 0, 0, 0, 
  0, 496, 
1, 41, 7728, 0, 0, 0, 0, 310, 
  0, 0, 0, 0, 488, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7730, 7732, 
1, 41, 7729, 0, 0, 0, 0, 
  311, 0, 0, 0, 0, 489, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7731, 7733, 
1, 42, 313, 0, 0, 0, 
  0, 315, 0, 0, 0, 0, 317, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7734, 7738, 7740, 
1, 42, 314, 0, 
  0, 0, 0, 316, 0, 0, 0, 0, 
  318, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7735, 7739, 7741, 
1, 41, 
  340, 0, 0, 0, 0, 342, 0, 0, 
  0, 7768, 344, 0, 0, 528, 530, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7770, 
  7774, 
1, 41, 341, 0, 0, 0, 0, 343, 0, 
  0, 0, 7769, 345, 0, 0, 529, 531, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7771, 7775, 
1, 40, 346, 348, 0, 0, 0, 350, 
  0, 0, 0, 7776, 352, 0, 0, 0, 
  0, 536, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7778, 
1, 40, 347, 349, 0, 0, 0, 351, 
  0, 0, 0, 7777, 353, 0, 0, 0, 
  0, 537, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7779, 
6, 42, 354, 0, 0, 0, 7786, 356, 
  0, 0, 0, 0, 538, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 7788, 7790, 7792, 
4, 42, 7831, 
  0, 355, 0, 0, 0, 7787, 357, 0, 
  0, 0, 0, 539, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7789, 7791, 7793, 
0, 40, 7808, 7810, 
  372, 0, 7812, 0, 0, 0, 0, 0, 
  7814, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7816, 
0, 40, 7809, 
  7811, 373, 0, 7813, 7832, 0, 0, 0, 
  0, 7815, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7817, 
1, 41, 
  377, 7824, 0, 0, 0, 0, 0, 0, 
  0, 379, 381, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7826, 
  7828, 
1, 41, 378, 7825, 0, 0, 0, 0, 0, 
  0, 0, 380, 382, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7827, 7829, 
0, 11, 475, 471, 0, 0, 0, 0, 
  0, 469, 0, 0, 0, 473, 
0, 11, 476, 472, 
  0, 0, 0, 0, 0, 470, 0, 0, 
  0, 474, 
7, 7, 478, 
7, 7, 479, 
7, 7, 480, 
7, 7, 481, 
1, 7, 508, 0, 
  0, 0, 0, 0, 482, 
1, 7, 509, 0, 0, 
  0, 0, 0, 483, 
7, 7, 492, 
7, 7, 493, 
11, 11, 494, 
11, 11, 495, 
1, 1, 
  506, 
1, 1, 507, 
1, 1, 510, 
1, 1, 511, 
7, 7, 554, 
7, 7, 555, 
1, 7, 7756, 0, 
  0, 7758, 0, 0, 556, 
1, 7, 7757, 0, 0, 
  7759, 0, 0, 557, 
7, 7, 560, 
7, 7, 561, 
0, 49, 8173, 901, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 8129, 
0, 50, 
  8122, 902, 0, 0, 0, 0, 0, 8121, 
  8120, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7944, 
  7945, 0, 8124, 
0, 48, 8136, 904, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7960, 7961, 
0, 50, 8138, 905, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7976, 7977, 0, 8140, 
0, 48, 8154, 
  906, 0, 0, 938, 0, 0, 8153, 8152, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7992, 7993, 
0, 48, 
  8184, 908, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 8008, 
  8009, 
0, 48, 8170, 910, 0, 0, 939, 0, 0, 
  8169, 8168, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8025, 
0, 50, 8186, 911, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8040, 8041, 0, 8188, 
0, 49, 8146, 912, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 8151, 
0, 50, 8048, 
  940, 0, 0, 0, 0, 0, 8113, 8112, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7936, 7937, 
  8118, 8115, 
0, 48, 8050, 941, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7952, 7953, 
0, 50, 8052, 942, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7968, 7969, 8134, 8131, 
0, 49, 8054, 943, 
  0, 0, 970, 0, 0, 8145, 8144, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7984, 7985, 8150, 
0, 49, 
  8162, 944, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8167, 
0, 49, 8058, 973, 0, 0, 971, 0, 
  0, 8161, 8160, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8016, 8017, 8166, 
0, 48, 8056, 972, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 8000, 8001, 
0, 50, 8060, 974, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 8032, 8033, 8182, 8179, 
1, 4, 
  979, 0, 0, 980, 
0, 8, 1024, 0, 0, 0, 
  1025, 0, 0, 0, 1238, 
1, 1, 1027, 
4, 4, 1031, 
1, 1, 1036, 
0, 8, 
  1037, 0, 0, 0, 1252, 0, 0, 1250, 
  1049, 
4, 12, 1264, 0, 0, 1262, 1038, 0, 0, 
  0, 1266, 
0, 8, 1117, 0, 0, 0, 1253, 0, 
  0, 1251, 1081, 
0, 8, 1104, 0, 0, 0, 1105, 
  0, 0, 0, 1239, 
1, 1, 1107, 
4, 4, 1111, 
1, 1, 1116, 
4, 12, 1265, 
  0, 0, 1263, 1118, 0, 0, 0, 1267, 
14, 14, 
  1142, 
14, 14, 1143, 
4, 8, 1244, 0, 0, 0, 1217, 
4, 8, 1245, 
  0, 0, 0, 1218, 
4, 8, 1234, 0, 0, 0, 
  1232, 
4, 8, 1235, 0, 0, 0, 1233, 
4, 4, 1242, 
4, 4, 1243, 
4, 4, 
  1246, 
4, 4, 1247, 
4, 4, 1254, 
4, 4, 1255, 
4, 4, 1258, 
4, 4, 1259, 
4, 4, 1260, 
4, 4, 1261, 
4, 4, 
  1268, 
4, 4, 1269, 
4, 4, 1272, 
4, 4, 1273, 
17, 19, 1570, 1571, 1573, 
18, 18, 1572, 
18, 18, 
  1574, 
18, 18, 1728, 
18, 18, 1730, 
18, 18, 1747, 
20, 20, 2345, 
20, 20, 2353, 
20, 20, 2356, 
21, 22, 2507, 
  2508, 
23, 25, 2888, 2891, 2892, 
26, 26, 2964, 
26, 27, 3020, 3018, 
27, 27, 3019, 
28, 28, 
  3144, 
29, 29, 3264, 
29, 31, 3271, 3272, 3274, 
29, 29, 3275, 
32, 33, 3402, 3404, 
32, 32, 
  3403, 
34, 36, 3546, 3548, 3550, 
34, 34, 3549, 
37, 37, 4134, 
38, 38, 6918, 
38, 38, 6920, 
38, 38, 
  6922, 
38, 38, 6924, 
38, 38, 6926, 
38, 38, 6930, 
38, 38, 6971, 
38, 38, 6973, 
38, 38, 6976, 
38, 38, 6977, 
38, 38, 
  6979, 
10, 41, 7682, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7684, 
  7686, 
10, 41, 7683, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7685, 
  7687, 
1, 1, 7688, 
1, 1, 7689, 
0, 1, 7700, 7702, 
0, 1, 7701, 7703, 
8, 8, 7708, 
8, 8, 
  7709, 
10, 10, 7710, 
10, 10, 7711, 
1, 1, 7726, 
1, 1, 7727, 
7, 7, 7736, 
7, 7, 7737, 
1, 40, 7742, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7744, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7746, 
1, 40, 7743, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7745, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7747, 
0, 1, 7760, 
  7762, 
0, 1, 7761, 7763, 
1, 10, 7764, 0, 0, 0, 0, 
  0, 0, 0, 0, 7766, 
1, 10, 7765, 0, 0, 
  0, 0, 0, 0, 0, 0, 7767, 
7, 7, 7772, 
7, 7, 
  7773, 
10, 10, 7780, 
10, 10, 7781, 
10, 10, 7782, 
10, 10, 7783, 
10, 10, 7784, 
10, 10, 7785, 
1, 1, 7800, 
1, 1, 
  7801, 
4, 4, 7802, 
4, 4, 7803, 
3, 40, 7804, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7806, 
3, 40, 7805, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7807, 
4, 10, 7820, 
  0, 0, 0, 0, 0, 7818, 
4, 10, 7821, 0, 
  0, 0, 0, 0, 7819, 
10, 10, 7835, 
0, 46, 7846, 7844, 
  0, 7850, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 7848, 
0, 46, 7847, 7845, 0, 
  7851, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7849, 
2, 8, 7852, 0, 0, 0, 
  0, 0, 7862, 
2, 8, 7853, 0, 0, 0, 0, 
  0, 7863, 
0, 46, 7856, 7854, 0, 7860, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7858, 
0, 46, 7857, 7855, 0, 7861, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7859, 
0, 46, 
  7872, 7870, 0, 7876, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7874, 
0, 46, 7873, 
  7871, 0, 7877, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7875, 
2, 2, 7878, 
2, 2, 7879, 
0, 46, 
  7890, 7888, 0, 7894, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7892, 
0, 46, 7891, 
  7889, 0, 7895, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7893, 
2, 2, 7896, 
2, 2, 7897, 
0, 46, 
  7900, 7898, 0, 7904, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7906, 0, 0, 0, 0, 0, 7902, 
0, 46, 7901, 
  7899, 0, 7905, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7907, 
  0, 0, 0, 0, 0, 7903, 
0, 46, 7914, 7912, 
  0, 7918, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7920, 0, 
  0, 0, 0, 0, 7916, 
0, 46, 7915, 7913, 0, 
  7919, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7921, 0, 0, 
  0, 0, 0, 7917, 
0, 50, 7938, 7940, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7942, 8064, 
0, 50, 7939, 
  7941, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  7943, 8065, 
0, 50, 7946, 7948, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7950, 8072, 
0, 50, 7947, 7949, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 7951, 8073, 
0, 1, 
  7954, 7956, 
0, 1, 7955, 7957, 
0, 1, 7962, 7964, 
0, 1, 7963, 7965, 
0, 50, 
  7970, 7972, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7974, 8080, 
0, 50, 7971, 7973, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 7975, 8081, 
0, 50, 7978, 7980, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7982, 
  8088, 
0, 50, 7979, 7981, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 7983, 8089, 
0, 49, 7986, 7988, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 7990, 
0, 49, 7987, 7989, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 7991, 
0, 49, 
  7994, 7996, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 7998, 
0, 49, 7995, 7997, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 7999, 
0, 1, 8002, 8004, 
0, 1, 8003, 8005, 
0, 1, 
  8010, 8012, 
0, 1, 8011, 8013, 
0, 49, 8018, 8020, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 8022, 
0, 49, 8019, 8021, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 8023, 
0, 49, 
  8027, 8029, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8031, 
0, 50, 8034, 8036, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 8038, 8096, 
0, 50, 8035, 8037, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 8039, 8097, 
0, 50, 
  8042, 8044, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8046, 8104, 
0, 50, 8043, 8045, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 8047, 8105, 
50, 50, 8066, 
50, 50, 8067, 
50, 50, 
  8068, 
50, 50, 8069, 
50, 50, 8070, 
50, 50, 8071, 
50, 50, 8074, 
50, 50, 8075, 
50, 50, 8076, 
50, 50, 8077, 
50, 50, 
  8078, 
50, 50, 8079, 
50, 50, 8082, 
50, 50, 8083, 
50, 50, 8084, 
50, 50, 8085, 
50, 50, 8086, 
50, 50, 8087, 
50, 50, 
  8090, 
50, 50, 8091, 
50, 50, 8092, 
50, 50, 8093, 
50, 50, 8094, 
50, 50, 8095, 
50, 50, 8098, 
50, 50, 8099, 
50, 50, 
  8100, 
50, 50, 8101, 
50, 50, 8102, 
50, 50, 8103, 
50, 50, 8106, 
50, 50, 8107, 
50, 50, 8108, 
50, 50, 8109, 
50, 50, 
  8110, 
50, 50, 8111, 
50, 50, 8114, 
50, 50, 8116, 
50, 50, 8119, 
50, 50, 8130, 
50, 50, 8132, 
50, 50, 8135, 
0, 49, 
  8141, 8142, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 8143, 
0, 49, 8157, 8158, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 0, 0, 0, 0, 0, 
  0, 0, 0, 8159, 
47, 48, 8164, 8165, 
48, 48, 8172, 
50, 50, 8178, 
50, 50, 
  8180, 
50, 50, 8183, 
51, 51, 8602, 
51, 51, 8603, 
51, 51, 8622, 
51, 51, 8653, 
51, 51, 8654, 
51, 51, 8655, 
51, 51, 
  8708, 
51, 51, 8713, 
51, 51, 8716, 
51, 51, 8740, 
51, 51, 8742, 
51, 51, 8769, 
51, 51, 8772, 
51, 51, 8775, 
51, 51, 
  8777, 
51, 51, 8800, 
51, 51, 8802, 
51, 51, 8813, 
51, 51, 8814, 
51, 51, 8815, 
51, 51, 8816, 
51, 51, 8817, 
51, 51, 
  8820, 
51, 51, 8821, 
51, 51, 8824, 
51, 51, 8825, 
51, 51, 8832, 
51, 51, 8833, 
51, 51, 8836, 
51, 51, 8837, 
51, 51, 
  8840, 
51, 51, 8841, 
51, 51, 8876, 
51, 51, 8877, 
51, 51, 8878, 
51, 51, 8879, 
51, 51, 8928, 
51, 51, 8929, 
51, 51, 
  8930, 
51, 51, 8931, 
51, 51, 8938, 
51, 51, 8939, 
51, 51, 8940, 
51, 51, 8941, 
51, 51, 10972, 
52, 52, 12364, 
52, 52, 
  12366, 
52, 52, 12368, 
52, 52, 12370, 
52, 52, 12372, 
52, 52, 12374, 
52, 52, 12376, 
52, 52, 12378, 
52, 52, 12380, 
52, 52, 
  12382, 
52, 52, 12384, 
52, 52, 12386, 
52, 52, 12389, 
52, 52, 12391, 
52, 52, 12393, 
52, 53, 12400, 12401, 
52, 53, 
  12403, 12404, 
52, 53, 12406, 12407, 
52, 53, 12409, 12410, 
52, 53, 12412, 12413, 
52, 52, 
  12436, 
52, 52, 12446, 
52, 52, 12460, 
52, 52, 12462, 
52, 52, 12464, 
52, 52, 12466, 
52, 52, 12468, 
52, 52, 12470, 
52, 52, 
  12472, 
52, 52, 12474, 
52, 52, 12476, 
52, 52, 12478, 
52, 52, 12480, 
52, 52, 12482, 
52, 52, 12485, 
52, 52, 12487, 
52, 52, 
  12489, 
52, 53, 12496, 12497, 
52, 53, 12499, 12500, 
52, 53, 12502, 12503, 
52, 53, 12505, 
  12506, 
52, 53, 12508, 12509, 
52, 52, 12532, 
52, 52, 12535, 
52, 52, 12536, 
52, 52, 12537, 
52, 52, 12538, 
52, 52, 
  12542, 
54, 55, 1, 4250, 
54, 55, 1, 4252, 
54, 55, 1, 4267, 
56, 57, 1, 4398, 
56, 57, 1, 4399, 
58, 61, 1, 4939, 1, 4940, 
62, 67, 
  1, 5307, 1, 5308, 1, 5310, 
68, 69, 1, 5562, 
68, 69, 1, 5563, 
70, 71, 1, 53598, 
70, 71, 1, 53599, 
72, 81, 1, 53600, 
  1, 53601, 1, 53602, 1, 53603, 1, 53604, 
70, 71, 1, 53691, 
70, 71, 1, 53692, 
72, 75, 1, 53693, 1, 53695, 
72, 75, 
  1, 53694, 1, 53696, 
};




UTF8PROC_DLLEXPORT const utf8proc_int8_t utf8proc_utf8class[256] = {
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 };

#define UTF8PROC_HANGUL_SBASE 0xAC00
#define UTF8PROC_HANGUL_LBASE 0x1100
#define UTF8PROC_HANGUL_VBASE 0x1161
#define UTF8PROC_HANGUL_TBASE 0x11A7
#define UTF8PROC_HANGUL_LCOUNT 19
#define UTF8PROC_HANGUL_VCOUNT 21
#define UTF8PROC_HANGUL_TCOUNT 28
#define UTF8PROC_HANGUL_NCOUNT 588
#define UTF8PROC_HANGUL_SCOUNT 11172
/* END is exclusive */
#define UTF8PROC_HANGUL_L_START  0x1100
#define UTF8PROC_HANGUL_L_END    0x115A
#define UTF8PROC_HANGUL_L_FILLER 0x115F
#define UTF8PROC_HANGUL_V_START  0x1160
#define UTF8PROC_HANGUL_V_END    0x11A3
#define UTF8PROC_HANGUL_T_START  0x11A8
#define UTF8PROC_HANGUL_T_END    0x11FA
#define UTF8PROC_HANGUL_S_START  0xAC00
#define UTF8PROC_HANGUL_S_END    0xD7A4

/* Should follow semantic-versioning rules (semver.org) based on API
   compatibility.  (Note that the shared-library version number will
   be different, being based on ABI compatibility.): */
#define STRINGIZEx(x) #x
#define STRINGIZE(x) STRINGIZEx(x)
UTF8PROC_DLLEXPORT const char *utf8proc_version(void) {
  return STRINGIZE(UTF8PROC_VERSION_MAJOR) "." STRINGIZE(UTF8PROC_VERSION_MINOR) "." STRINGIZE(UTF8PROC_VERSION_PATCH) "";
}

UTF8PROC_DLLEXPORT const char *utf8proc_unicode_version(void) {
  return "12.1.0";
}

UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode) {
  switch (errcode) {
    case UTF8PROC_ERROR_NOMEM:
    return "Memory for processing UTF-8 data could not be allocated.";
    case UTF8PROC_ERROR_OVERFLOW:
    return "UTF-8 string is too long to be processed.";
    case UTF8PROC_ERROR_INVALIDUTF8:
    return "Invalid UTF-8 string";
    case UTF8PROC_ERROR_NOTASSIGNED:
    return "Unassigned Unicode code point found in UTF-8 string.";
    case UTF8PROC_ERROR_INVALIDOPTS:
    return "Invalid options for UTF-8 processing chosen.";
    default:
    return "An unknown error occurred while processing UTF-8 data.";
  }
}

#define utf_cont(ch)  (((ch) & 0xc0) == 0x80)
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_int32_t *dst
) {
  utf8proc_uint32_t uc;
  const utf8proc_uint8_t *end;

  *dst = -1;
  if (!strlen) return 0;
  end = str + ((strlen < 0) ? 4 : strlen);
  uc = *str++;
  if (uc < 0x80) {
    *dst = uc;
    return 1;
  }
  // Must be between 0xc2 and 0xf4 inclusive to be valid
  if ((uc - 0xc2) > (0xf4-0xc2)) return UTF8PROC_ERROR_INVALIDUTF8;
  if (uc < 0xe0) {         // 2-byte sequence
     // Must have valid continuation character
     if (str >= end || !utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8;
     *dst = ((uc & 0x1f)<<6) | (*str & 0x3f);
     return 2;
  }
  if (uc < 0xf0) {        // 3-byte sequence
     if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1]))
        return UTF8PROC_ERROR_INVALIDUTF8;
     // Check for surrogate chars
     if (uc == 0xed && *str > 0x9f)
         return UTF8PROC_ERROR_INVALIDUTF8;
     uc = ((uc & 0xf)<<12) | ((*str & 0x3f)<<6) | (str[1] & 0x3f);
     if (uc < 0x800)
         return UTF8PROC_ERROR_INVALIDUTF8;
     *dst = uc;
     return 3;
  }
  // 4-byte sequence
  // Must have 3 valid continuation characters
  if ((str + 2 >= end) || !utf_cont(*str) || !utf_cont(str[1]) || !utf_cont(str[2]))
     return UTF8PROC_ERROR_INVALIDUTF8;
  // Make sure in correct range (0x10000 - 0x10ffff)
  if (uc == 0xf0) {
    if (*str < 0x90) return UTF8PROC_ERROR_INVALIDUTF8;
  } else if (uc == 0xf4) {
    if (*str > 0x8f) return UTF8PROC_ERROR_INVALIDUTF8;
  }
  *dst = ((uc & 7)<<18) | ((*str & 0x3f)<<12) | ((str[1] & 0x3f)<<6) | (str[2] & 0x3f);
  return 4;
}

UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t uc) {
    return (((utf8proc_uint32_t)uc)-0xd800 > 0x07ff) && ((utf8proc_uint32_t)uc < 0x110000);
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t uc, utf8proc_uint8_t *dst) {
  if (uc < 0x00) {
    return 0;
  } else if (uc < 0x80) {
    dst[0] = (utf8proc_uint8_t) uc;
    return 1;
  } else if (uc < 0x800) {
    dst[0] = (utf8proc_uint8_t)(0xC0 + (uc >> 6));
    dst[1] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
    return 2;
  // Note: we allow encoding 0xd800-0xdfff here, so as not to change
  // the API, however, these are actually invalid in UTF-8
  } else if (uc < 0x10000) {
    dst[0] = (utf8proc_uint8_t)(0xE0 + (uc >> 12));
    dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
    dst[2] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
    return 3;
  } else if (uc < 0x110000) {
    dst[0] = (utf8proc_uint8_t)(0xF0 + (uc >> 18));
    dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 12) & 0x3F));
    dst[2] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
    dst[3] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
    return 4;
  } else return 0;
}

/* internal version used for inserting 0xff bytes between graphemes */
static utf8proc_ssize_t charbound_encode_char(utf8proc_int32_t uc, utf8proc_uint8_t *dst) {
   if (uc < 0x00) {
      if (uc == -1) { /* internal value used for grapheme breaks */
        dst[0] = (utf8proc_uint8_t)0xFF;
        return 1;
      }
      return 0;
   } else if (uc < 0x80) {
      dst[0] = (utf8proc_uint8_t)uc;
      return 1;
   } else if (uc < 0x800) {
      dst[0] = (utf8proc_uint8_t)(0xC0 + (uc >> 6));
      dst[1] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
      return 2;
   } else if (uc < 0x10000) {
      dst[0] = (utf8proc_uint8_t)(0xE0 + (uc >> 12));
      dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
      dst[2] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
      return 3;
   } else if (uc < 0x110000) {
      dst[0] = (utf8proc_uint8_t)(0xF0 + (uc >> 18));
      dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 12) & 0x3F));
      dst[2] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
      dst[3] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
      return 4;
   } else return 0;
}

/* internal "unsafe" version that does not check whether uc is in range */
static const utf8proc_property_t *unsafe_get_property(utf8proc_int32_t uc) {
  /* ASSERT: uc >= 0 && uc < 0x110000 */
  return utf8proc_properties + (
    utf8proc_stage2table[
      utf8proc_stage1table[uc >> 8] + (uc & 0xFF)
    ]
  );
}

UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8proc_int32_t uc) {
  return uc < 0 || uc >= 0x110000 ? utf8proc_properties : unsafe_get_property(uc);
}

/* return whether there is a grapheme break between boundclasses lbc and tbc
   (according to the definition of extended grapheme clusters)

  Rule numbering refers to TR29 Version 29 (Unicode 9.0.0):
  http://www.unicode.org/reports/tr29/tr29-29.html

  CAVEATS:
   Please note that evaluation of GB10 (grapheme breaks between emoji zwj sequences)
   and GB 12/13 (regional indicator code points) require knowledge of previous characters
   and are thus not handled by this function. This may result in an incorrect break before
   an E_Modifier class codepoint and an incorrectly missing break between two
   REGIONAL_INDICATOR class code points if such support does not exist in the caller.

   See the special support in grapheme_break_extended, for required bookkeeping by the caller.
*/
static utf8proc_bool grapheme_break_simple(int lbc, int tbc) {
  return
    (lbc == UTF8PROC_BOUNDCLASS_START) ? true :       // GB1
    (lbc == UTF8PROC_BOUNDCLASS_CR &&                 // GB3
     tbc == UTF8PROC_BOUNDCLASS_LF) ? false :         // ---
    (lbc >= UTF8PROC_BOUNDCLASS_CR && lbc <= UTF8PROC_BOUNDCLASS_CONTROL) ? true :  // GB4
    (tbc >= UTF8PROC_BOUNDCLASS_CR && tbc <= UTF8PROC_BOUNDCLASS_CONTROL) ? true :  // GB5
    (lbc == UTF8PROC_BOUNDCLASS_L &&                  // GB6
     (tbc == UTF8PROC_BOUNDCLASS_L ||                 // ---
      tbc == UTF8PROC_BOUNDCLASS_V ||                 // ---
      tbc == UTF8PROC_BOUNDCLASS_LV ||                // ---
      tbc == UTF8PROC_BOUNDCLASS_LVT)) ? false :      // ---
    ((lbc == UTF8PROC_BOUNDCLASS_LV ||                // GB7
      lbc == UTF8PROC_BOUNDCLASS_V) &&                // ---
     (tbc == UTF8PROC_BOUNDCLASS_V ||                 // ---
      tbc == UTF8PROC_BOUNDCLASS_T)) ? false :        // ---
    ((lbc == UTF8PROC_BOUNDCLASS_LVT ||               // GB8
      lbc == UTF8PROC_BOUNDCLASS_T) &&                // ---
     tbc == UTF8PROC_BOUNDCLASS_T) ? false :          // ---
    (tbc == UTF8PROC_BOUNDCLASS_EXTEND ||             // GB9
     tbc == UTF8PROC_BOUNDCLASS_ZWJ ||                // ---
     tbc == UTF8PROC_BOUNDCLASS_SPACINGMARK ||        // GB9a
     lbc == UTF8PROC_BOUNDCLASS_PREPEND) ? false :    // GB9b
    (lbc == UTF8PROC_BOUNDCLASS_E_ZWG &&              // GB11 (requires additional handling below)
     tbc == UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC) ? false : // ----
    (lbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR &&          // GB12/13 (requires additional handling below)
     tbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR) ? false :  // ----
    true; // GB999
}

static utf8proc_bool grapheme_break_extended(int lbc, int tbc, utf8proc_int32_t *state)
{
  int lbc_override = ((state && *state != UTF8PROC_BOUNDCLASS_START)
                      ? *state : lbc);
  utf8proc_bool break_permitted = grapheme_break_simple(lbc_override, tbc);
  if (state) {
    // Special support for GB 12/13 made possible by GB999. After two RI
    // class codepoints we want to force a break. Do this by resetting the
    // second RI's bound class to UTF8PROC_BOUNDCLASS_OTHER, to force a break
    // after that character according to GB999 (unless of course such a break is
    // forbidden by a different rule such as GB9).
    if (*state == tbc && tbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR)
      *state = UTF8PROC_BOUNDCLASS_OTHER;
    // Special support for GB11 (emoji extend* zwj / emoji)
    else if (*state == UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC) {
      if (tbc == UTF8PROC_BOUNDCLASS_EXTEND) // fold EXTEND codepoints into emoji
        *state = UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC;
      else if (tbc == UTF8PROC_BOUNDCLASS_ZWJ)
        *state = UTF8PROC_BOUNDCLASS_E_ZWG; // state to record emoji+zwg combo
      else
        *state = tbc;
    }
    else
      *state = tbc;
  }
  return break_permitted;
}

UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful(
    utf8proc_int32_t c1, utf8proc_int32_t c2, utf8proc_int32_t *state) {

  return grapheme_break_extended(utf8proc_get_property(c1)->boundclass,
                                 utf8proc_get_property(c2)->boundclass,
                                 state);
}


UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break(
    utf8proc_int32_t c1, utf8proc_int32_t c2) {
  return utf8proc_grapheme_break_stateful(c1, c2, NULL);
}

static utf8proc_int32_t seqindex_decode_entry(const utf8proc_uint16_t **entry)
{
  utf8proc_int32_t entry_cp = **entry;
  if ((entry_cp & 0xF800) == 0xD800) {
    *entry = *entry + 1;
    entry_cp = ((entry_cp & 0x03FF) << 10) | (**entry & 0x03FF);
    entry_cp += 0x10000;
  }
  return entry_cp;
}

static utf8proc_int32_t seqindex_decode_index(const utf8proc_uint32_t seqindex)
{
  const utf8proc_uint16_t *entry = &utf8proc_sequences[seqindex];
  return seqindex_decode_entry(&entry);
}

static utf8proc_ssize_t seqindex_write_char_decomposed(utf8proc_uint16_t seqindex, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, utf8proc_option_t options, int *last_boundclass) {
  utf8proc_ssize_t written = 0;
  const utf8proc_uint16_t *entry = &utf8proc_sequences[seqindex & 0x1FFF];
  int len = seqindex >> 13;
  if (len >= 7) {
    len = *entry;
    entry++;
  }
  for (; len >= 0; entry++, len--) {
    utf8proc_int32_t entry_cp = seqindex_decode_entry(&entry);

    written += utf8proc_decompose_char(entry_cp, dst+written,
      (bufsize > written) ? (bufsize - written) : 0, options,
    last_boundclass);
    if (written < 0) return UTF8PROC_ERROR_OVERFLOW;
  }
  return written;
}

UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c)
{
  utf8proc_int32_t cl = utf8proc_get_property(c)->lowercase_seqindex;
  return cl != UINT16_MAX ? seqindex_decode_index(cl) : c;
}

UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c)
{
  utf8proc_int32_t cu = utf8proc_get_property(c)->uppercase_seqindex;
  return cu != UINT16_MAX ? seqindex_decode_index(cu) : c;
}

UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c)
{
  utf8proc_int32_t cu = utf8proc_get_property(c)->titlecase_seqindex;
  return cu != UINT16_MAX ? seqindex_decode_index(cu) : c;
}

/* return a character width analogous to wcwidth (except portable and
   hopefully less buggy than most system wcwidth functions). */
UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t c) {
  return utf8proc_get_property(c)->charwidth;
}

UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t c) {
  return (utf8proc_category_t)utf8proc_get_property(c)->category;
}

UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t c) {
  static const char s[][3] = {"Cn","Lu","Ll","Lt","Lm","Lo","Mn","Mc","Me","Nd","Nl","No","Pc","Pd","Ps","Pe","Pi","Pf","Po","Sm","Sc","Sk","So","Zs","Zl","Zp","Cc","Cf","Cs","Co"};
  return s[utf8proc_category(c)];
}

#define utf8proc_decompose_lump(replacement_uc) \
  return utf8proc_decompose_char((replacement_uc), dst, bufsize, \
  (utf8proc_option_t) (options & ~UTF8PROC_LUMP), last_boundclass)

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(utf8proc_int32_t uc, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, utf8proc_option_t options, int *last_boundclass) {
  const utf8proc_property_t *property;
  utf8proc_propval_t category;
  utf8proc_int32_t hangul_sindex;
  if (uc < 0 || uc >= 0x110000) return UTF8PROC_ERROR_NOTASSIGNED;
  property = unsafe_get_property(uc);
  category = property->category;
  hangul_sindex = uc - UTF8PROC_HANGUL_SBASE;
  if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) {
    if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT) {
      utf8proc_int32_t hangul_tindex;
      if (bufsize >= 1) {
        dst[0] = UTF8PROC_HANGUL_LBASE +
          hangul_sindex / UTF8PROC_HANGUL_NCOUNT;
        if (bufsize >= 2) dst[1] = UTF8PROC_HANGUL_VBASE +
          (hangul_sindex % UTF8PROC_HANGUL_NCOUNT) / UTF8PROC_HANGUL_TCOUNT;
      }
      hangul_tindex = hangul_sindex % UTF8PROC_HANGUL_TCOUNT;
      if (!hangul_tindex) return 2;
      if (bufsize >= 3) dst[2] = UTF8PROC_HANGUL_TBASE + hangul_tindex;
      return 3;
    }
  }
  if (options & UTF8PROC_REJECTNA) {
    if (!category) return UTF8PROC_ERROR_NOTASSIGNED;
  }
  if (options & UTF8PROC_IGNORE) {
    if (property->ignorable) return 0;
  }
  if (options & UTF8PROC_STRIPNA) {
    if (!category) return 0;
  }
  if (options & UTF8PROC_LUMP) {
    if (category == UTF8PROC_CATEGORY_ZS) utf8proc_decompose_lump(0x0020);
    if (uc == 0x2018 || uc == 0x2019 || uc == 0x02BC || uc == 0x02C8)
      utf8proc_decompose_lump(0x0027);
    if (category == UTF8PROC_CATEGORY_PD || uc == 0x2212)
      utf8proc_decompose_lump(0x002D);
    if (uc == 0x2044 || uc == 0x2215) utf8proc_decompose_lump(0x002F);
    if (uc == 0x2236) utf8proc_decompose_lump(0x003A);
    if (uc == 0x2039 || uc == 0x2329 || uc == 0x3008)
      utf8proc_decompose_lump(0x003C);
    if (uc == 0x203A || uc == 0x232A || uc == 0x3009)
      utf8proc_decompose_lump(0x003E);
    if (uc == 0x2216) utf8proc_decompose_lump(0x005C);
    if (uc == 0x02C4 || uc == 0x02C6 || uc == 0x2038 || uc == 0x2303)
      utf8proc_decompose_lump(0x005E);
    if (category == UTF8PROC_CATEGORY_PC || uc == 0x02CD)
      utf8proc_decompose_lump(0x005F);
    if (uc == 0x02CB) utf8proc_decompose_lump(0x0060);
    if (uc == 0x2223) utf8proc_decompose_lump(0x007C);
    if (uc == 0x223C) utf8proc_decompose_lump(0x007E);
    if ((options & UTF8PROC_NLF2LS) && (options & UTF8PROC_NLF2PS)) {
      if (category == UTF8PROC_CATEGORY_ZL ||
          category == UTF8PROC_CATEGORY_ZP)
        utf8proc_decompose_lump(0x000A);
    }
  }
  if (options & UTF8PROC_STRIPMARK) {
    if (category == UTF8PROC_CATEGORY_MN ||
      category == UTF8PROC_CATEGORY_MC ||
      category == UTF8PROC_CATEGORY_ME) return 0;
  }
  if (options & UTF8PROC_CASEFOLD) {
    if (property->casefold_seqindex != UINT16_MAX) {
      return seqindex_write_char_decomposed(property->casefold_seqindex, dst, bufsize, options, last_boundclass);
    }
  }
  if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) {
    if (property->decomp_seqindex != UINT16_MAX &&
        (!property->decomp_type || (options & UTF8PROC_COMPAT))) {
      return seqindex_write_char_decomposed(property->decomp_seqindex, dst, bufsize, options, last_boundclass);
    }
  }
  if (options & UTF8PROC_CHARBOUND) {
    utf8proc_bool boundary;
    int tbc = property->boundclass;
    boundary = grapheme_break_extended(*last_boundclass, tbc, last_boundclass);
    if (boundary) {
      if (bufsize >= 1) dst[0] = -1; /* sentinel value for grapheme break */
      if (bufsize >= 2) dst[1] = uc;
      return 2;
    }
  }
  if (bufsize >= 1) *dst = uc;
  return 1;
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
  utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options
) {
    return utf8proc_decompose_custom(str, strlen, buffer, bufsize, options, NULL, NULL);
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
  utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options,
  utf8proc_custom_func custom_func, void *custom_data
) {
  /* strlen will be ignored, if UTF8PROC_NULLTERM is set in options */
  utf8proc_ssize_t wpos = 0;
  if ((options & UTF8PROC_COMPOSE) && (options & UTF8PROC_DECOMPOSE))
    return UTF8PROC_ERROR_INVALIDOPTS;
  if ((options & UTF8PROC_STRIPMARK) &&
      !(options & UTF8PROC_COMPOSE) && !(options & UTF8PROC_DECOMPOSE))
    return UTF8PROC_ERROR_INVALIDOPTS;
  {
    utf8proc_int32_t uc;
    utf8proc_ssize_t rpos = 0;
    utf8proc_ssize_t decomp_result;
    int boundclass = UTF8PROC_BOUNDCLASS_START;
    while (1) {
      if (options & UTF8PROC_NULLTERM) {
        rpos += utf8proc_iterate(str + rpos, -1, &uc);
        /* checking of return value is not necessary,
           as 'uc' is < 0 in case of error */
        if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8;
        if (rpos < 0) return UTF8PROC_ERROR_OVERFLOW;
        if (uc == 0) break;
      } else {
        if (rpos >= strlen) break;
        rpos += utf8proc_iterate(str + rpos, strlen - rpos, &uc);
        if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8;
      }
      if (custom_func != NULL) {
        uc = custom_func(uc, custom_data);   /* user-specified custom mapping */
      }
      decomp_result = utf8proc_decompose_char(
        uc, buffer + wpos, (bufsize > wpos) ? (bufsize - wpos) : 0, options,
        &boundclass
      );
      if (decomp_result < 0) return decomp_result;
      wpos += decomp_result;
      /* prohibiting integer overflows due to too long strings: */
      if (wpos < 0 ||
          wpos > (utf8proc_ssize_t)(SSIZE_MAX/sizeof(utf8proc_int32_t)/2))
        return UTF8PROC_ERROR_OVERFLOW;
    }
  }
  if ((options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) && bufsize >= wpos) {
    utf8proc_ssize_t pos = 0;
    while (pos < wpos-1) {
      utf8proc_int32_t uc1, uc2;
      const utf8proc_property_t *property1, *property2;
      uc1 = buffer[pos];
      uc2 = buffer[pos+1];
      property1 = unsafe_get_property(uc1);
      property2 = unsafe_get_property(uc2);
      if (property1->combining_class > property2->combining_class &&
          property2->combining_class > 0) {
        buffer[pos] = uc2;
        buffer[pos+1] = uc1;
        if (pos > 0) pos--; else pos++;
      } else {
        pos++;
      }
    }
  }
  return wpos;
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options) {
  /* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored */
  if (options & (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS | UTF8PROC_STRIPCC)) {
    utf8proc_ssize_t rpos;
    utf8proc_ssize_t wpos = 0;
    utf8proc_int32_t uc;
    for (rpos = 0; rpos < length; rpos++) {
      uc = buffer[rpos];
      if (uc == 0x000D && rpos < length-1 && buffer[rpos+1] == 0x000A) rpos++;
      if (uc == 0x000A || uc == 0x000D || uc == 0x0085 ||
          ((options & UTF8PROC_STRIPCC) && (uc == 0x000B || uc == 0x000C))) {
        if (options & UTF8PROC_NLF2LS) {
          if (options & UTF8PROC_NLF2PS) {
            buffer[wpos++] = 0x000A;
          } else {
            buffer[wpos++] = 0x2028;
          }
        } else {
          if (options & UTF8PROC_NLF2PS) {
            buffer[wpos++] = 0x2029;
          } else {
            buffer[wpos++] = 0x0020;
          }
        }
      } else if ((options & UTF8PROC_STRIPCC) &&
          (uc < 0x0020 || (uc >= 0x007F && uc < 0x00A0))) {
        if (uc == 0x0009) buffer[wpos++] = 0x0020;
      } else {
        buffer[wpos++] = uc;
      }
    }
    length = wpos;
  }
  if (options & UTF8PROC_COMPOSE) {
    utf8proc_int32_t *starter = NULL;
    utf8proc_int32_t current_char;
    const utf8proc_property_t *starter_property = NULL, *current_property;
    utf8proc_propval_t max_combining_class = -1;
    utf8proc_ssize_t rpos;
    utf8proc_ssize_t wpos = 0;
    utf8proc_int32_t composition;
    for (rpos = 0; rpos < length; rpos++) {
      current_char = buffer[rpos];
      current_property = unsafe_get_property(current_char);
      if (starter && current_property->combining_class > max_combining_class) {
        /* combination perhaps possible */
        utf8proc_int32_t hangul_lindex;
        utf8proc_int32_t hangul_sindex;
        hangul_lindex = *starter - UTF8PROC_HANGUL_LBASE;
        if (hangul_lindex >= 0 && hangul_lindex < UTF8PROC_HANGUL_LCOUNT) {
          utf8proc_int32_t hangul_vindex;
          hangul_vindex = current_char - UTF8PROC_HANGUL_VBASE;
          if (hangul_vindex >= 0 && hangul_vindex < UTF8PROC_HANGUL_VCOUNT) {
            *starter = UTF8PROC_HANGUL_SBASE +
              (hangul_lindex * UTF8PROC_HANGUL_VCOUNT + hangul_vindex) *
              UTF8PROC_HANGUL_TCOUNT;
            starter_property = NULL;
            continue;
          }
        }
        hangul_sindex = *starter - UTF8PROC_HANGUL_SBASE;
        if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT &&
            (hangul_sindex % UTF8PROC_HANGUL_TCOUNT) == 0) {
          utf8proc_int32_t hangul_tindex;
          hangul_tindex = current_char - UTF8PROC_HANGUL_TBASE;
          if (hangul_tindex >= 0 && hangul_tindex < UTF8PROC_HANGUL_TCOUNT) {
            *starter += hangul_tindex;
            starter_property = NULL;
            continue;
          }
        }
        if (!starter_property) {
          starter_property = unsafe_get_property(*starter);
        }
        if (starter_property->comb_index < 0x8000 &&
            current_property->comb_index != UINT16_MAX &&
            current_property->comb_index >= 0x8000) {
          int sidx = starter_property->comb_index;
          int idx = current_property->comb_index & 0x3FFF;
          if (idx >= utf8proc_combinations[sidx] && idx <= utf8proc_combinations[sidx + 1] ) {
            idx += sidx + 2 - utf8proc_combinations[sidx];
            if (current_property->comb_index & 0x4000) {
              composition = (utf8proc_combinations[idx] << 16) | utf8proc_combinations[idx+1];
            } else
              composition = utf8proc_combinations[idx];

            if (composition > 0 && (!(options & UTF8PROC_STABLE) ||
                !(unsafe_get_property(composition)->comp_exclusion))) {
              *starter = composition;
              starter_property = NULL;
              continue;
            }
          }
        }
      }
      buffer[wpos] = current_char;
      if (current_property->combining_class) {
        if (current_property->combining_class > max_combining_class) {
          max_combining_class = current_property->combining_class;
        }
      } else {
        starter = buffer + wpos;
        starter_property = NULL;
        max_combining_class = -1;
      }
      wpos++;
    }
    length = wpos;
  }
  return length;
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options) {
  /* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored
     ASSERT: 'buffer' has one spare byte of free space at the end! */
  length = utf8proc_normalize_utf32(buffer, length, options);
  if (length < 0) return length;
  {
    utf8proc_ssize_t rpos, wpos = 0;
    utf8proc_int32_t uc;
    if (options & UTF8PROC_CHARBOUND) {
        for (rpos = 0; rpos < length; rpos++) {
            uc = buffer[rpos];
            wpos += charbound_encode_char(uc, ((utf8proc_uint8_t *)buffer) + wpos);
        }
    } else {
        for (rpos = 0; rpos < length; rpos++) {
            uc = buffer[rpos];
            wpos += utf8proc_encode_char(uc, ((utf8proc_uint8_t *)buffer) + wpos);
        }
    }
    ((utf8proc_uint8_t *)buffer)[wpos] = 0;
    return wpos;
  }
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options
) {
    return utf8proc_map_custom(str, strlen, dstptr, options, NULL, NULL);
}

UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom(
  const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options,
  utf8proc_custom_func custom_func, void *custom_data
) {
  utf8proc_int32_t *buffer;
  utf8proc_ssize_t result;
  *dstptr = NULL;
  result = utf8proc_decompose_custom(str, strlen, NULL, 0, options, custom_func, custom_data);
  if (result < 0) return result;
  buffer = (utf8proc_int32_t *) malloc(result * sizeof(utf8proc_int32_t) + 1);
  if (!buffer) return UTF8PROC_ERROR_NOMEM;
  result = utf8proc_decompose_custom(str, strlen, buffer, result, options, custom_func, custom_data);
  if (result < 0) {
    free(buffer);
    return result;
  }
  result = utf8proc_reencode(buffer, result, options);
  if (result < 0) {
    free(buffer);
    return result;
  }
  {
    utf8proc_int32_t *newptr;
    newptr = (utf8proc_int32_t *) realloc(buffer, (size_t)result+1);
    if (newptr) buffer = newptr;
  }
  *dstptr = (utf8proc_uint8_t *)buffer;
  return result;
}

UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str) {
  utf8proc_uint8_t *retval;
  utf8proc_map(str, 0, &retval, (utf8proc_option_t)(UTF8PROC_NULLTERM | UTF8PROC_STABLE |
    UTF8PROC_DECOMPOSE));
  return retval;
}

UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str) {
  utf8proc_uint8_t *retval;
  utf8proc_map(str, 0, &retval, (utf8proc_option_t)(UTF8PROC_NULLTERM | UTF8PROC_STABLE |
    UTF8PROC_COMPOSE));
  return retval;
}

UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str) {
  utf8proc_uint8_t *retval;
  utf8proc_map(str, 0, &retval, (utf8proc_option_t)(UTF8PROC_NULLTERM | UTF8PROC_STABLE |
    UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT));
  return retval;
}

UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str) {
  utf8proc_uint8_t *retval;
  utf8proc_map(str, 0, &retval, (utf8proc_option_t)(UTF8PROC_NULLTERM | UTF8PROC_STABLE |
    UTF8PROC_COMPOSE | UTF8PROC_COMPAT));
  return retval;
}

UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8_t *str) {
  utf8proc_uint8_t *retval;
  utf8proc_map(str, 0, &retval, (utf8proc_option_t)(UTF8PROC_NULLTERM | UTF8PROC_STABLE |
    UTF8PROC_COMPOSE | UTF8PROC_COMPAT | UTF8PROC_CASEFOLD | UTF8PROC_IGNORE));
  return retval;
}



using namespace duckdb;
using namespace std;

// This function efficiently checks if a string is valid UTF8.
// It was originally written by Sjoerd Mullender.

// Here is the table that makes it work:

// B 		= Number of Bytes in UTF8 encoding
// C_MIN 	= First Unicode code point
// C_MAX 	= Last Unicode code point
// B1 		= First Byte Prefix

// 	B	C_MIN		C_MAX		B1
//	1	U+000000	U+00007F		0xxxxxxx
//	2	U+000080	U+0007FF		110xxxxx
//	3	U+000800	U+00FFFF		1110xxxx
//	4	U+010000	U+10FFFF		11110xxx

UnicodeType Utf8Proc::Analyze(const char *s, size_t len) {
	UnicodeType type = UnicodeType::ASCII;
	char c;
	for (size_t i = 0; i < len; i++) {
		c = s[i];
		// 1 Byte / ASCII
		if ((c & 0x80) == 0)
			continue;
		type = UnicodeType::UNICODE;
		if ((s[++i] & 0xC0) != 0x80)
			return UnicodeType::INVALID;
		if ((c & 0xE0) == 0xC0)
			continue;
		if ((s[++i] & 0xC0) != 0x80)
			return UnicodeType::INVALID;
		if ((c & 0xF0) == 0xE0)
			continue;
		if ((s[++i] & 0xC0) != 0x80)
			return UnicodeType::INVALID;
		if ((c & 0xF8) == 0xF0)
			continue;
		return UnicodeType::INVALID;
	}

	return type;
}


std::string Utf8Proc::Normalize(std::string s) {
	auto normalized = Normalize(s.c_str());
	auto res = std::string(normalized);
	free(normalized);
	return res;
}
;

char* Utf8Proc::Normalize(const char *s) {
	assert(s);
	assert(Utf8Proc::Analyze(s) != UnicodeType::INVALID);
	return (char*) utf8proc_NFC((const utf8proc_uint8_t*) s);
}
;

;
#include <stdexcept>
#include <string>
#include <thread>
#include <mutex>


#include <stdlib.h>






typedef struct parse_result_str parse_result;
struct parse_result_str {
	bool success;
	PGList* parse_tree;
	char* error_message;
	int error_location;
};

void pg_parser_init();
void pg_parser_parse(const char* query, parse_result *res);
void pg_parser_cleanup();

// error handling
int ereport(int code, ...);

void elog(int code, const char* fmt,...);
int errcode(int sqlerrcode);
int errmsg(const char* fmt, ...);
int errhint(const char* msg);
int	errmsg_internal(const char *fmt,...);
int	errdetail(const char *fmt,...);
int	errposition(int cursorpos);
char *psprintf(const char *fmt,...);

// memory mgmt
char *pstrdup(const char *in);
void* palloc(size_t n);
void pfree(void* ptr);
void* palloc0fast(size_t n);
void* repalloc(void* ptr, size_t n);

char *NameListToString(PGList *names);
void * copyObject(const void *from);
bool equal(const void *a, const void *b);
int exprLocation(const PGNode *expr);

// string gunk
int pg_database_encoding_max_length(void);
bool pg_verifymbstr(const char *mbstr, int len, bool noError);
int	pg_mbstrlen_with_len(const char *mbstr, int len);
int pg_mbcliplen(const char *mbstr, int len, int limit);
int pg_mblen(const char *mbstr);

PGDefElem * defWithOids(bool value);

typedef unsigned int pg_wchar;
unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);



#include <stdarg.h>
#include <mutex>
#include <cstring>


// max parse tree size approx 100 MB, should be enough
#define PG_MALLOC_SIZE 10240
#define PG_MALLOC_LIMIT 1000

typedef struct pg_parser_state_str parser_state;
struct pg_parser_state_str {
	int pg_err_code;
	int pg_err_pos;
	char pg_err_msg[BUFSIZ];

	size_t malloc_pos;
	size_t malloc_ptr_idx;
	char *malloc_ptrs[PG_MALLOC_LIMIT];
};

static __thread parser_state pg_parser_state;

#ifndef __GNUC__
__thread PGNode *newNodeMacroHolder;
#endif

static void allocate_new(parser_state* state, size_t n) {
	if (state->malloc_ptr_idx + 1 >= PG_MALLOC_LIMIT) {
		throw std::runtime_error("Memory allocation failure");
	}
	if (n < PG_MALLOC_SIZE) {
		n = PG_MALLOC_SIZE;
	}
	char* base_ptr = (char*) malloc(n);
	if (!base_ptr) {
		throw std::runtime_error("Memory allocation failure");
	}
	state->malloc_ptrs[state->malloc_ptr_idx] = base_ptr;
	state->malloc_ptr_idx++;
	state->malloc_pos = 0;
}


void* palloc(size_t n) {
	if (pg_parser_state.malloc_pos + n > PG_MALLOC_SIZE) {
		allocate_new(&pg_parser_state, n);
	}

	void *ptr = pg_parser_state.malloc_ptrs[pg_parser_state.malloc_ptr_idx - 1] + pg_parser_state.malloc_pos;
	memset(ptr, 0, n);
	pg_parser_state.malloc_pos += n;
	return ptr;
}



void pg_parser_init() {
	pg_parser_state.pg_err_code = PGUNDEFINED;
	pg_parser_state.pg_err_msg[0] = '\0';

	pg_parser_state.malloc_ptr_idx = 0;
	allocate_new(&pg_parser_state, 1);
}

void pg_parser_parse(const char* query, parse_result *res) {

	res->parse_tree = nullptr;
	try{
		res->parse_tree = raw_parser(query);
		res->success = pg_parser_state.pg_err_code == PGUNDEFINED;
	} catch (...) {
		res->success = false;

	}
	res->error_message = pg_parser_state.pg_err_msg;
	res->error_location = pg_parser_state.pg_err_pos;
}


void pg_parser_cleanup() {
	for (size_t ptr_idx = 0; ptr_idx < pg_parser_state.malloc_ptr_idx; ptr_idx++) {
		char *ptr = pg_parser_state.malloc_ptrs[ptr_idx];
		if (ptr) {
			free(ptr);
			pg_parser_state.malloc_ptrs[ptr_idx] = nullptr;
		}
	}
}

int ereport(int code, ...) {
	std::string err = "parser error : " + std::string(pg_parser_state.pg_err_msg);
    throw std::runtime_error(err);
}
void elog(int code, const char* fmt,...) {
    throw std::runtime_error("elog NOT IMPLEMENTED");
}
int errcode(int sqlerrcode) {
	pg_parser_state.pg_err_code = sqlerrcode;
	return 1;
}
int errmsg(const char* fmt, ...) {
	 va_list argptr;
	 va_start(argptr, fmt);
	 vsnprintf(pg_parser_state.pg_err_msg, BUFSIZ, fmt, argptr);
	 va_end(argptr);
	 return 1;
}
int errhint(const char* msg) {
    throw std::runtime_error("errhint NOT IMPLEMENTED");
}
int	errmsg_internal(const char *fmt,...) {
    throw std::runtime_error("errmsg_internal NOT IMPLEMENTED");
}
int	errdetail(const char *fmt,...) {
    throw std::runtime_error("errdetail NOT IMPLEMENTED");
}
int	errposition(int cursorpos) {
	pg_parser_state.pg_err_pos = cursorpos;
	return 1;
}


char *
psprintf(const char *fmt,...) {
	char buf[BUFSIZ];
	va_list		args;
	size_t newlen;

	// attempt one: use stack buffer and determine length
	va_start(args, fmt);
	newlen = vsnprintf(buf, BUFSIZ, fmt, args);
	va_end(args);
	if (newlen < BUFSIZ) {
		return pstrdup(buf);
	}

	// attempt two, malloc
	char* mbuf = (char*) palloc(newlen);
	va_start(args, fmt);
	vsnprintf(mbuf, newlen, fmt, args);
	va_end(args);
	return mbuf;
}

char *pstrdup(const char *in) {
	char* new_str = (char*) palloc(strlen(in)+1);
	memcpy(new_str, in, strlen(in));
	return new_str;
}

void pfree(void* ptr) {
    // nop, we free up entire context on parser cleanup
}
void* palloc0fast(size_t n) { // very fast
    return palloc(n);
}
void* repalloc(void* ptr, size_t n) {
    throw std::runtime_error("repalloc NOT IMPLEMENTED");
}
char *NameListToString(PGList *names) {
    throw std::runtime_error("NameListToString NOT IMPLEMENTED");
}
void * copyObject(const void *from) {
    throw std::runtime_error("copyObject NOT IMPLEMENTED");
}
bool equal(const void *a, const void *b) {
    throw std::runtime_error("equal NOT IMPLEMENTED");
}
int exprLocation(const PGNode *expr) {
    throw std::runtime_error("exprLocation NOT IMPLEMENTED");
}
bool pg_verifymbstr(const char *mbstr, int len, bool noError) {
    throw std::runtime_error("pg_verifymbstr NOT IMPLEMENTED");
}

int pg_database_encoding_max_length(void) {
	return 4; // UTF8
}

static int
pg_utf_mblen(const unsigned char *s)
{
	int	len;

	if ((*s & 0x80) == 0)
		len = 1;
	else if ((*s & 0xe0) == 0xc0)
		len = 2;
	else if ((*s & 0xf0) == 0xe0)
		len = 3;
	else if ((*s & 0xf8) == 0xf0)
		len = 4;
#ifdef NOT_USED
	else if ((*s & 0xfc) == 0xf8)
		len = 5;
	else if ((*s & 0xfe) == 0xfc)
		len = 6;
#endif
	else
		len = 1;
	return len;
}


int pg_mbstrlen_with_len(const char *mbstr, int limit) {
	int	len = 0;
	while (limit > 0 && *mbstr)	{
		int	l = pg_utf_mblen((const unsigned char*) mbstr);
		limit -= l;
		mbstr += l;
		len++;
	}
	return len;
}


int pg_mbcliplen(const char *mbstr, int len, int limit) {
    throw std::runtime_error("pg_mbcliplen NOT IMPLEMENTED");
}
int pg_mblen(const char *mbstr) {
    throw std::runtime_error("pg_mblen NOT IMPLEMENTED");
}
PGDefElem * defWithOids(bool value) {
    throw std::runtime_error("defWithOids NOT IMPLEMENTED");
}
unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string) {
    throw std::runtime_error("unicode_to_utf8 NOT IMPLEMENTED");
}






using namespace duckdb;
using namespace std;

PostgresParser::PostgresParser() : success(false), parse_tree(nullptr), error_message(""), error_location(0) {};


void PostgresParser::Parse(string query) {
	pg_parser_init();
	parse_result res;
	pg_parser_parse(query.c_str(), &res);
	success = res.success;

	if (success) {
		parse_tree = res.parse_tree;
	} else {
		error_message = string(res.error_message);
		error_location = res.error_location;
	}
};

PostgresParser::~PostgresParser()  {
	pg_parser_cleanup();
};
/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - lappend
 * - new_list
 * - new_tail_cell
 * - lcons
 * - new_head_cell
 * - list_concat
 * - list_nth
 * - list_nth_cell
 * - list_delete_cell
 * - list_free
 * - list_free_private
 * - list_copy
 * - list_copy_tail
 * - list_truncate
 *--------------------------------------------------------------------
 */

/*-------------------------------------------------------------------------
 *
 * list.c
 *	  implementation for PostgreSQL generic linked list package
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/nodes/list.c
 *
 *-------------------------------------------------------------------------
 */




/*
 * Routines to simplify writing assertions about the type of a list; a
 * NIL list is considered to be an empty list of any type.
 */
#define IsPointerList(l)		((l) == NIL || IsA((l), PGList))
#define IsIntegerList(l)		((l) == NIL || IsA((l), IntList))
#define IsOidList(l)			((l) == NIL || IsA((l), OidList))

#ifdef USE_ASSERT_CHECKING
/*
 * Check that the specified PGList is valid (so far as we can tell).
 */
static void
check_list_invariants(const PGList *list)
{
	if (list == NIL)
		return;

	Assert(list->length > 0);
	Assert(list->head != NULL);
	Assert(list->tail != NULL);

	Assert(list->type == T_PGList ||
		   list->type == T_PGIntList ||
		   list->type == T_PGOidList);

	if (list->length == 1)
		Assert(list->head == list->tail);
	if (list->length == 2)
		Assert(list->head->next == list->tail);
	Assert(list->tail->next == NULL);
}
#else
#define check_list_invariants(l)
#endif							/* USE_ASSERT_CHECKING */

/*
 * Return a freshly allocated List. Since empty non-NIL lists are
 * invalid, new_list() also allocates the head cell of the new list:
 * the caller should be sure to fill in that cell's data.
 */
static PGList *
new_list(PGNodeTag type)
{
	PGList	   *new_list;
	PGListCell   *new_head;

	new_head = (PGListCell *) palloc(sizeof(*new_head));
	new_head->next = NULL;
	/* new_head->data is left undefined! */

	new_list = (PGList *) palloc(sizeof(*new_list));
	new_list->type = type;
	new_list->length = 1;
	new_list->head = new_head;
	new_list->tail = new_head;

	return new_list;
}

/*
 * Allocate a new cell and make it the head of the specified
 * list. Assumes the list it is passed is non-NIL.
 *
 * The data in the new head cell is undefined; the caller should be
 * sure to fill it in
 */
static void
new_head_cell(PGList *list)
{
	PGListCell   *new_head;

	new_head = (PGListCell *) palloc(sizeof(*new_head));
	new_head->next = list->head;

	list->head = new_head;
	list->length++;
}

/*
 * Allocate a new cell and make it the tail of the specified
 * list. Assumes the list it is passed is non-NIL.
 *
 * The data in the new tail cell is undefined; the caller should be
 * sure to fill it in
 */
static void
new_tail_cell(PGList *list)
{
	PGListCell   *new_tail;

	new_tail = (PGListCell *) palloc(sizeof(*new_tail));
	new_tail->next = NULL;

	list->tail->next = new_tail;
	list->tail = new_tail;
	list->length++;
}

/*
 * PGAppend a pointer to the list. A pointer to the modified list is
 * returned. Note that this function may or may not destructively
 * modify the list; callers should always use this function's return
 * value, rather than continuing to use the pointer passed as the
 * first argument.
 */
PGList *
lappend(PGList *list, void *datum)
{
	Assert(IsPointerList(list));

	if (list == NIL)
		list = new_list(T_PGList);
	else
		new_tail_cell(list);

	lfirst(list->tail) = datum;
	check_list_invariants(list);
	return list;
}

/*
 * PGAppend an integer to the specified list. See lappend()
 */


/*
 * PGAppend an OID to the specified list. See lappend()
 */


/*
 * Add a new cell to the list, in the position after 'prev_cell'. The
 * data in the cell is left undefined, and must be filled in by the
 * caller. 'list' is assumed to be non-NIL, and 'prev_cell' is assumed
 * to be non-NULL and a member of 'list'.
 */


/*
 * Add a new cell to the specified list (which must be non-NIL);
 * it will be placed after the list cell 'prev' (which must be
 * non-NULL and a member of 'list'). The data placed in the new cell
 * is 'datum'. The newly-constructed cell is returned.
 */






/*
 * Prepend a new element to the list. A pointer to the modified list
 * is returned. Note that this function may or may not destructively
 * modify the list; callers should always use this function's return
 * value, rather than continuing to use the pointer passed as the
 * second argument.
 *
 * Caution: before Postgres 8.0, the original PGList was unmodified and
 * could be considered to retain its separate identity.  This is no longer
 * the case.
 */
PGList *
lcons(void *datum, PGList *list)
{
	Assert(IsPointerList(list));

	if (list == NIL)
		list = new_list(T_PGList);
	else
		new_head_cell(list);

	lfirst(list->head) = datum;
	check_list_invariants(list);
	return list;
}

/*
 * Prepend an integer to the list. See lcons()
 */


/*
 * Prepend an OID to the list. See lcons()
 */


/*
 * Concatenate list2 to the end of list1, and return list1. list1 is
 * destructively changed. Callers should be sure to use the return
 * value as the new pointer to the concatenated list: the 'list1'
 * input pointer may or may not be the same as the returned pointer.
 *
 * The nodes in list2 are merely appended to the end of list1 in-place
 * (i.e. they aren't copied; the two lists will share some of the same
 * storage). Therefore, invoking list_free() on list2 will also
 * invalidate a portion of list1.
 */
PGList *
list_concat(PGList *list1, PGList *list2)
{
	if (list1 == NIL)
		return list2;
	if (list2 == NIL)
		return list1;
	if (list1 == list2)
		elog(ERROR, "cannot list_concat() a list to itself");

	Assert(list1->type == list2->type);

	list1->length += list2->length;
	list1->tail->next = list2->head;
	list1->tail = list2->tail;

	check_list_invariants(list1);
	return list1;
}

/*
 * Truncate 'list' to contain no more than 'new_size' elements. This
 * modifies the list in-place! Despite this, callers should use the
 * pointer returned by this function to refer to the newly truncated
 * list -- it may or may not be the same as the pointer that was
 * passed.
 *
 * Note that any cells removed by list_truncate() are NOT pfree'd.
 */
PGList *
list_truncate(PGList *list, int new_size)
{
	PGListCell   *cell;
	int			n;

	if (new_size <= 0)
		return NIL;				/* truncate to zero length */

	/* If asked to effectively extend the list, do nothing */
	if (new_size >= list_length(list))
		return list;

	n = 1;
	foreach(cell, list)
	{
		if (n == new_size)
		{
			cell->next = NULL;
			list->tail = cell;
			list->length = new_size;
			check_list_invariants(list);
			return list;
		}
		n++;
	}

	/* keep the compiler quiet; never reached */
	Assert(false);
	return list;
}

/*
 * Locate the n'th cell (counting from 0) of the list.  It is an assertion
 * failure if there is no such cell.
 */
PGListCell *
list_nth_cell(const PGList *list, int n)
{
	PGListCell   *match;

	Assert(list != NIL);
	Assert(n >= 0);
	Assert(n < list->length);
	check_list_invariants(list);

	/* Does the caller actually mean to fetch the tail? */
	if (n == list->length - 1)
		return list->tail;

	for (match = list->head; n-- > 0; match = match->next)
		;

	return match;
}

/*
 * Return the data value contained in the n'th element of the
 * specified list. (PGList elements begin at 0.)
 */
void *
list_nth(const PGList *list, int n)
{
	Assert(IsPointerList(list));
	return lfirst(list_nth_cell(list, n));
}

/*
 * Delete 'cell' from 'list'; 'prev' is the previous element to 'cell'
 * in 'list', if any (i.e. prev == NULL iff list->head == cell)
 *
 * The cell is pfree'd, as is the PGList header if this was the last member.
 */
PGList *
list_delete_cell(PGList *list, PGListCell *cell, PGListCell *prev)
{
	check_list_invariants(list);
	Assert(prev != NULL ? lnext(prev) == cell : list_head(list) == cell);

	/*
	 * If we're about to delete the last node from the list, free the whole
	 * list instead and return NIL, which is the only valid representation of
	 * a zero-length list.
	 */
	if (list->length == 1)
	{
		list_free(list);
		return NIL;
	}

	/*
	 * Otherwise, adjust the necessary list links, deallocate the particular
	 * node we have just removed, and return the list we were given.
	 */
	list->length--;

	if (prev)
		prev->next = cell->next;
	else
		list->head = cell->next;

	if (list->tail == cell)
		list->tail = prev;

	pfree(cell);
	return list;
}

/*
 * Free all storage in a list, and optionally the pointed-to elements
 */
static void
list_free_private(PGList *list, bool deep)
{
	PGListCell   *cell;

	check_list_invariants(list);

	cell = list_head(list);
	while (cell != NULL)
	{
		PGListCell   *tmp = cell;

		cell = lnext(cell);
		if (deep)
			pfree(lfirst(tmp));
		pfree(tmp);
	}

	if (list)
		pfree(list);
}

/*
 * Free all the cells of the list, as well as the list itself. Any
 * objects that are pointed-to by the cells of the list are NOT
 * free'd.
 *
 * On return, the argument to this function has been freed, so the
 * caller would be wise to set it to NIL for safety's sake.
 */
void
list_free(PGList *list)
{
	list_free_private(list, false);
}

/*
 * Free all the cells of the list, the list itself, and all the
 * objects pointed-to by the cells of the list (each element in the
 * list must contain a pointer to a palloc()'d region of memory!)
 *
 * On return, the argument to this function has been freed, so the
 * caller would be wise to set it to NIL for safety's sake.
 */


/*
 * Return a shallow copy of the specified list.
 */
PGList *
list_copy(const PGList *oldlist)
{
	PGList	   *newlist;
	PGListCell   *newlist_prev;
	PGListCell   *oldlist_cur;

	if (oldlist == NIL)
		return NIL;

	newlist = new_list(oldlist->type);
	newlist->length = oldlist->length;

	/*
	 * Copy over the data in the first cell; new_list() has already allocated
	 * the head cell itself
	 */
	newlist->head->data = oldlist->head->data;

	newlist_prev = newlist->head;
	oldlist_cur = oldlist->head->next;
	while (oldlist_cur)
	{
		PGListCell   *newlist_cur;

		newlist_cur = (PGListCell *) palloc(sizeof(*newlist_cur));
		newlist_cur->data = oldlist_cur->data;
		newlist_prev->next = newlist_cur;

		newlist_prev = newlist_cur;
		oldlist_cur = oldlist_cur->next;
	}

	newlist_prev->next = NULL;
	newlist->tail = newlist_prev;

	check_list_invariants(newlist);
	return newlist;
}

/*
 * Return a shallow copy of the specified list, without the first N elements.
 */
PGList *
list_copy_tail(const PGList *oldlist, int nskip)
{
	PGList	   *newlist;
	PGListCell   *newlist_prev;
	PGListCell   *oldlist_cur;

	if (nskip < 0)
		nskip = 0;				/* would it be better to elog? */

	if (oldlist == NIL || nskip >= oldlist->length)
		return NIL;

	newlist = new_list(oldlist->type);
	newlist->length = oldlist->length - nskip;

	/*
	 * Skip over the unwanted elements.
	 */
	oldlist_cur = oldlist->head;
	while (nskip-- > 0)
		oldlist_cur = oldlist_cur->next;

	/*
	 * Copy over the data in the first remaining cell; new_list() has already
	 * allocated the head cell itself
	 */
	newlist->head->data = oldlist_cur->data;

	newlist_prev = newlist->head;
	oldlist_cur = oldlist_cur->next;
	while (oldlist_cur)
	{
		PGListCell   *newlist_cur;

		newlist_cur = (PGListCell *) palloc(sizeof(*newlist_cur));
		newlist_cur->data = oldlist_cur->data;
		newlist_prev->next = newlist_cur;

		newlist_prev = newlist_cur;
		oldlist_cur = oldlist_cur->next;
	}

	newlist_prev->next = NULL;
	newlist->tail = newlist_prev;

	check_list_invariants(newlist);
	return newlist;
}

/*
 * Temporary compatibility functions
 *
 * In order to avoid warnings for these function definitions, we need
 * to include a prototype here as well as in pg_list.h. That's because
 * we don't enable list API compatibility in list.c, so we
 * don't see the prototypes for these functions.
 */

/*
 * Given a list, return its length. This is merely defined for the
 * sake of backward compatibility: we can't afford to define a macro
 * called "length", so it must be a function. New code should use the
 * list_length() macro in order to avoid the overhead of a function
 * call.
 */
int			length(const PGList *list);


/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - makeDefElem
 * - makeTypeNameFromNameList
 * - makeDefElemExtended
 * - makeAlias
 * - makeSimpleAExpr
 * - makeGroupingSet
 * - makeTypeName
 * - makeFuncCall
 * - makeAExpr
 * - makeRangeVar
 * - makeBoolExpr
 *--------------------------------------------------------------------
 */

/*-------------------------------------------------------------------------
 *
 * makefuncs.c
 *	  creator functions for primitive nodes. The functions here are for
 *	  the most frequently created nodes.
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/nodes/makefuncs.c
 *
 *-------------------------------------------------------------------------
 */



/*-------------------------------------------------------------------------
 *
 * fmgr.h
 *	  Definitions for the Postgres function manager and function-call
 *	  interface.
 *
 * This file must be included by all Postgres modules that either define
 * or call fmgr-callable functions.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/fmgr.h
 *
 *-------------------------------------------------------------------------
 */




typedef struct PGFunctionCallInfoData *PGFunctionCallInfo;

/* Standard parameter list for fmgr-compatible functions */
#define PG_FUNCTION_ARGS	PGFunctionCallInfo fcinfo

/*-------------------------------------------------------------------------
 *
 * makefuncs.h
 *	  prototypes for the creator functions (for primitive nodes)
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/makefuncs.h
 *
 *-------------------------------------------------------------------------
 */




extern PGAExpr *makeAExpr(PGAExpr_Kind kind, PGList *name,
		   PGNode *lexpr, PGNode *rexpr, int location);

extern PGAExpr *makeSimpleAExpr(PGAExpr_Kind kind, const char *name,
				 PGNode *lexpr, PGNode *rexpr, int location);

extern PGVar *makeVar(PGIndex varno,
		PGAttrNumber varattno,
		PGOid vartype,
		int32_t vartypmod,
		PGOid varcollid,
		PGIndex varlevelsup);

extern PGVar *makeVarFromTargetEntry(PGIndex varno,
					   PGTargetEntry *tle);

extern PGVar *makeWholeRowVar(PGRangeTblEntry *rte,
				PGIndex varno,
				PGIndex varlevelsup,
				bool allowScalar);

extern PGTargetEntry *makeTargetEntry(PGExpr *expr,
				PGAttrNumber resno,
				char *resname,
				bool resjunk);

extern PGTargetEntry *flatCopyTargetEntry(PGTargetEntry *src_tle);

extern PGFromExpr *makeFromExpr(PGList *fromlist, PGNode *quals);

extern PGConst *makeConst(PGOid consttype,
		  int32_t consttypmod,
		  PGOid constcollid,
		  int constlen,
		  PGDatum constvalue,
		  bool constisnull,
		  bool constbyval);

extern PGConst *makeNullConst(PGOid consttype, int32_t consttypmod, PGOid constcollid);

extern PGNode *makeBoolConst(bool value, bool isnull);

extern PGExpr *makeBoolExpr(PGBoolExprType boolop, PGList *args, int location);

extern PGAlias *makeAlias(const char *aliasname, PGList *colnames);

extern PGRelabelType *makeRelabelType(PGExpr *arg, PGOid rtype, int32_t rtypmod,
				PGOid rcollid, PGCoercionForm rformat);

extern PGRangeVar *makeRangeVar(char *schemaname, char *relname, int location);

extern PGTypeName *makeTypeName(char *typnam);
extern PGTypeName *makeTypeNameFromNameList(PGList *names);
extern PGTypeName *makeTypeNameFromOid(PGOid typeOid, int32_t typmod);

extern PGColumnDef *makeColumnDef(const char *colname,
			  PGOid typeOid, int32_t typmod, PGOid collOid);

extern PGFuncExpr *makeFuncExpr(PGOid funcid, PGOid rettype, PGList *args,
			 PGOid funccollid, PGOid inputcollid, PGCoercionForm fformat);

extern PGFuncCall *makeFuncCall(PGList *name, PGList *args, int location);

extern PGDefElem *makeDefElem(const char *name, PGNode *arg, int location);
extern PGDefElem *makeDefElemExtended(const char *nameSpace, const char *name, PGNode *arg,
					PGDefElemAction defaction, int location);

extern PGGroupingSet *makeGroupingSet(GroupingSetKind kind, PGList *content, int location);

/*-------------------------------------------------------------------------
 *
 * nodeFuncs.h
 *		Various general-purpose manipulations of PGNode trees
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/nodeFuncs.h
 *
 *-------------------------------------------------------------------------
 */





/* flags bits for query_tree_walker and query_tree_mutator */
#define QTW_IGNORE_RT_SUBQUERIES	0x01	/* subqueries in rtable */
#define QTW_IGNORE_CTE_SUBQUERIES	0x02	/* subqueries in cteList */
#define QTW_IGNORE_RC_SUBQUERIES	0x03	/* both of above */
#define QTW_IGNORE_JOINALIASES		0x04	/* JOIN alias var lists */
#define QTW_IGNORE_RANGE_TABLE		0x08	/* skip rangetable entirely */
#define QTW_EXAMINE_RTES			0x10	/* examine RTEs */
#define QTW_DONT_COPY_QUERY			0x20	/* do not copy top PGQuery */

/* callback function for check_functions_in_node */
typedef bool (*check_function_callback) (PGOid func_id, void *context);


extern PGOid	exprType(const PGNode *expr);
extern int32_t exprTypmod(const PGNode *expr);
extern bool exprIsLengthCoercion(const PGNode *expr, int32_t *coercedTypmod);
extern PGNode *relabel_to_typmod(PGNode *expr, int32_t typmod);
extern PGNode *strip_implicit_coercions(PGNode *node);
extern bool expression_returns_set(PGNode *clause);

extern PGOid	exprCollation(const PGNode *expr);
extern PGOid	exprInputCollation(const PGNode *expr);
extern void exprSetCollation(PGNode *expr, PGOid collation);
extern void exprSetInputCollation(PGNode *expr, PGOid inputcollation);

extern int	exprLocation(const PGNode *expr);

extern void fix_opfuncids(PGNode *node);
extern void set_opfuncid(PGOpExpr *opexpr);
extern void set_sa_opfuncid(PGScalarArrayOpExpr *opexpr);

extern bool check_functions_in_node(PGNode *node, check_function_callback checker,
						void *context);

extern bool expression_tree_walker(PGNode *node, bool (*walker) (),
								   void *context);
extern PGNode *expression_tree_mutator(PGNode *node, PGNode *(*mutator) (),
									 void *context);

extern bool query_tree_walker(PGQuery *query, bool (*walker) (),
							  void *context, int flags);
extern PGQuery *query_tree_mutator(PGQuery *query, PGNode *(*mutator) (),
								 void *context, int flags);

extern bool range_table_walker(PGList *rtable, bool (*walker) (),
							   void *context, int flags);
extern PGList *range_table_mutator(PGList *rtable, PGNode *(*mutator) (),
								 void *context, int flags);

extern bool query_or_expression_tree_walker(PGNode *node, bool (*walker) (),
											void *context, int flags);
extern PGNode *query_or_expression_tree_mutator(PGNode *node, PGNode *(*mutator) (),
											  void *context, int flags);

extern bool raw_expression_tree_walker(PGNode *node, bool (*walker) (),
									   void *context);

struct PlanState;
extern bool planstate_tree_walker(struct PlanState *planstate, bool (*walker) (),
								  void *context);


//#include "utils/lsyscache.hpp"


/*
 * makeAExpr -
 *		makes an PGAExpr node
 */
PGAExpr *
makeAExpr(PGAExpr_Kind kind, PGList *name,
		   PGNode *lexpr, PGNode *rexpr, int location)
{
	PGAExpr	   *a = makeNode(PGAExpr);

	a->kind = kind;
	a->name = name;
	a->lexpr = lexpr;
	a->rexpr = rexpr;
	a->location = location;
	return a;
}

/*
 * makeSimpleAExpr -
 *		As above, given a simple (unqualified) operator name
 */
PGAExpr *
makeSimpleAExpr(PGAExpr_Kind kind, const char *name,
				 PGNode *lexpr, PGNode *rexpr, int location)
{
	PGAExpr	   *a = makeNode(PGAExpr);

	a->kind = kind;
	a->name = list_make1(makeString((char *) name));
	a->lexpr = lexpr;
	a->rexpr = rexpr;
	a->location = location;
	return a;
}

/*
 * makeVar -
 *	  creates a PGVar node
 */


/*
 * makeVarFromTargetEntry -
 *		convenience function to create a same-level PGVar node from a
 *		PGTargetEntry
 */


/*
 * makeWholeRowVar -
 *	  creates a PGVar node representing a whole row of the specified RTE
 *
 * A whole-row reference is a PGVar with varno set to the correct range
 * table entry, and varattno == 0 to signal that it references the whole
 * tuple.  (Use of zero here is unclean, since it could easily be confused
 * with error cases, but it's not worth changing now.)  The vartype indicates
 * a rowtype; either a named composite type, or RECORD.  This function
 * encapsulates the logic for determining the correct rowtype OID to use.
 *
 * If allowScalar is true, then for the case where the RTE is a single function
 * returning a non-composite result type, we produce a normal PGVar referencing
 * the function's result directly, instead of the single-column composite
 * value that the whole-row notation might otherwise suggest.
 */


/*
 * makeTargetEntry -
 *	  creates a PGTargetEntry node
 */


/*
 * flatCopyTargetEntry -
 *	  duplicate a PGTargetEntry, but don't copy substructure
 *
 * This is commonly used when we just want to modify the resno or substitute
 * a new expression.
 */


/*
 * makeFromExpr -
 *	  creates a PGFromExpr node
 */


/*
 * makeConst -
 *	  creates a PGConst node
 */


/*
 * makeNullConst -
 *	  creates a PGConst node representing a NULL of the specified type/typmod
 *
 * This is a convenience routine that just saves a lookup of the type's
 * storage properties.
 */


/*
 * makeBoolConst -
 *	  creates a PGConst node representing a boolean value (can be NULL too)
 */


/*
 * makeBoolExpr -
 *	  creates a PGBoolExpr node
 */
PGExpr *
makeBoolExpr(PGBoolExprType boolop, PGList *args, int location)
{
	PGBoolExpr   *b = makeNode(PGBoolExpr);

	b->boolop = boolop;
	b->args = args;
	b->location = location;

	return (PGExpr *) b;
}

/*
 * makeAlias -
 *	  creates an PGAlias node
 *
 * NOTE: the given name is copied, but the colnames list (if any) isn't.
 */
PGAlias *
makeAlias(const char *aliasname, PGList *colnames)
{
	PGAlias	   *a = makeNode(PGAlias);

	a->aliasname = pstrdup(aliasname);
	a->colnames = colnames;

	return a;
}

/*
 * makeRelabelType -
 *	  creates a PGRelabelType node
 */


/*
 * makeRangeVar -
 *	  creates a PGRangeVar node (rather oversimplified case)
 */
PGRangeVar *
makeRangeVar(char *schemaname, char *relname, int location)
{
	PGRangeVar   *r = makeNode(PGRangeVar);

	r->catalogname = NULL;
	r->schemaname = schemaname;
	r->relname = relname;
	r->inh = true;
	r->relpersistence = RELPERSISTENCE_PERMANENT;
	r->alias = NULL;
	r->location = location;

	return r;
}

/*
 * makeTypeName -
 *	build a PGTypeName node for an unqualified name.
 *
 * typmod is defaulted, but can be changed later by caller.
 */
PGTypeName *
makeTypeName(char *typnam)
{
	return makeTypeNameFromNameList(list_make1(makeString(typnam)));
}

/*
 * makeTypeNameFromNameList -
 *	build a PGTypeName node for a String list representing a qualified name.
 *
 * typmod is defaulted, but can be changed later by caller.
 */
PGTypeName *
makeTypeNameFromNameList(PGList *names)
{
	PGTypeName   *n = makeNode(PGTypeName);

	n->names = names;
	n->typmods = NIL;
	n->typemod = -1;
	n->location = -1;
	return n;
}

/*
 * makeTypeNameFromOid -
 *	build a PGTypeName node to represent a type already known by OID/typmod.
 */


/*
 * makeColumnDef -
 *	build a PGColumnDef node to represent a simple column definition.
 *
 * Type and collation are specified by OID.
 * Other properties are all basic to start with.
 */


/*
 * makeFuncExpr -
 *	build an expression tree representing a function call.
 *
 * The argument expressions must have been transformed already.
 */


/*
 * makeDefElem -
 *	build a PGDefElem node
 *
 * This is sufficient for the "typical" case with an unqualified option name
 * and no special action.
 */
PGDefElem *
makeDefElem(const char *name, PGNode *arg, int location)
{
	PGDefElem    *res = makeNode(PGDefElem);

	res->defnamespace = NULL;
	res->defname = (char*) name;
	res->arg = arg;
	res->defaction = PG_DEFELEM_UNSPEC;
	res->location = location;

	return res;
}

/*
 * makeDefElemExtended -
 *	build a PGDefElem node with all fields available to be specified
 */
PGDefElem *
makeDefElemExtended(const char *nameSpace, const char *name, PGNode *arg,
					PGDefElemAction defaction, int location)
{
	PGDefElem    *res = makeNode(PGDefElem);

	res->defnamespace = (char*) nameSpace;
	res->defname = (char*) name;
	res->arg = arg;
	res->defaction = defaction;
	res->location = location;

	return res;
}

/*
 * makeFuncCall -
 *
 * Initialize a PGFuncCall struct with the information every caller must
 * supply.  Any non-default parameters have to be inserted by the caller.
 */
PGFuncCall *
makeFuncCall(PGList *name, PGList *args, int location)
{
	PGFuncCall   *n = makeNode(PGFuncCall);

	n->funcname = name;
	n->args = args;
	n->agg_order = NIL;
	n->agg_filter = NULL;
	n->agg_within_group = false;
	n->agg_star = false;
	n->agg_distinct = false;
	n->func_variadic = false;
	n->over = NULL;
	n->location = location;
	return n;
}

/*
 * makeGroupingSet
 *
 */
PGGroupingSet *
makeGroupingSet(GroupingSetKind kind, PGList *content, int location)
{
	PGGroupingSet *n = makeNode(PGGroupingSet);

	n->kind = kind;
	n->content = content;
	n->location = location;
	return n;
}
/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - makeInteger
 * - makeString
 * - makeFloat
 *--------------------------------------------------------------------
 */

/*-------------------------------------------------------------------------
 *
 * value.c
 *	  implementation of PGValue nodes
 *
 *
 * Copyright (c) 2003-2017, PostgreSQL Global Development PGGroup
 *
 *
 * IDENTIFICATION
 *	  src/backend/nodes/value.c
 *
 *-------------------------------------------------------------------------
 */




/*
 *	makeInteger
 */
PGValue *
makeInteger(long i)
{
	PGValue	   *v = makeNode(PGValue);

	v->type = T_PGInteger;
	v->val.ival = i;
	return v;
}

/*
 *	makeFloat
 *
 * Caller is responsible for passing a palloc'd string.
 */
PGValue *
makeFloat(char *numericStr)
{
	PGValue	   *v = makeNode(PGValue);

	v->type = T_PGFloat;
	v->val.str = numericStr;
	return v;
}

/*
 *	makeString
 *
 * Caller is responsible for passing a palloc'd string.
 */
PGValue *
makeString(const char *str)
{
	PGValue	   *v = makeNode(PGValue);

	v->type = T_PGString;
	v->val.str = (char*) str;
	return v;
}

/*
 *	makeBitString
 *
 * Caller is responsible for passing a palloc'd string.
 */

/* A Bison parser, made by GNU Bison 2.3.  */

/* Skeleton implementation for Bison's Yacc-like parsers in C

   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

   This program 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 2, or (at your option)
   any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/* As a special exception, you may create a larger work that contains
   part or all of the Bison parser skeleton and distribute that work
   under terms of your choice, so long as that work isn't itself a
   parser generator using the skeleton or a modified version thereof
   as a parser skeleton.  Alternatively, if you modify or redistribute
   the parser skeleton itself, you may (at your option) remove this
   special exception, which will cause the skeleton and the resulting
   Bison output files to be licensed under the GNU General Public
   License without this special exception.

   This special exception was added by the Free Software Foundation in
   version 2.2 of Bison.  */

/* C LALR(1) parser skeleton written by Richard Stallman, by
   simplifying the original so-called "semantic" parser.  */

/* All symbols defined below should begin with yy or YY, to avoid
   infringing on user name space.  This should be done even for local
   variables, as they might otherwise be expanded by user macros.
   There are some unavoidable exceptions within include files to
   define necessary library symbols; they are noted "INFRINGES ON
   USER NAME SPACE" below.  */

/* Identify Bison output.  */
#define YYBISON 1

/* Bison version.  */
#define YYBISON_VERSION "2.3"

/* Skeleton name.  */
#define YYSKELETON_NAME "yacc.c"

/* Pure parsers.  */
#define YYPURE 1

/* Using locations.  */
#define YYLSP_NEEDED 1

/* Substitute the variable and function names.  */
#define yyparse base_yyparse
#define yylex   base_yylex
#define yyerror base_yyerror
#define yylval  base_yylval
#define yychar  base_yychar
#define yydebug base_yydebug
#define yynerrs base_yynerrs
#define yylloc base_yylloc

/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     IDENT = 258,
     FCONST = 259,
     SCONST = 260,
     BCONST = 261,
     XCONST = 262,
     Op = 263,
     ICONST = 264,
     PARAM = 265,
     TYPECAST = 266,
     DOT_DOT = 267,
     COLON_EQUALS = 268,
     EQUALS_GREATER = 269,
     LESS_EQUALS = 270,
     GREATER_EQUALS = 271,
     NOT_EQUALS = 272,
     ABORT_P = 273,
     ABSOLUTE_P = 274,
     ACCESS = 275,
     ACTION = 276,
     ADD_P = 277,
     ADMIN = 278,
     AFTER = 279,
     AGGREGATE = 280,
     ALL = 281,
     ALSO = 282,
     ALTER = 283,
     ALWAYS = 284,
     ANALYSE = 285,
     ANALYZE = 286,
     AND = 287,
     ANY = 288,
     ARRAY = 289,
     AS = 290,
     ASC_P = 291,
     ASSERTION = 292,
     ASSIGNMENT = 293,
     ASYMMETRIC = 294,
     AT = 295,
     ATTACH = 296,
     ATTRIBUTE = 297,
     AUTHORIZATION = 298,
     BACKWARD = 299,
     BEFORE = 300,
     BEGIN_P = 301,
     BETWEEN = 302,
     BIGINT = 303,
     BINARY = 304,
     BIT = 305,
     BOOLEAN_P = 306,
     BOTH = 307,
     BY = 308,
     CACHE = 309,
     CALLED = 310,
     CASCADE = 311,
     CASCADED = 312,
     CASE = 313,
     CAST = 314,
     CATALOG_P = 315,
     CHAIN = 316,
     CHAR_P = 317,
     CHARACTER = 318,
     CHARACTERISTICS = 319,
     CHECK_P = 320,
     CHECKPOINT = 321,
     CLASS = 322,
     CLOSE = 323,
     CLUSTER = 324,
     COALESCE = 325,
     COLLATE = 326,
     COLLATION = 327,
     COLUMN = 328,
     COLUMNS = 329,
     COMMENT = 330,
     COMMENTS = 331,
     COMMIT = 332,
     COMMITTED = 333,
     CONCURRENTLY = 334,
     CONFIGURATION = 335,
     CONFLICT = 336,
     CONNECTION = 337,
     CONSTRAINT = 338,
     CONSTRAINTS = 339,
     CONTENT_P = 340,
     CONTINUE_P = 341,
     CONVERSION_P = 342,
     COPY = 343,
     COST = 344,
     CREATE_P = 345,
     CROSS = 346,
     CSV = 347,
     CUBE = 348,
     CURRENT_P = 349,
     CURRENT_CATALOG = 350,
     CURRENT_DATE = 351,
     CURRENT_ROLE = 352,
     CURRENT_SCHEMA = 353,
     CURRENT_TIME = 354,
     CURRENT_TIMESTAMP = 355,
     CURRENT_USER = 356,
     CURSOR = 357,
     CYCLE = 358,
     DATA_P = 359,
     DATABASE = 360,
     DAY_P = 361,
     DEALLOCATE = 362,
     DEC = 363,
     DECIMAL_P = 364,
     DECLARE = 365,
     DEFAULT = 366,
     DEFAULTS = 367,
     DEFERRABLE = 368,
     DEFERRED = 369,
     DEFINER = 370,
     DELETE_P = 371,
     DELIMITER = 372,
     DELIMITERS = 373,
     DEPENDS = 374,
     DESC_P = 375,
     DETACH = 376,
     DICTIONARY = 377,
     DISABLE_P = 378,
     DISCARD = 379,
     DISTINCT = 380,
     DO = 381,
     DOCUMENT_P = 382,
     DOMAIN_P = 383,
     DOUBLE_P = 384,
     DROP = 385,
     EACH = 386,
     ELSE = 387,
     ENABLE_P = 388,
     ENCODING = 389,
     ENCRYPTED = 390,
     END_P = 391,
     ENUM_P = 392,
     ESCAPE = 393,
     EVENT = 394,
     EXCEPT = 395,
     EXCLUDE = 396,
     EXCLUDING = 397,
     EXCLUSIVE = 398,
     EXECUTE = 399,
     EXISTS = 400,
     EXPLAIN = 401,
     EXTENSION = 402,
     EXTERNAL = 403,
     EXTRACT = 404,
     FALSE_P = 405,
     FAMILY = 406,
     FETCH = 407,
     FILTER = 408,
     FIRST_P = 409,
     FLOAT_P = 410,
     FOLLOWING = 411,
     FOR = 412,
     FORCE = 413,
     FOREIGN = 414,
     FORWARD = 415,
     FREEZE = 416,
     FROM = 417,
     FULL = 418,
     FUNCTION = 419,
     FUNCTIONS = 420,
     GENERATED = 421,
     GLOBAL = 422,
     GRANT = 423,
     GRANTED = 424,
     GREATEST = 425,
     GROUP_P = 426,
     GROUPING = 427,
     HANDLER = 428,
     HAVING = 429,
     HEADER_P = 430,
     HOLD = 431,
     HOUR_P = 432,
     IDENTITY_P = 433,
     IF_P = 434,
     ILIKE = 435,
     IMMEDIATE = 436,
     IMMUTABLE = 437,
     IMPLICIT_P = 438,
     IMPORT_P = 439,
     IN_P = 440,
     INCLUDING = 441,
     INCREMENT = 442,
     INDEX = 443,
     INDEXES = 444,
     INHERIT = 445,
     INHERITS = 446,
     INITIALLY = 447,
     INLINE_P = 448,
     INNER_P = 449,
     INOUT = 450,
     INPUT_P = 451,
     INSENSITIVE = 452,
     INSERT = 453,
     INSTEAD = 454,
     INT_P = 455,
     INTEGER = 456,
     INTERSECT = 457,
     INTERVAL = 458,
     INTO = 459,
     INVOKER = 460,
     IS = 461,
     ISNULL = 462,
     ISOLATION = 463,
     JOIN = 464,
     KEY = 465,
     LABEL = 466,
     LANGUAGE = 467,
     LARGE_P = 468,
     LAST_P = 469,
     LATERAL_P = 470,
     LEADING = 471,
     LEAKPROOF = 472,
     LEAST = 473,
     LEFT = 474,
     LEVEL = 475,
     LIKE = 476,
     LIMIT = 477,
     LISTEN = 478,
     LOAD = 479,
     LOCAL = 480,
     LOCALTIME = 481,
     LOCALTIMESTAMP = 482,
     LOCATION = 483,
     LOCK_P = 484,
     LOCKED = 485,
     LOGGED = 486,
     MAPPING = 487,
     MATCH = 488,
     MATERIALIZED = 489,
     MAXVALUE = 490,
     METHOD = 491,
     MINUTE_P = 492,
     MINVALUE = 493,
     MODE = 494,
     MONTH_P = 495,
     MOVE = 496,
     NAME_P = 497,
     NAMES = 498,
     NATIONAL = 499,
     NATURAL = 500,
     NCHAR = 501,
     NEW = 502,
     NEXT = 503,
     NO = 504,
     NONE = 505,
     NOT = 506,
     NOTHING = 507,
     NOTIFY = 508,
     NOTNULL = 509,
     NOWAIT = 510,
     NULL_P = 511,
     NULLIF = 512,
     NULLS_P = 513,
     NUMERIC = 514,
     OBJECT_P = 515,
     OF = 516,
     OFF = 517,
     OFFSET = 518,
     OIDS = 519,
     OLD = 520,
     ON = 521,
     ONLY = 522,
     OPERATOR = 523,
     OPTION = 524,
     OPTIONS = 525,
     OR = 526,
     ORDER = 527,
     ORDINALITY = 528,
     OUT_P = 529,
     OUTER_P = 530,
     OVER = 531,
     OVERLAPS = 532,
     OVERLAY = 533,
     OVERRIDING = 534,
     OWNED = 535,
     OWNER = 536,
     PARALLEL = 537,
     PARSER = 538,
     PARTIAL = 539,
     PARTITION = 540,
     PASSING = 541,
     PASSWORD = 542,
     PLACING = 543,
     PLANS = 544,
     POLICY = 545,
     POSITION = 546,
     PRAGMA_P = 547,
     PRECEDING = 548,
     PRECISION = 549,
     PREPARE = 550,
     PREPARED = 551,
     PRESERVE = 552,
     PRIMARY = 553,
     PRIOR = 554,
     PRIVILEGES = 555,
     PROCEDURAL = 556,
     PROCEDURE = 557,
     PROGRAM = 558,
     PUBLICATION = 559,
     QUOTE = 560,
     RANGE = 561,
     READ_P = 562,
     REAL = 563,
     REASSIGN = 564,
     RECHECK = 565,
     RECURSIVE = 566,
     REF = 567,
     REFERENCES = 568,
     REFERENCING = 569,
     REFRESH = 570,
     REINDEX = 571,
     RELATIVE_P = 572,
     RELEASE = 573,
     RENAME = 574,
     REPEATABLE = 575,
     REPLACE = 576,
     REPLICA = 577,
     RESET = 578,
     RESTART = 579,
     RESTRICT = 580,
     RETURNING = 581,
     RETURNS = 582,
     REVOKE = 583,
     RIGHT = 584,
     ROLE = 585,
     ROLLBACK = 586,
     ROLLUP = 587,
     ROW = 588,
     ROWS = 589,
     RULE = 590,
     SAVEPOINT = 591,
     SCHEMA = 592,
     SCHEMAS = 593,
     SCROLL = 594,
     SEARCH = 595,
     SECOND_P = 596,
     SECURITY = 597,
     SELECT = 598,
     SEQUENCE = 599,
     SEQUENCES = 600,
     SERIALIZABLE = 601,
     SERVER = 602,
     SESSION = 603,
     SESSION_USER = 604,
     SET = 605,
     SETOF = 606,
     SETS = 607,
     SHARE = 608,
     SHOW = 609,
     SIMILAR = 610,
     SIMPLE = 611,
     SKIP = 612,
     SMALLINT = 613,
     SNAPSHOT = 614,
     SOME = 615,
     SQL_P = 616,
     STABLE = 617,
     STANDALONE_P = 618,
     START = 619,
     STATEMENT = 620,
     STATISTICS = 621,
     STDIN = 622,
     STDOUT = 623,
     STORAGE = 624,
     STRICT_P = 625,
     STRIP_P = 626,
     SUBSCRIPTION = 627,
     SUBSTRING = 628,
     SYMMETRIC = 629,
     SYSID = 630,
     SYSTEM_P = 631,
     TABLE = 632,
     TABLES = 633,
     TABLESAMPLE = 634,
     TABLESPACE = 635,
     TEMP = 636,
     TEMPLATE = 637,
     TEMPORARY = 638,
     TEXT_P = 639,
     THEN = 640,
     TIME = 641,
     TIMESTAMP = 642,
     TO = 643,
     TRAILING = 644,
     TRANSACTION = 645,
     TRANSFORM = 646,
     TREAT = 647,
     TRIGGER = 648,
     TRIM = 649,
     TRUE_P = 650,
     TRUNCATE = 651,
     TRUSTED = 652,
     TYPE_P = 653,
     TYPES_P = 654,
     UNBOUNDED = 655,
     UNCOMMITTED = 656,
     UNENCRYPTED = 657,
     UNION = 658,
     UNIQUE = 659,
     UNKNOWN = 660,
     UNLISTEN = 661,
     UNLOGGED = 662,
     UNTIL = 663,
     UPDATE = 664,
     USER = 665,
     USING = 666,
     VACUUM = 667,
     VALID = 668,
     VALIDATE = 669,
     VALIDATOR = 670,
     VALUE_P = 671,
     VALUES = 672,
     VARCHAR = 673,
     VARIADIC = 674,
     VARYING = 675,
     VERBOSE = 676,
     VERSION_P = 677,
     VIEW = 678,
     VIEWS = 679,
     VOLATILE = 680,
     WHEN = 681,
     WHERE = 682,
     WHITESPACE_P = 683,
     WINDOW = 684,
     WITH = 685,
     WITHIN = 686,
     WITHOUT = 687,
     WORK = 688,
     WRAPPER = 689,
     WRITE_P = 690,
     XML_P = 691,
     XMLATTRIBUTES = 692,
     XMLCONCAT = 693,
     XMLELEMENT = 694,
     XMLEXISTS = 695,
     XMLFOREST = 696,
     XMLNAMESPACES = 697,
     XMLPARSE = 698,
     XMLPI = 699,
     XMLROOT = 700,
     XMLSERIALIZE = 701,
     XMLTABLE = 702,
     YEAR_P = 703,
     YES_P = 704,
     ZONE = 705,
     NOT_LA = 706,
     NULLS_LA = 707,
     WITH_LA = 708,
     POSTFIXOP = 709,
     UMINUS = 710
   };
#endif
/* Tokens.  */
#define IDENT 258
#define FCONST 259
#define SCONST 260
#define BCONST 261
#define XCONST 262
#define Op 263
#define ICONST 264
#define PARAM 265
#define TYPECAST 266
#define DOT_DOT 267
#define COLON_EQUALS 268
#define EQUALS_GREATER 269
#define LESS_EQUALS 270
#define GREATER_EQUALS 271
#define NOT_EQUALS 272
#define ABORT_P 273
#define ABSOLUTE_P 274
#define ACCESS 275
#define ACTION 276
#define ADD_P 277
#define ADMIN 278
#define AFTER 279
#define AGGREGATE 280
#define ALL 281
#define ALSO 282
#define ALTER 283
#define ALWAYS 284
#define ANALYSE 285
#define ANALYZE 286
#define AND 287
#define ANY 288
#define ARRAY 289
#define AS 290
#define ASC_P 291
#define ASSERTION 292
#define ASSIGNMENT 293
#define ASYMMETRIC 294
#define AT 295
#define ATTACH 296
#define ATTRIBUTE 297
#define AUTHORIZATION 298
#define BACKWARD 299
#define BEFORE 300
#define BEGIN_P 301
#define BETWEEN 302
#define BIGINT 303
#define BINARY 304
#define BIT 305
#define BOOLEAN_P 306
#define BOTH 307
#define BY 308
#define CACHE 309
#define CALLED 310
#define CASCADE 311
#define CASCADED 312
#define CASE 313
#define CAST 314
#define CATALOG_P 315
#define CHAIN 316
#define CHAR_P 317
#define CHARACTER 318
#define CHARACTERISTICS 319
#define CHECK_P 320
#define CHECKPOINT 321
#define CLASS 322
#define CLOSE 323
#define CLUSTER 324
#define COALESCE 325
#define COLLATE 326
#define COLLATION 327
#define COLUMN 328
#define COLUMNS 329
#define COMMENT 330
#define COMMENTS 331
#define COMMIT 332
#define COMMITTED 333
#define CONCURRENTLY 334
#define CONFIGURATION 335
#define CONFLICT 336
#define CONNECTION 337
#define CONSTRAINT 338
#define CONSTRAINTS 339
#define CONTENT_P 340
#define CONTINUE_P 341
#define CONVERSION_P 342
#define COPY 343
#define COST 344
#define CREATE_P 345
#define CROSS 346
#define CSV 347
#define CUBE 348
#define CURRENT_P 349
#define CURRENT_CATALOG 350
#define CURRENT_DATE 351
#define CURRENT_ROLE 352
#define CURRENT_SCHEMA 353
#define CURRENT_TIME 354
#define CURRENT_TIMESTAMP 355
#define CURRENT_USER 356
#define CURSOR 357
#define CYCLE 358
#define DATA_P 359
#define DATABASE 360
#define DAY_P 361
#define DEALLOCATE 362
#define DEC 363
#define DECIMAL_P 364
#define DECLARE 365
#define DEFAULT 366
#define DEFAULTS 367
#define DEFERRABLE 368
#define DEFERRED 369
#define DEFINER 370
#define DELETE_P 371
#define DELIMITER 372
#define DELIMITERS 373
#define DEPENDS 374
#define DESC_P 375
#define DETACH 376
#define DICTIONARY 377
#define DISABLE_P 378
#define DISCARD 379
#define DISTINCT 380
#define DO 381
#define DOCUMENT_P 382
#define DOMAIN_P 383
#define DOUBLE_P 384
#define DROP 385
#define EACH 386
#define ELSE 387
#define ENABLE_P 388
#define ENCODING 389
#define ENCRYPTED 390
#define END_P 391
#define ENUM_P 392
#define ESCAPE 393
#define EVENT 394
#define EXCEPT 395
#define EXCLUDE 396
#define EXCLUDING 397
#define EXCLUSIVE 398
#define EXECUTE 399
#define EXISTS 400
#define EXPLAIN 401
#define EXTENSION 402
#define EXTERNAL 403
#define EXTRACT 404
#define FALSE_P 405
#define FAMILY 406
#define FETCH 407
#define FILTER 408
#define FIRST_P 409
#define FLOAT_P 410
#define FOLLOWING 411
#define FOR 412
#define FORCE 413
#define FOREIGN 414
#define FORWARD 415
#define FREEZE 416
#define FROM 417
#define FULL 418
#define FUNCTION 419
#define FUNCTIONS 420
#define GENERATED 421
#define GLOBAL 422
#define GRANT 423
#define GRANTED 424
#define GREATEST 425
#define GROUP_P 426
#define GROUPING 427
#define HANDLER 428
#define HAVING 429
#define HEADER_P 430
#define HOLD 431
#define HOUR_P 432
#define IDENTITY_P 433
#define IF_P 434
#define ILIKE 435
#define IMMEDIATE 436
#define IMMUTABLE 437
#define IMPLICIT_P 438
#define IMPORT_P 439
#define IN_P 440
#define INCLUDING 441
#define INCREMENT 442
#define INDEX 443
#define INDEXES 444
#define INHERIT 445
#define INHERITS 446
#define INITIALLY 447
#define INLINE_P 448
#define INNER_P 449
#define INOUT 450
#define INPUT_P 451
#define INSENSITIVE 452
#define INSERT 453
#define INSTEAD 454
#define INT_P 455
#define INTEGER 456
#define INTERSECT 457
#define INTERVAL 458
#define INTO 459
#define INVOKER 460
#define IS 461
#define ISNULL 462
#define ISOLATION 463
#define JOIN 464
#define KEY 465
#define LABEL 466
#define LANGUAGE 467
#define LARGE_P 468
#define LAST_P 469
#define LATERAL_P 470
#define LEADING 471
#define LEAKPROOF 472
#define LEAST 473
#define LEFT 474
#define LEVEL 475
#define LIKE 476
#define LIMIT 477
#define LISTEN 478
#define LOAD 479
#define LOCAL 480
#define LOCALTIME 481
#define LOCALTIMESTAMP 482
#define LOCATION 483
#define LOCK_P 484
#define LOCKED 485
#define LOGGED 486
#define MAPPING 487
#define MATCH 488
#define MATERIALIZED 489
#define MAXVALUE 490
#define METHOD 491
#define MINUTE_P 492
#define MINVALUE 493
#define MODE 494
#define MONTH_P 495
#define MOVE 496
#define NAME_P 497
#define NAMES 498
#define NATIONAL 499
#define NATURAL 500
#define NCHAR 501
#define NEW 502
#define NEXT 503
#define NO 504
#define NONE 505
#define NOT 506
#define NOTHING 507
#define NOTIFY 508
#define NOTNULL 509
#define NOWAIT 510
#define NULL_P 511
#define NULLIF 512
#define NULLS_P 513
#define NUMERIC 514
#define OBJECT_P 515
#define OF 516
#define OFF 517
#define OFFSET 518
#define OIDS 519
#define OLD 520
#define ON 521
#define ONLY 522
#define OPERATOR 523
#define OPTION 524
#define OPTIONS 525
#define OR 526
#define ORDER 527
#define ORDINALITY 528
#define OUT_P 529
#define OUTER_P 530
#define OVER 531
#define OVERLAPS 532
#define OVERLAY 533
#define OVERRIDING 534
#define OWNED 535
#define OWNER 536
#define PARALLEL 537
#define PARSER 538
#define PARTIAL 539
#define PARTITION 540
#define PASSING 541
#define PASSWORD 542
#define PLACING 543
#define PLANS 544
#define POLICY 545
#define POSITION 546
#define PRAGMA_P 547
#define PRECEDING 548
#define PRECISION 549
#define PREPARE 550
#define PREPARED 551
#define PRESERVE 552
#define PRIMARY 553
#define PRIOR 554
#define PRIVILEGES 555
#define PROCEDURAL 556
#define PROCEDURE 557
#define PROGRAM 558
#define PUBLICATION 559
#define QUOTE 560
#define RANGE 561
#define READ_P 562
#define REAL 563
#define REASSIGN 564
#define RECHECK 565
#define RECURSIVE 566
#define REF 567
#define REFERENCES 568
#define REFERENCING 569
#define REFRESH 570
#define REINDEX 571
#define RELATIVE_P 572
#define RELEASE 573
#define RENAME 574
#define REPEATABLE 575
#define REPLACE 576
#define REPLICA 577
#define RESET 578
#define RESTART 579
#define RESTRICT 580
#define RETURNING 581
#define RETURNS 582
#define REVOKE 583
#define RIGHT 584
#define ROLE 585
#define ROLLBACK 586
#define ROLLUP 587
#define ROW 588
#define ROWS 589
#define RULE 590
#define SAVEPOINT 591
#define SCHEMA 592
#define SCHEMAS 593
#define SCROLL 594
#define SEARCH 595
#define SECOND_P 596
#define SECURITY 597
#define SELECT 598
#define SEQUENCE 599
#define SEQUENCES 600
#define SERIALIZABLE 601
#define SERVER 602
#define SESSION 603
#define SESSION_USER 604
#define SET 605
#define SETOF 606
#define SETS 607
#define SHARE 608
#define SHOW 609
#define SIMILAR 610
#define SIMPLE 611
#define SKIP 612
#define SMALLINT 613
#define SNAPSHOT 614
#define SOME 615
#define SQL_P 616
#define STABLE 617
#define STANDALONE_P 618
#define START 619
#define STATEMENT 620
#define STATISTICS 621
#define STDIN 622
#define STDOUT 623
#define STORAGE 624
#define STRICT_P 625
#define STRIP_P 626
#define SUBSCRIPTION 627
#define SUBSTRING 628
#define SYMMETRIC 629
#define SYSID 630
#define SYSTEM_P 631
#define TABLE 632
#define TABLES 633
#define TABLESAMPLE 634
#define TABLESPACE 635
#define TEMP 636
#define TEMPLATE 637
#define TEMPORARY 638
#define TEXT_P 639
#define THEN 640
#define TIME 641
#define TIMESTAMP 642
#define TO 643
#define TRAILING 644
#define TRANSACTION 645
#define TRANSFORM 646
#define TREAT 647
#define TRIGGER 648
#define TRIM 649
#define TRUE_P 650
#define TRUNCATE 651
#define TRUSTED 652
#define TYPE_P 653
#define TYPES_P 654
#define UNBOUNDED 655
#define UNCOMMITTED 656
#define UNENCRYPTED 657
#define UNION 658
#define UNIQUE 659
#define UNKNOWN 660
#define UNLISTEN 661
#define UNLOGGED 662
#define UNTIL 663
#define UPDATE 664
#define USER 665
#define USING 666
#define VACUUM 667
#define VALID 668
#define VALIDATE 669
#define VALIDATOR 670
#define VALUE_P 671
#define VALUES 672
#define VARCHAR 673
#define VARIADIC 674
#define VARYING 675
#define VERBOSE 676
#define VERSION_P 677
#define VIEW 678
#define VIEWS 679
#define VOLATILE 680
#define WHEN 681
#define WHERE 682
#define WHITESPACE_P 683
#define WINDOW 684
#define WITH 685
#define WITHIN 686
#define WITHOUT 687
#define WORK 688
#define WRAPPER 689
#define WRITE_P 690
#define XML_P 691
#define XMLATTRIBUTES 692
#define XMLCONCAT 693
#define XMLELEMENT 694
#define XMLEXISTS 695
#define XMLFOREST 696
#define XMLNAMESPACES 697
#define XMLPARSE 698
#define XMLPI 699
#define XMLROOT 700
#define XMLSERIALIZE 701
#define XMLTABLE 702
#define YEAR_P 703
#define YES_P 704
#define ZONE 705
#define NOT_LA 706
#define NULLS_LA 707
#define WITH_LA 708
#define POSTFIXOP 709
#define UMINUS 710




/* Copy the first part of user declarations.  */
#line 1 "third_party/libpg_query/grammar/grammar.y.tmp"

#line 1 "third_party/libpg_query/grammar/grammar.hpp"
/*#define YYDEBUG 1*/
/*-------------------------------------------------------------------------
 *
 * gram.y
 *	  POSTGRESQL BISON rules/actions
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/parser/gram.y
 *
 * HISTORY
 *	  AUTHOR			DATE			MAJOR EVENT
 *	  Andrew Yu			Sept, 1994		POSTQUEL to SQL conversion
 *	  Andrew Yu			Oct, 1994		lispy code conversion
 *
 * NOTES
 *	  CAPITALS are used to represent terminal symbols.
 *	  non-capitals are used to represent non-terminals.
 *
 *	  In general, nothing in this file should initiate database accesses
 *	  nor depend on changeable state (such as SET variables).  If you do
 *	  database accesses, your code will fail when we have aborted the
 *	  current transaction and are just parsing commands to find the next
 *	  ROLLBACK or COMMIT.  If you make use of SET variables, then you
 *	  will do the wrong thing in multi-query strings like this:
 *			SET constraint_exclusion TO off; SELECT * FROM foo;
 *	  because the entire string is parsed by gram.y before the SET gets
 *	  executed.  Anything that depends on the database or changeable state
 *	  should be handled during parse analysis so that it happens at the
 *	  right time not the wrong time.
 *
 * WARNINGS
 *	  If you use a list, make sure the datum is a node so that the printing
 *	  routines work.
 *
 *	  Sometimes we assign constants to makeStrings. Make sure we don't free
 *	  those.
 *
 *-------------------------------------------------------------------------
 */

#include <string.h>

#include <ctype.h>
#include <limits.h>



/*-------------------------------------------------------------------------
 *
 * gramparse.h
 *		Shared definitions for the "raw" parser (flex and bison phases only)
 *
 * NOTE: this file is only meant to be included in the core parsing files,
 * ie, parser.c, gram.y, scan.l, and src/common/keywords.c.
 * Definitions that are needed outside the core parser should be in parser.h.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/gramparse.h
 *
 *-------------------------------------------------------------------------
 */




/*-------------------------------------------------------------------------
 *
 * scanner.h
 *		API for the core scanner (flex machine)
 *
 * The core scanner is also used by PL/pgSQL, so we provide a public API
 * for it.  However, the rest of the backend is only expected to use the
 * higher-level API provided by parser.h.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/scanner.h
 *
 *-------------------------------------------------------------------------
 */



#include <cstdint>

/*-------------------------------------------------------------------------
 *
 * keywords.h
 *	  lexical token lookup for key words in PostgreSQL
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/common/keywords.h
 *
 *-------------------------------------------------------------------------
 */


#include <cstdint>

/* Keyword categories --- should match lists in gram.y */
#define UNRESERVED_KEYWORD		0
#define COL_NAME_KEYWORD		1
#define TYPE_FUNC_NAME_KEYWORD	2
#define RESERVED_KEYWORD		3


typedef struct PGScanKeyword
{
	const char *name;			/* in lower case */
	int16_t		value;			/* grammar's token code */
	int16_t		category;		/* see codes above */
} PGScanKeyword;

extern const PGScanKeyword ScanKeywords[];
extern const int NumScanKeywords;

extern const PGScanKeyword *ScanKeywordLookup(const char *text,
				  const PGScanKeyword *keywords,
				  int num_keywords);



/*
 * The scanner returns extra data about scanned tokens in this union type.
 * Note that this is a subset of the fields used in YYSTYPE of the bison
 * parsers built atop the scanner.
 */
typedef union core_YYSTYPE
{
	int			ival;			/* for integer literals */
	char	   *str;			/* for identifiers and non-integer literals */
	const char *keyword;		/* canonical spelling of keywords */
} core_YYSTYPE;

/*
 * We track token locations in terms of byte offsets from the start of the
 * source string, not the column number/line number representation that
 * bison uses by default.  Also, to minimize overhead we track only one
 * location (usually the first token location) for each construct, not
 * the beginning and ending locations as bison does by default.  It's
 * therefore sufficient to make YYLTYPE an int.
 */
#define YYLTYPE  int

/*
 * Another important component of the scanner's API is the token code numbers.
 * However, those are not defined in this file, because bison insists on
 * defining them for itself.  The token codes used by the core scanner are
 * the ASCII characters plus these:
 *	%token <str>	IDENT FCONST SCONST BCONST XCONST Op
 *	%token <ival>	ICONST PARAM
 *	%token			TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
 *	%token			LESS_EQUALS GREATER_EQUALS NOT_EQUALS
 * The above token definitions *must* be the first ones declared in any
 * bison parser built atop this scanner, so that they will have consistent
 * numbers assigned to them (specifically, IDENT = 258 and so on).
 */

/*
 * The YY_EXTRA data that a flex scanner allows us to pass around.
 * Private state needed by the core scanner goes here.  Note that the actual
 * yy_extra struct may be larger and have this as its first component, thus
 * allowing the calling parser to keep some fields of its own in YY_EXTRA.
 */
typedef struct core_yy_extra_type
{
	/*
	 * The string the scanner is physically scanning.  We keep this mainly so
	 * that we can cheaply compute the offset of the current token (yytext).
	 */
	char	   *scanbuf;
	PGSize		scanbuflen;

	/*
	 * The keyword list to use.
	 */
	const PGScanKeyword *keywords;
	int			num_keywords;

	/*
	 * Scanner settings to use.  These are initialized from the corresponding
	 * GUC variables by scanner_init().  Callers can modify them after
	 * scanner_init() if they don't want the scanner's behavior to follow the
	 * prevailing GUC settings.
	 */
	int			backslash_quote;
	bool		escape_string_warning;
	bool		standard_conforming_strings;

	/*
	 * literalbuf is used to accumulate literal values when multiple rules are
	 * needed to parse a single literal.  Call startlit() to reset buffer to
	 * empty, addlit() to add text.  NOTE: the string in literalbuf is NOT
	 * necessarily null-terminated, but there always IS room to add a trailing
	 * null at offset literallen.  We store a null only when we need it.
	 */
	char	   *literalbuf;		/* palloc'd expandable buffer */
	int			literallen;		/* actual current string length */
	int			literalalloc;	/* current allocated buffer size */

	int			xcdepth;		/* depth of nesting in slash-star comments */
	char	   *dolqstart;		/* current $foo$ quote start string */

	/* first part of UTF16 surrogate pair for Unicode escapes */
	int32_t		utf16_first_part;

	/* state variables for literal-lexing warnings */
	bool		warn_on_first_escape;
	bool		saw_non_ascii;
} core_yy_extra_type;

/*
 * The type of yyscanner is opaque outside scan.l.
 */
typedef void *core_yyscan_t;


/* Entry points in parser/scan.l */
extern core_yyscan_t scanner_init(const char *str,
			 core_yy_extra_type *yyext,
			 const PGScanKeyword *keywords,
			 int num_keywords);
extern void scanner_finish(core_yyscan_t yyscanner);
extern int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp,
		   core_yyscan_t yyscanner);
extern int	scanner_errposition(int location, core_yyscan_t yyscanner);
extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner);

/* A Bison parser, made by GNU Bison 2.3.  */

/* Skeleton interface for Bison's Yacc-like parsers in C

   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

   This program 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 2, or (at your option)
   any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/* As a special exception, you may create a larger work that contains
   part or all of the Bison parser skeleton and distribute that work
   under terms of your choice, so long as that work isn't itself a
   parser generator using the skeleton or a modified version thereof
   as a parser skeleton.  Alternatively, if you modify or redistribute
   the parser skeleton itself, you may (at your option) remove this
   special exception, which will cause the skeleton and the resulting
   Bison output files to be licensed under the GNU General Public
   License without this special exception.

   This special exception was added by the Free Software Foundation in
   version 2.2 of Bison.  */

/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     IDENT = 258,
     FCONST = 259,
     SCONST = 260,
     BCONST = 261,
     XCONST = 262,
     Op = 263,
     ICONST = 264,
     PARAM = 265,
     TYPECAST = 266,
     DOT_DOT = 267,
     COLON_EQUALS = 268,
     EQUALS_GREATER = 269,
     LESS_EQUALS = 270,
     GREATER_EQUALS = 271,
     NOT_EQUALS = 272,
     ABORT_P = 273,
     ABSOLUTE_P = 274,
     ACCESS = 275,
     ACTION = 276,
     ADD_P = 277,
     ADMIN = 278,
     AFTER = 279,
     AGGREGATE = 280,
     ALL = 281,
     ALSO = 282,
     ALTER = 283,
     ALWAYS = 284,
     ANALYSE = 285,
     ANALYZE = 286,
     AND = 287,
     ANY = 288,
     ARRAY = 289,
     AS = 290,
     ASC_P = 291,
     ASSERTION = 292,
     ASSIGNMENT = 293,
     ASYMMETRIC = 294,
     AT = 295,
     ATTACH = 296,
     ATTRIBUTE = 297,
     AUTHORIZATION = 298,
     BACKWARD = 299,
     BEFORE = 300,
     BEGIN_P = 301,
     BETWEEN = 302,
     BIGINT = 303,
     BINARY = 304,
     BIT = 305,
     BOOLEAN_P = 306,
     BOTH = 307,
     BY = 308,
     CACHE = 309,
     CALLED = 310,
     CASCADE = 311,
     CASCADED = 312,
     CASE = 313,
     CAST = 314,
     CATALOG_P = 315,
     CHAIN = 316,
     CHAR_P = 317,
     CHARACTER = 318,
     CHARACTERISTICS = 319,
     CHECK_P = 320,
     CHECKPOINT = 321,
     CLASS = 322,
     CLOSE = 323,
     CLUSTER = 324,
     COALESCE = 325,
     COLLATE = 326,
     COLLATION = 327,
     COLUMN = 328,
     COLUMNS = 329,
     COMMENT = 330,
     COMMENTS = 331,
     COMMIT = 332,
     COMMITTED = 333,
     CONCURRENTLY = 334,
     CONFIGURATION = 335,
     CONFLICT = 336,
     CONNECTION = 337,
     CONSTRAINT = 338,
     CONSTRAINTS = 339,
     CONTENT_P = 340,
     CONTINUE_P = 341,
     CONVERSION_P = 342,
     COPY = 343,
     COST = 344,
     CREATE_P = 345,
     CROSS = 346,
     CSV = 347,
     CUBE = 348,
     CURRENT_P = 349,
     CURRENT_CATALOG = 350,
     CURRENT_DATE = 351,
     CURRENT_ROLE = 352,
     CURRENT_SCHEMA = 353,
     CURRENT_TIME = 354,
     CURRENT_TIMESTAMP = 355,
     CURRENT_USER = 356,
     CURSOR = 357,
     CYCLE = 358,
     DATA_P = 359,
     DATABASE = 360,
     DAY_P = 361,
     DEALLOCATE = 362,
     DEC = 363,
     DECIMAL_P = 364,
     DECLARE = 365,
     DEFAULT = 366,
     DEFAULTS = 367,
     DEFERRABLE = 368,
     DEFERRED = 369,
     DEFINER = 370,
     DELETE_P = 371,
     DELIMITER = 372,
     DELIMITERS = 373,
     DEPENDS = 374,
     DESC_P = 375,
     DETACH = 376,
     DICTIONARY = 377,
     DISABLE_P = 378,
     DISCARD = 379,
     DISTINCT = 380,
     DO = 381,
     DOCUMENT_P = 382,
     DOMAIN_P = 383,
     DOUBLE_P = 384,
     DROP = 385,
     EACH = 386,
     ELSE = 387,
     ENABLE_P = 388,
     ENCODING = 389,
     ENCRYPTED = 390,
     END_P = 391,
     ENUM_P = 392,
     ESCAPE = 393,
     EVENT = 394,
     EXCEPT = 395,
     EXCLUDE = 396,
     EXCLUDING = 397,
     EXCLUSIVE = 398,
     EXECUTE = 399,
     EXISTS = 400,
     EXPLAIN = 401,
     EXTENSION = 402,
     EXTERNAL = 403,
     EXTRACT = 404,
     FALSE_P = 405,
     FAMILY = 406,
     FETCH = 407,
     FILTER = 408,
     FIRST_P = 409,
     FLOAT_P = 410,
     FOLLOWING = 411,
     FOR = 412,
     FORCE = 413,
     FOREIGN = 414,
     FORWARD = 415,
     FREEZE = 416,
     FROM = 417,
     FULL = 418,
     FUNCTION = 419,
     FUNCTIONS = 420,
     GENERATED = 421,
     GLOBAL = 422,
     GRANT = 423,
     GRANTED = 424,
     GREATEST = 425,
     GROUP_P = 426,
     GROUPING = 427,
     HANDLER = 428,
     HAVING = 429,
     HEADER_P = 430,
     HOLD = 431,
     HOUR_P = 432,
     IDENTITY_P = 433,
     IF_P = 434,
     ILIKE = 435,
     IMMEDIATE = 436,
     IMMUTABLE = 437,
     IMPLICIT_P = 438,
     IMPORT_P = 439,
     IN_P = 440,
     INCLUDING = 441,
     INCREMENT = 442,
     INDEX = 443,
     INDEXES = 444,
     INHERIT = 445,
     INHERITS = 446,
     INITIALLY = 447,
     INLINE_P = 448,
     INNER_P = 449,
     INOUT = 450,
     INPUT_P = 451,
     INSENSITIVE = 452,
     INSERT = 453,
     INSTEAD = 454,
     INT_P = 455,
     INTEGER = 456,
     INTERSECT = 457,
     INTERVAL = 458,
     INTO = 459,
     INVOKER = 460,
     IS = 461,
     ISNULL = 462,
     ISOLATION = 463,
     JOIN = 464,
     KEY = 465,
     LABEL = 466,
     LANGUAGE = 467,
     LARGE_P = 468,
     LAST_P = 469,
     LATERAL_P = 470,
     LEADING = 471,
     LEAKPROOF = 472,
     LEAST = 473,
     LEFT = 474,
     LEVEL = 475,
     LIKE = 476,
     LIMIT = 477,
     LISTEN = 478,
     LOAD = 479,
     LOCAL = 480,
     LOCALTIME = 481,
     LOCALTIMESTAMP = 482,
     LOCATION = 483,
     LOCK_P = 484,
     LOCKED = 485,
     LOGGED = 486,
     MAPPING = 487,
     MATCH = 488,
     MATERIALIZED = 489,
     MAXVALUE = 490,
     METHOD = 491,
     MINUTE_P = 492,
     MINVALUE = 493,
     MODE = 494,
     MONTH_P = 495,
     MOVE = 496,
     NAME_P = 497,
     NAMES = 498,
     NATIONAL = 499,
     NATURAL = 500,
     NCHAR = 501,
     NEW = 502,
     NEXT = 503,
     NO = 504,
     NONE = 505,
     NOT = 506,
     NOTHING = 507,
     NOTIFY = 508,
     NOTNULL = 509,
     NOWAIT = 510,
     NULL_P = 511,
     NULLIF = 512,
     NULLS_P = 513,
     NUMERIC = 514,
     OBJECT_P = 515,
     OF = 516,
     OFF = 517,
     OFFSET = 518,
     OIDS = 519,
     OLD = 520,
     ON = 521,
     ONLY = 522,
     OPERATOR = 523,
     OPTION = 524,
     OPTIONS = 525,
     OR = 526,
     ORDER = 527,
     ORDINALITY = 528,
     OUT_P = 529,
     OUTER_P = 530,
     OVER = 531,
     OVERLAPS = 532,
     OVERLAY = 533,
     OVERRIDING = 534,
     OWNED = 535,
     OWNER = 536,
     PARALLEL = 537,
     PARSER = 538,
     PARTIAL = 539,
     PARTITION = 540,
     PASSING = 541,
     PASSWORD = 542,
     PLACING = 543,
     PLANS = 544,
     POLICY = 545,
     POSITION = 546,
     PRAGMA_P = 547,
     PRECEDING = 548,
     PRECISION = 549,
     PREPARE = 550,
     PREPARED = 551,
     PRESERVE = 552,
     PRIMARY = 553,
     PRIOR = 554,
     PRIVILEGES = 555,
     PROCEDURAL = 556,
     PROCEDURE = 557,
     PROGRAM = 558,
     PUBLICATION = 559,
     QUOTE = 560,
     RANGE = 561,
     READ_P = 562,
     REAL = 563,
     REASSIGN = 564,
     RECHECK = 565,
     RECURSIVE = 566,
     REF = 567,
     REFERENCES = 568,
     REFERENCING = 569,
     REFRESH = 570,
     REINDEX = 571,
     RELATIVE_P = 572,
     RELEASE = 573,
     RENAME = 574,
     REPEATABLE = 575,
     REPLACE = 576,
     REPLICA = 577,
     RESET = 578,
     RESTART = 579,
     RESTRICT = 580,
     RETURNING = 581,
     RETURNS = 582,
     REVOKE = 583,
     RIGHT = 584,
     ROLE = 585,
     ROLLBACK = 586,
     ROLLUP = 587,
     ROW = 588,
     ROWS = 589,
     RULE = 590,
     SAVEPOINT = 591,
     SCHEMA = 592,
     SCHEMAS = 593,
     SCROLL = 594,
     SEARCH = 595,
     SECOND_P = 596,
     SECURITY = 597,
     SELECT = 598,
     SEQUENCE = 599,
     SEQUENCES = 600,
     SERIALIZABLE = 601,
     SERVER = 602,
     SESSION = 603,
     SESSION_USER = 604,
     SET = 605,
     SETOF = 606,
     SETS = 607,
     SHARE = 608,
     SHOW = 609,
     SIMILAR = 610,
     SIMPLE = 611,
     SKIP = 612,
     SMALLINT = 613,
     SNAPSHOT = 614,
     SOME = 615,
     SQL_P = 616,
     STABLE = 617,
     STANDALONE_P = 618,
     START = 619,
     STATEMENT = 620,
     STATISTICS = 621,
     STDIN = 622,
     STDOUT = 623,
     STORAGE = 624,
     STRICT_P = 625,
     STRIP_P = 626,
     SUBSCRIPTION = 627,
     SUBSTRING = 628,
     SYMMETRIC = 629,
     SYSID = 630,
     SYSTEM_P = 631,
     TABLE = 632,
     TABLES = 633,
     TABLESAMPLE = 634,
     TABLESPACE = 635,
     TEMP = 636,
     TEMPLATE = 637,
     TEMPORARY = 638,
     TEXT_P = 639,
     THEN = 640,
     TIME = 641,
     TIMESTAMP = 642,
     TO = 643,
     TRAILING = 644,
     TRANSACTION = 645,
     TRANSFORM = 646,
     TREAT = 647,
     TRIGGER = 648,
     TRIM = 649,
     TRUE_P = 650,
     TRUNCATE = 651,
     TRUSTED = 652,
     TYPE_P = 653,
     TYPES_P = 654,
     UNBOUNDED = 655,
     UNCOMMITTED = 656,
     UNENCRYPTED = 657,
     UNION = 658,
     UNIQUE = 659,
     UNKNOWN = 660,
     UNLISTEN = 661,
     UNLOGGED = 662,
     UNTIL = 663,
     UPDATE = 664,
     USER = 665,
     USING = 666,
     VACUUM = 667,
     VALID = 668,
     VALIDATE = 669,
     VALIDATOR = 670,
     VALUE_P = 671,
     VALUES = 672,
     VARCHAR = 673,
     VARIADIC = 674,
     VARYING = 675,
     VERBOSE = 676,
     VERSION_P = 677,
     VIEW = 678,
     VIEWS = 679,
     VOLATILE = 680,
     WHEN = 681,
     WHERE = 682,
     WHITESPACE_P = 683,
     WINDOW = 684,
     WITH = 685,
     WITHIN = 686,
     WITHOUT = 687,
     WORK = 688,
     WRAPPER = 689,
     WRITE_P = 690,
     XML_P = 691,
     XMLATTRIBUTES = 692,
     XMLCONCAT = 693,
     XMLELEMENT = 694,
     XMLEXISTS = 695,
     XMLFOREST = 696,
     XMLNAMESPACES = 697,
     XMLPARSE = 698,
     XMLPI = 699,
     XMLROOT = 700,
     XMLSERIALIZE = 701,
     XMLTABLE = 702,
     YEAR_P = 703,
     YES_P = 704,
     ZONE = 705,
     NOT_LA = 706,
     NULLS_LA = 707,
     WITH_LA = 708,
     POSTFIXOP = 709,
     UMINUS = 710
   };
#endif
/* Tokens.  */
#define IDENT 258
#define FCONST 259
#define SCONST 260
#define BCONST 261
#define XCONST 262
#define Op 263
#define ICONST 264
#define PARAM 265
#define TYPECAST 266
#define DOT_DOT 267
#define COLON_EQUALS 268
#define EQUALS_GREATER 269
#define LESS_EQUALS 270
#define GREATER_EQUALS 271
#define NOT_EQUALS 272
#define ABORT_P 273
#define ABSOLUTE_P 274
#define ACCESS 275
#define ACTION 276
#define ADD_P 277
#define ADMIN 278
#define AFTER 279
#define AGGREGATE 280
#define ALL 281
#define ALSO 282
#define ALTER 283
#define ALWAYS 284
#define ANALYSE 285
#define ANALYZE 286
#define AND 287
#define ANY 288
#define ARRAY 289
#define AS 290
#define ASC_P 291
#define ASSERTION 292
#define ASSIGNMENT 293
#define ASYMMETRIC 294
#define AT 295
#define ATTACH 296
#define ATTRIBUTE 297
#define AUTHORIZATION 298
#define BACKWARD 299
#define BEFORE 300
#define BEGIN_P 301
#define BETWEEN 302
#define BIGINT 303
#define BINARY 304
#define BIT 305
#define BOOLEAN_P 306
#define BOTH 307
#define BY 308
#define CACHE 309
#define CALLED 310
#define CASCADE 311
#define CASCADED 312
#define CASE 313
#define CAST 314
#define CATALOG_P 315
#define CHAIN 316
#define CHAR_P 317
#define CHARACTER 318
#define CHARACTERISTICS 319
#define CHECK_P 320
#define CHECKPOINT 321
#define CLASS 322
#define CLOSE 323
#define CLUSTER 324
#define COALESCE 325
#define COLLATE 326
#define COLLATION 327
#define COLUMN 328
#define COLUMNS 329
#define COMMENT 330
#define COMMENTS 331
#define COMMIT 332
#define COMMITTED 333
#define CONCURRENTLY 334
#define CONFIGURATION 335
#define CONFLICT 336
#define CONNECTION 337
#define CONSTRAINT 338
#define CONSTRAINTS 339
#define CONTENT_P 340
#define CONTINUE_P 341
#define CONVERSION_P 342
#define COPY 343
#define COST 344
#define CREATE_P 345
#define CROSS 346
#define CSV 347
#define CUBE 348
#define CURRENT_P 349
#define CURRENT_CATALOG 350
#define CURRENT_DATE 351
#define CURRENT_ROLE 352
#define CURRENT_SCHEMA 353
#define CURRENT_TIME 354
#define CURRENT_TIMESTAMP 355
#define CURRENT_USER 356
#define CURSOR 357
#define CYCLE 358
#define DATA_P 359
#define DATABASE 360
#define DAY_P 361
#define DEALLOCATE 362
#define DEC 363
#define DECIMAL_P 364
#define DECLARE 365
#define DEFAULT 366
#define DEFAULTS 367
#define DEFERRABLE 368
#define DEFERRED 369
#define DEFINER 370
#define DELETE_P 371
#define DELIMITER 372
#define DELIMITERS 373
#define DEPENDS 374
#define DESC_P 375
#define DETACH 376
#define DICTIONARY 377
#define DISABLE_P 378
#define DISCARD 379
#define DISTINCT 380
#define DO 381
#define DOCUMENT_P 382
#define DOMAIN_P 383
#define DOUBLE_P 384
#define DROP 385
#define EACH 386
#define ELSE 387
#define ENABLE_P 388
#define ENCODING 389
#define ENCRYPTED 390
#define END_P 391
#define ENUM_P 392
#define ESCAPE 393
#define EVENT 394
#define EXCEPT 395
#define EXCLUDE 396
#define EXCLUDING 397
#define EXCLUSIVE 398
#define EXECUTE 399
#define EXISTS 400
#define EXPLAIN 401
#define EXTENSION 402
#define EXTERNAL 403
#define EXTRACT 404
#define FALSE_P 405
#define FAMILY 406
#define FETCH 407
#define FILTER 408
#define FIRST_P 409
#define FLOAT_P 410
#define FOLLOWING 411
#define FOR 412
#define FORCE 413
#define FOREIGN 414
#define FORWARD 415
#define FREEZE 416
#define FROM 417
#define FULL 418
#define FUNCTION 419
#define FUNCTIONS 420
#define GENERATED 421
#define GLOBAL 422
#define GRANT 423
#define GRANTED 424
#define GREATEST 425
#define GROUP_P 426
#define GROUPING 427
#define HANDLER 428
#define HAVING 429
#define HEADER_P 430
#define HOLD 431
#define HOUR_P 432
#define IDENTITY_P 433
#define IF_P 434
#define ILIKE 435
#define IMMEDIATE 436
#define IMMUTABLE 437
#define IMPLICIT_P 438
#define IMPORT_P 439
#define IN_P 440
#define INCLUDING 441
#define INCREMENT 442
#define INDEX 443
#define INDEXES 444
#define INHERIT 445
#define INHERITS 446
#define INITIALLY 447
#define INLINE_P 448
#define INNER_P 449
#define INOUT 450
#define INPUT_P 451
#define INSENSITIVE 452
#define INSERT 453
#define INSTEAD 454
#define INT_P 455
#define INTEGER 456
#define INTERSECT 457
#define INTERVAL 458
#define INTO 459
#define INVOKER 460
#define IS 461
#define ISNULL 462
#define ISOLATION 463
#define JOIN 464
#define KEY 465
#define LABEL 466
#define LANGUAGE 467
#define LARGE_P 468
#define LAST_P 469
#define LATERAL_P 470
#define LEADING 471
#define LEAKPROOF 472
#define LEAST 473
#define LEFT 474
#define LEVEL 475
#define LIKE 476
#define LIMIT 477
#define LISTEN 478
#define LOAD 479
#define LOCAL 480
#define LOCALTIME 481
#define LOCALTIMESTAMP 482
#define LOCATION 483
#define LOCK_P 484
#define LOCKED 485
#define LOGGED 486
#define MAPPING 487
#define MATCH 488
#define MATERIALIZED 489
#define MAXVALUE 490
#define METHOD 491
#define MINUTE_P 492
#define MINVALUE 493
#define MODE 494
#define MONTH_P 495
#define MOVE 496
#define NAME_P 497
#define NAMES 498
#define NATIONAL 499
#define NATURAL 500
#define NCHAR 501
#define NEW 502
#define NEXT 503
#define NO 504
#define NONE 505
#define NOT 506
#define NOTHING 507
#define NOTIFY 508
#define NOTNULL 509
#define NOWAIT 510
#define NULL_P 511
#define NULLIF 512
#define NULLS_P 513
#define NUMERIC 514
#define OBJECT_P 515
#define OF 516
#define OFF 517
#define OFFSET 518
#define OIDS 519
#define OLD 520
#define ON 521
#define ONLY 522
#define OPERATOR 523
#define OPTION 524
#define OPTIONS 525
#define OR 526
#define ORDER 527
#define ORDINALITY 528
#define OUT_P 529
#define OUTER_P 530
#define OVER 531
#define OVERLAPS 532
#define OVERLAY 533
#define OVERRIDING 534
#define OWNED 535
#define OWNER 536
#define PARALLEL 537
#define PARSER 538
#define PARTIAL 539
#define PARTITION 540
#define PASSING 541
#define PASSWORD 542
#define PLACING 543
#define PLANS 544
#define POLICY 545
#define POSITION 546
#define PRAGMA_P 547
#define PRECEDING 548
#define PRECISION 549
#define PREPARE 550
#define PREPARED 551
#define PRESERVE 552
#define PRIMARY 553
#define PRIOR 554
#define PRIVILEGES 555
#define PROCEDURAL 556
#define PROCEDURE 557
#define PROGRAM 558
#define PUBLICATION 559
#define QUOTE 560
#define RANGE 561
#define READ_P 562
#define REAL 563
#define REASSIGN 564
#define RECHECK 565
#define RECURSIVE 566
#define REF 567
#define REFERENCES 568
#define REFERENCING 569
#define REFRESH 570
#define REINDEX 571
#define RELATIVE_P 572
#define RELEASE 573
#define RENAME 574
#define REPEATABLE 575
#define REPLACE 576
#define REPLICA 577
#define RESET 578
#define RESTART 579
#define RESTRICT 580
#define RETURNING 581
#define RETURNS 582
#define REVOKE 583
#define RIGHT 584
#define ROLE 585
#define ROLLBACK 586
#define ROLLUP 587
#define ROW 588
#define ROWS 589
#define RULE 590
#define SAVEPOINT 591
#define SCHEMA 592
#define SCHEMAS 593
#define SCROLL 594
#define SEARCH 595
#define SECOND_P 596
#define SECURITY 597
#define SELECT 598
#define SEQUENCE 599
#define SEQUENCES 600
#define SERIALIZABLE 601
#define SERVER 602
#define SESSION 603
#define SESSION_USER 604
#define SET 605
#define SETOF 606
#define SETS 607
#define SHARE 608
#define SHOW 609
#define SIMILAR 610
#define SIMPLE 611
#define SKIP 612
#define SMALLINT 613
#define SNAPSHOT 614
#define SOME 615
#define SQL_P 616
#define STABLE 617
#define STANDALONE_P 618
#define START 619
#define STATEMENT 620
#define STATISTICS 621
#define STDIN 622
#define STDOUT 623
#define STORAGE 624
#define STRICT_P 625
#define STRIP_P 626
#define SUBSCRIPTION 627
#define SUBSTRING 628
#define SYMMETRIC 629
#define SYSID 630
#define SYSTEM_P 631
#define TABLE 632
#define TABLES 633
#define TABLESAMPLE 634
#define TABLESPACE 635
#define TEMP 636
#define TEMPLATE 637
#define TEMPORARY 638
#define TEXT_P 639
#define THEN 640
#define TIME 641
#define TIMESTAMP 642
#define TO 643
#define TRAILING 644
#define TRANSACTION 645
#define TRANSFORM 646
#define TREAT 647
#define TRIGGER 648
#define TRIM 649
#define TRUE_P 650
#define TRUNCATE 651
#define TRUSTED 652
#define TYPE_P 653
#define TYPES_P 654
#define UNBOUNDED 655
#define UNCOMMITTED 656
#define UNENCRYPTED 657
#define UNION 658
#define UNIQUE 659
#define UNKNOWN 660
#define UNLISTEN 661
#define UNLOGGED 662
#define UNTIL 663
#define UPDATE 664
#define USER 665
#define USING 666
#define VACUUM 667
#define VALID 668
#define VALIDATE 669
#define VALIDATOR 670
#define VALUE_P 671
#define VALUES 672
#define VARCHAR 673
#define VARIADIC 674
#define VARYING 675
#define VERBOSE 676
#define VERSION_P 677
#define VIEW 678
#define VIEWS 679
#define VOLATILE 680
#define WHEN 681
#define WHERE 682
#define WHITESPACE_P 683
#define WINDOW 684
#define WITH 685
#define WITHIN 686
#define WITHOUT 687
#define WORK 688
#define WRAPPER 689
#define WRITE_P 690
#define XML_P 691
#define XMLATTRIBUTES 692
#define XMLCONCAT 693
#define XMLELEMENT 694
#define XMLEXISTS 695
#define XMLFOREST 696
#define XMLNAMESPACES 697
#define XMLPARSE 698
#define XMLPI 699
#define XMLROOT 700
#define XMLSERIALIZE 701
#define XMLTABLE 702
#define YEAR_P 703
#define YES_P 704
#define ZONE 705
#define NOT_LA 706
#define NULLS_LA 707
#define WITH_LA 708
#define POSTFIXOP 709
#define UMINUS 710




#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 14 "third_party/libpg_query/grammar/grammar.y"
{
	core_YYSTYPE		core_yystype;
	/* these fields must match core_YYSTYPE: */
	int					ival;
	char				*str;
	const char			*keyword;
	const char          *conststr;

	char				chr;
	bool				boolean;
	PGJoinType			jtype;
	PGDropBehavior		dbehavior;
	PGOnCommitAction		oncommit;
	PGList				*list;
	PGNode				*node;
	PGValue				*value;
	PGObjectType			objtype;
	PGTypeName			*typnam;
	PGObjectWithArgs		*objwithargs;
	PGDefElem				*defelt;
	PGSortBy				*sortby;
	PGWindowDef			*windef;
	PGJoinExpr			*jexpr;
	PGIndexElem			*ielem;
	PGAlias				*alias;
	PGRangeVar			*range;
	PGIntoClause			*into;
	PGWithClause			*with;
	PGInferClause			*infer;
	PGOnConflictClause	*onconflict;
	PGAIndices			*aind;
	PGResTarget			*target;
	PGInsertStmt			*istmt;
	PGVariableSetStmt		*vsetstmt;
	PGOverridingKind       override;
	PGSortByDir            sortorder;
	PGSortByNulls          nullorder;
	PGLockClauseStrength lockstrength;
	PGLockWaitPolicy lockwaitpolicy;
	PGSubLinkType subquerytype;
	PGViewCheckOption viewcheckoption;
}
/* Line 1529 of yacc.c.  */
#line 1002 "third_party/libpg_query/grammar/grammar_out.hpp"
	YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif



#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
{
  int first_line;
  int first_column;
  int last_line;
  int last_column;
} YYLTYPE;
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif




/*
 * The YY_EXTRA data that a flex scanner allows us to pass around.  Private
 * state needed for raw parsing/lexing goes here.
 */
typedef struct base_yy_extra_type
{
	/*
	 * Fields used by the core scanner.
	 */
	core_yy_extra_type core_yy_extra;

	/*
	 * State variables for base_yylex().
	 */
	bool		have_lookahead; /* is lookahead info valid? */
	int			lookahead_token;	/* one-token lookahead */
	core_YYSTYPE lookahead_yylval;	/* yylval for lookahead token */
	YYLTYPE		lookahead_yylloc;	/* yylloc for lookahead token */
	char	   *lookahead_end;	/* end of current token */
	char		lookahead_hold_char;	/* to be put back at *lookahead_end */

	/*
	 * State variables that belong to the grammar.
	 */
	PGList	   *parsetree;		/* final parse result is delivered here */
} base_yy_extra_type;

/*
 * In principle we should use yyget_extra() to fetch the yyextra field
 * from a yyscanner struct.  However, flex always puts that field first,
 * and this is sufficiently performance-critical to make it seem worth
 * cheating a bit to use an inline macro.
 */
#define pg_yyget_extra(yyscanner) (*((base_yy_extra_type **) (yyscanner)))


/* from parser.c */
extern int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp,
		   core_yyscan_t yyscanner);

/* from gram.y */
extern void parser_init(base_yy_extra_type *yyext);
extern int	base_yyparse(core_yyscan_t yyscanner);



/*-------------------------------------------------------------------------
 *
 * parse_expr.h
 *	  handle expressions in parser
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/parse_expr.h
 *
 *-------------------------------------------------------------------------
 */


/*-------------------------------------------------------------------------
 *
 * parse_node.h
 *		Internal definitions for parser
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/parse_node.h
 *
 *-------------------------------------------------------------------------
 */





/*
 * Expression kinds distinguished by transformExpr().  Many of these are not
 * semantically distinct so far as expression transformation goes; rather,
 * we distinguish them so that context-specific error messages can be printed.
 *
 * Note: PG_EXPR_KIND_OTHER is not used in the core code, but is left for use
 * by extension code that might need to call transformExpr().  The core code
 * will not enforce any context-driven restrictions on PG_EXPR_KIND_OTHER
 * expressions, so the caller would have to check for sub-selects, aggregates,
 * window functions, SRFs, etc if those need to be disallowed.
 */
typedef enum PGParseExprKind
{
	PG_EXPR_KIND_NONE = 0,			/* "not in an expression" */
	PG_EXPR_KIND_OTHER,			/* reserved for extensions */
	PG_EXPR_KIND_JOIN_ON,			/* JOIN ON */
	PG_EXPR_KIND_JOIN_USING,		/* JOIN USING */
	PG_EXPR_KIND_FROM_SUBSELECT,	/* sub-SELECT in FROM clause */
	PG_EXPR_KIND_FROM_FUNCTION,	/* function in FROM clause */
	PG_EXPR_KIND_WHERE,			/* WHERE */
	PG_EXPR_KIND_HAVING,			/* HAVING */
	PG_EXPR_KIND_FILTER,			/* FILTER */
	PG_EXPR_KIND_WINDOW_PARTITION, /* window definition PARTITION BY */
	PG_EXPR_KIND_WINDOW_ORDER,		/* window definition ORDER BY */
	PG_EXPR_KIND_WINDOW_FRAME_RANGE,	/* window frame clause with RANGE */
	PG_EXPR_KIND_WINDOW_FRAME_ROWS,	/* window frame clause with ROWS */
	PG_EXPR_KIND_SELECT_TARGET,	/* SELECT target list item */
	PG_EXPR_KIND_INSERT_TARGET,	/* INSERT target list item */
	PG_EXPR_KIND_UPDATE_SOURCE,	/* UPDATE assignment source item */
	PG_EXPR_KIND_UPDATE_TARGET,	/* UPDATE assignment target item */
	PG_EXPR_KIND_GROUP_BY,			/* GROUP BY */
	PG_EXPR_KIND_ORDER_BY,			/* ORDER BY */
	PG_EXPR_KIND_DISTINCT_ON,		/* DISTINCT ON */
	PG_EXPR_KIND_LIMIT,			/* LIMIT */
	PG_EXPR_KIND_OFFSET,			/* OFFSET */
	PG_EXPR_KIND_RETURNING,		/* RETURNING */
	PG_EXPR_KIND_VALUES,			/* VALUES */
	PG_EXPR_KIND_VALUES_SINGLE,	/* single-row VALUES (in INSERT only) */
	PG_EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */
	PG_EXPR_KIND_DOMAIN_CHECK,		/* CHECK constraint for a domain */
	PG_EXPR_KIND_COLUMN_DEFAULT,	/* default value for a table column */
	PG_EXPR_KIND_FUNCTION_DEFAULT, /* default parameter value for function */
	PG_EXPR_KIND_INDEX_EXPRESSION, /* index expression */
	PG_EXPR_KIND_INDEX_PREDICATE,	/* index predicate */
	PG_EXPR_KIND_ALTER_COL_TRANSFORM,	/* transform expr in ALTER COLUMN TYPE */
	PG_EXPR_KIND_EXECUTE_PARAMETER,	/* parameter value in EXECUTE */
	PG_EXPR_KIND_TRIGGER_WHEN,		/* WHEN condition in CREATE TRIGGER */
	PG_EXPR_KIND_POLICY,			/* USING or WITH CHECK expr in policy */
	EXPR_KIND_PARTITION_EXPRESSION	/* PARTITION BY expression */
} PGParseExprKind;


/*
 * Function signatures for parser hooks
 */
typedef struct PGParseState ParseState;

typedef PGNode *(*PreParseColumnRefHook) (PGParseState *pstate, PGColumnRef *cref);
typedef PGNode *(*PostParseColumnRefHook) (PGParseState *pstate, PGColumnRef *cref, PGNode *var);
typedef PGNode *(*ParseParamRefHook) (PGParseState *pstate, PGParamRef *pref);
typedef PGNode *(*CoerceParamHook) (PGParseState *pstate, PGParam *param,
								  PGOid targetTypeId, int32_t targetTypeMod,
								  int location);


/*
 * State information used during parse analysis
 *
 * parentParseState: NULL in a top-level ParseState.  When parsing a subquery,
 * links to current parse state of outer query.
 *
 * p_sourcetext: source string that generated the raw parsetree being
 * analyzed, or NULL if not available.  (The string is used only to
 * generate cursor positions in error messages: we need it to convert
 * byte-wise locations in parse structures to character-wise cursor
 * positions.)
 *
 * p_rtable: list of RTEs that will become the rangetable of the query.
 * Note that neither relname nor refname of these entries are necessarily
 * unique; searching the rtable by name is a bad idea.
 *
 * p_joinexprs: list of PGJoinExpr nodes associated with p_rtable entries.
 * This is one-for-one with p_rtable, but contains NULLs for non-join
 * RTEs, and may be shorter than p_rtable if the last RTE(s) aren't joins.
 *
 * p_joinlist: list of join items (PGRangeTblRef and PGJoinExpr nodes) that
 * will become the fromlist of the query's top-level PGFromExpr node.
 *
 * p_namespace: list of ParseNamespaceItems that represents the current
 * namespace for table and column lookup.  (The RTEs listed here may be just
 * a subset of the whole rtable.  See PGParseNamespaceItem comments below.)
 *
 * p_lateral_active: true if we are currently parsing a LATERAL subexpression
 * of this parse level.  This makes p_lateral_only namespace items visible,
 * whereas they are not visible when p_lateral_active is false.
 *
 * p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
 * at the moment.  This is entirely different from p_namespace because a CTE
 * is not an RTE, rather "visibility" means you could make an RTE from it.
 *
 * p_future_ctes: list of CommonTableExprs (WITH items) that are not yet
 * visible due to scope rules.  This is used to help improve error messages.
 *
 * p_parent_cte: PGCommonTableExpr that immediately contains the current query,
 * if any.
 *
 * p_target_relation: target relation, if query is INSERT, UPDATE, or DELETE.
 *
 * p_target_rangetblentry: target relation's entry in the rtable list.
 *
 * p_is_insert: true to process assignment expressions like INSERT, false
 * to process them like UPDATE.  (Note this can change intra-statement, for
 * cases like INSERT ON CONFLICT UPDATE.)
 *
 * p_windowdefs: list of WindowDefs representing WINDOW and OVER clauses.
 * We collect these while transforming expressions and then transform them
 * afterwards (so that any resjunk tlist items needed for the sort/group
 * clauses end up at the end of the query tlist).  A WindowDef's location in
 * this list, counting from 1, is the winref number to use to reference it.
 *
 * p_expr_kind: kind of expression we're currently parsing, as per enum above;
 * PG_EXPR_KIND_NONE when not in an expression.
 *
 * p_next_resno: next TargetEntry.resno to assign, starting from 1.
 *
 * p_multiassign_exprs: partially-processed PGMultiAssignRef source expressions.
 *
 * p_locking_clause: query's FOR UPDATE/FOR SHARE clause, if any.
 *
 * p_locked_from_parent: true if parent query level applies FOR UPDATE/SHARE
 * to this subquery as a whole.
 *
 * p_resolve_unknowns: resolve unknown-type SELECT output columns as type TEXT
 * (this is true by default).
 *
 * p_hasAggs, p_hasWindowFuncs, etc: true if we've found any of the indicated
 * constructs in the query.
 *
 * p_last_srf: the set-returning PGFuncExpr or PGOpExpr most recently found in
 * the query, or NULL if none.
 *
 * p_pre_columnref_hook, etc: optional parser hook functions for modifying the
 * interpretation of ColumnRefs and ParamRefs.
 *
 * p_ref_hook_state: passthrough state for the parser hook functions.
 */
struct PGParseState
{
	struct PGParseState *parentParseState;	/* stack link */
	const char *p_sourcetext;	/* source text, or NULL if not available */
	PGList	   *p_rtable;		/* range table so far */
	PGList	   *p_joinexprs;	/* JoinExprs for PG_RTE_JOIN p_rtable entries */
	PGList	   *p_joinlist;		/* join items so far (will become PGFromExpr
								 * node's fromlist) */
	PGList	   *p_namespace;	/* currently-referenceable RTEs (PGList of
								 * PGParseNamespaceItem) */
	bool		p_lateral_active;	/* p_lateral_only items visible? */
	PGList	   *p_ctenamespace; /* current namespace for common table exprs */
	PGList	   *p_future_ctes;	/* common table exprs not yet in namespace */
	PGCommonTableExpr *p_parent_cte;	/* this query's containing CTE */
	void*	p_target_relation;	/* INSERT/UPDATE/DELETE target rel */
	PGRangeTblEntry *p_target_rangetblentry;	/* target rel's RTE */
	bool		p_is_insert;	/* process assignment like INSERT not UPDATE */
	PGList	   *p_windowdefs;	/* raw representations of window clauses */
	PGParseExprKind p_expr_kind;	/* what kind of expression we're parsing */
	int			p_next_resno;	/* next targetlist resno to assign */
	PGList	   *p_multiassign_exprs;	/* junk tlist entries for multiassign */
	PGList	   *p_locking_clause;	/* raw FOR UPDATE/FOR SHARE info */
	bool		p_locked_from_parent;	/* parent has marked this subquery
										 * with FOR UPDATE/FOR SHARE */
	bool		p_resolve_unknowns; /* resolve unknown-type SELECT outputs as
									 * type text */

	void *p_queryEnv;	/* curr env, incl refs to enclosing env */

	/* Flags telling about things found in the query: */
	bool		p_hasAggs;
	bool		p_hasWindowFuncs;
	bool		p_hasTargetSRFs;
	bool		p_hasSubLinks;
	bool		p_hasModifyingCTE;

	PGNode	   *p_last_srf;		/* most recent set-returning func/op found */

	/*
	 * Optional hook functions for parser callbacks.  These are null unless
	 * set up by the caller of make_parsestate.
	 */
	PreParseColumnRefHook p_pre_columnref_hook;
	PostParseColumnRefHook p_post_columnref_hook;
	ParseParamRefHook p_paramref_hook;
	CoerceParamHook p_coerce_param_hook;
	void	   *p_ref_hook_state;	/* common passthrough link for above */
};

/*
 * An element of a namespace list.
 *
 * Namespace items with p_rel_visible set define which RTEs are accessible by
 * qualified names, while those with p_cols_visible set define which RTEs are
 * accessible by unqualified names.  These sets are different because a JOIN
 * without an alias does not hide the contained tables (so they must be
 * visible for qualified references) but it does hide their columns
 * (unqualified references to the columns refer to the JOIN, not the member
 * tables, so we must not complain that such a reference is ambiguous).
 * Various special RTEs such as NEW/OLD for rules may also appear with only
 * one flag set.
 *
 * While processing the FROM clause, namespace items may appear with
 * p_lateral_only set, meaning they are visible only to LATERAL
 * subexpressions.  (The pstate's p_lateral_active flag tells whether we are
 * inside such a subexpression at the moment.)	If p_lateral_ok is not set,
 * it's an error to actually use such a namespace item.  One might think it
 * would be better to just exclude such items from visibility, but the wording
 * of SQL:2008 requires us to do it this way.  We also use p_lateral_ok to
 * forbid LATERAL references to an UPDATE/DELETE target table.
 *
 * At no time should a namespace list contain two entries that conflict
 * according to the rules in checkNameSpaceConflicts; but note that those
 * are more complicated than "must have different alias names", so in practice
 * code searching a namespace list has to check for ambiguous references.
 */
typedef struct PGParseNamespaceItem
{
	PGRangeTblEntry *p_rte;		/* The relation's rangetable entry */
	bool		p_rel_visible;	/* Relation name is visible? */
	bool		p_cols_visible; /* Column names visible as unqualified refs? */
	bool		p_lateral_only; /* Is only visible to LATERAL expressions? */
	bool		p_lateral_ok;	/* If so, does join type allow use? */
} PGParseNamespaceItem;

/* Support for parser_errposition_callback function */
typedef struct PGParseCallbackState
{
	PGParseState *pstate;
	int			location;
	void* errcallback;
} PGParseCallbackState;


extern PGParseState *make_parsestate(PGParseState *parentParseState);
extern void free_parsestate(PGParseState *pstate);
extern int	parser_errposition(PGParseState *pstate, int location);

extern void setup_parser_errposition_callback(PGParseCallbackState *pcbstate,
								  PGParseState *pstate, int location);
extern void cancel_parser_errposition_callback(PGParseCallbackState *pcbstate);

extern PGVar *make_var(PGParseState *pstate, PGRangeTblEntry *rte, int attrno,
		 int location);
extern PGOid	transformArrayType(PGOid *arrayType, int32_t *arrayTypmod);
extern PGArrayRef *transformArraySubscripts(PGParseState *pstate,
						 PGNode *arrayBase,
						 PGOid arrayType,
						 PGOid elementType,
						 int32_t arrayTypMod,
						 PGList *indirection,
						 PGNode *assignFrom);
extern PGConst *make_const(PGParseState *pstate, PGValue *value, int location);


/* GUC parameters */
//extern __thread  bool operator_precedence_warning;
extern bool Transform_null_equals;

extern PGNode *transformExpr(PGParseState *pstate, PGNode *expr, PGParseExprKind exprKind);

extern const char *ParseExprKindName(PGParseExprKind exprKind);

/*-------------------------------------------------------------------------
 *
 * datetime.h
 *	  Definitions for date/time support code.
 *	  The support code is shared with other date data types,
 *	   including abstime, reltime, date, and time.
 *
 *
 * Portions Copyright (c) 1996-2015, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/utils/datetime.h
 *
 *-------------------------------------------------------------------------
 */



/*-------------------------------------------------------------------------
 *
 * timestamp.h
 *	  Definitions for the SQL "timestamp" and "interval" types.
 *
 * Portions Copyright (c) 1996-2015, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/utils/timestamp.h
 *
 *-------------------------------------------------------------------------
 */


/*-------------------------------------------------------------------------
 *
 * timestamp.h
 *	  PGTimestamp and PGInterval typedefs and related macros.
 *
 * Note: this file must be includable in both frontend and backend contexts.
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/datatype/timestamp.h
 *
 *-------------------------------------------------------------------------
 */


#include <cstdint>

/*
 * PGTimestamp represents absolute time.
 *
 * PGInterval represents delta time. Keep track of months (and years), days,
 * and hours/minutes/seconds separately since the elapsed time spanned is
 * unknown until instantiated relative to an absolute time.
 *
 * Note that Postgres uses "time interval" to mean a bounded interval,
 * consisting of a beginning and ending time, not a time span - thomas 97/03/20
 *
 * Timestamps, as well as the h/m/s fields of intervals, are stored as
 * int64_t values with units of microseconds.  (Once upon a time they were
 * double values with units of seconds.)
 *
 * PGTimeOffset and pg_fsec_t are convenience typedefs for temporary variables.
 * Do not use pg_fsec_t in values stored on-disk.
 * Also, pg_fsec_t is only meant for *fractional* seconds; beware of overflow
 * if the value you need to store could be many seconds.
 */

typedef int64_t PGTimestamp;
typedef int64_t PGTimestampTz;
typedef int64_t PGTimeOffset;
typedef int32_t pg_fsec_t;			/* fractional seconds (in microseconds) */

typedef struct
{
	PGTimeOffset	time;			/* all time units other than days, months and
								 * years */
	int32_t		day;			/* days, after time for alignment */
	int32_t		month;			/* months and years, after time for alignment */
} PGInterval;


/*-------------------------------------------------------------------------
 *
 * pgtime.h
 *	  PostgreSQL internal timezone library
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 *
 * IDENTIFICATION
 *	  src/include/pgtime.h
 *
 *-------------------------------------------------------------------------
 */


#include <cstdint>

/*
 * The API of this library is generally similar to the corresponding
 * C library functions, except that we use pg_time_t which (we hope) is
 * 64 bits wide, and which is most definitely signed not unsigned.
 */

typedef int64_t pg_time_t;

struct pg_tm
{
	int			tm_sec;
	int			tm_min;
	int			tm_hour;
	int			tm_mday;
	int			tm_mon;			/* origin 1, not 0! */
	int			tm_year;		/* relative to 1900 */
	int			tm_wday;
	int			tm_yday;
	int			tm_isdst;
	long int	tm_gmtoff;
	const char *tm_zone;
};

typedef struct pg_tz pg_tz;
typedef struct pg_tzenum pg_tzenum;

/* Maximum length of a timezone name (not including trailing null) */
#define TZ_STRLEN_MAX 255

/* these functions are in localtime.c */

extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz);
extern struct pg_tm *pg_gmtime(const pg_time_t *timep);
extern int pg_next_dst_boundary(const pg_time_t *timep,
					 long int *before_gmtoff,
					 int *before_isdst,
					 pg_time_t *boundary,
					 long int *after_gmtoff,
					 int *after_isdst,
					 const pg_tz *tz);
extern bool pg_interpret_timezone_abbrev(const char *abbrev,
							 const pg_time_t *timep,
							 long int *gmtoff,
							 int *isdst,
							 const pg_tz *tz);
extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff);
extern const char *pg_get_timezone_name(pg_tz *tz);
extern bool pg_tz_acceptable(pg_tz *tz);

/* these functions and variables are in pgtz.c */

extern pg_tz *session_timezone;
extern pg_tz *log_timezone;

extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
extern pg_tz *pg_tzset_offset(long gmtoffset);

extern pg_tzenum *pg_tzenumerate_start(void);
extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir);
extern void pg_tzenumerate_end(pg_tzenum *dir);


/* Macros to handle packing and unpacking the typmod field for intervals */
#define INTERVAL_FULL_RANGE (0x7FFF)
#define INTERVAL_RANGE_MASK (0x7FFF)
#define INTERVAL_FULL_PRECISION (0xFFFF)
#define INTERVAL_PRECISION_MASK (0xFFFF)
#define INTERVAL_TYPMOD(p,r) ((((r) & INTERVAL_RANGE_MASK) << 16) | ((p) & INTERVAL_PRECISION_MASK))
#define INTERVAL_PRECISION(t) ((t) & INTERVAL_PRECISION_MASK)
#define INTERVAL_RANGE(t) (((t) >> 16) & INTERVAL_RANGE_MASK)



/*
 * Field types for time decoding.
 *
 * Can't have more of these than there are bits in an unsigned int
 * since these are turned into bit masks during parsing and decoding.
 *
 * Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
 * must be in the range 0..14 so that the associated bitmasks can fit
 * into the left half of an INTERVAL's typmod value.  Since those bits
 * are stored in typmods, you can't change them without initdb!
 */

#define RESERV	0
#define MONTH	1
#define YEAR	2
#define DAY		3
#define JULIAN	4
#define TZ		5				/* fixed-offset timezone abbreviation */
#define DTZ		6				/* fixed-offset timezone abbrev, DST */
#define DYNTZ	7				/* dynamic timezone abbreviation */
#define IGNORE_DTF	8
#define AMPM	9
#define HOUR	10
#define MINUTE	11
#define SECOND	12
#define MILLISECOND 13
#define MICROSECOND 14
#define DOY		15
#define DOW		16
#define UNITS	17
#define ADBC	18
/* these are only for relative dates */
#define AGO		19
#define ABS_BEFORE		20
#define ABS_AFTER		21
/* generic fields to help with parsing */
#define ISODATE 22
#define ISOTIME 23
/* these are only for parsing intervals */
#define WEEK		24
#define DECADE		25
#define CENTURY		26
#define MILLENNIUM	27
/* hack for parsing two-word timezone specs "MET DST" etc */
#define DTZMOD	28				/* "DST" as a separate word */
/* reserved for unrecognized string values */
#define UNKNOWN_FIELD	31




#define DEFAULT_SCHEMA "main"

/*
 * Location tracking support --- simpler than bison's default, since we only
 * want to track the start position not the end position of each nonterminal.
 */
#define YYLLOC_DEFAULT(Current, Rhs, N) \
	do { \
		if ((N) > 0) \
			(Current) = (Rhs)[1]; \
		else \
			(Current) = (-1); \
	} while (0)

/*
 * The above macro assigns -1 (unknown) as the parse location of any
 * nonterminal that was reduced from an empty rule, or whose leftmost
 * component was reduced from an empty rule.  This is problematic
 * for nonterminals defined like
 *		OptFooList: / * EMPTY * / { ... } | OptFooList Foo { ... } ;
 * because we'll set -1 as the location during the first reduction and then
 * copy it during each subsequent reduction, leaving us with -1 for the
 * location even when the list is not empty.  To fix that, do this in the
 * action for the nonempty rule(s):
 *		if (@$ < 0) @$ = @2;
 * (Although we have many nonterminals that follow this pattern, we only
 * bother with fixing @$ like this when the nonterminal's parse location
 * is actually referenced in some rule.)
 *
 * A cleaner answer would be to make YYLLOC_DEFAULT scan all the Rhs
 * locations until it's found one that's not -1.  Then we'd get a correct
 * location for any nonterminal that isn't entirely empty.  But this way
 * would add overhead to every rule reduction, and so far there's not been
 * a compelling reason to pay that overhead.
 */

/*
 * Bison doesn't allocate anything that needs to live across parser calls,
 * so we can easily have it use palloc instead of malloc.  This prevents
 * memory leaks if we error out during parsing.  Note this only works with
 * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
 * if possible, so there's not really much problem anyhow, at least if
 * you're building with gcc.
 */
#define YYMALLOC palloc
#define YYFREE   pfree
#define YYINITDEPTH 1000

/* yields an integer bitmask of these flags: */
#define CAS_NOT_DEFERRABLE			0x01
#define CAS_DEFERRABLE				0x02
#define CAS_INITIALLY_IMMEDIATE		0x04
#define CAS_INITIALLY_DEFERRED		0x08
#define CAS_NOT_VALID				0x10
#define CAS_NO_INHERIT				0x20


#define parser_yyerror(msg)  scanner_yyerror(msg, yyscanner)
#define parser_errposition(pos)  scanner_errposition(pos, yyscanner)

static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
						 const char *msg);
static PGRawStmt *makeRawStmt(PGNode *stmt, int stmt_location);
static void updateRawStmtEnd(PGRawStmt *rs, int end_location);
static PGNode *makeColumnRef(char *colname, PGList *indirection,
						   int location, core_yyscan_t yyscanner);
static PGNode *makeTypeCast(PGNode *arg, PGTypeName *tpname, int location);
static PGNode *makeStringConst(char *str, int location);
static PGNode *makeStringConstCast(char *str, int location, PGTypeName *tpname);
static PGNode *makeIntConst(int val, int location);
static PGNode *makeFloatConst(char *str, int location);
static PGNode *makeBitStringConst(char *str, int location);
static PGNode *makeNullAConst(int location);
static PGNode *makeAConst(PGValue *v, int location);
static PGNode *makeBoolAConst(bool state, int location);
static PGNode *makeParamRef(int number, int location);
static PGNode *makeParamRefCast(int number, int location, PGTypeName *tpname);
static void check_qualified_name(PGList *names, core_yyscan_t yyscanner);
static PGList *check_func_name(PGList *names, core_yyscan_t yyscanner);
static PGList *check_indirection(PGList *indirection, core_yyscan_t yyscanner);
static void insertSelectOptions(PGSelectStmt *stmt,
								PGList *sortClause, PGList *lockingClause,
								PGNode *limitOffset, PGNode *limitCount,
								PGWithClause *withClause,
								core_yyscan_t yyscanner);
static PGNode *makeSetOp(PGSetOperation op, bool all, PGNode *larg, PGNode *rarg);
static PGNode *doNegate(PGNode *n, int location);
static void doNegateFloat(PGValue *v);
static PGNode *makeAndExpr(PGNode *lexpr, PGNode *rexpr, int location);
static PGNode *makeOrExpr(PGNode *lexpr, PGNode *rexpr, int location);
static PGNode *makeNotExpr(PGNode *expr, int location);
static PGNode *makeSQLValueFunction(PGSQLValueFunctionOp op, int32_t typmod,
								  int location);
static void SplitColQualList(PGList *qualList,
							 PGList **constraintList, PGCollateClause **collClause,
							 core_yyscan_t yyscanner);
static void processCASbits(int cas_bits, int location, const char *constrType,
			   bool *deferrable, bool *initdeferred, bool *not_valid,
			   bool *no_inherit, core_yyscan_t yyscanner);
static PGNode *makeRecursiveViewSelect(char *relname, PGList *aliases, PGNode *query);



/* Enabling traces.  */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif

/* Enabling verbose error messages.  */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 0
#endif

/* Enabling the token table.  */
#ifndef YYTOKEN_TABLE
# define YYTOKEN_TABLE 0
#endif

#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 14 "third_party/libpg_query/grammar/grammar.y"
{
	core_YYSTYPE		core_yystype;
	/* these fields must match core_YYSTYPE: */
	int					ival;
	char				*str;
	const char			*keyword;
	const char          *conststr;

	char				chr;
	bool				boolean;
	PGJoinType			jtype;
	PGDropBehavior		dbehavior;
	PGOnCommitAction		oncommit;
	PGList				*list;
	PGNode				*node;
	PGValue				*value;
	PGObjectType			objtype;
	PGTypeName			*typnam;
	PGObjectWithArgs		*objwithargs;
	PGDefElem				*defelt;
	PGSortBy				*sortby;
	PGWindowDef			*windef;
	PGJoinExpr			*jexpr;
	PGIndexElem			*ielem;
	PGAlias				*alias;
	PGRangeVar			*range;
	PGIntoClause			*into;
	PGWithClause			*with;
	PGInferClause			*infer;
	PGOnConflictClause	*onconflict;
	PGAIndices			*aind;
	PGResTarget			*target;
	PGInsertStmt			*istmt;
	PGVariableSetStmt		*vsetstmt;
	PGOverridingKind       override;
	PGSortByDir            sortorder;
	PGSortByNulls          nullorder;
	PGLockClauseStrength lockstrength;
	PGLockWaitPolicy lockwaitpolicy;
	PGSubLinkType subquerytype;
	PGViewCheckOption viewcheckoption;
}
/* Line 193 of yacc.c.  */
#line 1218 "third_party/libpg_query/grammar/grammar_out.cpp"
	YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif

#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
{
  int first_line;
  int first_column;
  int last_line;
  int last_column;
} YYLTYPE;
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif


/* Copy the second part of user declarations.  */


/* Line 216 of yacc.c.  */
#line 1243 "third_party/libpg_query/grammar/grammar_out.cpp"

#ifdef short
# undef short
#endif

#ifdef YYTYPE_UINT8
typedef YYTYPE_UINT8 yytype_uint8;
#else
typedef unsigned char yytype_uint8;
#endif

#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
#elif (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
typedef signed char yytype_int8;
#else
typedef short int yytype_int8;
#endif

#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
typedef unsigned short int yytype_uint16;
#endif

#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
typedef short int yytype_int16;
#endif

#ifndef YYSIZE_T
# ifdef __SIZE_TYPE__
#  define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
#  define YYSIZE_T size_t
# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
#  define YYSIZE_T size_t
# else
#  define YYSIZE_T unsigned int
# endif
#endif

#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)

#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
#  if ENABLE_NLS
#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
#   define YY_(msgid) dgettext ("bison-runtime", msgid)
#  endif
# endif
# ifndef YY_
#  define YY_(msgid) msgid
# endif
#endif

/* Suppress unused-variable warnings by "using" E.  */
#if ! defined lint || defined __GNUC__
# define YYUSE(e) ((void) (e))
#else
# define YYUSE(e) /* empty */
#endif

/* Identity function, used to suppress warnings about constant conditions.  */
#ifndef lint
# define YYID(n) (n)
#else
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static int
YYID (int i)
#else
static int
YYID (i)
    int i;
#endif
{
  return i;
}
#endif

#if ! defined yyoverflow || YYERROR_VERBOSE

/* The parser invokes alloca or malloc; define the necessary symbols.  */

# ifdef YYSTACK_USE_ALLOCA
#  if YYSTACK_USE_ALLOCA
#   ifdef __GNUC__
#    define YYSTACK_ALLOC __builtin_alloca
#   elif defined __BUILTIN_VA_ARG_INCR
#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
#   elif defined _AIX
#    define YYSTACK_ALLOC __alloca
#   elif defined _MSC_VER
#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
#    define alloca _alloca
#   else
#    define YYSTACK_ALLOC alloca
#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
#     ifndef _STDLIB_H
#      define _STDLIB_H 1
#     endif
#    endif
#   endif
#  endif
# endif

# ifdef YYSTACK_ALLOC
   /* Pacify GCC's `empty if-body' warning.  */
#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
#  ifndef YYSTACK_ALLOC_MAXIMUM
    /* The OS might guarantee only one guard page at the bottom of the stack,
       and a page size can be as small as 4096 bytes.  So we cannot safely
       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
       to allow for a few compiler-allocated temporary stack slots.  */
#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
#  endif
# else
#  define YYSTACK_ALLOC YYMALLOC
#  define YYSTACK_FREE YYFREE
#  ifndef YYSTACK_ALLOC_MAXIMUM
#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
#  endif
#  if (defined __cplusplus && ! defined _STDLIB_H \
       && ! ((defined YYMALLOC || defined malloc) \
	     && (defined YYFREE || defined free)))
#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
#   ifndef _STDLIB_H
#    define _STDLIB_H 1
#   endif
#  endif
#  ifndef YYMALLOC
#   define YYMALLOC malloc
#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
#   endif
#  endif
#  ifndef YYFREE
#   define YYFREE free
#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
#   endif
#  endif
# endif
#endif /* ! defined yyoverflow || YYERROR_VERBOSE */


#if (! defined yyoverflow \
     && (! defined __cplusplus \
	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))

/* A type that is properly aligned for any stack member.  */
union yyalloc
{
  yytype_int16 yyss;
  YYSTYPE yyvs;
    YYLTYPE yyls;
};

/* The size of the maximum gap between one aligned stack and the next.  */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)

/* The size of an array large to enough to hold all stacks, each with
   N elements.  */
# define YYSTACK_BYTES(N) \
     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
      + 2 * YYSTACK_GAP_MAXIMUM)

/* Copy COUNT objects from FROM to TO.  The source and destination do
   not overlap.  */
# ifndef YYCOPY
#  if defined __GNUC__ && 1 < __GNUC__
#   define YYCOPY(To, From, Count) \
      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
#  else
#   define YYCOPY(To, From, Count)		\
      do					\
	{					\
	  YYSIZE_T yyi;				\
	  for (yyi = 0; yyi < (Count); yyi++)	\
	    (To)[yyi] = (From)[yyi];		\
	}					\
      while (YYID (0))
#  endif
# endif

/* Relocate STACK from its old location to the new one.  The
   local variables YYSIZE and YYSTACKSIZE give the old and new number of
   elements in the stack, and YYPTR gives the new location of the
   stack.  Advance YYPTR to a properly aligned location for the next
   stack.  */
# define YYSTACK_RELOCATE(Stack)					\
    do									\
      {									\
	YYSIZE_T yynewbytes;						\
	YYCOPY (&yyptr->Stack, Stack, yysize);				\
	Stack = &yyptr->Stack;						\
	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
	yyptr += yynewbytes / sizeof (*yyptr);				\
      }									\
    while (YYID (0))

#endif

/* YYFINAL -- State number of the termination state.  */
#define YYFINAL  512
/* YYLAST -- Last index in YYTABLE.  */
#define YYLAST   43953

/* YYNTOKENS -- Number of terminals.  */
#define YYNTOKENS  474
/* YYNNTS -- Number of nonterminals.  */
#define YYNNTS  337
/* YYNRULES -- Number of rules.  */
#define YYNRULES  1548
/* YYNRULES -- Number of states.  */
#define YYNSTATES  2593

/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
#define YYUNDEFTOK  2
#define YYMAXUTOK   710

#define YYTRANSLATE(YYX)						\
  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)

/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
static const yytype_uint16 yytranslate[] =
{
       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,   462,     2,     2,
     467,   468,   460,   458,   471,   459,   469,   461,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,   473,   470,
     454,   456,   455,   472,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,   465,     2,   466,   463,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,
     125,   126,   127,   128,   129,   130,   131,   132,   133,   134,
     135,   136,   137,   138,   139,   140,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,   152,   153,   154,
     155,   156,   157,   158,   159,   160,   161,   162,   163,   164,
     165,   166,   167,   168,   169,   170,   171,   172,   173,   174,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
     195,   196,   197,   198,   199,   200,   201,   202,   203,   204,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
     215,   216,   217,   218,   219,   220,   221,   222,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,   263,   264,
     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
     385,   386,   387,   388,   389,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,   403,   404,
     405,   406,   407,   408,   409,   410,   411,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,   426,   427,   428,   429,   430,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,   452,   453,   457,
     464
};

#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
   YYRHS.  */
static const yytype_uint16 yyprhs[] =
{
       0,     0,     3,     5,     9,    11,    13,    15,    17,    19,
      21,    23,    25,    27,    29,    31,    33,    35,    37,    39,
      41,    43,    45,    47,    49,    51,    53,    55,    57,    59,
      61,    63,    65,    67,    69,    70,    75,    82,    87,    94,
      99,   106,   111,   118,   120,   123,   127,   130,   132,   136,
     139,   143,   145,   149,   152,   158,   162,   169,   174,   181,
     188,   195,   201,   207,   214,   224,   229,   235,   243,   250,
     255,   264,   269,   272,   277,   281,   288,   293,   296,   299,
     302,   305,   307,   310,   311,   313,   316,   319,   322,   324,
     328,   333,   336,   337,   340,   344,   347,   351,   358,   365,
     374,   381,   390,   397,   406,   413,   422,   431,   442,   451,
     462,   464,   465,   473,   475,   480,   485,   493,   496,   498,
     502,   507,   511,   512,   514,   515,   518,   522,   528,   537,
     543,   544,   550,   556,   564,   567,   568,   570,   572,   574,
     578,   581,   582,   584,   585,   587,   591,   593,   597,   599,
     603,   606,   609,   614,   620,   626,   635,   637,   638,   642,
     652,   665,   669,   670,   675,   682,   684,   687,   689,   691,
     692,   694,   697,   700,   702,   705,   708,   710,   713,   717,
     720,   723,   726,   729,   733,   737,   741,   743,   747,   749,
     750,   752,   755,   758,   761,   764,   767,   770,   773,   776,
     778,   780,   781,   791,   804,   805,   808,   810,   812,   814,
     816,   818,   820,   824,   825,   827,   830,   832,   834,   837,
     840,   844,   846,   848,   851,   854,   856,   859,   863,   869,
     872,   878,   884,   887,   891,   893,   895,   898,   901,   902,
     907,   908,   912,   917,   922,   923,   927,   930,   931,   935,
     937,   939,   941,   943,   945,   947,   949,   951,   953,   955,
     959,   963,   965,   968,   971,   974,   977,   980,   983,   984,
     988,   992,   996,   997,   999,  1002,  1004,  1007,  1010,  1013,
    1016,  1021,  1023,  1027,  1029,  1033,  1035,  1037,  1039,  1041,
    1045,  1047,  1050,  1051,  1053,  1054,  1056,  1060,  1061,  1064,
    1065,  1069,  1073,  1075,  1081,  1085,  1087,  1091,  1093,  1098,
    1104,  1110,  1117,  1121,  1129,  1134,  1146,  1148,  1152,  1155,
    1158,  1161,  1162,  1166,  1168,  1170,  1173,  1176,  1179,  1182,
    1184,  1185,  1187,  1190,  1197,  1202,  1209,  1214,  1221,  1230,
    1232,  1234,  1236,  1239,  1241,  1244,  1246,  1248,  1250,  1254,
    1258,  1262,  1266,  1269,  1272,  1274,  1278,  1280,  1282,  1284,
    1286,  1290,  1292,  1294,  1295,  1297,  1299,  1301,  1310,  1322,
    1332,  1334,  1336,  1340,  1341,  1343,  1347,  1349,  1350,  1352,
    1353,  1355,  1356,  1358,  1362,  1364,  1366,  1368,  1372,  1373,
    1376,  1379,  1380,  1383,  1384,  1386,  1387,  1389,  1391,  1393,
    1397,  1401,  1403,  1405,  1409,  1413,  1417,  1421,  1426,  1430,
    1433,  1435,  1437,  1439,  1441,  1443,  1447,  1449,  1451,  1455,
    1459,  1461,  1464,  1469,  1474,  1477,  1481,  1487,  1493,  1495,
    1497,  1507,  1517,  1519,  1522,  1527,  1532,  1537,  1540,  1543,
    1547,  1549,  1553,  1560,  1563,  1564,  1568,  1572,  1577,  1582,
    1587,  1592,  1596,  1599,  1601,  1603,  1604,  1606,  1608,  1609,
    1611,  1617,  1619,  1620,  1622,  1623,  1627,  1629,  1633,  1638,
    1642,  1644,  1646,  1647,  1650,  1653,  1654,  1657,  1660,  1662,
    1664,  1666,  1667,  1670,  1675,  1681,  1686,  1689,  1693,  1695,
    1697,  1699,  1701,  1704,  1707,  1709,  1711,  1713,  1715,  1717,
    1719,  1723,  1724,  1726,  1730,  1732,  1734,  1737,  1740,  1741,
    1743,  1747,  1749,  1750,  1752,  1755,  1759,  1762,  1767,  1770,
    1774,  1777,  1778,  1780,  1783,  1784,  1789,  1795,  1798,  1799,
    1801,  1805,  1808,  1812,  1815,  1819,  1822,  1826,  1828,  1833,
    1837,  1842,  1848,  1853,  1859,  1864,  1870,  1873,  1878,  1880,
    1882,  1883,  1885,  1890,  1896,  1901,  1902,  1905,  1908,  1911,
    1913,  1915,  1916,  1921,  1924,  1926,  1929,  1932,  1937,  1944,
    1949,  1950,  1953,  1960,  1963,  1965,  1969,  1974,  1975,  1978,
    1979,  1982,  1983,  1985,  1989,  1993,  1996,  1997,  2000,  2004,
    2010,  2017,  2020,  2024,  2028,  2033,  2034,  2036,  2038,  2040,
    2042,  2044,  2047,  2052,  2054,  2056,  2058,  2060,  2063,  2067,
    2071,  2072,  2074,  2076,  2078,  2080,  2082,  2085,  2088,  2091,
    2094,  2097,  2099,  2103,  2104,  2106,  2108,  2110,  2112,  2118,
    2121,  2123,  2125,  2127,  2129,  2134,  2136,  2139,  2142,  2144,
    2148,  2152,  2155,  2157,  2158,  2164,  2167,  2173,  2176,  2178,
    2182,  2186,  2187,  2189,  2191,  2193,  2195,  2197,  2199,  2203,
    2207,  2211,  2215,  2219,  2223,  2227,  2228,  2230,  2235,  2237,
    2241,  2245,  2251,  2254,  2257,  2261,  2265,  2269,  2273,  2277,
    2281,  2285,  2289,  2293,  2297,  2301,  2305,  2309,  2312,  2315,
    2319,  2323,  2326,  2329,  2333,  2339,  2344,  2351,  2355,  2361,
    2366,  2373,  2378,  2385,  2391,  2399,  2403,  2406,  2411,  2415,
    2418,  2422,  2426,  2431,  2435,  2440,  2444,  2449,  2455,  2462,
    2469,  2477,  2484,  2492,  2499,  2507,  2511,  2516,  2521,  2528,
    2530,  2532,  2536,  2539,  2542,  2546,  2550,  2554,  2558,  2562,
    2566,  2570,  2574,  2578,  2582,  2586,  2590,  2594,  2597,  2600,
    2606,  2613,  2620,  2628,  2630,  2632,  2635,  2638,  2643,  2645,
    2647,  2649,  2652,  2655,  2659,  2665,  2672,  2681,  2688,  2695,
    2700,  2705,  2707,  2709,  2711,  2717,  2719,  2721,  2726,  2728,
    2733,  2735,  2740,  2742,  2747,  2749,  2751,  2753,  2755,  2757,
    2759,  2766,  2771,  2776,  2781,  2786,  2793,  2799,  2805,  2811,
    2816,  2823,  2828,  2833,  2838,  2844,  2845,  2851,  2852,  2855,
    2856,  2858,  2862,  2866,  2869,  2872,  2873,  2880,  2882,  2883,
    2887,  2888,  2891,  2894,  2895,  2897,  2902,  2905,  2908,  2911,
    2914,  2917,  2922,  2926,  2932,  2934,  2936,  2938,  2940,  2942,
    2944,  2946,  2948,  2950,  2952,  2954,  2956,  2958,  2960,  2962,
    2964,  2966,  2968,  2973,  2975,  2980,  2982,  2987,  2989,  2992,
    2994,  2997,  2999,  3003,  3005,  3009,  3011,  3015,  3017,  3021,
    3025,  3027,  3031,  3035,  3036,  3038,  3040,  3042,  3044,  3046,
    3048,  3050,  3052,  3057,  3061,  3064,  3068,  3069,  3073,  3077,
    3080,  3083,  3085,  3086,  3089,  3092,  3096,  3099,  3101,  3103,
    3107,  3113,  3115,  3118,  3123,  3126,  3127,  3129,  3130,  3132,
    3135,  3138,  3141,  3145,  3151,  3153,  3154,  3156,  3159,  3160,
    3163,  3165,  3166,  3168,  3169,  3171,  3175,  3179,  3182,  3184,
    3186,  3188,  3192,  3194,  3197,  3199,  3203,  3205,  3207,  3209,
    3212,  3214,  3216,  3218,  3220,  3222,  3225,  3232,  3235,  3239,
    3245,  3252,  3254,  3256,  3258,  3260,  3262,  3264,  3266,  3268,
    3270,  3272,  3274,  3276,  3279,  3282,  3286,  3290,  3291,  3293,
    3295,  3297,  3299,  3301,  3303,  3309,  3313,  3314,  3316,  3318,
    3320,  3322,  3327,  3335,  3338,  3339,  3341,  3343,  3345,  3347,
    3361,  3378,  3380,  3383,  3384,  3386,  3387,  3389,  3390,  3393,
    3394,  3396,  3397,  3404,  3413,  3420,  3429,  3436,  3445,  3447,
    3450,  3455,  3459,  3465,  3467,  3468,  3470,  3472,  3473,  3475,
    3477,  3479,  3481,  3483,  3485,  3487,  3489,  3491,  3493,  3495,
    3497,  3501,  3503,  3505,  3507,  3509,  3511,  3513,  3516,  3518,
    3520,  3523,  3527,  3531,  3533,  3537,  3541,  3544,  3548,  3552,
    3556,  3560,  3562,  3564,  3566,  3568,  3572,  3578,  3580,  3582,
    3584,  3586,  3590,  3593,  3595,  3600,  3606,  3612,  3617,  3624,
    3626,  3628,  3630,  3632,  3634,  3636,  3637,  3639,  3643,  3645,
    3646,  3654,  3656,  3659,  3663,  3666,  3667,  3670,  3671,  3674,
    3679,  3682,  3684,  3686,  3688,  3691,  3695,  3698,  3702,  3707,
    3710,  3712,  3716,  3726,  3738,  3751,  3766,  3770,  3775,  3780,
    3781,  3789,  3800,  3803,  3807,  3808,  3813,  3815,  3817,  3819,
    3821,  3823,  3825,  3827,  3829,  3831,  3833,  3835,  3837,  3839,
    3841,  3843,  3845,  3847,  3849,  3851,  3853,  3855,  3857,  3859,
    3861,  3863,  3865,  3867,  3869,  3871,  3873,  3875,  3877,  3879,
    3881,  3883,  3885,  3887,  3889,  3891,  3893,  3895,  3897,  3899,
    3901,  3903,  3905,  3907,  3909,  3911,  3913,  3915,  3917,  3919,
    3921,  3923,  3925,  3927,  3929,  3931,  3933,  3935,  3937,  3939,
    3941,  3943,  3945,  3947,  3949,  3951,  3953,  3955,  3957,  3959,
    3961,  3963,  3965,  3967,  3969,  3971,  3973,  3975,  3977,  3979,
    3981,  3983,  3985,  3987,  3989,  3991,  3993,  3995,  3997,  3999,
    4001,  4003,  4005,  4007,  4009,  4011,  4013,  4015,  4017,  4019,
    4021,  4023,  4025,  4027,  4029,  4031,  4033,  4035,  4037,  4039,
    4041,  4043,  4045,  4047,  4049,  4051,  4053,  4055,  4057,  4059,
    4061,  4063,  4065,  4067,  4069,  4071,  4073,  4075,  4077,  4079,
    4081,  4083,  4085,  4087,  4089,  4091,  4093,  4095,  4097,  4099,
    4101,  4103,  4105,  4107,  4109,  4111,  4113,  4115,  4117,  4119,
    4121,  4123,  4125,  4127,  4129,  4131,  4133,  4135,  4137,  4139,
    4141,  4143,  4145,  4147,  4149,  4151,  4153,  4155,  4157,  4159,
    4161,  4163,  4165,  4167,  4169,  4171,  4173,  4175,  4177,  4179,
    4181,  4183,  4185,  4187,  4189,  4191,  4193,  4195,  4197,  4199,
    4201,  4203,  4205,  4207,  4209,  4211,  4213,  4215,  4217,  4219,
    4221,  4223,  4225,  4227,  4229,  4231,  4233,  4235,  4237,  4239,
    4241,  4243,  4245,  4247,  4249,  4251,  4253,  4255,  4257,  4259,
    4261,  4263,  4265,  4267,  4269,  4271,  4273,  4275,  4277,  4279,
    4281,  4283,  4285,  4287,  4289,  4291,  4293,  4295,  4297,  4299,
    4301,  4303,  4305,  4307,  4309,  4311,  4313,  4315,  4317,  4319,
    4321,  4323,  4325,  4327,  4329,  4331,  4333,  4335,  4337,  4339,
    4341,  4343,  4345,  4347,  4349,  4351,  4353,  4355,  4357,  4359,
    4361,  4363,  4365,  4367,  4369,  4371,  4373,  4375,  4377,  4379,
    4381,  4383,  4385,  4387,  4389,  4391,  4393,  4395,  4397,  4399,
    4401,  4403,  4405,  4407,  4409,  4411,  4413,  4415,  4417,  4419,
    4421,  4423,  4425,  4427,  4429,  4431,  4433,  4435,  4437,  4439,
    4441,  4443,  4445,  4447,  4449,  4451,  4453,  4455,  4457,  4459,
    4461,  4463,  4465,  4467,  4469,  4471,  4473,  4475,  4477,  4479,
    4481,  4483,  4485,  4487,  4489,  4491,  4493,  4495,  4497,  4499,
    4501,  4503,  4505,  4507,  4509,  4511,  4513,  4515,  4517,  4519,
    4521,  4523,  4525,  4527,  4529,  4531,  4533,  4535,  4537,  4539,
    4541,  4543,  4545,  4547,  4549,  4551,  4553,  4555,  4557,  4559,
    4561,  4563,  4565,  4567,  4569,  4571,  4573,  4575,  4577,  4579,
    4581,  4583,  4585,  4587,  4589,  4591,  4593,  4595,  4597,  4599,
    4601,  4603,  4605,  4607,  4609,  4611,  4613,  4615,  4617,  4619,
    4621,  4623,  4625,  4627,  4629,  4631,  4633,  4635,  4637,  4639,
    4641,  4643,  4645,  4647,  4649,  4651,  4653,  4655,  4657,  4659,
    4661,  4663,  4665,  4667,  4669,  4671,  4673,  4675,  4677
};

/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
static const yytype_int16 yyrhs[] =
{
     475,     0,    -1,   476,    -1,   476,   470,   477,    -1,   477,
      -1,   766,    -1,   515,    -1,   478,    -1,   796,    -1,   767,
      -1,   577,    -1,   804,    -1,   756,    -1,   511,    -1,   524,
      -1,   489,    -1,   792,    -1,   570,    -1,   513,    -1,   768,
      -1,   759,    -1,   492,    -1,   785,    -1,   510,    -1,   753,
      -1,   490,    -1,   594,    -1,   522,    -1,   576,    -1,   787,
      -1,   797,    -1,   779,    -1,   800,    -1,   802,    -1,    -1,
      28,   377,   647,   486,    -1,    28,   377,   179,   145,   647,
     486,    -1,    28,   188,   738,   486,    -1,    28,   188,   179,
     145,   738,   486,    -1,    28,   344,   738,   486,    -1,    28,
     344,   179,   145,   738,   486,    -1,    28,   423,   738,   486,
      -1,    28,   423,   179,   145,   738,   486,    -1,   481,    -1,
     479,   481,    -1,   350,   111,   682,    -1,   130,   111,    -1,
     324,    -1,   324,   517,   518,    -1,   350,   519,    -1,   350,
     166,   569,    -1,   485,    -1,   482,   471,   485,    -1,    22,
     549,    -1,    22,   179,   251,   145,   549,    -1,    22,    73,
     549,    -1,    22,    73,   179,   251,   145,   549,    -1,    28,
     491,   746,   480,    -1,    28,   491,   746,   130,   251,   256,
      -1,    28,   491,   746,   350,   251,   256,    -1,    28,   491,
     746,   350,   366,   521,    -1,    28,   491,   746,   350,   537,
      -1,    28,   491,   746,   323,   537,    -1,    28,   491,   746,
     350,   369,   746,    -1,    28,   491,   746,    22,   166,   569,
      35,   178,   527,    -1,    28,   491,   746,   479,    -1,    28,
     491,   746,   130,   178,    -1,    28,   491,   746,   130,   178,
     179,   145,    -1,   130,   491,   179,   145,   746,   574,    -1,
     130,   491,   746,   574,    -1,    28,   491,   746,   488,   398,
     659,   658,   484,    -1,    28,   491,   746,   487,    -1,    22,
     539,    -1,    28,    83,   740,   525,    -1,   414,    83,   740,
      -1,   130,    83,   179,   145,   740,   574,    -1,   130,    83,
     740,   574,    -1,   350,   231,    -1,   350,   407,    -1,   350,
     537,    -1,   323,   537,    -1,   487,    -1,   411,   682,    -1,
      -1,   532,    -1,   350,   532,    -1,    22,   532,    -1,   130,
     547,    -1,   483,    -1,   486,   471,   483,    -1,   270,   467,
     482,   468,    -1,   350,   104,    -1,    -1,   107,   740,    -1,
     107,   295,   740,    -1,   107,    26,    -1,   107,   295,    26,
      -1,    28,   337,   740,   319,   388,   740,    -1,    28,   377,
     647,   319,   388,   740,    -1,    28,   377,   179,   145,   647,
     319,   388,   740,    -1,    28,   344,   738,   319,   388,   740,
      -1,    28,   344,   179,   145,   738,   319,   388,   740,    -1,
      28,   423,   738,   319,   388,   740,    -1,    28,   423,   179,
     145,   738,   319,   388,   740,    -1,    28,   188,   738,   319,
     388,   740,    -1,    28,   188,   179,   145,   738,   319,   388,
     740,    -1,    28,   377,   647,   319,   491,   740,   388,   740,
      -1,    28,   377,   179,   145,   647,   319,   491,   740,   388,
     740,    -1,    28,   377,   647,   319,    83,   740,   388,   740,
      -1,    28,   377,   179,   145,   647,   319,    83,   740,   388,
     740,    -1,    73,    -1,    -1,   496,   198,   204,   494,   493,
     499,   501,    -1,   594,    -1,   279,   502,   416,   594,    -1,
     467,   506,   468,   594,    -1,   467,   506,   468,   279,   502,
     416,   594,    -1,   111,   417,    -1,   738,    -1,   738,    35,
     746,    -1,   467,   508,   468,   655,    -1,   266,    83,   740,
      -1,    -1,   599,    -1,    -1,   746,   732,    -1,   509,   456,
     682,    -1,   467,   503,   468,   456,   682,    -1,   266,    81,
     495,   126,   409,   350,   507,   655,    -1,   266,    81,   495,
     126,   252,    -1,    -1,   746,   504,   505,   612,   613,    -1,
     687,   504,   505,   612,   613,    -1,   467,   682,   468,   504,
     505,   612,   613,    -1,   326,   735,    -1,    -1,   410,    -1,
     376,    -1,   509,    -1,   503,   471,   509,    -1,    71,   748,
      -1,    -1,   748,    -1,    -1,   497,    -1,   506,   471,   497,
      -1,   498,    -1,   507,   471,   498,    -1,   500,    -1,   508,
     471,   500,    -1,   746,   732,    -1,   292,   746,    -1,   292,
     746,   456,   784,    -1,   292,   746,   467,   710,   468,    -1,
      90,   568,   344,   738,   512,    -1,    90,   568,   344,   179,
     251,   145,   738,   512,    -1,   516,    -1,    -1,   144,   740,
     514,    -1,    90,   568,   377,   806,    35,   144,   740,   514,
     805,    -1,    90,   568,   377,   179,   251,   145,   806,    35,
     144,   740,   514,   805,    -1,   467,   709,   468,    -1,    -1,
      28,   344,   738,   516,    -1,    28,   344,   179,   145,   738,
     516,    -1,   519,    -1,   516,   519,    -1,   430,    -1,   453,
      -1,    -1,     4,    -1,   458,     4,    -1,   459,     4,    -1,
     521,    -1,    35,   661,    -1,    54,   518,    -1,   103,    -1,
     249,   103,    -1,   187,   520,   518,    -1,   235,   518,    -1,
     238,   518,    -1,   249,   235,    -1,   249,   238,    -1,   280,
      53,   748,    -1,   344,   242,   748,    -1,   364,   517,   518,
      -1,   324,    -1,   324,   517,   518,    -1,    53,    -1,    -1,
     744,    -1,   458,   744,    -1,   459,   744,    -1,    18,   523,
      -1,    46,   523,    -1,   364,   523,    -1,    77,   523,    -1,
     136,   523,    -1,   331,   523,    -1,   433,    -1,   390,    -1,
      -1,    90,   568,   377,   738,   467,   556,   468,   544,   536,
      -1,    90,   568,   377,   179,   251,   145,   738,   467,   556,
     468,   544,   536,    -1,    -1,   525,   548,    -1,   563,    -1,
     810,    -1,   706,    -1,   518,    -1,   745,    -1,   250,    -1,
     467,   516,   468,    -1,    -1,   745,    -1,   249,    21,    -1,
     325,    -1,    56,    -1,   350,   256,    -1,   350,   111,    -1,
      83,   740,   531,    -1,   531,    -1,   543,    -1,    71,   748,
      -1,   251,   256,    -1,   256,    -1,   404,   555,    -1,   298,
     210,   555,    -1,    65,   467,   682,   468,   538,    -1,   111,
     683,    -1,   166,   569,    35,   178,   527,    -1,   313,   738,
     558,   566,   534,    -1,   547,   528,    -1,   266,   409,   529,
      -1,   533,    -1,   560,    -1,   533,   560,    -1,   560,   533,
      -1,    -1,   270,   467,   550,   468,    -1,    -1,   266,    77,
     130,    -1,   266,    77,   116,   334,    -1,   266,    77,   297,
     334,    -1,    -1,   467,   541,   468,    -1,   249,   190,    -1,
      -1,    83,   740,   564,    -1,   564,    -1,    76,    -1,    84,
      -1,   112,    -1,   178,    -1,   189,    -1,   366,    -1,   369,
      -1,    26,    -1,   561,    -1,   541,   471,   561,    -1,   411,
     188,   552,    -1,   113,    -1,   251,   113,    -1,   192,   114,
      -1,   192,   181,    -1,   430,   537,    -1,   430,   264,    -1,
     432,   264,    -1,    -1,   467,   551,   468,    -1,   546,   186,
     540,    -1,   546,   142,   540,    -1,    -1,   752,    -1,   251,
     113,    -1,   113,    -1,   192,   181,    -1,   192,   114,    -1,
     251,   413,    -1,   249,   190,    -1,   746,   659,   535,   559,
      -1,   532,    -1,   550,   471,   532,    -1,   554,    -1,   551,
     471,   554,    -1,   746,    -1,   549,    -1,   567,    -1,   539,
      -1,   752,   456,   526,    -1,   752,    -1,   430,   545,    -1,
      -1,   565,    -1,    -1,   746,    -1,   467,   562,   468,    -1,
      -1,   559,   530,    -1,    -1,   266,   116,   529,    -1,   752,
     456,   526,    -1,   752,    -1,   752,   469,   752,   456,   526,
      -1,   752,   469,   752,    -1,   557,    -1,   562,   471,   557,
      -1,   659,    -1,   747,   749,   462,   398,    -1,   351,   747,
     749,   462,   398,    -1,    65,   467,   682,   468,   525,    -1,
     404,   467,   562,   468,   555,   525,    -1,   404,   542,   525,
      -1,   298,   210,   467,   562,   468,   555,   525,    -1,   298,
     210,   542,   525,    -1,   159,   210,   467,   562,   468,   313,
     738,   558,   566,   534,   525,    -1,   553,    -1,   565,   471,
     553,    -1,   233,   163,    -1,   233,   284,    -1,   233,   356,
      -1,    -1,   221,   738,   546,    -1,   383,    -1,   381,    -1,
     225,   383,    -1,   225,   381,    -1,   167,   383,    -1,   167,
     381,    -1,   407,    -1,    -1,    29,    -1,    53,   111,    -1,
     130,   571,   179,   145,   573,   574,    -1,   130,   571,   573,
     574,    -1,   130,   572,   179,   145,   739,   574,    -1,   130,
     572,   739,   574,    -1,   130,   575,   740,   266,   748,   574,
      -1,   130,   575,   179,   145,   740,   266,   748,   574,    -1,
     377,    -1,   344,    -1,   423,    -1,   234,   423,    -1,   188,
      -1,   159,   377,    -1,    72,    -1,    87,    -1,   366,    -1,
     384,   340,   283,    -1,   384,   340,   122,    -1,   384,   340,
     382,    -1,   384,   340,    80,    -1,    20,   236,    -1,   139,
     393,    -1,   147,    -1,   159,   104,   434,    -1,   304,    -1,
     337,    -1,   347,    -1,   748,    -1,   573,   471,   748,    -1,
      56,    -1,   325,    -1,    -1,   290,    -1,   335,    -1,   393,
      -1,   496,   409,   793,   350,   507,   637,   794,   501,    -1,
      88,   589,   738,   558,   587,   578,   583,   592,   579,   517,
     584,    -1,    88,   467,   755,   468,   388,   583,   592,   517,
     584,    -1,   162,    -1,   388,    -1,   581,   118,   745,    -1,
      -1,   591,    -1,   580,   471,   591,    -1,   411,    -1,    -1,
      35,    -1,    -1,   303,    -1,    -1,   588,    -1,   467,   593,
     468,    -1,   776,    -1,   518,    -1,   460,    -1,   467,   580,
     468,    -1,    -1,   752,   585,    -1,   430,   264,    -1,    -1,
     588,   590,    -1,    -1,    49,    -1,    -1,    49,    -1,   264,
      -1,   161,    -1,   117,   582,   745,    -1,   256,   582,   745,
      -1,    92,    -1,   175,    -1,   305,   582,   745,    -1,   138,
     582,   745,    -1,   158,   305,   562,    -1,   158,   305,   460,
      -1,   158,   251,   256,   562,    -1,   158,   256,   562,    -1,
     134,   745,    -1,   776,    -1,   745,    -1,   367,    -1,   368,
      -1,   586,    -1,   593,   471,   586,    -1,   596,    -1,   595,
      -1,   467,   596,   468,    -1,   467,   595,   468,    -1,   598,
      -1,   597,   609,    -1,   597,   608,   629,   615,    -1,   597,
     608,   614,   630,    -1,   599,   597,    -1,   599,   597,   609,
      -1,   599,   597,   608,   629,   615,    -1,   599,   597,   608,
     614,   630,    -1,   598,    -1,   595,    -1,   343,   607,   734,
     602,   637,   655,   624,   628,   691,    -1,   343,   606,   735,
     602,   637,   655,   624,   628,   691,    -1,   636,    -1,   377,
     647,    -1,   597,   403,   605,   597,    -1,   597,   202,   605,
     597,    -1,   597,   140,   605,   597,    -1,   430,   600,    -1,
     453,   600,    -1,   430,   311,   600,    -1,   601,    -1,   600,
     471,   601,    -1,   740,   750,    35,   467,   755,   468,    -1,
     204,   603,    -1,    -1,   383,   604,   738,    -1,   381,   604,
     738,    -1,   225,   383,   604,   738,    -1,   225,   381,   604,
     738,    -1,   167,   383,   604,   738,    -1,   167,   381,   604,
     738,    -1,   407,   604,   738,    -1,   377,   738,    -1,   738,
      -1,   377,    -1,    -1,    26,    -1,   125,    -1,    -1,   125,
      -1,   125,   266,   467,   709,   468,    -1,    26,    -1,    -1,
     609,    -1,    -1,   272,    53,   610,    -1,   611,    -1,   610,
     471,   611,    -1,   682,   411,   706,   613,    -1,   682,   612,
     613,    -1,    36,    -1,   120,    -1,    -1,   452,   154,    -1,
     452,   214,    -1,    -1,   616,   617,    -1,   617,   616,    -1,
     616,    -1,   617,    -1,   614,    -1,    -1,   222,   618,    -1,
     222,   618,   471,   619,    -1,   152,   623,   620,   622,   267,
      -1,   152,   623,   622,   267,    -1,   263,   619,    -1,   263,
     620,   622,    -1,   682,    -1,    26,    -1,   682,    -1,   684,
      -1,   458,   621,    -1,   459,   621,    -1,   744,    -1,     4,
      -1,   333,    -1,   334,    -1,   154,    -1,   248,    -1,   171,
      53,   625,    -1,    -1,   626,    -1,   625,   471,   626,    -1,
     682,    -1,   627,    -1,   467,   468,    -1,   174,   682,    -1,
      -1,   631,    -1,   157,   307,   267,    -1,   629,    -1,    -1,
     632,    -1,   631,   632,    -1,   633,   634,   635,    -1,   157,
     409,    -1,   157,   249,   210,   409,    -1,   157,   353,    -1,
     157,   210,   353,    -1,   261,   737,    -1,    -1,   255,    -1,
     357,   230,    -1,    -1,   417,   467,   709,   468,    -1,   636,
     471,   467,   709,   468,    -1,   162,   638,    -1,    -1,   639,
      -1,   638,   471,   639,    -1,   647,   642,    -1,   647,   642,
     648,    -1,   650,   643,    -1,   215,   650,   643,    -1,   595,
     642,    -1,   215,   595,   642,    -1,   640,    -1,   467,   640,
     468,   641,    -1,   467,   640,   468,    -1,   639,    91,   209,
     639,    -1,   639,   644,   209,   639,   646,    -1,   639,   209,
     639,   646,    -1,   639,   245,   644,   209,   639,    -1,   639,
     245,   209,   639,    -1,    35,   746,   467,   739,   468,    -1,
      35,   746,    -1,   746,   467,   739,   468,    -1,   746,    -1,
     641,    -1,    -1,   641,    -1,    35,   467,   656,   468,    -1,
      35,   746,   467,   656,   468,    -1,   746,   467,   656,   468,
      -1,    -1,   163,   645,    -1,   219,   645,    -1,   329,   645,
      -1,   194,    -1,   275,    -1,    -1,   411,   467,   739,   468,
      -1,   266,   682,    -1,   738,    -1,   738,   460,    -1,   267,
     738,    -1,   267,   467,   738,   468,    -1,   379,   742,   467,
     709,   468,   649,    -1,   320,   467,   682,   468,    -1,    -1,
     687,   654,    -1,   334,   162,   467,   652,   468,   654,    -1,
     687,   653,    -1,   651,    -1,   652,   471,   651,    -1,    35,
     467,   656,   468,    -1,    -1,   453,   273,    -1,    -1,   427,
     682,    -1,    -1,   657,    -1,   656,   471,   657,    -1,   746,
     659,   658,    -1,    71,   748,    -1,    -1,   661,   660,    -1,
     351,   661,   660,    -1,   661,    34,   465,   744,   466,    -1,
     351,   661,    34,   465,   744,   466,    -1,   661,    34,    -1,
     351,   661,    34,    -1,   660,   465,   466,    -1,   660,   465,
     744,   466,    -1,    -1,   663,    -1,   665,    -1,   667,    -1,
     671,    -1,   677,    -1,   678,   680,    -1,   678,   467,   744,
     468,    -1,   665,    -1,   668,    -1,   672,    -1,   677,    -1,
     747,   664,    -1,   747,   749,   664,    -1,   467,   709,   468,
      -1,    -1,   200,    -1,   201,    -1,   358,    -1,    48,    -1,
     308,    -1,   155,   666,    -1,   129,   294,    -1,   109,   664,
      -1,   108,   664,    -1,   259,   664,    -1,    51,    -1,   467,
     744,   468,    -1,    -1,   669,    -1,   670,    -1,   669,    -1,
     670,    -1,    50,   676,   467,   709,   468,    -1,    50,   676,
      -1,   673,    -1,   674,    -1,   673,    -1,   674,    -1,   675,
     467,   744,   468,    -1,   675,    -1,    63,   676,    -1,    62,
     676,    -1,   418,    -1,   244,    63,   676,    -1,   244,    62,
     676,    -1,   246,   676,    -1,   420,    -1,    -1,   387,   467,
     744,   468,   679,    -1,   387,   679,    -1,   386,   467,   744,
     468,   679,    -1,   386,   679,    -1,   203,    -1,   453,   386,
     450,    -1,   432,   386,   450,    -1,    -1,   448,    -1,   240,
      -1,   106,    -1,   177,    -1,   237,    -1,   681,    -1,   448,
     388,   240,    -1,   106,   388,   177,    -1,   106,   388,   237,
      -1,   106,   388,   681,    -1,   177,   388,   237,    -1,   177,
     388,   681,    -1,   237,   388,   681,    -1,    -1,   341,    -1,
     341,   467,   744,   468,    -1,   684,    -1,   682,    11,   659,
      -1,   682,    71,   748,    -1,   682,    40,   386,   450,   682,
      -1,   458,   682,    -1,   459,   682,    -1,   682,   458,   682,
      -1,   682,   459,   682,    -1,   682,   460,   682,    -1,   682,
     461,   682,    -1,   682,   462,   682,    -1,   682,   463,   682,
      -1,   682,   454,   682,    -1,   682,   455,   682,    -1,   682,
     456,   682,    -1,   682,    15,   682,    -1,   682,    16,   682,
      -1,   682,    17,   682,    -1,   682,   705,   682,    -1,   705,
     682,    -1,   682,   705,    -1,   682,    32,   682,    -1,   682,
     271,   682,    -1,   251,   682,    -1,   451,   682,    -1,   682,
     221,   682,    -1,   682,   221,   682,   138,   682,    -1,   682,
     451,   221,   682,    -1,   682,   451,   221,   682,   138,   682,
      -1,   682,   180,   682,    -1,   682,   180,   682,   138,   682,
      -1,   682,   451,   180,   682,    -1,   682,   451,   180,   682,
     138,   682,    -1,   682,   355,   388,   682,    -1,   682,   355,
     388,   682,   138,   682,    -1,   682,   451,   355,   388,   682,
      -1,   682,   451,   355,   388,   682,   138,   682,    -1,   682,
     206,   256,    -1,   682,   207,    -1,   682,   206,   251,   256,
      -1,   682,   251,   256,    -1,   682,   254,    -1,   701,   277,
     701,    -1,   682,   206,   395,    -1,   682,   206,   251,   395,
      -1,   682,   206,   150,    -1,   682,   206,   251,   150,    -1,
     682,   206,   405,    -1,   682,   206,   251,   405,    -1,   682,
     206,   125,   162,   682,    -1,   682,   206,   251,   125,   162,
     682,    -1,   682,   206,   261,   467,   712,   468,    -1,   682,
     206,   251,   261,   467,   712,   468,    -1,   682,    47,   733,
     683,    32,   682,    -1,   682,   451,    47,   733,   683,    32,
     682,    -1,   682,    47,   374,   683,    32,   682,    -1,   682,
     451,    47,   374,   683,    32,   682,    -1,   682,   185,   722,
      -1,   682,   451,   185,   722,    -1,   682,   707,   702,   595,
      -1,   682,   707,   702,   467,   682,   468,    -1,   111,    -1,
     684,    -1,   683,    11,   659,    -1,   458,   683,    -1,   459,
     683,    -1,   683,   458,   683,    -1,   683,   459,   683,    -1,
     683,   460,   683,    -1,   683,   461,   683,    -1,   683,   462,
     683,    -1,   683,   463,   683,    -1,   683,   454,   683,    -1,
     683,   455,   683,    -1,   683,   456,   683,    -1,   683,    15,
     683,    -1,   683,    16,   683,    -1,   683,    17,   683,    -1,
     683,   705,   683,    -1,   705,   683,    -1,   683,   705,    -1,
     683,   206,   125,   162,   683,    -1,   683,   206,   251,   125,
     162,   683,    -1,   683,   206,   261,   467,   712,   468,    -1,
     683,   206,   251,   261,   467,   712,   468,    -1,   728,    -1,
     743,    -1,   472,   732,    -1,    10,   732,    -1,   467,   682,
     468,   732,    -1,   723,    -1,   686,    -1,   595,    -1,   595,
     731,    -1,   145,   595,    -1,   742,   467,   468,    -1,   742,
     467,   710,   608,   468,    -1,   742,   467,   419,   711,   608,
     468,    -1,   742,   467,   710,   471,   419,   711,   608,   468,
      -1,   742,   467,    26,   710,   608,   468,    -1,   742,   467,
     125,   710,   608,   468,    -1,   742,   467,   460,   468,    -1,
     685,   689,   690,   694,    -1,   688,    -1,   685,    -1,   688,
      -1,    72,   157,   467,   682,   468,    -1,    96,    -1,    99,
      -1,    99,   467,   744,   468,    -1,   100,    -1,   100,   467,
     744,   468,    -1,   226,    -1,   226,   467,   744,   468,    -1,
     227,    -1,   227,   467,   744,   468,    -1,    97,    -1,   101,
      -1,   349,    -1,   410,    -1,    95,    -1,    98,    -1,    59,
     467,   682,    35,   659,   468,    -1,   149,   467,   713,   468,
      -1,   278,   467,   715,   468,    -1,   291,   467,   717,   468,
      -1,   373,   467,   718,   468,    -1,   392,   467,   682,    35,
     659,   468,    -1,   394,   467,    52,   721,   468,    -1,   394,
     467,   216,   721,   468,    -1,   394,   467,   389,   721,   468,
      -1,   394,   467,   721,   468,    -1,   257,   467,   682,   471,
     682,   468,    -1,    70,   467,   709,   468,    -1,   170,   467,
     709,   468,    -1,   218,   467,   709,   468,    -1,   431,   171,
     467,   609,   468,    -1,    -1,   153,   467,   427,   682,   468,
      -1,    -1,   429,   692,    -1,    -1,   693,    -1,   692,   471,
     693,    -1,   746,    35,   695,    -1,   276,   695,    -1,   276,
     746,    -1,    -1,   467,   696,   697,   608,   698,   468,    -1,
     746,    -1,    -1,   285,    53,   709,    -1,    -1,   306,   699,
      -1,   334,   699,    -1,    -1,   700,    -1,    47,   700,    32,
     700,    -1,   400,   293,    -1,   400,   156,    -1,    94,   333,
      -1,   682,   293,    -1,   682,   156,    -1,   333,   467,   709,
     468,    -1,   333,   467,   468,    -1,   467,   709,   471,   682,
     468,    -1,    33,    -1,   360,    -1,    26,    -1,     8,    -1,
     704,    -1,   458,    -1,   459,    -1,   460,    -1,   461,    -1,
     462,    -1,   463,    -1,   454,    -1,   455,    -1,   456,    -1,
      15,    -1,    16,    -1,    17,    -1,     8,    -1,   268,   467,
     708,   468,    -1,   703,    -1,   268,   467,   708,   468,    -1,
     703,    -1,   268,   467,   708,   468,    -1,   221,    -1,   451,
     221,    -1,   180,    -1,   451,   180,    -1,   703,    -1,   746,
     469,   708,    -1,   682,    -1,   709,   471,   682,    -1,   711,
      -1,   710,   471,   711,    -1,   682,    -1,   751,    13,   682,
      -1,   751,    14,   682,    -1,   659,    -1,   712,   471,   659,
      -1,   714,   162,   682,    -1,    -1,     3,    -1,   448,    -1,
     240,    -1,   106,    -1,   177,    -1,   237,    -1,   341,    -1,
     745,    -1,   682,   716,   719,   720,    -1,   682,   716,   719,
      -1,   288,   682,    -1,   683,   185,   683,    -1,    -1,   682,
     719,   720,    -1,   682,   720,   719,    -1,   682,   719,    -1,
     682,   720,    -1,   709,    -1,    -1,   162,   682,    -1,   157,
     682,    -1,   682,   162,   709,    -1,   162,   709,    -1,   709,
      -1,   595,    -1,   467,   709,   468,    -1,    58,   727,   724,
     726,   136,    -1,   725,    -1,   724,   725,    -1,   426,   682,
     385,   682,    -1,   132,   682,    -1,    -1,   682,    -1,    -1,
     746,    -1,   746,   731,    -1,   469,   741,    -1,   469,   460,
      -1,   465,   682,   466,    -1,   465,   730,   473,   730,   466,
      -1,   682,    -1,    -1,   729,    -1,   731,   729,    -1,    -1,
     732,   729,    -1,    39,    -1,    -1,   735,    -1,    -1,   736,
      -1,   735,   471,   736,    -1,   682,    35,   752,    -1,   682,
       3,    -1,   682,    -1,   460,    -1,   738,    -1,   737,   471,
     738,    -1,   746,    -1,   746,   731,    -1,   740,    -1,   739,
     471,   740,    -1,   746,    -1,   752,    -1,   747,    -1,   746,
     731,    -1,   744,    -1,     4,    -1,   745,    -1,     6,    -1,
       7,    -1,   742,   745,    -1,   742,   467,   710,   608,   468,
     745,    -1,   662,   745,    -1,   678,   745,   680,    -1,   678,
     467,   744,   468,   745,    -1,   678,   467,   472,   468,   472,
     680,    -1,   395,    -1,   150,    -1,   256,    -1,     9,    -1,
       5,    -1,     3,    -1,   807,    -1,   808,    -1,     3,    -1,
     807,    -1,   809,    -1,   746,    -1,   746,   749,    -1,   469,
     741,    -1,   749,   469,   741,    -1,   467,   739,   468,    -1,
      -1,   747,    -1,     3,    -1,   807,    -1,   808,    -1,   809,
      -1,   810,    -1,   295,   740,   754,    35,   755,    -1,   467,
     712,   468,    -1,    -1,   594,    -1,   492,    -1,   576,    -1,
     792,    -1,    90,   337,   746,   757,    -1,    90,   337,   179,
     251,   145,   746,   757,    -1,   757,   758,    -1,    -1,   524,
      -1,   759,    -1,   511,    -1,   802,    -1,    90,   765,   188,
     762,   763,   266,   738,   761,   467,   508,   468,   764,   655,
      -1,    90,   765,   188,   762,   179,   251,   145,   552,   266,
     738,   761,   467,   508,   468,   764,   655,    -1,   746,    -1,
     411,   760,    -1,    -1,    79,    -1,    -1,   552,    -1,    -1,
     430,   537,    -1,    -1,   404,    -1,    -1,    28,   377,   647,
     350,   337,   740,    -1,    28,   377,   179,   145,   647,   350,
     337,   740,    -1,    28,   344,   738,   350,   337,   740,    -1,
      28,   344,   179,   145,   738,   350,   337,   740,    -1,    28,
     423,   738,   350,   337,   740,    -1,    28,   423,   179,   145,
     738,   350,   337,   740,    -1,    66,    -1,   146,   771,    -1,
     146,   775,   769,   771,    -1,   146,   421,   771,    -1,   146,
     467,   774,   468,   771,    -1,   421,    -1,    -1,   776,    -1,
     518,    -1,    -1,   594,    -1,   492,    -1,   576,    -1,   792,
      -1,   804,    -1,     3,    -1,   807,    -1,   808,    -1,   809,
      -1,   772,    -1,   745,    -1,   777,    -1,   774,   471,   777,
      -1,    31,    -1,    30,    -1,   395,    -1,   150,    -1,   266,
      -1,   773,    -1,   778,   770,    -1,   772,    -1,   775,    -1,
     350,   780,    -1,   350,   225,   780,    -1,   350,   348,   780,
      -1,   781,    -1,   801,   162,    94,    -1,   386,   450,   783,
      -1,   337,   745,    -1,   801,   388,   784,    -1,   801,   456,
     784,    -1,   801,   388,   111,    -1,   801,   456,   111,    -1,
     776,    -1,   518,    -1,   745,    -1,     3,    -1,   678,   745,
     680,    -1,   678,   467,   744,   468,   745,    -1,   518,    -1,
     111,    -1,   225,    -1,   782,    -1,   784,   471,   782,    -1,
     224,   786,    -1,   745,    -1,   412,   789,   791,   769,    -1,
     412,   789,   791,   769,   738,    -1,   412,   789,   791,   769,
     796,    -1,   412,   467,   790,   468,    -1,   412,   467,   790,
     468,   738,   750,    -1,   775,    -1,   421,    -1,   161,    -1,
     163,    -1,     3,    -1,   163,    -1,    -1,   788,    -1,   790,
     471,   788,    -1,   161,    -1,    -1,   496,   116,   162,   793,
     795,   794,   501,    -1,   647,    -1,   647,   746,    -1,   647,
      35,   746,    -1,   427,   682,    -1,    -1,   411,   638,    -1,
      -1,   775,   769,    -1,   775,   769,   738,   750,    -1,   323,
     799,    -1,   801,    -1,    26,    -1,   798,    -1,   386,   450,
      -1,   390,   208,   220,    -1,   354,   801,    -1,   354,   386,
     450,    -1,   354,   390,   208,   220,    -1,   354,    26,    -1,
     746,    -1,   801,   469,   746,    -1,    90,   568,   423,   738,
     558,   764,    35,   594,   803,    -1,    90,   271,   321,   568,
     423,   738,   558,   764,    35,   594,   803,    -1,    90,   568,
     311,   423,   738,   467,   562,   468,   764,    35,   594,   803,
      -1,    90,   271,   321,   568,   311,   423,   738,   467,   562,
     468,   764,    35,   594,   803,    -1,   430,    65,   269,    -1,
     430,    57,    65,   269,    -1,   430,   225,    65,   269,    -1,
      -1,    90,   568,   377,   806,    35,   594,   805,    -1,    90,
     568,   377,   179,   251,   145,   806,    35,   594,   805,    -1,
     430,   104,    -1,   430,   249,   104,    -1,    -1,   738,   558,
     544,   536,    -1,    18,    -1,    19,    -1,    20,    -1,    21,
      -1,    22,    -1,    23,    -1,    24,    -1,    25,    -1,    27,
      -1,    28,    -1,    29,    -1,    37,    -1,    38,    -1,    40,
      -1,    41,    -1,    42,    -1,    44,    -1,    45,    -1,    46,
      -1,    53,    -1,    54,    -1,    55,    -1,    56,    -1,    57,
      -1,    60,    -1,    61,    -1,    64,    -1,    66,    -1,    67,
      -1,    68,    -1,    69,    -1,    74,    -1,    75,    -1,    76,
      -1,    77,    -1,    78,    -1,    80,    -1,    81,    -1,    82,
      -1,    84,    -1,    85,    -1,    86,    -1,    87,    -1,    88,
      -1,    89,    -1,    92,    -1,    93,    -1,    94,    -1,   102,
      -1,   103,    -1,   104,    -1,   105,    -1,   106,    -1,   107,
      -1,   110,    -1,   112,    -1,   114,    -1,   115,    -1,   116,
      -1,   117,    -1,   118,    -1,   119,    -1,   121,    -1,   122,
      -1,   123,    -1,   124,    -1,   127,    -1,   128,    -1,   129,
      -1,   130,    -1,   131,    -1,   133,    -1,   134,    -1,   135,
      -1,   137,    -1,   138,    -1,   139,    -1,   141,    -1,   142,
      -1,   143,    -1,   144,    -1,   146,    -1,   147,    -1,   148,
      -1,   151,    -1,   153,    -1,   154,    -1,   156,    -1,   158,
      -1,   160,    -1,   164,    -1,   165,    -1,   166,    -1,   167,
      -1,   169,    -1,   173,    -1,   175,    -1,   176,    -1,   177,
      -1,   178,    -1,   179,    -1,   181,    -1,   182,    -1,   183,
      -1,   184,    -1,   186,    -1,   187,    -1,   188,    -1,   189,
      -1,   190,    -1,   191,    -1,   193,    -1,   196,    -1,   197,
      -1,   198,    -1,   199,    -1,   205,    -1,   208,    -1,   210,
      -1,   211,    -1,   212,    -1,   213,    -1,   214,    -1,   217,
      -1,   220,    -1,   223,    -1,   224,    -1,   225,    -1,   228,
      -1,   229,    -1,   230,    -1,   231,    -1,   232,    -1,   233,
      -1,   234,    -1,   235,    -1,   236,    -1,   237,    -1,   238,
      -1,   239,    -1,   240,    -1,   241,    -1,   242,    -1,   243,
      -1,   247,    -1,   248,    -1,   249,    -1,   252,    -1,   253,
      -1,   255,    -1,   258,    -1,   260,    -1,   261,    -1,   262,
      -1,   264,    -1,   265,    -1,   268,    -1,   269,    -1,   270,
      -1,   273,    -1,   276,    -1,   279,    -1,   280,    -1,   281,
      -1,   282,    -1,   283,    -1,   284,    -1,   285,    -1,   286,
      -1,   287,    -1,   289,    -1,   290,    -1,   292,    -1,   293,
      -1,   295,    -1,   296,    -1,   297,    -1,   299,    -1,   300,
      -1,   301,    -1,   302,    -1,   303,    -1,   304,    -1,   305,
      -1,   306,    -1,   307,    -1,   309,    -1,   310,    -1,   311,
      -1,   312,    -1,   314,    -1,   315,    -1,   316,    -1,   317,
      -1,   318,    -1,   319,    -1,   320,    -1,   321,    -1,   322,
      -1,   323,    -1,   324,    -1,   325,    -1,   327,    -1,   328,
      -1,   330,    -1,   331,    -1,   332,    -1,   334,    -1,   335,
      -1,   336,    -1,   337,    -1,   338,    -1,   339,    -1,   340,
      -1,   341,    -1,   342,    -1,   344,    -1,   345,    -1,   346,
      -1,   347,    -1,   348,    -1,   350,    -1,   352,    -1,   353,
      -1,   354,    -1,   356,    -1,   357,    -1,   359,    -1,   361,
      -1,   362,    -1,   363,    -1,   364,    -1,   365,    -1,   366,
      -1,   367,    -1,   368,    -1,   369,    -1,   370,    -1,   371,
      -1,   372,    -1,   375,    -1,   376,    -1,   378,    -1,   380,
      -1,   381,    -1,   382,    -1,   383,    -1,   384,    -1,   390,
      -1,   391,    -1,   393,    -1,   396,    -1,   397,    -1,   398,
      -1,   399,    -1,   400,    -1,   401,    -1,   402,    -1,   405,
      -1,   406,    -1,   407,    -1,   408,    -1,   409,    -1,   412,
      -1,   413,    -1,   414,    -1,   415,    -1,   416,    -1,   420,
      -1,   422,    -1,   423,    -1,   424,    -1,   425,    -1,   428,
      -1,   431,    -1,   432,    -1,   433,    -1,   434,    -1,   435,
      -1,   436,    -1,   448,    -1,   449,    -1,   450,    -1,    47,
      -1,    48,    -1,    50,    -1,    51,    -1,    62,    -1,    63,
      -1,    70,    -1,   108,    -1,   109,    -1,   145,    -1,   149,
      -1,   155,    -1,   170,    -1,   172,    -1,   195,    -1,   200,
      -1,   201,    -1,   203,    -1,   218,    -1,   244,    -1,   246,
      -1,   250,    -1,   257,    -1,   259,    -1,   274,    -1,   278,
      -1,   291,    -1,   294,    -1,   308,    -1,   333,    -1,   351,
      -1,   358,    -1,   373,    -1,   386,    -1,   387,    -1,   392,
      -1,   394,    -1,   417,    -1,   418,    -1,   437,    -1,   438,
      -1,   439,    -1,   440,    -1,   441,    -1,   442,    -1,   443,
      -1,   444,    -1,   445,    -1,   446,    -1,   447,    -1,    43,
      -1,    49,    -1,    72,    -1,    79,    -1,    91,    -1,    98,
      -1,   161,    -1,   163,    -1,   180,    -1,   194,    -1,   206,
      -1,   207,    -1,   209,    -1,   219,    -1,   221,    -1,   245,
      -1,   254,    -1,   275,    -1,   277,    -1,   329,    -1,   355,
      -1,   379,    -1,   421,    -1,    26,    -1,    30,    -1,    31,
      -1,    32,    -1,    33,    -1,    34,    -1,    35,    -1,    36,
      -1,    39,    -1,    52,    -1,    58,    -1,    59,    -1,    65,
      -1,    71,    -1,    73,    -1,    83,    -1,    90,    -1,    95,
      -1,    96,    -1,    97,    -1,    99,    -1,   100,    -1,   101,
      -1,   111,    -1,   113,    -1,   120,    -1,   125,    -1,   126,
      -1,   132,    -1,   136,    -1,   140,    -1,   150,    -1,   152,
      -1,   157,    -1,   159,    -1,   162,    -1,   168,    -1,   171,
      -1,   174,    -1,   185,    -1,   192,    -1,   202,    -1,   204,
      -1,   215,    -1,   216,    -1,   222,    -1,   226,    -1,   227,
      -1,   251,    -1,   256,    -1,   263,    -1,   266,    -1,   267,
      -1,   271,    -1,   272,    -1,   288,    -1,   298,    -1,   313,
      -1,   326,    -1,   343,    -1,   349,    -1,   360,    -1,   374,
      -1,   377,    -1,   385,    -1,   388,    -1,   389,    -1,   395,
      -1,   403,    -1,   404,    -1,   410,    -1,   411,    -1,   419,
      -1,   426,    -1,   427,    -1,   429,    -1,   430,    -1
};

/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
static const yytype_uint16 yyrline[] =
{
       0,   448,   448,   464,   476,   485,   486,   487,   488,   489,
     490,   491,   492,   493,   494,   495,   496,   497,   498,   499,
     500,   501,   502,   503,   504,   505,   506,   507,   508,   509,
     510,   511,   512,   513,   515,     9,    18,    27,    36,    45,
      54,    63,    72,    85,    87,    93,    94,    99,   103,   107,
     118,   126,   130,   139,   148,   157,   166,   175,   184,   192,
     200,   209,   218,   227,   236,   253,   262,   271,   280,   290,
     303,   318,   327,   335,   350,   358,   368,   378,   385,   392,
     400,   407,   418,   419,   424,   428,   433,   438,   446,   447,
     452,   456,   457,     7,    13,    19,    25,     6,    15,    25,
      35,    45,    55,    65,    75,    85,    95,   106,   117,   127,
     140,   141,     8,    21,    27,    34,    40,    47,    57,    61,
      70,    79,    88,    95,    96,   101,   113,   118,   143,   153,
     163,   169,   180,   191,   206,   207,   213,   214,   219,   220,
     226,   227,   231,   232,   237,   239,   245,   246,   250,   251,
     256,     7,    14,    22,     9,    19,    32,    33,     7,    14,
      31,    51,    52,     9,    17,    29,    30,    34,    35,    36,
      41,    42,    43,    48,    52,    56,    60,    64,    68,    72,
      76,    80,    84,    88,    92,    97,   101,   105,   112,   113,
     117,   118,   119,     2,     9,    15,    21,    28,    35,    45,
      46,    47,     7,    21,    41,    42,    69,    70,    71,    72,
      73,    74,    78,    79,    84,    89,    90,    91,    92,    93,
      98,   105,   106,   107,   124,   131,   138,   148,   158,   170,
     179,   188,   207,   214,   219,   221,   223,   225,   228,   233,
     234,   238,   239,   240,   241,   246,   250,   251,   256,   263,
     268,   269,   270,   271,   272,   273,   274,   275,   281,   282,
     286,   291,   298,   305,   312,   324,   325,   326,   327,   331,
     336,   337,   338,   343,   348,   349,   350,   351,   352,   353,
     358,   381,   385,   392,   393,   397,   401,   402,   403,   407,
     411,   419,   420,   425,   426,   430,   438,   439,   444,   445,
     449,   454,   458,   462,   467,   475,   476,   480,   481,   487,
     498,   511,   525,   539,   553,   567,   590,   594,   601,   605,
     613,   618,   625,   635,   636,   637,   638,   639,   646,   653,
     654,   659,   660,     9,    19,    29,    39,    49,    59,    73,
      74,    75,    76,    77,    78,    79,    80,    81,    82,    83,
      84,    85,    90,    91,    92,    93,    94,    95,    96,   101,
     102,   107,   108,   109,   114,   115,   116,     7,     1,    30,
      53,    54,    59,    63,    68,    72,    80,    81,    85,    86,
      91,    92,    96,    97,   102,   103,   104,   105,   106,   111,
     119,   123,   128,   129,   134,   138,   143,   147,   151,   155,
     159,   163,   167,   171,   175,   179,   183,   187,   191,   195,
     203,   209,   210,   211,   216,   220,    47,    48,    52,    53,
      68,    69,    76,    84,    92,   100,   108,   116,   127,   128,
     155,   169,   184,   185,   204,   208,   212,   229,   236,   243,
     253,   254,   257,   269,   280,   288,   293,   298,   303,   308,
     316,   324,   329,   334,   341,   342,   346,   347,   348,   355,
     356,   360,   361,   365,   366,   370,   374,   375,   378,   387,
     398,   399,   400,   403,   404,   405,   409,   410,   411,   412,
     416,   417,   421,   423,   439,   441,   446,   449,   454,   455,
     463,   483,   484,   486,   491,   492,   496,   497,   500,   501,
     526,   527,   531,   532,   536,   537,   541,   554,   555,   559,
     560,   564,   565,   569,   570,   574,   585,   586,   587,   588,
     592,   593,   598,   599,   600,   609,   615,   633,   634,   638,
     639,   645,   650,   658,   665,   673,   708,   733,   737,   763,
     767,   779,   792,   806,   817,   832,   838,   843,   849,   856,
     857,   865,   869,   873,   879,   886,   891,   892,   893,   894,
     898,   899,   911,   912,   917,   924,   931,   938,   961,   974,
     975,   990,  1000,  1012,  1017,  1018,  1021,  1022,  1025,  1026,
    1031,  1032,  1037,  1041,  1047,  1068,  1076,  1088,  1093,  1100,
    1105,  1111,  1116,  1125,  1127,  1130,  1134,  1135,  1136,  1137,
    1138,  1139,  1144,  1164,  1165,  1166,  1167,  1178,  1184,  1192,
    1193,  1199,  1204,  1209,  1214,  1219,  1224,  1229,  1234,  1240,
    1246,  1252,  1259,  1281,  1290,  1294,  1302,  1306,  1314,  1326,
    1347,  1351,  1357,  1361,  1374,  1382,  1392,  1394,  1396,  1398,
    1400,  1402,  1407,  1408,  1415,  1424,  1432,  1441,  1452,  1460,
    1461,  1462,  1466,  1468,  1470,  1472,  1474,  1476,  1478,  1483,
    1488,  1494,  1502,  1507,  1514,  1521,  1525,  1529,  1565,  1566,
    1568,  1576,  1591,  1593,  1595,  1597,  1599,  1601,  1603,  1605,
    1607,  1609,  1611,  1613,  1615,  1617,  1620,  1622,  1624,  1627,
    1629,  1631,  1633,  1636,  1641,  1649,  1654,  1662,  1667,  1675,
    1680,  1689,  1697,  1705,  1713,  1731,  1739,  1747,  1755,  1763,
    1771,  1787,  1795,  1803,  1811,  1819,  1827,  1835,  1839,  1843,
    1847,  1851,  1859,  1867,  1875,  1883,  1903,  1925,  1936,  1943,
    1968,  1970,  1972,  1974,  1976,  1978,  1980,  1982,  1984,  1986,
    1988,  1990,  1992,  1994,  1996,  1998,  2000,  2002,  2004,  2006,
    2010,  2014,  2018,  2032,  2033,  2034,  2046,  2061,  2073,  2075,
    2077,  2088,  2112,  2125,  2129,  2135,  2142,  2149,  2159,  2166,
    2194,  2229,  2240,  2241,  2248,  2254,  2258,  2262,  2266,  2270,
    2274,  2278,  2282,  2286,  2290,  2294,  2298,  2302,  2306,  2310,
    2314,  2316,  2320,  2329,  2334,  2341,  2356,  2363,  2367,  2371,
    2375,  2379,  2386,  2394,  2409,  2410,  2414,  2415,  2423,  2424,
    2428,  2429,  2434,  2442,  2444,  2458,  2461,  2488,  2489,  2492,
    2493,  2504,  2522,  2529,  2538,  2555,  2600,  2608,  2616,  2624,
    2632,  2653,  2654,  2655,  2658,  2659,  2660,  2663,  2664,  2667,
    2668,  2669,  2670,  2671,  2672,  2673,  2674,  2675,  2676,  2677,
    2678,  2681,  2683,  2688,  2690,  2695,  2697,  2699,  2701,  2703,
    2705,  2719,  2721,  2725,  2729,  2736,  2740,  2746,  2750,  2759,
    2770,  2771,  2775,  2779,  2786,  2787,  2788,  2789,  2790,  2791,
    2792,  2793,  2803,  2807,  2814,  2821,  2822,  2838,  2842,  2847,
    2851,  2866,  2871,  2875,  2878,  2881,  2882,  2883,  2886,  2893,
    2903,  2917,  2918,  2922,  2933,  2934,  2937,  2938,  2941,  2945,
    2952,  2956,  2960,  2968,  2979,  2980,  2984,  2985,  2989,  2990,
    2993,  2994,  3004,  3005,  3009,  3010,  3013,  3029,  3037,  3045,
    3067,  3068,  3079,  3083,  3110,  3112,  3117,  3119,  3129,  3131,
    3142,  3146,  3150,  3154,  3158,  3167,  3174,  3206,  3210,  3216,
    3224,  3236,  3240,  3244,  3250,  3251,  3267,  3268,  3269,  3274,
    3275,  3276,  3279,  3280,  3283,  3285,  3290,  3291,  3294,  3302,
    3303,  3304,  3305,  3306,     7,    18,    19,    23,    24,    25,
      26,     7,    16,    34,    41,    46,    47,    48,    49,     8,
      33,    62,    66,    67,    72,    73,    78,    79,    83,    84,
      89,    90,     7,    16,    25,    34,    43,    52,     5,     9,
      16,    26,    33,    44,    45,    50,    51,    52,    57,    58,
      59,    60,    61,    65,    66,    67,    68,    73,    74,    79,
      83,    91,    92,    97,    98,    99,   105,   110,   118,   119,
      10,    16,    22,    32,    33,    41,    52,    64,    72,    80,
      87,    97,    99,   105,   109,   113,   128,   135,   136,   137,
     141,   142,     7,    16,     8,    22,    36,    48,    56,    70,
      71,    72,    73,    74,    87,    88,    93,    94,    98,    99,
       7,    21,    25,    32,    43,    44,    50,    51,     9,    19,
       2,     7,    14,    24,    25,    32,     3,     9,    15,    21,
      30,    31,     8,    21,    34,    52,    74,    75,    76,    77,
      11,    24,    41,    42,    43,    48,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
      61,    61,    61,    61,    61,    61,    61,    61,    61,    62,
      62,    62,    62,    62,    62,    62,    62,    62,    62,    62,
      62,    62,    62,    62,    62,    62,    62,    62,    62,    62,
      62,    62,    62,    62,    62,    62,    62,    62,    62,    62,
      62,    62,    62,    62,    62,    62,    62,    62,    62,    62,
      62,    62,    62,    62,    62,    62,    62,    62,    62,    63,
      63,    63,    63,    63,    63,    63,    63,    63,    63,    63,
      63,    63,    63,    63,    63,    63,    63,    63,    63,    63,
      63,    63,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
      64,    64,    64,    64,    64,    64,    64,    64,    64
};
#endif

#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
static const char *const yytname[] =
{
  "$end", "error", "$undefined", "IDENT", "FCONST", "SCONST", "BCONST",
  "XCONST", "Op", "ICONST", "PARAM", "TYPECAST", "DOT_DOT", "COLON_EQUALS",
  "EQUALS_GREATER", "LESS_EQUALS", "GREATER_EQUALS", "NOT_EQUALS",
  "ABORT_P", "ABSOLUTE_P", "ACCESS", "ACTION", "ADD_P", "ADMIN", "AFTER",
  "AGGREGATE", "ALL", "ALSO", "ALTER", "ALWAYS", "ANALYSE", "ANALYZE",
  "AND", "ANY", "ARRAY", "AS", "ASC_P", "ASSERTION", "ASSIGNMENT",
  "ASYMMETRIC", "AT", "ATTACH", "ATTRIBUTE", "AUTHORIZATION", "BACKWARD",
  "BEFORE", "BEGIN_P", "BETWEEN", "BIGINT", "BINARY", "BIT", "BOOLEAN_P",
  "BOTH", "BY", "CACHE", "CALLED", "CASCADE", "CASCADED", "CASE", "CAST",
  "CATALOG_P", "CHAIN", "CHAR_P", "CHARACTER", "CHARACTERISTICS",
  "CHECK_P", "CHECKPOINT", "CLASS", "CLOSE", "CLUSTER", "COALESCE",
  "COLLATE", "COLLATION", "COLUMN", "COLUMNS", "COMMENT", "COMMENTS",
  "COMMIT", "COMMITTED", "CONCURRENTLY", "CONFIGURATION", "CONFLICT",
  "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTENT_P", "CONTINUE_P",
  "CONVERSION_P", "COPY", "COST", "CREATE_P", "CROSS", "CSV", "CUBE",
  "CURRENT_P", "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_ROLE",
  "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER",
  "CURSOR", "CYCLE", "DATA_P", "DATABASE", "DAY_P", "DEALLOCATE", "DEC",
  "DECIMAL_P", "DECLARE", "DEFAULT", "DEFAULTS", "DEFERRABLE", "DEFERRED",
  "DEFINER", "DELETE_P", "DELIMITER", "DELIMITERS", "DEPENDS", "DESC_P",
  "DETACH", "DICTIONARY", "DISABLE_P", "DISCARD", "DISTINCT", "DO",
  "DOCUMENT_P", "DOMAIN_P", "DOUBLE_P", "DROP", "EACH", "ELSE", "ENABLE_P",
  "ENCODING", "ENCRYPTED", "END_P", "ENUM_P", "ESCAPE", "EVENT", "EXCEPT",
  "EXCLUDE", "EXCLUDING", "EXCLUSIVE", "EXECUTE", "EXISTS", "EXPLAIN",
  "EXTENSION", "EXTERNAL", "EXTRACT", "FALSE_P", "FAMILY", "FETCH",
  "FILTER", "FIRST_P", "FLOAT_P", "FOLLOWING", "FOR", "FORCE", "FOREIGN",
  "FORWARD", "FREEZE", "FROM", "FULL", "FUNCTION", "FUNCTIONS",
  "GENERATED", "GLOBAL", "GRANT", "GRANTED", "GREATEST", "GROUP_P",
  "GROUPING", "HANDLER", "HAVING", "HEADER_P", "HOLD", "HOUR_P",
  "IDENTITY_P", "IF_P", "ILIKE", "IMMEDIATE", "IMMUTABLE", "IMPLICIT_P",
  "IMPORT_P", "IN_P", "INCLUDING", "INCREMENT", "INDEX", "INDEXES",
  "INHERIT", "INHERITS", "INITIALLY", "INLINE_P", "INNER_P", "INOUT",
  "INPUT_P", "INSENSITIVE", "INSERT", "INSTEAD", "INT_P", "INTEGER",
  "INTERSECT", "INTERVAL", "INTO", "INVOKER", "IS", "ISNULL", "ISOLATION",
  "JOIN", "KEY", "LABEL", "LANGUAGE", "LARGE_P", "LAST_P", "LATERAL_P",
  "LEADING", "LEAKPROOF", "LEAST", "LEFT", "LEVEL", "LIKE", "LIMIT",
  "LISTEN", "LOAD", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP", "LOCATION",
  "LOCK_P", "LOCKED", "LOGGED", "MAPPING", "MATCH", "MATERIALIZED",
  "MAXVALUE", "METHOD", "MINUTE_P", "MINVALUE", "MODE", "MONTH_P", "MOVE",
  "NAME_P", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NEW", "NEXT", "NO",
  "NONE", "NOT", "NOTHING", "NOTIFY", "NOTNULL", "NOWAIT", "NULL_P",
  "NULLIF", "NULLS_P", "NUMERIC", "OBJECT_P", "OF", "OFF", "OFFSET",
  "OIDS", "OLD", "ON", "ONLY", "OPERATOR", "OPTION", "OPTIONS", "OR",
  "ORDER", "ORDINALITY", "OUT_P", "OUTER_P", "OVER", "OVERLAPS", "OVERLAY",
  "OVERRIDING", "OWNED", "OWNER", "PARALLEL", "PARSER", "PARTIAL",
  "PARTITION", "PASSING", "PASSWORD", "PLACING", "PLANS", "POLICY",
  "POSITION", "PRAGMA_P", "PRECEDING", "PRECISION", "PREPARE", "PREPARED",
  "PRESERVE", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURAL", "PROCEDURE",
  "PROGRAM", "PUBLICATION", "QUOTE", "RANGE", "READ_P", "REAL", "REASSIGN",
  "RECHECK", "RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REFRESH",
  "REINDEX", "RELATIVE_P", "RELEASE", "RENAME", "REPEATABLE", "REPLACE",
  "REPLICA", "RESET", "RESTART", "RESTRICT", "RETURNING", "RETURNS",
  "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROW", "ROWS", "RULE",
  "SAVEPOINT", "SCHEMA", "SCHEMAS", "SCROLL", "SEARCH", "SECOND_P",
  "SECURITY", "SELECT", "SEQUENCE", "SEQUENCES", "SERIALIZABLE", "SERVER",
  "SESSION", "SESSION_USER", "SET", "SETOF", "SETS", "SHARE", "SHOW",
  "SIMILAR", "SIMPLE", "SKIP", "SMALLINT", "SNAPSHOT", "SOME", "SQL_P",
  "STABLE", "STANDALONE_P", "START", "STATEMENT", "STATISTICS", "STDIN",
  "STDOUT", "STORAGE", "STRICT_P", "STRIP_P", "SUBSCRIPTION", "SUBSTRING",
  "SYMMETRIC", "SYSID", "SYSTEM_P", "TABLE", "TABLES", "TABLESAMPLE",
  "TABLESPACE", "TEMP", "TEMPLATE", "TEMPORARY", "TEXT_P", "THEN", "TIME",
  "TIMESTAMP", "TO", "TRAILING", "TRANSACTION", "TRANSFORM", "TREAT",
  "TRIGGER", "TRIM", "TRUE_P", "TRUNCATE", "TRUSTED", "TYPE_P", "TYPES_P",
  "UNBOUNDED", "UNCOMMITTED", "UNENCRYPTED", "UNION", "UNIQUE", "UNKNOWN",
  "UNLISTEN", "UNLOGGED", "UNTIL", "UPDATE", "USER", "USING", "VACUUM",
  "VALID", "VALIDATE", "VALIDATOR", "VALUE_P", "VALUES", "VARCHAR",
  "VARIADIC", "VARYING", "VERBOSE", "VERSION_P", "VIEW", "VIEWS",
  "VOLATILE", "WHEN", "WHERE", "WHITESPACE_P", "WINDOW", "WITH", "WITHIN",
  "WITHOUT", "WORK", "WRAPPER", "WRITE_P", "XML_P", "XMLATTRIBUTES",
  "XMLCONCAT", "XMLELEMENT", "XMLEXISTS", "XMLFOREST", "XMLNAMESPACES",
  "XMLPARSE", "XMLPI", "XMLROOT", "XMLSERIALIZE", "XMLTABLE", "YEAR_P",
  "YES_P", "ZONE", "NOT_LA", "NULLS_LA", "WITH_LA", "'<'", "'>'", "'='",
  "POSTFIXOP", "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "UMINUS", "'['",
  "']'", "'('", "')'", "'.'", "';'", "','", "'?'", "':'", "$accept",
  "stmtblock", "stmtmulti", "stmt", "AlterTableStmt",
  "alter_identity_column_option_list", "alter_column_default",
  "alter_identity_column_option", "alter_generic_option_list",
  "alter_table_cmd", "alter_using", "alter_generic_option_elem",
  "alter_table_cmds", "alter_generic_options", "opt_set_data",
  "DeallocateStmt", "RenameStmt", "opt_column", "InsertStmt",
  "insert_rest", "insert_target", "opt_conf_expr", "opt_with_clause",
  "insert_column_item", "set_clause", "opt_on_conflict", "index_elem",
  "returning_clause", "override_kind", "set_target_list", "opt_collate",
  "opt_class", "insert_column_list", "set_clause_list", "index_params",
  "set_target", "PragmaStmt", "CreateSeqStmt", "OptSeqOptList",
  "ExecuteStmt", "execute_param_clause", "AlterSeqStmt", "SeqOptList",
  "opt_with", "NumericOnly", "SeqOptElem", "opt_by", "SignedIconst",
  "TransactionStmt", "opt_transaction", "CreateStmt",
  "ConstraintAttributeSpec", "def_arg", "OptParenthesizedSeqOptList",
  "generic_option_arg", "key_action", "ColConstraint", "ColConstraintElem",
  "generic_option_elem", "key_update", "key_actions",
  "create_generic_options", "OnCommitOption", "reloptions",
  "opt_no_inherit", "TableConstraint", "TableLikeOption", "reloption_list",
  "ExistingIndex", "ConstraintAttr", "OptWith", "definition",
  "TableLikeOptionList", "generic_option_name", "ConstraintAttributeElem",
  "columnDef", "generic_option_list", "def_list", "index_name",
  "TableElement", "def_elem", "opt_definition", "OptTableElementList",
  "columnElem", "opt_column_list", "ColQualList", "key_delete",
  "reloption_elem", "columnList", "func_type", "ConstraintElem",
  "TableElementList", "key_match", "TableLikeClause", "OptTemp",
  "generated_when", "DropStmt", "drop_type_any_name", "drop_type_name",
  "any_name_list", "opt_drop_behavior", "drop_type_name_on_any_name",
  "UpdateStmt", "CopyStmt", "copy_from", "copy_delimiter",
  "copy_generic_opt_arg_list", "opt_using", "opt_as", "opt_program",
  "copy_options", "copy_generic_opt_arg", "copy_generic_opt_elem",
  "opt_oids", "copy_opt_list", "opt_binary", "copy_opt_item",
  "copy_generic_opt_arg_list_item", "copy_file_name",
  "copy_generic_opt_list", "SelectStmt", "select_with_parens",
  "select_no_parens", "select_clause", "simple_select", "with_clause",
  "cte_list", "common_table_expr", "into_clause", "OptTempTableName",
  "opt_table", "all_or_distinct", "distinct_clause", "opt_all_clause",
  "opt_sort_clause", "sort_clause", "sortby_list", "sortby",
  "opt_asc_desc", "opt_nulls_order", "select_limit", "opt_select_limit",
  "limit_clause", "offset_clause", "select_limit_value",
  "select_offset_value", "select_fetch_first_value", "I_or_F_const",
  "row_or_rows", "first_or_next", "group_clause", "group_by_list",
  "group_by_item", "empty_grouping_set", "having_clause",
  "for_locking_clause", "opt_for_locking_clause", "for_locking_items",
  "for_locking_item", "for_locking_strength", "locked_rels_list",
  "opt_nowait_or_skip", "values_clause", "from_clause", "from_list",
  "table_ref", "joined_table", "alias_clause", "opt_alias_clause",
  "func_alias_clause", "join_type", "join_outer", "join_qual",
  "relation_expr", "tablesample_clause", "opt_repeatable_clause",
  "func_table", "rowsfrom_item", "rowsfrom_list", "opt_col_def_list",
  "opt_ordinality", "where_clause", "TableFuncElementList",
  "TableFuncElement", "opt_collate_clause", "Typename", "opt_array_bounds",
  "SimpleTypename", "ConstTypename", "GenericType", "opt_type_modifiers",
  "Numeric", "opt_float", "Bit", "ConstBit", "BitWithLength",
  "BitWithoutLength", "Character", "ConstCharacter", "CharacterWithLength",
  "CharacterWithoutLength", "character", "opt_varying", "ConstDatetime",
  "ConstInterval", "opt_timezone", "opt_interval", "interval_second",
  "a_expr", "b_expr", "c_expr", "func_application", "func_expr",
  "func_expr_windowless", "func_expr_common_subexpr",
  "within_group_clause", "filter_clause", "window_clause",
  "window_definition_list", "window_definition", "over_clause",
  "window_specification", "opt_existing_window_name",
  "opt_partition_clause", "opt_frame_clause", "frame_extent",
  "frame_bound", "row", "sub_type", "all_Op", "MathOp", "qual_Op",
  "qual_all_Op", "subquery_Op", "any_operator", "expr_list",
  "func_arg_list", "func_arg_expr", "type_list", "extract_list",
  "extract_arg", "overlay_list", "overlay_placing", "position_list",
  "substr_list", "substr_from", "substr_for", "trim_list", "in_expr",
  "case_expr", "when_clause_list", "when_clause", "case_default",
  "case_arg", "columnref", "indirection_el", "opt_slice_bound",
  "indirection", "opt_indirection", "opt_asymmetric", "opt_target_list",
  "target_list", "target_el", "qualified_name_list", "qualified_name",
  "name_list", "name", "attr_name", "func_name", "AexprConst", "Iconst",
  "Sconst", "ColId", "type_function_name", "any_name", "attrs",
  "opt_name_list", "param_name", "ColLabel", "PrepareStmt",
  "prep_type_clause", "PreparableStmt", "CreateSchemaStmt",
  "OptSchemaEltList", "schema_stmt", "IndexStmt", "access_method",
  "access_method_clause", "opt_concurrently", "opt_index_name",
  "opt_reloptions", "opt_unique", "AlterObjectSchemaStmt",
  "CheckPointStmt", "ExplainStmt", "opt_verbose", "explain_option_arg",
  "ExplainableStmt", "NonReservedWord", "NonReservedWord_or_Sconst",
  "explain_option_list", "analyze_keyword", "opt_boolean_or_string",
  "explain_option_elem", "explain_option_name", "VariableSetStmt",
  "set_rest", "generic_set", "var_value", "zone_value", "var_list",
  "LoadStmt", "file_name", "VacuumStmt", "vacuum_option_elem", "opt_full",
  "vacuum_option_list", "opt_freeze", "DeleteStmt",
  "relation_expr_opt_alias", "where_or_current_clause", "using_clause",
  "AnalyzeStmt", "VariableResetStmt", "generic_reset", "reset_rest",
  "VariableShowStmt", "var_name", "ViewStmt", "opt_check_option",
  "CreateAsStmt", "opt_with_data", "create_as_target",
  "unreserved_keyword", "col_name_keyword", "type_func_name_keyword",
  "reserved_keyword", 0
};
#endif

# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
   token YYLEX-NUM.  */
static const yytype_uint16 yytoknum[] =
{
       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
     385,   386,   387,   388,   389,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,   403,   404,
     405,   406,   407,   408,   409,   410,   411,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,   426,   427,   428,   429,   430,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,   452,   453,   454,
     455,   456,   457,   458,   459,   460,   461,   462,   463,   464,
     465,   466,   467,   468,   469,   470,   471,   472,   473,   474,
     475,   476,   477,   478,   479,   480,   481,   482,   483,   484,
     485,   486,   487,   488,   489,   490,   491,   492,   493,   494,
     495,   496,   497,   498,   499,   500,   501,   502,   503,   504,
     505,   506,   507,   508,   509,   510,   511,   512,   513,   514,
     515,   516,   517,   518,   519,   520,   521,   522,   523,   524,
     525,   526,   527,   528,   529,   530,   531,   532,   533,   534,
     535,   536,   537,   538,   539,   540,   541,   542,   543,   544,
     545,   546,   547,   548,   549,   550,   551,   552,   553,   554,
     555,   556,   557,   558,   559,   560,   561,   562,   563,   564,
     565,   566,   567,   568,   569,   570,   571,   572,   573,   574,
     575,   576,   577,   578,   579,   580,   581,   582,   583,   584,
     585,   586,   587,   588,   589,   590,   591,   592,   593,   594,
     595,   596,   597,   598,   599,   600,   601,   602,   603,   604,
     605,   606,   607,   608,   609,   610,   611,   612,   613,   614,
     615,   616,   617,   618,   619,   620,   621,   622,   623,   624,
     625,   626,   627,   628,   629,   630,   631,   632,   633,   634,
     635,   636,   637,   638,   639,   640,   641,   642,   643,   644,
     645,   646,   647,   648,   649,   650,   651,   652,   653,   654,
     655,   656,   657,   658,   659,   660,   661,   662,   663,   664,
     665,   666,   667,   668,   669,   670,   671,   672,   673,   674,
     675,   676,   677,   678,   679,   680,   681,   682,   683,   684,
     685,   686,   687,   688,   689,   690,   691,   692,   693,   694,
     695,   696,   697,   698,   699,   700,   701,   702,   703,   704,
     705,   706,   707,   708,    60,    62,    61,   709,    43,    45,
      42,    47,    37,    94,   710,    91,    93,    40,    41,    46,
      59,    44,    63,    58
};
# endif

/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
static const yytype_uint16 yyr1[] =
{
       0,   474,   475,   476,   476,   477,   477,   477,   477,   477,
     477,   477,   477,   477,   477,   477,   477,   477,   477,   477,
     477,   477,   477,   477,   477,   477,   477,   477,   477,   477,
     477,   477,   477,   477,   477,   478,   478,   478,   478,   478,
     478,   478,   478,   479,   479,   480,   480,   481,   481,   481,
     481,   482,   482,   483,   483,   483,   483,   483,   483,   483,
     483,   483,   483,   483,   483,   483,   483,   483,   483,   483,
     483,   483,   483,   483,   483,   483,   483,   483,   483,   483,
     483,   483,   484,   484,   485,   485,   485,   485,   486,   486,
     487,   488,   488,   489,   489,   489,   489,   490,   490,   490,
     490,   490,   490,   490,   490,   490,   490,   490,   490,   490,
     491,   491,   492,   493,   493,   493,   493,   493,   494,   494,
     495,   495,   495,   496,   496,   497,   498,   498,   499,   499,
     499,   500,   500,   500,   501,   501,   502,   502,   503,   503,
     504,   504,   505,   505,   506,   506,   507,   507,   508,   508,
     509,   510,   510,   510,   511,   511,   512,   512,   513,   513,
     513,   514,   514,   515,   515,   516,   516,   517,   517,   517,
     518,   518,   518,   518,   519,   519,   519,   519,   519,   519,
     519,   519,   519,   519,   519,   519,   519,   519,   520,   520,
     521,   521,   521,   522,   522,   522,   522,   522,   522,   523,
     523,   523,   524,   524,   525,   525,   526,   526,   526,   526,
     526,   526,   527,   527,   528,   529,   529,   529,   529,   529,
     530,   530,   530,   530,   531,   531,   531,   531,   531,   531,
     531,   531,   532,   533,   534,   534,   534,   534,   534,   535,
     535,   536,   536,   536,   536,   537,   538,   538,   539,   539,
     540,   540,   540,   540,   540,   540,   540,   540,   541,   541,
     542,   543,   543,   543,   543,   544,   544,   544,   544,   545,
     546,   546,   546,   547,   548,   548,   548,   548,   548,   548,
     549,   550,   550,   551,   551,   552,   553,   553,   553,   554,
     554,   555,   555,   556,   556,   557,   558,   558,   559,   559,
     560,   561,   561,   561,   561,   562,   562,   563,   563,   563,
     564,   564,   564,   564,   564,   564,   565,   565,   566,   566,
     566,   566,   567,   568,   568,   568,   568,   568,   568,   568,
     568,   569,   569,   570,   570,   570,   570,   570,   570,   571,
     571,   571,   571,   571,   571,   571,   571,   571,   571,   571,
     571,   571,   572,   572,   572,   572,   572,   572,   572,   573,
     573,   574,   574,   574,   575,   575,   575,   576,   577,   577,
     578,   578,   579,   579,   580,   580,   581,   581,   582,   582,
     583,   583,   584,   584,   585,   585,   585,   585,   585,   586,
     587,   587,   588,   588,   589,   589,   590,   590,   590,   590,
     590,   590,   590,   590,   590,   590,   590,   590,   590,   590,
     591,   592,   592,   592,   593,   593,   594,   594,   595,   595,
     596,   596,   596,   596,   596,   596,   596,   596,   597,   597,
     598,   598,   598,   598,   598,   598,   598,   599,   599,   599,
     600,   600,   601,   602,   602,   603,   603,   603,   603,   603,
     603,   603,   603,   603,   604,   604,   605,   605,   605,   606,
     606,   607,   607,   608,   608,   609,   610,   610,   611,   611,
     612,   612,   612,   613,   613,   613,   614,   614,   614,   614,
     615,   615,   616,   616,   616,   616,   617,   617,   618,   618,
     619,   620,   620,   620,   621,   621,   622,   622,   623,   623,
     624,   624,   625,   625,   626,   626,   627,   628,   628,   629,
     629,   630,   630,   631,   631,   632,   633,   633,   633,   633,
     634,   634,   635,   635,   635,   636,   636,   637,   637,   638,
     638,   639,   639,   639,   639,   639,   639,   639,   639,   640,
     640,   640,   640,   640,   640,   641,   641,   641,   641,   642,
     642,   643,   643,   643,   643,   643,   644,   644,   644,   644,
     645,   645,   646,   646,   647,   647,   647,   647,   648,   649,
     649,   650,   650,   651,   652,   652,   653,   653,   654,   654,
     655,   655,   656,   656,   657,   658,   658,   659,   659,   659,
     659,   659,   659,   660,   660,   660,   661,   661,   661,   661,
     661,   661,   661,   662,   662,   662,   662,   663,   663,   664,
     664,   665,   665,   665,   665,   665,   665,   665,   665,   665,
     665,   665,   666,   666,   667,   667,   668,   668,   669,   670,
     671,   671,   672,   672,   673,   674,   675,   675,   675,   675,
     675,   675,   676,   676,   677,   677,   677,   677,   678,   679,
     679,   679,   680,   680,   680,   680,   680,   680,   680,   680,
     680,   680,   680,   680,   680,   680,   681,   681,   682,   682,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
     683,   683,   683,   683,   683,   683,   683,   683,   683,   683,
     683,   683,   683,   683,   683,   683,   683,   683,   683,   683,
     683,   683,   683,   684,   684,   684,   684,   684,   684,   684,
     684,   684,   684,   685,   685,   685,   685,   685,   685,   685,
     686,   686,   687,   687,   688,   688,   688,   688,   688,   688,
     688,   688,   688,   688,   688,   688,   688,   688,   688,   688,
     688,   688,   688,   688,   688,   688,   688,   688,   688,   688,
     688,   688,   688,   688,   689,   689,   690,   690,   691,   691,
     692,   692,   693,   694,   694,   694,   695,   696,   696,   697,
     697,   698,   698,   698,   699,   699,   700,   700,   700,   700,
     700,   701,   701,   701,   702,   702,   702,   703,   703,   704,
     704,   704,   704,   704,   704,   704,   704,   704,   704,   704,
     704,   705,   705,   706,   706,   707,   707,   707,   707,   707,
     707,   708,   708,   709,   709,   710,   710,   711,   711,   711,
     712,   712,   713,   713,   714,   714,   714,   714,   714,   714,
     714,   714,   715,   715,   716,   717,   717,   718,   718,   718,
     718,   718,   718,   719,   720,   721,   721,   721,   722,   722,
     723,   724,   724,   725,   726,   726,   727,   727,   728,   728,
     729,   729,   729,   729,   730,   730,   731,   731,   732,   732,
     733,   733,   734,   734,   735,   735,   736,   736,   736,   736,
     737,   737,   738,   738,   739,   739,   740,   741,   742,   742,
     743,   743,   743,   743,   743,   743,   743,   743,   743,   743,
     743,   743,   743,   743,   744,   745,   746,   746,   746,   747,
     747,   747,   748,   748,   749,   749,   750,   750,   751,   752,
     752,   752,   752,   752,   753,   754,   754,   755,   755,   755,
     755,   756,   756,   757,   757,   758,   758,   758,   758,   759,
     759,   760,   761,   761,   762,   762,   763,   763,   764,   764,
     765,   765,   766,   766,   766,   766,   766,   766,   767,   768,
     768,   768,   768,   769,   769,   770,   770,   770,   771,   771,
     771,   771,   771,   772,   772,   772,   772,   773,   773,   774,
     774,   775,   775,   776,   776,   776,   776,   777,   778,   778,
     779,   779,   779,   780,   780,   780,   780,   781,   781,   781,
     781,   782,   782,   783,   783,   783,   783,   783,   783,   783,
     784,   784,   785,   786,   787,   787,   787,   787,   787,   788,
     788,   788,   788,   788,   789,   789,   790,   790,   791,   791,
     792,   793,   793,   793,   794,   794,   795,   795,   796,   796,
     797,   798,   798,   799,   799,   799,   800,   800,   800,   800,
     801,   801,   802,   802,   802,   802,   803,   803,   803,   803,
     804,   804,   805,   805,   805,   806,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   807,
     807,   807,   807,   807,   807,   807,   807,   807,   807,   808,
     808,   808,   808,   808,   808,   808,   808,   808,   808,   808,
     808,   808,   808,   808,   808,   808,   808,   808,   808,   808,
     808,   808,   808,   808,   808,   808,   808,   808,   808,   808,
     808,   808,   808,   808,   808,   808,   808,   808,   808,   808,
     808,   808,   808,   808,   808,   808,   808,   808,   808,   809,
     809,   809,   809,   809,   809,   809,   809,   809,   809,   809,
     809,   809,   809,   809,   809,   809,   809,   809,   809,   809,
     809,   809,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810,   810,
     810,   810,   810,   810,   810,   810,   810,   810,   810
};

/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
static const yytype_uint8 yyr2[] =
{
       0,     2,     1,     3,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     0,     4,     6,     4,     6,     4,
       6,     4,     6,     1,     2,     3,     2,     1,     3,     2,
       3,     1,     3,     2,     5,     3,     6,     4,     6,     6,
       6,     5,     5,     6,     9,     4,     5,     7,     6,     4,
       8,     4,     2,     4,     3,     6,     4,     2,     2,     2,
       2,     1,     2,     0,     1,     2,     2,     2,     1,     3,
       4,     2,     0,     2,     3,     2,     3,     6,     6,     8,
       6,     8,     6,     8,     6,     8,     8,    10,     8,    10,
       1,     0,     7,     1,     4,     4,     7,     2,     1,     3,
       4,     3,     0,     1,     0,     2,     3,     5,     8,     5,
       0,     5,     5,     7,     2,     0,     1,     1,     1,     3,
       2,     0,     1,     0,     1,     3,     1,     3,     1,     3,
       2,     2,     4,     5,     5,     8,     1,     0,     3,     9,
      12,     3,     0,     4,     6,     1,     2,     1,     1,     0,
       1,     2,     2,     1,     2,     2,     1,     2,     3,     2,
       2,     2,     2,     3,     3,     3,     1,     3,     1,     0,
       1,     2,     2,     2,     2,     2,     2,     2,     2,     1,
       1,     0,     9,    12,     0,     2,     1,     1,     1,     1,
       1,     1,     3,     0,     1,     2,     1,     1,     2,     2,
       3,     1,     1,     2,     2,     1,     2,     3,     5,     2,
       5,     5,     2,     3,     1,     1,     2,     2,     0,     4,
       0,     3,     4,     4,     0,     3,     2,     0,     3,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
       3,     1,     2,     2,     2,     2,     2,     2,     0,     3,
       3,     3,     0,     1,     2,     1,     2,     2,     2,     2,
       4,     1,     3,     1,     3,     1,     1,     1,     1,     3,
       1,     2,     0,     1,     0,     1,     3,     0,     2,     0,
       3,     3,     1,     5,     3,     1,     3,     1,     4,     5,
       5,     6,     3,     7,     4,    11,     1,     3,     2,     2,
       2,     0,     3,     1,     1,     2,     2,     2,     2,     1,
       0,     1,     2,     6,     4,     6,     4,     6,     8,     1,
       1,     1,     2,     1,     2,     1,     1,     1,     3,     3,
       3,     3,     2,     2,     1,     3,     1,     1,     1,     1,
       3,     1,     1,     0,     1,     1,     1,     8,    11,     9,
       1,     1,     3,     0,     1,     3,     1,     0,     1,     0,
       1,     0,     1,     3,     1,     1,     1,     3,     0,     2,
       2,     0,     2,     0,     1,     0,     1,     1,     1,     3,
       3,     1,     1,     3,     3,     3,     3,     4,     3,     2,
       1,     1,     1,     1,     1,     3,     1,     1,     3,     3,
       1,     2,     4,     4,     2,     3,     5,     5,     1,     1,
       9,     9,     1,     2,     4,     4,     4,     2,     2,     3,
       1,     3,     6,     2,     0,     3,     3,     4,     4,     4,
       4,     3,     2,     1,     1,     0,     1,     1,     0,     1,
       5,     1,     0,     1,     0,     3,     1,     3,     4,     3,
       1,     1,     0,     2,     2,     0,     2,     2,     1,     1,
       1,     0,     2,     4,     5,     4,     2,     3,     1,     1,
       1,     1,     2,     2,     1,     1,     1,     1,     1,     1,
       3,     0,     1,     3,     1,     1,     2,     2,     0,     1,
       3,     1,     0,     1,     2,     3,     2,     4,     2,     3,
       2,     0,     1,     2,     0,     4,     5,     2,     0,     1,
       3,     2,     3,     2,     3,     2,     3,     1,     4,     3,
       4,     5,     4,     5,     4,     5,     2,     4,     1,     1,
       0,     1,     4,     5,     4,     0,     2,     2,     2,     1,
       1,     0,     4,     2,     1,     2,     2,     4,     6,     4,
       0,     2,     6,     2,     1,     3,     4,     0,     2,     0,
       2,     0,     1,     3,     3,     2,     0,     2,     3,     5,
       6,     2,     3,     3,     4,     0,     1,     1,     1,     1,
       1,     2,     4,     1,     1,     1,     1,     2,     3,     3,
       0,     1,     1,     1,     1,     1,     2,     2,     2,     2,
       2,     1,     3,     0,     1,     1,     1,     1,     5,     2,
       1,     1,     1,     1,     4,     1,     2,     2,     1,     3,
       3,     2,     1,     0,     5,     2,     5,     2,     1,     3,
       3,     0,     1,     1,     1,     1,     1,     1,     3,     3,
       3,     3,     3,     3,     3,     0,     1,     4,     1,     3,
       3,     5,     2,     2,     3,     3,     3,     3,     3,     3,
       3,     3,     3,     3,     3,     3,     3,     2,     2,     3,
       3,     2,     2,     3,     5,     4,     6,     3,     5,     4,
       6,     4,     6,     5,     7,     3,     2,     4,     3,     2,
       3,     3,     4,     3,     4,     3,     4,     5,     6,     6,
       7,     6,     7,     6,     7,     3,     4,     4,     6,     1,
       1,     3,     2,     2,     3,     3,     3,     3,     3,     3,
       3,     3,     3,     3,     3,     3,     3,     2,     2,     5,
       6,     6,     7,     1,     1,     2,     2,     4,     1,     1,
       1,     2,     2,     3,     5,     6,     8,     6,     6,     4,
       4,     1,     1,     1,     5,     1,     1,     4,     1,     4,
       1,     4,     1,     4,     1,     1,     1,     1,     1,     1,
       6,     4,     4,     4,     4,     6,     5,     5,     5,     4,
       6,     4,     4,     4,     5,     0,     5,     0,     2,     0,
       1,     3,     3,     2,     2,     0,     6,     1,     0,     3,
       0,     2,     2,     0,     1,     4,     2,     2,     2,     2,
       2,     4,     3,     5,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     4,     1,     4,     1,     4,     1,     2,     1,
       2,     1,     3,     1,     3,     1,     3,     1,     3,     3,
       1,     3,     3,     0,     1,     1,     1,     1,     1,     1,
       1,     1,     4,     3,     2,     3,     0,     3,     3,     2,
       2,     1,     0,     2,     2,     3,     2,     1,     1,     3,
       5,     1,     2,     4,     2,     0,     1,     0,     1,     2,
       2,     2,     3,     5,     1,     0,     1,     2,     0,     2,
       1,     0,     1,     0,     1,     3,     3,     2,     1,     1,
       1,     3,     1,     2,     1,     3,     1,     1,     1,     2,
       1,     1,     1,     1,     1,     2,     6,     2,     3,     5,
       6,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     2,     2,     3,     3,     0,     1,     1,
       1,     1,     1,     1,     5,     3,     0,     1,     1,     1,
       1,     4,     7,     2,     0,     1,     1,     1,     1,    13,
      16,     1,     2,     0,     1,     0,     1,     0,     2,     0,
       1,     0,     6,     8,     6,     8,     6,     8,     1,     2,
       4,     3,     5,     1,     0,     1,     1,     0,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       3,     1,     1,     1,     1,     1,     1,     2,     1,     1,
       2,     3,     3,     1,     3,     3,     2,     3,     3,     3,
       3,     1,     1,     1,     1,     3,     5,     1,     1,     1,
       1,     3,     2,     1,     4,     5,     5,     4,     6,     1,
       1,     1,     1,     1,     1,     0,     1,     3,     1,     0,
       7,     1,     2,     3,     2,     0,     2,     0,     2,     4,
       2,     1,     1,     1,     2,     3,     2,     3,     4,     2,
       1,     3,     9,    11,    12,    14,     3,     4,     4,     0,
       7,    10,     2,     3,     0,     4,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1,     1,     1,     1,     1,     1,     1,     1,     1
};

/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
   means the default is an error.  */
static const yytype_uint16 yydefact[] =
{
     124,   201,     0,  1032,  1031,   201,  1008,   201,   395,   330,
       0,     0,   201,     0,   124,     0,     0,     0,     0,   201,
     462,     0,     0,   201,     0,  1075,     0,     0,     0,     0,
       0,     2,     4,     7,    15,    25,    21,     0,    23,    13,
      18,     6,    27,    14,    17,    28,    10,    26,   429,   416,
     464,   428,   123,   432,    24,    12,    20,     5,     9,    19,
    1014,    31,    22,    29,    16,     8,    30,    32,    33,    11,
     200,   199,   193,     0,     0,     0,     0,     0,   194,   196,
     394,   124,     0,     0,     0,     0,     0,   324,   323,  1000,
     329,     0,     0,   956,  1116,  1117,  1118,  1119,  1120,  1121,
    1122,  1123,    95,  1124,  1125,  1126,  1127,  1128,  1129,  1130,
    1131,  1132,  1133,  1134,  1399,  1400,  1401,  1402,  1135,  1136,
    1137,  1138,  1139,  1140,  1141,  1403,  1404,  1142,  1143,  1144,
    1145,  1146,  1405,  1147,  1148,  1149,  1150,  1151,  1152,  1153,
    1154,  1155,  1156,  1157,  1158,  1159,  1160,  1161,  1162,  1163,
    1164,  1165,  1166,  1167,  1168,  1169,  1406,  1407,  1170,  1171,
    1172,  1173,  1174,  1175,  1176,  1177,  1178,  1179,  1180,  1181,
    1182,  1183,  1184,  1185,  1186,  1187,  1188,  1189,  1190,  1191,
    1192,  1193,  1194,  1195,  1196,  1408,  1197,  1198,  1199,  1409,
    1200,  1201,  1202,  1410,  1203,  1204,  1205,  1206,  1207,  1208,
    1209,  1210,  1411,  1412,  1211,  1212,  1213,  1214,  1215,  1216,
    1217,  1218,  1219,  1220,  1221,  1222,  1223,  1224,  1225,  1226,
    1227,  1413,  1228,  1229,  1230,  1231,  1414,  1415,  1416,  1232,
    1233,  1234,  1235,  1236,  1237,  1238,  1239,  1417,  1240,  1241,
    1242,  1243,  1244,  1245,  1246,  1247,  1248,  1249,  1250,  1251,
    1252,  1253,  1254,  1255,  1256,  1257,  1258,  1259,  1418,  1419,
    1260,  1261,  1262,  1420,  1263,  1264,  1265,  1421,  1266,  1422,
    1267,  1268,  1269,  1270,  1271,  1272,  1273,  1274,  1275,  1423,
    1276,  1424,  1277,  1278,  1279,  1280,  1281,  1282,  1283,  1284,
    1285,  1286,  1287,  1425,  1288,  1289,  1426,  1290,  1291,  1292,
    1293,  1294,  1295,  1296,  1297,  1298,  1299,  1300,  1301,  1427,
    1302,  1303,  1304,  1305,  1306,  1307,  1308,  1309,  1310,  1311,
    1312,  1313,  1314,  1315,  1316,  1317,  1318,  1319,  1320,  1321,
    1322,  1428,  1323,  1324,  1325,  1326,  1327,  1328,  1329,  1330,
    1331,  1332,  1333,  1334,  1335,  1336,  1337,  1429,  1338,  1339,
    1340,  1341,  1342,  1430,  1343,  1344,  1345,  1346,  1347,  1348,
    1349,  1350,  1351,  1352,  1353,  1354,  1355,  1431,  1356,  1357,
    1358,  1359,  1360,  1361,  1362,  1363,  1432,  1433,  1364,  1365,
    1434,  1366,  1435,  1367,  1368,  1369,  1370,  1371,  1372,  1373,
    1374,  1375,  1376,  1377,  1378,  1379,  1380,  1381,  1382,  1383,
    1436,  1437,  1384,  1385,  1386,  1387,  1388,  1389,  1390,  1391,
    1392,  1393,  1394,  1395,  1438,  1439,  1440,  1441,  1442,  1443,
    1444,  1445,  1446,  1447,  1448,  1396,  1397,  1398,    93,   936,
     957,   958,     0,   345,   346,     0,   354,     0,   343,     0,
     364,   356,   365,   357,   340,   358,   347,   339,     0,   366,
     341,     0,     0,     0,   197,  1290,   162,   330,   124,     0,
    1019,  1020,  1018,  1009,  1014,  1021,  1022,   955,  1063,  1062,
     151,   976,  1092,  1432,  1364,  1100,  1093,  1090,  1091,   198,
     461,   459,     0,   923,  1243,  1326,  1336,  1432,  1040,  1043,
       0,  1099,  1432,  1364,  1096,   195,     0,   433,   564,   932,
    1074,     0,  1079,     0,  1304,   437,   440,   967,   438,   429,
       0,     0,     1,   124,     0,     0,     0,   458,   458,     0,
     458,     0,   421,   429,   424,   428,     0,  1013,  1088,  1216,
       0,     0,  1216,     0,  1216,     0,  1216,     0,   978,   979,
     977,     0,   980,   297,   328,   327,   326,   325,   330,  1216,
     984,     0,     0,     0,     0,   995,    96,    94,   352,   353,
       0,   344,   342,     0,  1216,   363,   962,   359,  1216,   363,
     934,  1216,     0,     0,   158,     0,  1011,  1023,  1449,  1450,
    1451,  1452,  1453,  1454,  1455,  1456,  1457,  1458,  1459,  1460,
    1461,  1462,  1463,  1464,  1465,  1466,  1467,  1468,  1469,  1470,
    1436,  1471,  1038,     0,  1039,  1029,  1017,  1024,  1025,  1026,
     124,     0,     0,     0,     0,  1094,     0,     0,     0,   956,
     941,   943,   944,   851,   954,   918,  1400,  1401,  1402,   907,
       0,  1403,  1404,  1405,  1451,   788,   775,   784,   789,   776,
     778,   785,  1406,  1407,   729,  1184,  1408,  1409,   952,  1410,
    1411,  1414,  1415,  1416,  1417,   780,   782,  1418,  1419,     0,
     953,  1421,  1422,  1272,  1424,  1425,  1427,  1428,   786,  1430,
    1431,  1432,  1433,  1434,  1435,   951,   787,  1437,     0,     0,
       0,   929,     0,   918,   760,     0,   603,   604,   626,   627,
     605,   632,   633,   635,   606,     0,   928,   668,   805,   759,
     771,     0,     0,   758,   753,   444,   924,     0,   754,   940,
     942,   908,   938,   957,   961,   444,   922,  1041,  1046,  1042,
       0,     0,     0,     0,  1097,     0,     0,   566,   565,   915,
       0,   916,   933,  1073,  1071,  1072,  1070,  1069,  1076,     0,
    1078,  1014,   863,     0,   439,     0,     0,     0,   419,   418,
       3,     0,     0,  1081,     0,   456,   457,     0,     0,     0,
       0,     0,     0,     0,     0,   512,   478,   479,   481,   509,
     513,   521,     0,   425,     0,   967,     0,     0,   111,   111,
       0,     0,     0,     0,     0,    88,    37,    81,     0,     0,
       0,     0,   176,   189,     0,     0,     0,     0,     0,   186,
       0,     0,   169,    39,   163,   165,     0,   111,     0,    35,
       0,     0,     0,    41,     0,     0,   391,     0,     0,   981,
       0,  1216,   157,  1216,   297,     0,   297,   994,   997,   355,
     351,   349,   348,   350,     0,   361,   362,     0,   334,     0,
     963,     0,     0,   336,     0,     0,     0,     0,   124,     0,
     170,  1034,  1035,  1033,     0,     0,  1016,   173,   190,  1028,
    1037,  1027,  1036,  1015,  1010,  1052,  1051,  1060,   152,   867,
       0,   865,   938,     0,   959,   614,   643,   621,   643,   643,
     610,   610,   623,   611,   612,   648,     0,   643,   610,   615,
       0,   613,   651,   651,   638,   870,   595,   596,   597,   598,
     624,   625,   599,   630,   631,   600,   665,     0,   610,   960,
     124,  1095,  1101,     0,   756,   642,   629,   906,     0,     0,
     637,   636,     0,     0,     0,     0,     0,   619,   618,   617,
     762,   873,     0,   616,     0,     0,     0,     0,   643,   643,
     641,   691,     0,   620,     0,     0,   886,     0,   892,     0,
       0,     0,   647,     0,   645,     0,     0,   692,   672,   673,
     760,   863,     0,   755,   761,   947,     0,     0,   665,   927,
     851,     0,   848,   849,   850,     0,     0,     0,   921,     0,
     859,     0,     0,   706,   857,     0,   709,     0,     0,     0,
       0,   845,   846,   847,   839,   840,   841,   842,   843,   844,
     855,   838,   688,     0,     0,   807,     0,   687,     0,     0,
     528,     0,   945,   909,   528,  1054,  1058,  1059,  1057,     0,
    1053,  1045,  1044,  1049,  1047,  1050,  1048,  1098,     0,   914,
       0,   969,  1472,  1473,  1474,  1475,  1476,  1477,  1478,  1479,
    1480,  1481,  1482,  1483,  1484,  1485,  1486,  1487,  1488,  1489,
    1490,  1491,  1492,  1493,  1494,  1495,  1496,  1497,  1498,  1499,
    1500,  1501,  1502,  1503,  1504,  1505,  1506,  1507,  1508,  1509,
    1510,  1511,  1512,  1513,  1514,  1515,  1516,  1517,  1518,  1519,
    1520,  1521,  1522,  1523,  1524,  1525,  1526,  1527,  1528,  1529,
    1530,  1531,  1532,  1533,  1534,  1535,  1536,  1537,  1538,  1539,
    1540,  1541,  1542,  1543,  1544,  1545,  1546,  1547,  1548,   911,
     910,   937,   970,   971,   972,   973,   917,  1067,     0,  1064,
     525,     0,   441,     0,     0,  1087,     0,   118,     0,  1082,
       0,   436,   435,   465,   466,   472,   434,   498,   499,     0,
       0,     0,     0,   518,   516,   489,   482,   488,     0,     0,
     486,     0,   490,   668,   511,   423,   476,   477,   480,   422,
       0,   514,     0,   524,   512,   481,     0,  1089,     0,     0,
       0,     0,     0,  1216,     0,     0,    72,    53,   249,     0,
     110,     0,     0,     0,     0,     0,     0,     0,    80,    77,
      78,    79,     0,     0,     0,     0,   174,   175,   188,     0,
     179,   180,   177,   181,   182,     0,     0,   167,   168,     0,
       0,     0,     0,   166,     0,     0,     0,     0,     0,     0,
       0,     0,   381,   305,     0,   295,     0,     0,     0,     0,
       0,   330,   987,   985,   983,   986,   988,     0,     0,   154,
     156,     0,   294,   268,     0,   999,  1216,   996,   285,     0,
     363,   360,   964,     0,   363,   935,     0,   363,   161,  1216,
     297,     0,  1012,  1030,   171,   191,   172,   192,     0,   153,
       0,     0,     0,   595,   591,   587,   654,   655,   656,   653,
     666,   652,     0,   601,   657,   975,     0,   607,   610,   974,
       0,   919,     0,     0,   905,   901,     0,     0,     0,     0,
       0,     0,   874,   877,   878,   879,   876,   880,   875,     0,
       0,   881,     0,     0,     0,     0,     0,   640,   639,     0,
     837,   848,   849,   850,   845,   846,   847,   839,   840,   841,
     842,   843,   844,   861,     0,     0,     0,     0,     0,     0,
       0,     0,   730,     0,     0,   832,     0,   863,   891,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   863,
     897,     0,   918,     0,     0,     0,     0,   948,   669,   683,
     684,   685,   689,   926,     0,   920,     0,     0,   670,   697,
       0,   898,   725,     0,   713,     0,   705,     0,   711,   715,
     693,   708,     0,   690,     0,   921,   860,     0,   858,     0,
     680,   681,   682,   674,   675,   676,   677,   678,   679,   686,
     836,   834,   835,     0,     0,     0,   815,     0,     0,   710,
    1209,  1243,     0,   455,   455,   455,   443,   453,   925,     0,
     581,     0,     0,     0,     0,   763,   464,   581,     0,   665,
     567,   912,   915,   967,  1077,  1065,  1066,   864,   966,   124,
       0,  1085,     0,     0,     0,   130,   113,     0,  1083,     0,
     146,   528,     0,   918,     0,   470,   471,     0,   475,  1428,
    1323,     0,     0,     0,     0,   491,   519,     0,   510,     0,
     941,   492,   940,   493,   496,   497,   487,   520,   930,   522,
       0,   515,   427,   426,   526,     0,    38,     0,  1216,    55,
       0,     0,     0,     0,     0,     0,   204,   240,   204,    92,
    1216,   363,  1216,   363,  1120,  1185,  1337,     0,    51,    84,
       0,   273,   104,     0,   258,   302,    74,    89,    97,     0,
       0,    40,   164,   178,   183,   100,   187,   184,  1004,   185,
     111,     0,    36,     0,    98,     0,  1002,     0,     0,    42,
     102,  1006,   380,     0,   296,     0,   390,   370,   371,   381,
       0,   297,   984,     0,     0,     0,     0,     0,   288,   286,
     316,     0,   293,   287,   295,     0,     0,   244,     0,  1114,
       0,     0,     0,     0,   333,   965,   335,     0,   337,     0,
       0,  1061,   866,   868,   869,   592,   588,     0,     0,     0,
       0,     0,     0,     0,     0,   871,   608,   460,     0,     0,
       0,   902,     0,     0,   801,     0,   777,   779,   609,   791,
       0,   622,   802,   803,   781,   783,     0,   852,     0,     0,
       0,   792,   732,   733,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   748,   747,   793,   831,     0,     0,   889,   890,   794,
     650,   649,   651,   651,     0,     0,   896,     0,     0,     0,
     799,   757,   864,   634,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   714,   707,     0,   712,   716,     0,     0,
       0,   701,     0,     0,   699,   726,   695,     0,     0,   727,
       0,     0,     0,   770,   455,   455,   455,   455,   452,   454,
       0,     0,     0,     0,  1323,     0,   550,   527,   529,   537,
     550,   555,   772,   579,   773,     0,   932,     0,   501,   464,
     464,   464,   769,     0,     0,   463,   501,     0,  1055,   914,
       0,  1068,     0,  1086,     0,   135,   117,   137,   136,     0,
     144,     0,   918,     0,   135,   119,     0,   138,     0,  1085,
       0,   150,   467,     0,   853,   475,     0,   469,   495,   494,
       0,   485,   517,   483,     0,   523,     0,     0,     0,   248,
       0,     0,     0,   204,     0,     0,   312,     0,   299,    73,
       0,     0,     0,    47,     0,    65,    57,    43,    71,     0,
       0,    76,     0,    69,    86,    87,    85,    90,     0,   232,
     214,   245,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,   412,   413,   169,   411,   306,
       0,     0,   999,   982,     0,     0,   157,   297,     0,   272,
     268,     0,   266,   265,   267,     0,  1115,   162,     0,  1110,
     998,     0,     0,   993,   363,     0,     0,     0,   593,     0,
     659,   660,   661,   662,   663,   664,     0,   658,   602,   628,
       0,   904,   900,     0,   774,   872,     0,   862,   884,   883,
     731,   743,   744,   745,   885,     0,     0,     0,   740,   741,
     742,   734,   735,   736,   737,   738,   739,   746,   894,   893,
     887,   888,   646,   644,     0,   796,   797,   798,   895,   833,
     665,   949,   671,     0,     0,   698,   899,   717,     0,     0,
       0,   694,   852,     0,     0,     0,     0,     0,   703,     0,
       0,     0,   818,   813,   814,     0,     0,     0,     0,   446,
     445,   451,   550,   555,     0,     0,   429,     0,   537,     0,
     549,   535,   548,     0,     0,   561,   559,     0,   561,     0,
     561,     0,   531,     0,   551,   533,   548,     0,   571,     0,
     933,   580,     0,   508,     0,     0,     0,     0,   764,   508,
       0,   913,   442,  1084,     0,  1080,     0,     0,     0,   125,
     122,   112,     0,     0,   147,   135,   126,     0,   468,   473,
     474,   484,   931,   105,   204,     0,     0,    54,     0,   314,
     260,   292,   275,     0,     0,     0,   205,     0,   280,     0,
      46,    66,     0,    62,     0,    91,     0,     0,     0,     0,
       0,    49,    61,     0,    44,     0,   363,   363,    52,   259,
     211,  1272,     0,   839,   840,   209,   301,   206,   307,   208,
     210,   610,   207,   304,   101,  1005,     0,    99,     0,  1003,
     108,   106,   103,  1007,   393,   373,     0,     0,  1216,     0,
     999,   155,   294,     0,   322,   244,   317,     0,  1114,  1112,
       0,  1109,     0,     0,     0,   338,     0,     0,   589,   594,
     667,   903,   790,   800,   882,     0,     0,     0,     0,   795,
     950,   723,   721,   718,     0,   719,   702,     0,     0,   700,
     696,     0,   728,   804,     0,   820,   817,   450,   449,   448,
     447,   536,   534,   939,     0,   539,   546,     0,   530,     0,
     560,   556,     0,   557,     0,     0,   558,     0,     0,   532,
       0,   546,     0,   578,   464,     0,     0,   809,   767,   768,
     765,   464,   946,   809,  1056,   134,   114,     0,   115,   145,
       0,     0,     0,     0,   139,   367,     0,   310,    56,     0,
     292,     0,   204,   277,   276,   279,   274,   278,   281,     0,
       0,     0,     0,     0,   261,     0,     0,     0,   225,     0,
       0,   292,   298,   221,   222,   331,     0,     0,     0,    58,
      48,    45,    50,    59,     0,     0,    60,    63,   586,    75,
      68,   610,   610,     0,     0,     0,     0,   369,   382,   376,
     169,     0,     0,     0,     0,   294,     0,     0,     0,  1114,
       0,     0,   202,     0,   241,     0,   159,  1113,     0,  1102,
       0,   991,   992,     0,     0,   590,   749,     0,     0,     0,
     720,   724,   722,   704,   806,     0,   464,   574,     0,   577,
     538,     0,     0,   540,     0,     0,   542,   544,     0,     0,
       0,     0,   582,     0,     0,     0,   936,     0,     0,   500,
     502,   505,   504,   507,     0,   431,     0,   430,     0,     0,
       0,   148,     0,   141,   141,     0,   127,   854,     0,   204,
       0,   291,   311,   239,     0,     0,   223,     0,   229,     0,
     263,   264,   262,   224,   292,   297,   226,   332,     0,    67,
       0,    83,   610,     0,   303,   109,   107,   414,     0,   388,
     396,   401,   379,     0,   379,     0,   398,   402,   379,   397,
     379,   392,   393,     0,   999,  1109,     0,     0,   268,   162,
    1111,   257,   250,   251,   252,   253,   254,   255,   256,   271,
     270,   242,   243,     0,     0,     0,   993,     0,   750,     0,
     751,     0,   823,   579,     0,     0,   573,     0,   547,   563,
       0,   543,   541,     0,   552,     0,   586,     0,   554,   764,
     506,     0,   808,   810,     0,   766,     0,   121,     0,   581,
       0,     0,   143,   143,   129,     0,   297,   313,     0,   283,
     290,   282,     0,     0,   220,     0,   227,   321,   213,   585,
       0,    70,     0,   308,   383,     0,   386,     0,   385,   389,
     384,   378,     0,   409,     0,     0,     0,     0,     0,     0,
     368,   372,     0,  1103,     0,  1109,   244,  1114,     0,  1106,
       0,     0,   999,   752,   819,     0,     0,     0,   572,   575,
       0,   545,     0,     0,   583,   584,   553,   503,     0,     0,
     116,   141,   120,   149,   140,   472,   142,   472,     0,   321,
     269,     0,     0,   247,   213,     0,   238,     0,    64,    82,
     309,   415,     0,   374,   410,   399,   404,     0,   408,   406,
     405,   400,   403,     0,   294,  1104,   203,   160,  1107,  1108,
       0,   581,  1399,  1163,  1371,     0,   821,   824,   822,   816,
       0,   562,   570,   811,   812,   143,   475,   475,   581,   238,
     284,   289,     0,   228,   230,   318,   319,   320,     0,   234,
     231,   235,     0,   387,     0,   407,  1109,     0,   989,     0,
     828,   827,   826,   830,   829,   576,     0,   568,   472,   132,
     131,   128,   204,   246,     0,     0,     0,   236,     0,   237,
     212,   375,  1105,   999,     0,     0,   475,   315,   217,     0,
     216,     0,   300,   233,   581,   825,     0,   133,   215,   219,
     218,   990,   569
};

/* YYDEFGOTO[NTERM-NUM].  */
static const yytype_int16 yydefgoto[] =
{
      -1,    30,    31,    32,    33,  1795,  1796,  1797,  1517,   785,
    2421,  1518,   786,   787,  1799,    34,    35,  1182,   460,  1455,
    1126,  2162,    37,  1750,  1460,  1754,  2291,  1985,  1749,  1756,
    2402,  2475,  1751,  1461,  2292,  1462,    38,    39,  1239,    40,
     574,    41,  1240,  1209,   865,   805,  1199,   857,    42,    72,
      43,  1786,  2046,  2488,  1809,  2582,  2192,  2193,  1519,  2539,
    2540,  1788,  1846,  1191,  2533,  1568,  2359,  1523,  1506,  2194,
    1577,  2301,  2074,  1520,  2016,  1569,  2179,  2408,  1247,  1570,
    2409,  2172,  1571,  1223,  1243,  2018,  2541,  1524,  1224,  2047,
    1178,  1572,  2486,  1573,    91,  2197,    44,   451,   452,   565,
     838,   453,   461,    46,  1559,  2220,  2492,  2221,  2432,  1553,
    2217,  2429,  2327,  1227,  2218,    82,  2341,  2493,  1827,  2328,
     462,   684,    49,    50,    51,   511,   505,   506,  1010,  1426,
    1710,   757,   482,   483,   521,  1735,  1133,  1134,  1468,  1767,
    1158,  1159,   766,   767,  1146,  1150,  1151,  1481,  1474,  1139,
    1973,  2279,  2280,  2281,  2147,  1154,  1155,   769,   770,   771,
    1163,  1491,    53,  1430,  1717,  1718,  1719,  1950,  1951,  1965,
    1961,  2131,  2266,  1720,  2139,  2557,  1721,  2257,  2258,  2376,
    1968,  1728,  2271,  2272,  2321,   895,  1275,   896,   685,   897,
    1287,   686,   933,   899,   687,   688,   689,   902,   690,   691,
     692,   693,   916,   694,   695,   952,  1283,  1284,   742,  1341,
     697,   698,   699,  1723,   700,  1005,  1416,  2285,  2392,  2393,
    1703,  1933,  2115,  2256,  2457,  2516,  2517,   701,  1413,  1000,
    1001,   702,  2049,  1003,  1334,  1360,   870,   871,   907,  1309,
    1310,  1337,  1630,  1344,  1349,  1657,  1658,  1361,  1382,   703,
    1294,  1295,  1612,   918,   704,   731,  1030,   964,   914,  1377,
     715,   705,   706,  1487,   498,  2262,   570,  1110,   707,   708,
     709,   710,   711,   712,  2476,   840,   747,   873,  1521,    54,
     614,   541,    55,   819,  1234,    56,  2242,  2084,   828,  1249,
    1581,    92,    57,    58,    59,   528,   860,   463,   861,   862,
     603,    60,   866,   605,   606,    61,   488,   489,   867,  1021,
     868,    62,   469,    63,   738,   502,   739,   741,   465,   754,
    1745,  1451,    65,    66,   476,   477,    67,   490,    68,  2239,
     466,  1849,   825,   430,   431,   714,  1115
};

/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
   STATE-NUM.  */
#define YYPACT_NINF -2247
static const int yypact[] =
{
    2450,   -77,    20, -2247, -2247,   -77, -2247,   -77,    53,  1978,
   29629,  5175,   -77, 33661,   924,   311, 33661, 33661, 30077,   -77,
     230, 34109, 30525,   -77, 30973,    -4,  -124, 34557, 33661,  1109,
     337,   -93, -2247, -2247, -2247, -2247, -2247,   107, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,    94, -2247,
     359,   160,   423,   -59, -2247, -2247, -2247, -2247, -2247, -2247,
     -35, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, 35005, 33661, 35453, 31421, 35901, -2247, -2247,
   -2247,  1109, 33661,   600,   622,   180, 36349, -2247, -2247, -2247,
   -2247,   457,   344, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, 31869, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247,   424, -2247, -2247,   318, -2247,    50, -2247,   313,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,   447, -2247,
   -2247, 36797, 37245, 37693, -2247, -2247,   296,   566,   507, 17743,
   -2247, -2247, -2247, -2247,   -35, -2247, -2247, -2247, -2247, -2247,
    -145,   348, -2247,   355,   623, -2247, -2247, -2247,   368, -2247,
   -2247,   628,  7545,  7545, 38141,   311, 38141,   486, -2247, -2247,
      15, -2247,   509,   763,   368, -2247, 18645, -2247,   527,    11,
   -2247,   189,   817,  9895, 33661,   526, -2247,   553,   526,   570,
     607,   423, -2247,  2450,   917,   881, 30973,   269,   269,  1072,
     269,   754,   935, -2247,   884, -2247,   673, -2247, 33661,  1000,
      95,   832,  1022,  3649,  1056,   721,  1059,   967, -2247, -2247,
   -2247,   742, -2247,   771, -2247, -2247, -2247, -2247,   566,   991,
   -2247,   823, 38589, 39037, 33661,  1172, -2247, -2247, -2247, -2247,
     835, -2247, -2247,    68,  1112,    47,   812, -2247,  1153,    51,
   -2247,  1187,  1076,  9895, -2247,   961, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
    -124, -2247, -2247,   215, -2247, -2247, 23978, -2247, -2247, -2247,
     507, 23978,  9895, 43069,  1311, -2247,  1137, 33661,   911,    85,
   -2247, -2247, -2247, -2247, -2247, -2247,  1387,    74,  1398,  9895,
     943,    74,    74,   945,  1257, -2247, -2247, -2247,    92,   953,
     954, -2247,   121,   121, -2247,  1134,   974,   978, -2247,   125,
    1004,  1462,  1468,   126,  1007,  1008,  1010,   591,    74,  9895,
   -2247,  1016,   121,  1018,  1020,  1024,  1484,  1026, -2247,  1490,
    1029,   133,   152,  1030,  1032, -2247, -2247,   127,  9895,  9895,
    9895, -2247,  6605, -2247,    11,   311, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247,  1033, -2247,   131,  4312, -2247,  1077, -2247,
   -2247,  1235,  9895, -2247, -2247,   -49, -2247,   140, -2247, -2247,
   -2247,    11, -2247,   120, -2247,  1312,  1044, -2247, -2247, -2247,
     206,  1428, 23082, 23530, -2247,  1305, 33661, -2247, -2247,  9895,
   22186, -2247,    11, -2247, -2247, -2247, -2247, -2247, -2247,   338,
   -2247,   -35, 25022,   357,   526, 33661, 33661,  1494, -2247, -2247,
   -2247, 30973, 33661, 39485,  1180, -2247, -2247,   423,   423,  9895,
     423,   119,   496,  8015, 10365,  1376,  1274,    96,   141,  1383,
   -2247,  1280,   754,   935,  9895,   553, 33661, 28285,   595,   686,
    1075,  1155,  1078,   395,  1463, -2247,  1079, -2247,  1165, 33661,
   43503,   154, -2247,  1505,   154,   154,   558,  1511,  1181,   218,
    1328,   -60,   237,  1079,  1314, -2247, 30973,    79,   561,  1079,
   33661,  1184,   710,  1079,  1186, 33661,  1147,   -69,  1440,  1496,
   33661,  1339,  1314,  1341,  1124,  1558,   771, -2247, 39933, -2247,
   -2247, -2247, -2247, -2247, 33661, -2247, -2247, 33661, -2247, 25597,
    1128, 33661, 33661, -2247, 33661, 33661,   450, 40381,   507, 27389,
   -2247, -2247, -2247, -2247,   680,   706, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,  1127, 25022,
     498, -2247,   767,   785, -2247, -2247,  1182, -2247,  1182,  1182,
    1138,  1138,  1139, -2247, -2247, -2247,   591,  1182,  1138, -2247,
   43503, -2247,   533,   576, -2247, -2247,  1570, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247,   781,   571,  -163, -2247,
    1109, -2247, -2247,  9895,    11, -2247,  1142, 25022,  1185,  9895,
   -2247, -2247,  9895,  1143,  1605,  1605,  9895, -2247, -2247, -2247,
   -2247,   904,  1605, -2247,  9895,  9895,  1605,  1605,  1182,  1182,
   -2247, 25151,  9895, -2247, 20897,  9895, 12715,  8485,  9895,  1230,
    1231,  1605, -2247,  1605, -2247,  9895,  7075, 25151,  1607,  1607,
    1827,  4459,  1150,    11,    11, -2247,  1605,    58,   748, -2247,
     173, 43069,  9895,  9895,  9895,  9895, 25597,  1236,   114, 33661,
    9895,  1158,  1099, -2247,  9895,  1370, -2247,  1163,  9895,  1243,
     153,  9895,  9895,  9895,  9895,  9895,  9895,  9895,  9895,  9895,
   -2247, -2247, 14584,   198,  1461,  1480,   -96,   176, 32317,  7545,
    1474,  5665, -2247,   139,  1474, -2247, -2247, -2247, -2247,   142,
   -2247, -2247, -2247, -2247,  1127, -2247,  1127, -2247,  1171,  5201,
    1168, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, 33661,   189, 29181,
   -2247,  9895, -2247,   596,  1178,  1232,   540,  1611, 33661, -2247,
   19095,  1446, -2247,  1179, -2247, 24423,  1446, -2247, -2247, 13174,
    1298,  1442,  1388, -2247, -2247, -2247,  1192, 25022, 10835, 10835,
   -2247,   536, 25022,   580, -2247, -2247, -2247, -2247, -2247, -2247,
     518, -2247, 33661,   387,  1376,   141,   606, -2247,  1106,  1189,
   40829, 33661,  1447,  1415,  1457,  -119, -2247, -2247, -2247, 43069,
   -2247, 33661, 33661, 41277, 41725, 26045, 33661, 25597, -2247, -2247,
   -2247, -2247, 33661,   900, 33661, 21735, -2247, -2247, -2247,   154,
   -2247, -2247, -2247, -2247, -2247, 33661, 33661, -2247, -2247,   154,
   33661, 33661,   154, -2247,  1130, 33661, 33661, 33661, 33661,  1198,
   33661, 33661,  1367, -2247,   612, -2247,  1411,     5,  1253, 33661,
   33661,  1176, -2247, -2247, -2247, -2247, -2247,  1210,  1535, -2247,
    1314,  1537, 28733,   661,    25,  1251,  1434, -2247, -2247,  1420,
      47, -2247, -2247, 25597,    51, -2247,  1421,   116, -2247,  1441,
     771,  1656, -2247, -2247, -2247, -2247, -2247, -2247, 23978, -2247,
    9895,  9895,  9895,  1661,  1240,  1244,  1308,  1309,  1313, -2247,
    1233,  1320,  1605, -2247, -2247, -2247, 43069, -2247,   643, -2247,
     630, -2247,  9895,  9895,    18, -2247, 24495,   631,  9895,  1242,
    1247,   678, -2247, -2247, -2247, -2247, -2247, -2247, -2247,  1250,
    1557, -2247,  1252,   682,   697,  1255,  1264, -2247, -2247,  3980,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247, -2247,  1265,  1256, 24533,  1267, 12715, 12715,
    6605,  2357, -2247, 12715,  1269, -2247,   729, 24436,  1268,  1270,
    1290,  1291,  1275,  1276, 24552,  8955,  9895,  8955,  8955, 24893,
    1268,  1277, -2247,  9895,  1279,  1281,  1282, -2247, -2247,  2157,
    2157,  2157, 25151, -2247,  1304, -2247, 12715, 12715, -2247,  3248,
    6605, -2247, -2247,  1586, -2247,   632, -2247,  1288, -2247, -2247,
    3419, -2247, 20897, 25111,  9895,   122,  9895,  1158,  9895,  1368,
    2157,  2157,  2157,   196,   196,    75,    75,    75,   701,   176,
   -2247, -2247, -2247,  1293,  1294,  1295,  1481,  1026,  9895, -2247,
     792,   880, 33661,  2873,  3045,  3803, -2247, -2247, -2247, 15943,
    1331,  9895,  9895,  9895,  1297, -2247,   -70,  1331,  1605,   748,
   -2247, -2247,  9895,   553, -2247, -2247, -2247, 25022, -2247,  1109,
   15943,  1343,  1350,   -85, 18194,  1506, -2247, 33661, -2247, 33661,
   -2247,   -23,  1317, -2247,  9895, -2247, -2247,   441,  1319,  1507,
    1509,   733,   733,   536,  1512, -2247, -2247,  1369, -2247,  9895,
     827, -2247,   855, -2247, -2247, -2247, -2247,  1318, -2247, -2247,
    1556, -2247, -2247, -2247, -2247,  1403,  1079,  9895,  1542, -2247,
     117,  1329,  1652,   -87,  1616, 33661, -2247,  1529, -2247,   640,
    1662,   116,  1664,   116, 25597, 25597, 25597,   731, -2247, -2247,
     311, -2247, -2247,   757, -2247,    57, -2247, -2247, -2247,  1418,
     736,  1079,  1314, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
     112,   741,  1079,  1422, -2247,  1423, -2247,  1424,   877,  1079,
   -2247, -2247, -2247,   136, -2247, 33661, -2247, -2247, -2247,  1367,
   33661,   771, -2247,   960, 33661, 33661, 33661, 33661, -2247, -2247,
   -2247,  1346,  1355, -2247, 43069,   -89,  1563,  1565, 33661,  1399,
    1078,  1797,  1688, 33661, -2247, -2247, -2247, 33661, -2247,  1691,
    1109, -2247, -2247, 25022, 25022,  1372,  1244,  1605,   100,    44,
     383,  1497,  1605,  1601,  1377, -2247, -2247, -2247,   776, 25009,
    9895, -2247,  1708, 43069, -2247,  4983, -2247, -2247, -2247, -2247,
    9895, -2247, -2247, -2247, -2247, -2247,  9895, -2247, 20897,  9895,
    1684, -2247,  1836,  1836,  4459, 43069, 12715, 12715, 12715, 12715,
     497,  1018, 12715, 12715, 12715, 12715, 12715, 12715, 12715, 12715,
   12715, 13644,   240, -2247, -2247,  9895,  9895,  1693,  1684, -2247,
   -2247, -2247,  -143,  -143, 43069,  1384,  1268,  1386,  1389,  9895,
   -2247,    11, 21353, -2247,  1379,   311,  9895,  1657,  2708,  9895,
     784,  9895,  1697, -2247, -2247,  1393, -2247, -2247, 43069,  9895,
    1394,  3446, 12715, 12715,  3929, -2247,  4602,  9895,  6605, -2247,
    1583,  1437, 19545, -2247,  1489,  1489,  1489,  1489, -2247, -2247,
   33661, 33661, 33661, 16393,  1709, 15492, 32765,  1406,   670, -2247,
   32765, 33213, -2247,  1417, -2247,  1413,    11,  9895,  1707,   -42,
     -42,  1583, -2247,  9425,  1414, -2247,  1707,  1425, -2247, 25022,
    1419, -2247,  1426,  1406,  9895,  1555, -2247, -2247, -2247,  1470,
   -2247,   797, -2247,  1807,  1555, -2247,   802, -2247, 19095,  1343,
    9895,    11, -2247,  1432, -2247,  1319,   167, -2247, -2247, -2247,
    1623, -2247, -2247, -2247, 33661, -2247, 33661, 21371,  1756, -2247,
   33661, 33661, 33661, -2247, 33661,   807,   534,  1436, -2247,   534,
    1739,   535,  1078,   218,  1899,   -10, -2247, -2247, -2247,  1519,
   33661, -2247, 33661, -2247, -2247, -2247, -2247, -2247, 26045, -2247,
   -2247, -2247, 25597, 20448, 25597, 33661, 33661, 33661, 33661, 33661,
   33661, 33661, 33661, 33661, 33661, -2247, -2247,   237, -2247, -2247,
     136,  1451,  1251,  1496, 42173,   808,  1314,  1452,  1885, -2247,
     661, 28733, -2247, -2247, -2247,  1844, -2247,   296,   134, -2247,
   -2247,  1109, 33661,  1513,   116, 33661,  1605,  1456, -2247,  1460,
   -2247, -2247, -2247, -2247, -2247, -2247,  1464, -2247, -2247, -2247,
    9895, 25022, -2247,  1467, -2247, 25022, 21390, -2247, 25022,  1693,
   -2247,  2780,  2780,  2780,  4620,  1766,   169,  1475,  2780,  2780,
    2780,   233,   233,    84,    84,    84,  1836,   240, 25022, 25022,
   -2247, -2247, -2247, -2247,  1473, -2247, -2247, -2247,  1268, -2247,
     748, -2247,   663,  9895,  9895,  2721, -2247,  4242,  9895, 43069,
     828,  2721,   257,  9895,  3490,  4197,  9895,  9895,  5076, 21428,
    1478,  9895, 42621, -2247, -2247, 33661, 33661, 33661, 33661, -2247,
   -2247, -2247, 32765, 33213,    11,  1492, 15041,   670,  1483, 33661,
   -2247, -2247,  1495, 15943,  1720,  1655, -2247, 15943,  1655,   510,
    1655,  1748,  1569, 19995, -2247, -2247,  1499,  1695, -2247,  5665,
     390, 25022,  1908,  1795,  1502,  1503,  1504,  9895,   311,  1795,
     311, -2247, -2247, 25022,  7545, -2247,  1109,   979, 33661,    11,
     -48, -2247,  1518, 33661, -2247,  1555, 25022, 20897, -2247, -2247,
   -2247, -2247, -2247, -2247, -2247, 33661,   847, -2247,   848,   534,
   -2247,  1545, -2247,   161,  1787,    55, -2247, 25597,  1536,   274,
   -2247,  1799,  1725, -2247,   154, -2247,  9895,   274,  1726,   157,
   33661, -2247, -2247,  2614, -2247, 43069,   116,   116, -2247, -2247,
   -2247,  1432, 43503,   680,   706, -2247, -2247, -2247, -2247, -2247,
   -2247,  -163, -2247,  1527, -2247, -2247,  1597, -2247,  1598, -2247,
   -2247, -2247, -2247, -2247,  1520,    22, 33661,  1955,  1740,  1525,
    1251, -2247, 28733,   531,   137,  1565, -2247,   124,  1399, -2247,
    1891,  1571,  1733, 33661,  1533, -2247,  1969,  1541, -2247, -2247,
   -2247, 25022, -2247, -2247, -2247, 12715,  1849,  1546, 43069, -2247,
   -2247,  2721,  2721,  4242,   853, -2247,  2721,  9895,  9895,  2721,
    2721,  9895, -2247, -2247, 21447,  1727, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247,    11, 26493, 32765,  1547, 33661,   670, 15943,
   -2247, -2247,  1315, -2247, 15943,  1806, -2247, 15943, 27837, -2247,
   33661,  1549, 33661, -2247,   -70, 11305,  9895,  1588, -2247, -2247,
   -2247,  1583, -2247,  1588, -2247,  1044, -2247,   -85, -2247, -2247,
    1935, 16843,  1893,  9895, -2247, -2247,  1553,   534, -2247,  1710,
    1545,  1559, -2247, -2247, -2247, -2247, -2247, -2247, -2247,   859,
    1560, 33661, 33661, 12715, -2247,   274,   188,   128, -2247,  1814,
   33661,  1545, -2247, -2247, -2247, -2247,  1917,  1995,  1887, -2247,
   -2247, 25022, -2247, -2247,  1605,  1605, -2247, -2247,  1963, -2247,
   -2247,  -163,   654, 20448, 33661, 33661, 25597, -2247,  2665, -2247,
     237,  1919,   890,  1109,  1890, 28733,  2003,  1572, 33661,  1399,
    1358,  1358, -2247,  1705, -2247,  1712, -2247, -2247,   192, -2247,
   33661, -2247, -2247, 16843,  1109, -2247,  4768, 12715, 43069,   891,
   -2247,  2721,  2721,  2721, -2247,  1989,  1583, -2247,   899,  2009,
   -2247, 33661,   901, -2247,  9895,  1578, -2247, -2247, 15943,  1315,
    1580,   903, -2247, 43069, 33661,   914, 43069,  1584,  6135,  1582,
   -2247, -2247, 25022, 25022, 33661, -2247,  1587, -2247,  1635, 33661,
    9895, -2247,   918,  1983,   175,   -13, 25022, -2247, 33661, -2247,
   25597, -2247,   534, -2247, 25597,  9895, -2247,  1618,  4620,  2021,
   -2247, -2247, -2247, -2247,  1545,   771, -2247, -2247,  1879, -2247,
   33661,  1647,   657,  1663, -2247, -2247, -2247, -2247,   919, 17293,
   -2247, -2247,  2024,   311,  2024,   621, -2247, -2247,  2024, -2247,
    2024, -2247,  1520,   311,  1251,  1571, 33661,  1109,   661,   296,
   -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247, -2247,
   -2247, -2247, -2247,  1998,  1791,  2001,  1513,   931,  4768,   936,
   -2247,  9895,    -5,  1417, 26493,  1602, -2247,   940, -2247, 25022,
   33661, -2247, -2247,  9895, -2247, 33661,  1963,   948, -2247, -2247,
   -2247, 11305,  1599, -2247,  2033, -2247,  1109, -2247, 21465,  1331,
   16843, 33661, 33661, 33661, -2247,  1721,   771,   534,   965, -2247,
    1620, -2247, 21500,  1816, -2247,  1897, -2247,  1845,  1612, -2247,
    9895, -2247,  1682, -2247, -2247, 25597, -2247, 26941, -2247, -2247,
   -2247, -2247,   311, -2247,   311,  1825, 33661, 22634,   311,   311,
   -2247, -2247,  2050, -2247,  1621,  1571,  1565,  1399,  1818, -2247,
    1820,  1624,  1251, -2247,  1268, 11775, 11775,  1625, -2247, -2247,
   33661, -2247,   986,   993, -2247, -2247, -2247, -2247, 33661,  1627,
   -2247,  1983, -2247, -2247, -2247,   224, -2247,   224, 19095,  1845,
   -2247, 25597, 20448,  1843,  1612,    35,  1830,  1314, -2247, 25022,
   -2247, -2247,   994, -2247, -2247, -2247, -2247, 33661,  1626, -2247,
    1626, -2247, -2247,  1109, 28733, -2247, -2247, -2247, -2247, -2247,
   16843,  1331, 14114,  1765,    77, 24476, -2247, -2247, -2247, -2247,
     995, -2247,  1780, -2247, -2247, 33661,  1319,  1319,  -130,  1830,
   -2247, -2247,  1912, -2247, -2247, -2247, -2247, -2247,    64,  1839,
   -2247,  1840,  1340, -2247, 26941,  1626,  1571,  1001, -2247,  2075,
   -2247, -2247, -2247, -2247, -2247, -2247,  1641, -2247,   224, -2247,
   -2247, -2247, -2247, -2247,    86,    86,  1993, -2247,  1701, -2247,
   -2247, -2247, -2247,  1251, 12245,  9895,  1319,   534, -2247,  2093,
   -2247,    93, -2247, -2247,  1331, -2247, 21732, -2247, -2247, -2247,
   -2247, -2247, -2247
};

/* YYPGOTO[NTERM-NUM].  */
static const yytype_int16 yypgoto[] =
{
   -2247, -2247, -2247,  1629, -2247, -2247, -2247,   334, -2247,   939,
   -2247,   325,  -354,   627, -2247, -2247, -2247,  -727,    30, -2247,
   -2247, -2247, -2247,   156,   382, -2247,  -254, -1590,    -8, -2247,
   -2105, -2150, -2247,  -331, -2029, -1390, -2247,  -781,   315, -2247,
   -1777, -2247,  -532,  -782,  -598,  -800, -2247,   123, -2247,  1157,
    -768, -1447, -2043,  -326, -2247,  -406, -2247,  -154, -1457,  -378,
    -360, -2247, -1948,  -722, -2247,  1401,   -67, -2247,   668, -2247,
   -1759, -2247, -2247,   660, -2247,  -746, -2247, -2247, -1532,   335,
    -301, -1783, -1976,   626,  -527, -2247,  -355,   373, -1421, -2247,
     687, -2247,  -291, -2247,  -399, -1854, -2247, -2247, -2247,  1352,
    -534, -2247,    32, -2247, -2247, -2247, -2247, -2247, -1315,   633,
    -153, -2247,  -235, -2247, -2247, -2247, -2247,  -349,   366, -2247,
      10,   174,   -27,    16,    37,    33,    45,  1454,  1485, -2247,
    -412,   805, -2247, -2247,  -490,   -47, -2247,   737, -1602, -1709,
    -335,  1037,  1438,  1443, -2247,   727,  1068, -1037, -1022, -2247,
     472, -2247,  -181, -2247,   232,  -293,  1048, -2247,  1444, -2247,
   -2247, -2247, -2247,  -922,   768, -1627,   502, -1611, -1529,   276,
     262,  -627,   -45,    24, -2247, -2247,   512,  -152, -2247, -2247,
    -146, -1398, -1986,  -151,  -155,  -947,   962,  -753, -2247, -2247,
    -616,  -400, -2247, -2247, -2247,  -240,   809, -2247, -2247,  1287,
    1449, -2247,   501,  1619,  -408,  -631,  -928,  -649,  3062, -1069,
    -588, -1034, -2247, -1881,   614, -2247, -2247,    83, -2247,  -231,
   -2247,  -229, -2247, -2247, -2247,  -218, -2246,  1239, -2247,  -931,
   -2247,  3215,   779, -2247, -1328,  -488,  -967, -1221, -1623, -2247,
   -2247, -2247, -2247, -2247, -2247, -1009, -1456,  -531,   851, -2247,
   -2247,   956, -2247, -2247, -2247,  -679,   810,  -494,  -641,   858,
   -2247,  -474,  1246, -2247,   186,  -431,    91,  -711,  -606, -2247,
    2264,   -15,     1,   723,  -445,  -872,  -713, -2247,  -718, -2247,
   -2247,  -847, -2247,   694, -2247,  -765, -2247,  -109, -2247, -2247,
   -1761, -2247, -2247, -2247, -2247,  -313, -2247,  -365,  -343, -2247,
   -2247,    36,  -599,  1410, -2247, -2247,   879, -2247,   992, -2247,
     675, -2247, -2247, -2247,  1146, -2247, -2247, -2247,    43,  1510,
     508, -2247,  1151, -2247, -2247, -2247, -2247,   700,  -764, -2167,
      72, -1958,  -802,  1711,  -377,  -324, -1747
};

/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
   positive, shift that token.  If negative, reduce the rule which
   number is the opposite.  If zero, do what YYDEFACT says.
   If YYTABLE_NINF, syntax error.  */
#define YYTABLE_NINF -1455
static const yytype_int16 yytable[] =
{
     468,   804,   510,   522,  1213,   732,   567,   863,   856,   716,
      47,   429,  1111,  1333,   429,   743,   816,   470,   429,   475,
    1212,   569,   475,   475,  1368,   499,   927,   928,   429,   429,
      36,  1177,    45,    52,   772,   843,  1288,  1196,  1232,  1736,
    1367,   954,   963,    64,  1436,  1261,   943,    52,   497,  1592,
     464,  1233,  1184,  1116,  1235,  1236,  1998,  1804,   575,  1806,
    1188,  1789,  1167,  1289,  1690,  1920,  2052,   624,   524,  1757,
    2078,  2067,    69,   508,   499,   429,   499,   499,   499,  -643,
    1217,  2075,   608,   499,  1785,   846,   971,   550,  1947,   525,
    -959,   540,  1437,   576,  -417,  1635,  2227, -1454,  -959,  -959,
     535,   428,    80,   835,   456, -1454, -1454,   835,   471,   624,
    1964,   538,  1483,   539,    52,   977,   602,   777,   507,   507,
    2236,  1111,  1018,   778,   542,  -960,  -610,  2232,  1252,  1486,
    -623,  -648,  -638,  -960,  -960,   609,   467,  1273,  -651,  1429,
    -377,   467,  2578,  1835,  -939,   467,   979,   467,   830,   817,
    1610,   610,  1180,  1375,   560,  1008,  2275,  -651,   850,   500,
    -420,  1375,  1215,   624,  1991,   531,   624,  1557,  2176,  1578,
    2324,  1189,   835,  2202,    48,  1842,  1153,   721,  2443,   803,
    2564,   809,  1169,   813,  -417,  1180,   765,   971,    48,  2403,
     831,  1962,   733,  1197,   962,  1817,  1200,  1201,  2535,  -837,
    1395,  1900,   519,   509,  2589,   906,  -837,   971,    73,  1015,
     850,   467,  1731,   898,  2367,   624,   977,  1013,  2160,     3,
       4,  1860,  -169,   514,  1410,   779,   523,  -169,   768,   608,
     519,  1411,  1507,  2551,   608,  1291,   977,  1417,  2079,  2404,
    2233,  2312,  1228,  2259,  1635,   864,  2401,   979,   761,  2363,
    -420,  1635,  2010,  2477,  2234,    48,   480,  2364,  1373,   530,
    1465,   533,   954,   537,   927,   928,  2549,   979,   543,  1632,
    1633,  2350,   943,  1137,  1652,  2173,  1172,  1211,  2505,  2230,
    2293,  1861,   609,  -856,  1291,  1116,  1166,   609,  2387,   949,
    -856,  1747,  1504,   761,  2096,   755,  2104,  1727,   429,  1245,
    1877,  2455,  2310,  2195,   926,   515,   839,  1677,  1678,  2226,
     950,   611,  1019,    70,  1793,  1123,   467,  1016,   763,  2536,
    2082,  1999,   612,  2231,  1504,  1748,  2128,  2196,  2585,  2456,
    2132,  2309,  1964,  1396,  1116,  2579,  2009,   512,  1397,  1605,
    2033,  1758,  2174,   503,  1466,   608,   608,  1190,  1505,  2590,
     734,   832,   735,  1113,  1229,   481,    71,    74,  1342,  2006,
    -417,  2008,  2293,   763,    75,   780,  2525,  1138,    20,  2311,
    2552,  1418,   836,   900,  1398,  2558,   836,   513,  1187,  2572,
    1782,  2000,   906,  2080,  2313,  1280,   527,  2299,   557,   567,
     898,  2537,  1251,  1558,   756,  1722,  2405,    76,   609,   609,
    1257,  1733,    24,   722,   764,  2165,  1114,  1187,  2316,   885,
    1254,  2580,   526,  2121,   781,  1174,  1722,  2365,   782,  2161,
    -417,  2235,  1009,  2094,  1499,  1290,  -420,   561,  1119,  1270,
    2097,  1017,   510,  2219,  1297,  1483,  2581,  1164,  1301,  2531,
    1213,   836,    26,    77,  1293,   783,  1313,  1314,  1758,  1320,
     833,  1770,   566,   429,   429,    27,  1321,  1322,  1323,  1346,
    1348,  1333,  1113,   501,  1729,  1730,  2052,  1216,  2177,  1525,
     718,   723,   608,  2565,  2520,  2249,   729,   773,    28,  1165,
     730,  2547,   906,  1262,   617,   475,  -420,   475,  1376,  2507,
     898,    52,    29,  2259,   915,   604,  1692,   499,  2506,   517,
    1818,   548,  2263,  1825,  1826,   429,   602,  2267,  1399,   784,
    2269,  1738,  1592,  1813,  2260,  1114,   516,   499,   837,  2293,
      81,  1175,   842,    47,  -417,   609,  1814,   524,  2227,   499,
    1365,  2416,   555,  -837,  1378,  1111,  1764,   737,   999,  1759,
     753,  -643,  1585,    36,   572,    45,    52,  1650,   525,   744,
     900,  1475,  -959,   499,   499,   499,    64,  2167,  1412, -1454,
    2178,   518,  -417,   906,  -417,   949,  1858,  1881,  1882,  1883,
    1884,   898,  2447,  1888,  1889,  1890,  1891,  1892,  1893,  1894,
    1895,  1896,  1897,  2442,   949,    69,   950,  -960,   926,  2446,
    -420,   859,   932,  -648,  -638,   507,   859,   457,   967,  1113,
     951,  1533,  1742,  2164,   729,   950,  -939,  1011,   730,  1438,
     736,  1536,   854,   855,  1539,  2204,  2205,  -856,   912,   953,
    1863,  1879,  1885,  1924,  1925,  2369,  1189,  1507,  -420,  2293,
    -420,   519,    48,   509,   994,   995,   996,   997,   998,   999,
     729,  2381,  1489,    52,   730,  2222,  2020,  2012,  1207,  1901,
     900,  1452,  1114,   938,   939,   510,   996,   997,   998,   999,
     558,  1202,  1790,  1532,   854,   855,  1873,  1207,  1180,  2166,
     965,  1208,  1606,  1955,   971,  2228,  -169,  -169,  1181,  1722,
     968,  1722,   727,   848,  1264,   523,   849,    48,  1880,   624,
    1208,  2511,  1012,  1647,  1648,  1649,  1650,  1333,  1645,  1646,
    1647,  1648,  1649,  1650,  1956,  1020,  1140,   859,   859,  1763,
    1266,   559,   971,  2021,   775,   624,  1584,  1904,   478,  2134,
    1586,  1671,   494,  1588,  1280,  2302,  2013,   499,  1140,  1958,
    1741,   900,  1213,    83,   979,  2052,   562,  1768,   822,   824,
     826,   977,   624,   777,  1490,  1141,   429,   429,  1886,   778,
    1342,  1342,   499,   499,  1129,  1342,  2151,  1682,  1887,  1180,
    1534,  1954,   520,   573,  1838,  1537,    20,  1141,   551,  1183,
    1791,   906,   979,  1131,  1132,   753,  1136,   499,  1179,   898,
    -968,  -968,  1683,  2014,    48,  2015,  2022,   563,  1342,  1342,
     499,    84,  1189,  1203,   525,   525,  1204,   525,  1271,  1272,
      24,   552,  1190,  1142,  1608,   615,  1117,   499,  1113,  1118,
    1113,   499,  2584,  1819,  1496,   613,  1225,  2559,  2560,  1453,
     930,   499,  1761,  1725,  1665,  1120,  1667,  1668,  1121,  1248,
    1214,   616,  1563,  1955,   553,   566,   507,   617,   566,  1960,
      26,  1531,   429,   429,  1725,   429,   566,  2411,   499,  1143,
      20,   779,  2407,  1843,  1276,   729,   960,  -939,  1850,   730,
    1542,  1114,  1187,  1114,  1956,  1549,  2048,  2587,  1666,  1484,
    1485,  1143,  2435,  2526,    20,  2527,  1113,  2436,   906,  1957,
     554,    52,  1764,    20,    24,   604,   898,  1276,  1684,  1958,
      29,   608,  1680,  1685,   618,  1324,  1325,  1326,  1218,  1327,
    1328,  1329,  1330,  1331,  1332,  1144,   761,  1302,    24,   467,
     780,   762,  1028,  -491,  -491,  1959,  1311,    24,  1258,  1722,
     540,  1121,   777,  1722,    26,  1277,  2437,  1144,   778,  1114,
     962,   523,   523,  1255,   523,  1256,   720,    27,  1127,   900,
     538,  1189,   539,    52,   609,  1335,  1734,    87,    26,    88,
    1862,  1864,  1865,   542,     3,     4,  2576,    26,  1277,   724,
      28,    27,  1168,  1792,  1793,   949,  1269,  1189,  1190,  1270,
      27,   725,  1189,    90,    29,  1195,   763,  1801,   740,  1803,
     566,   544,  2100,   545,    28,  1278,   950,   728,  1279,   777,
    1794,   780,  1291,    28,  2031,   778,  1219,   745,    29,  1960,
     951,  2472,  2144,   546,  1439,   547,  1237,  1454,   949,   499,
    1303,  2024,  1711,  1712,   457,  2498,  2500,   764,  1278,  2434,
     746,  1279,    48,  2438,   517,  2439,  2246,  1686,  1187,   950,
     779,  1902,  1903,  1260,  1832,  2007,  -464,  1687,   748,  1285,
     807,  -464,  1286,   953,   782,  2064,   900,  1221,  1342,  1342,
    1342,  1342,  1232,  2086,  1342,  1342,  1342,  1342,  1342,  1342,
    1342,  1342,  1342,  1342,  1448,  1233,  1333,   842,  1235,  1236,
    2023,   808,  2032,  1816,  1494,   749,  2545,  1121,  1820,   751,
    1554,  1304,  1291,  1555,    48,   752,   518,  -463,  2208,  1280,
    1722,  1575,  -463,  1576,  1525,  1722,  2053,   779,  1607,  1614,
    1722,  1121,  1121,  1722,  1342,  1342,  -464,  1725,  1189,  1725,
     926,  1989,  1253,  2548,  2308,  2577,  2323,  1190,   499,  2422,
     499,   926,  1280,  1253,   926,   759,  1253,  1722,   777,  1458,
    2561,  1463,   920,   921,   778,   784,  1456,  1113,  1113,  1113,
     774,  1305,  1854,  1190,  1306,   776,  1618,  -464,  1190,  1121,
    1622,   788,   777,  1121,   737,  1381,   519,  -463,   778,   940,
    -495,  -495,    78,   499,    79,  1623,   906,   789,  1121,   454,
     780,  1179,   429,  1704,   898,  1705,   479,  1187,  2368,  2212,
     495,  1908,   429,  1509,   429,  1513,  2591,   429,  -494,  -494,
    1114,  1114,  1114,   429,  1427,   429,  1281,  1654,  -463,  1807,
    1121,   806,  1808,  1187,   810,   906,   566,   429,  1187,  1722,
     814,   566,   429,   898,  1824,  2045,   429,   429,   429,   429,
     777,   429,   429,   782,  1383,  1811,   778,   906,  1812,  1281,
     499,  1562,  1970,  2031,  1722,   898,   779,   780,   815,  1974,
    1975,  1976,   818,  1574,  1869,  1307,   820,  1121,  1282,  1384,
     783,   827,  1916,   859,  1579,  1121,   906,   834,  2157,  2168,
     779,  1706,  1500,  1707,   898,  1987,  2048,    20,  1988,   829,
    1992,   551,  1508,  1993,  1511,  2011,  2070,  1522,  1555,  1555,
     906,   839,  1764,  1526,  1190,  1528,   811,   520,   898,  1273,
     782,  1116,  1935,  1936,  1937,  1938,  2105,  1535,   841,  1286,
      48,    24,  1538,  1443,   552,  1445,  1543,  1544,  1545,  1546,
    1291,  1550,  1551,   510,   784,  2169,  2170,   812,  1555,  1555,
    2085,  2250,    20,   758,  1286,   760,  2386,  2303,   779,  2386,
    2304,  2133,   844,  2136,   900,   872,   908,  1834,   847,  2322,
    1722,    26,   845,    83,  1187,   458,   910,  1725,  1488,   790,
    1385,  1725,  1308,   510,    27,  1386,    24,   911,  2344,  2370,
    1387,  1555,  1286,   717, -1001,   719,  1722,  2373,   791,  2378,
    2374,  2384,   842,   900,  2385,   790,   780,    28,   913,   920,
     921,   784,  2388,   554,  2351,  2385,  2399,  2424,   940,  2400,
    2425,   459,  -614,  1335,   791,   900,    26,  1024,  1026,  2452,
     780,    84,  2400,  -621,  2453,   906,  1954,  1286,  2461,    27,
     919,   842,   922,   898,   923,  1561,  2466,   792,    48,  2385,
     924,   925,   901,   499,   900,  1495,  2200,   510,   929,   782,
    1726,  1113,    28,  2480,  2352,  1113,  2481,  1113,  2342,  1317,
    1318,    29,  2353,   792,  1116,   931,    29,    85,   900,  1540,
    2123,  1726,    20,   782,  2521,  1752,   783,   842,  1755,   540,
    1463,  2522,  2543,  2555,  1121,  2544,  2385,  -611,   780,  2573,
    2354,   934,  2400,  -612,   935,   936,  1722,   937,  1955,   538,
    1541,   539,    52,   942,  1114,   944,    24,   945,  1114,  -615,
    1114,   946,   542,   947,  1388,  -613,   948,   955,  2329,   956,
     966,   793,  2209,  2210,  1389,  1810,  1225,  1342,  1004,  1956,
    2155,   906,  1006,   908,   960,  1009,  1008,  1547,  1725,   898,
     784,   782,  1022,  1725,  1957,  1027,    26,   793,  1725,  1124,
    1130,  1725,  2270,   762,  1958,  2048,  2355,   764,  1828,    27,
    1160,  1162,  1185,  1186,   784,  1187,  1192,  2356,  1548,   794,
    1193,  1764,   795,  1194,   960,  1725,  1225,    87,  1198,    88,
    1959,   499,    28,   796,  1205,  1225,   499,   499,   499,  1206,
    1210,  1381,  1220,   900,  1222,   794,    29,  1226,   795,   429,
      89,  2264,  2410,    90,   499,  1230,  1231,  1699,   566,   796,
    1238,  1242,  1241,  1244,   797,  1342,  1606,  1253,  1268,   901,
    1579,  2180,   915,  1716,  1274,   926,   932,  2181,  1708,  1292,
    1298,  1293,   784,   908,   624,  2045,  1350,  1351,   971,  2182,
     797,  1363,  1374,    48,  1716,  1380,  1391,   906,   509,  1335,
    1392,  1394,  1414,  1415,   906,   898,  1429,  1725,   799,  1440,
    1113,  1442,   898,  1450,  1960,  1449,  1457,  2183,   518,  2184,
    1464,  1476,  1477,  1930,  2277,  1478,  1497,  1501,   800,  1342,
    1911,  2286,  1725,  1479,   799,   623,  1502,  1503,  1635,  1847,
    1552,   510,  1636,  1637,  1638,  1556,  1560,  1564,   802,   900,
    1565,  1580,  1566,  2180,   800,  1582,  1583,  1587,   510,  1913,
     906,  1590,  1589,  1114,   908,  1595,  1599,  1600,   898,   901,
    1602,  1601,  2185,  1934,   802,  1597,  1606,  2329,  1603,  1598,
    1616,   499,   499,   499,  1944,  1617,  1726,  1952,  1619,  1620,
    1621,  1952,  1966,  1624,  2357,  1628,  2265,  2358,  2186,  2183,
    2430,  2428,  1625,  1627,   872,  1631,  2306,  1653,  1659,  1121,
    1660,  1661,  1213,  1662,  1663,  1670,  1831,  1673,  1681,  1674,
    1675,  1836,  1837,  1839,  1676,  1688,  1697,  1702,  1727,  1463,
    1698,  1700,  1701,  2410,    48,  1732,  2372,  1746,  1725,  1853,
    1744,  1766,  1753,  1760,  -496,   499,  -497,   429,  1772,  1771,
     901,  1225,  1179,  1225,  2185,  1248,  1775,  2187,  2417,  1774,
     962,  1776,  2188,  1778,  1725,   900,  1780,  1781,  2050,  1787,
    2123,   429,   900,  2037,  1784,   906,  1815,  1800,  2570,  1802,
    1821,  1822,  1823,   898,  1840,  1828,   429,   429,   429,   429,
     429,   429,   429,   429,   429,   429,  1841,  1844,  2494,  1848,
    2377,  1845,  1851,  1852,  2189,   499,  1855,  1856,  1280,  1113,
     906,  1867,  1179,  2377,  1872,  1868,  1656,  1635,   898,  2190,
    1655,  1910,  1905,  1248,  1906,   519,   499,  1907,   900,  1918,
    1919,  2081,  1922,  1640,  1931,   906,  1709,  2003,   906,  2413,
    1967,  1945,   960,   898,  2188,  2419,   898,  1953,  1972,  2479,
    1969,  1984,  1978,  2454,  2045,  1981,  1986,  1942,  1990,  1946,
    2001,  2036,  1114,  1980,  1982,  2463,  1939,  1940,  1941,  1997,
     903,  2005,   908,  2017,  1725,  2019,  2054,  2055,  2056,  2057,
    2058,  2059,  2060,  2061,  2062,  2063,  2189,  2035,  2066,  2072,
    2073,  2077,  2088,  1113,  2083,  1641,  2089,  1113,  2095,  2129,
    2130,  2190,  2090,  2116,   790,  2092,   499,   499,   499,   499,
    2191,  2099,  2098,  1952,  1966,  2494,  2113,  1952,  2138,  2462,
    2126,  2125,   608,   791,  1726,  2542,  2474,  2137,  1726,  2124,
    2002,  2145,  2127,  2152,  2141,  2154,  2142,  -429,  2143,  2146,
    2148,  2149,  2150,   900,  2163,  2171,  1114,  2175,  2198,  -429,
    1114,  2199,  2203,  2213,  -429,  2214,  2215,  2216,   901,  1752,
    2223,  2224,  2225,   872,  1463,  2237,  2156,  2158,  1335,  2240,
    2243,  2238,   792,  2025,  2244,   609,  1179,  2245,   900,   908,
    2026,  2247,  2255,  2248,  2261,  2268,  2274,  2284,  2289,  2295,
    2069,  2297,  2191,  2298,  2314,    48,  2300,  2305,  2317,  -429,
    2318,  2207,  2319,   900,  2320,  2346,   900,  2343,  2347,  2361,
    2348,  1260,  2371,  1724,  2375,  2380,  2362,  2383,  1113,  -429,
     608,  2396,  2389,  2391,  2401,  2395,  2415,  2418,  2420,  2431,
    2449,  2423,   904,  2448,  1724,  2027,  2450,  1225,  2469,  2460,
    2468,  2478,  2313,  1574,   906,  2484,  2482,   903,  2485,  2487,
    2490,  2497,   898,  2229,  2241,  2503,   793,  2508,  2504,  2509,
    -429,  2510,  2532,  2519,  1932,   901,  2538,  1555,  2550,  -429,
    2556,  1114,  2563,   609,  1113,  2566,  2568,  2574,  2575,  2564,
    2565,  1642,  1643,  1644,  2588,  1645,  1646,  1647,  1648,  1649,
    1650,  2117,  2118,  2119,  2120,  1944,  1952,  1716,   429,  2034,
    1726,  1716,  1527,  2038,   794,  1726,  1798,   795,  1726,  1944,
    1994,  2273,   750,  2276,  2159,    83,  2473,  2528,   796,  2288,
    2028,  2071,  2206,  2414,   872,   872,   872,  1114,  2534,  2583,
      48,    48,  2294,  2569,  2360,   970, -1001,   608,   971,  2562,
     607,  1783, -1455, -1455, -1455,  1805,  2076,   903,  1176,   797,
    2530,  1829,   566,   429,  2567,  2039,  1250,  1779,  2529,  2440,
    2491,   499,  1830,   713,   713,  2571,  2065,   977,  2050,  1122,
    1014,  1762,  1493,    84,   978,  1157,  1773,  1473,  1979,  1156,
    2467,  2153,  1492,  1161,   713,   429,   429,  1948,  1743,  2122,
     609,  2135,  2459,   799,  2382,  1943,  1179,  2458,   979,   429,
    -429,  2465,   905,  2345,  2464,  1596,  2287,  2523,  2518,   904,
    2524,   499,   900,   800,  2294,  1419,  1765,    48,  1695,    85,
    1611,   510,  1740,  1693,  2229,  1428,  1833,  2451,   903,  1263,
    1591,  1125,   429,   802,  1444,  2029,     0,  1995,  2030,  1726,
    1446,     0,     0,  2307,     0,  2276,     0,     0,     0,     0,
       0,     0,     0,     0,   713,  2394,     0,     0,     0,     0,
     429,     0,   729,     0,     0,   748,   730,   908,     0,   499,
       0,     0,     0,  1716,     0,  2325,  2326,     0,  1716,     0,
       0,  1716,     0,     0,   859,    86,     0,   607,  2433,  2349,
       0,   566,   607,   713,   909,     0,     0,  1724,  2441,  1724,
       0,     0,     0,     0,     0,     0,   908,   980,     0,   904,
     713,     0,   981,     0,     0,     0,     0,   499,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  2445,   908,    87,
       0,    88,     0,     0,     0,   623,  1187,     0,  1635,     0,
     713,     0,  1636,  1637,  1638,  1944,  2315,     0,   984,     0,
    2397,   429,    89,   901,     0,    90,  2273,   908,     0,   713,
     713,   713,     0,   713,     0,     0,     0,    48,     0,     0,
       0,  2294,   566,   566,   566,     0,  2470,     0,     0,   905,
       0,   908,   859,   713,     0,     0,     0,  2495,    48,  2496,
     904,     0,   901,  2501,  2502,   987,  2366,     0,     0,     0,
       0,     0,     0,   607,   607,     0,     0,  1225,  1225,     0,
     713,  1112,  1716,     0,   901,     0,     0,     0,     0,     0,
     -34,     0,   960,     0,     0,     0,   872,     0,     0,     0,
       0,  2273,     0,     0,     0,     0,   903,  2050,     1,  2394,
     713,     0,     0,   901,   713,   713,     0,     0,     2,  1463,
       3,     4,     0,     0,  2406,   713,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     5,   901,  1225,     0,
       0,   909,     0,     0,     0,  1179,     0,     0,     0,   905,
       0,  2294,   989,  2546,     0,     0,     6,     0,     0,     0,
       0,    48,     0,     0,     0,     0,   566,     7,     0,   859,
       0,     0,  2444,     0,     0,     0,  2051,     0,     8,     0,
       9,     0,  1639,     0,     0,     0,     0,     0,     0,     0,
    1112,     0,     0,     0,     0,     0,     0,    10,     0,     0,
     607,     0,     0,  1640,     0,     0,     0,  1724,     0,     0,
      48,  1724,     0,   903,     0,     0,     0,     0,     0,     0,
      11,     0,     0,     0,     0,     0,    12,     0,     0,     0,
     905,     0,     0,     0,    13,     0,    14,     0,     0,     0,
       0,   909,     0,     0,     0,     0,     0,     0,   990,     0,
       0, -1455, -1455, -1455,     0,   994,   995,   996,   997,   998,
     999,     0,   901,     0,   713,  1641,     0,     0,   904,     0,
     713,     0,     0,   713,     0,     0,     0,   713,     0,     0,
       0,     0,   908,     0,     0,   713,   713,     0,     0,   790,
       0,     0,     0,   713,     0,     0,   713,   713,   713,   713,
       0,     0,     0,     0,     0,     0,   713,   713,   791,     0,
       0,     0,     0,     0,    15,     0,     0,    48,     0,     0,
       0,     0,   909,   713,   713,   713,   713,  1112,     0,     0,
       0,   713,   872,     0,     0,   713,     0,     0,     0,   713,
     872,     0,   713,   713,   713,   713,   713,   713,   713,   713,
     713,     0,     0,   713,  2330,     0,   623,   792,     0,  1635,
     713,     0,   713,  1636,  1637,  1638,     0,     0,   901,   970,
       0,     0,   971,     0,     0,   904,     0,     0,  1724,     0,
    1914,     0,    16,  1724,     0,    17,     0,     0,  1724,     0,
       0,  1724,     0,     0,     0,     0,     0,  2331,   908,     0,
       0,   977,     0,     0,     0,  2211,     0,     0, -1455,     0,
       0,     0,     0,    18,     0,  1724,     0,     0,     0,     0,
    2027,    19,  2332,     0,     0,     0,     0,     0,   623,     0,
       0,  1635,   979,    20,     0, -1455, -1455, -1455,   905,  2333,
      21,   793,     0,  2334,    22,     0,     0,     0,     0,     0,
       0,  1642,  1643,  1644,    23,  1645,  1646,  1647,  1648,  1649,
    1650,   908,     0,  2335,     0,     0,  2336,    24,     0,     0,
       0,     0,   713,     0,     0,     0,     0,     0,     0,     0,
    2337,     0,     0,     0,   901,     0,     0,     0,     0,   794,
     713,   901,   795,     0,     0,     0,     0,  1724,     0,   713,
     713,   903,    25,   796,     0,     0,     0,    26,     0,     0,
     858,     0,     0, -1360,     0,   858,     0,     0,     0,     0,
      27,     0,  1724,     0,     0,     0,     0,     0,     0,     0,
     909,     0,     0,     0,   797,     0,  1112,     0,  1112,     0,
     903, -1455,     0,    28,     0,   905, -1455,   901,     0,     0,
       0,     0,     0,     0,  1640,     0,     0,    29,     0,     0,
     -34,  2338,   903,     0,     0,     0,     0,     0,     0,  2339,
       0,     0,     0,     0,     0,     0,  2051,     0,   799,     0,
       0,     0, -1455,     0,     0,     0,     0,     0,     0,     0,
       0,   903,     0,     0,     0,     0,     0,     0,   800,     0,
       0,     0,     0, -1360,  1112,     0,     0,     0,     0,     0,
    2340,   908,     0,     0,     0,   903,  1641,     0,   802,   607,
       0,   713,   713,   713,   858,     0,   858,   858,  1724,   987,
       0,     0,     0,     0,     0,     0,   908,   909,     0,   908,
       0,     0,     0,   713,   713,     0,     0,     0,     0,   713,
       0,     0,     0, -1360,  1724,     0,     0,     0,     0,     0,
       0,     0,   901,   904,     0, -1360,     0,     0,     0,     0,
   -1360,     0,     0,     0,     0, -1360,     0,     0,     0,     0,
       0,     0,     0,     0, -1360, -1362,     0, -1360,  1641,   713,
     713,   713,     0,     0,   713,   858,     0,   901,   858,   858,
       0,     0,   904,     0,     0,     0,   713,   713,   713,   713,
       0,     0,     0,     0,   713, -1360, -1455,     0,     0,     0,
       0,     0,   901,     0,   904,   901,     0,   713,   713,     0,
       0,   713,     0,     0,     0, -1360,     0,     0,     0,     0,
     903,     0,     0,     0,     0,   713,     0,   713,     0,   713,
       0,     0,     0,   904,     0,     0,     0,     0,  1265,  1267,
       0,     0,     0,     0,  1724,     0,     0,     0,     0,   713,
       0,     0,     0,     0,     0, -1362, -1360,   904,     0, -1360,
     713,     0,   713,   713,   713, -1360,     0,     0,     0,     0,
       0,     0,     0,   713,     0,     0,     0,     0,     0,     0,
       0,   713,  1642,  1643,  1644,     0,  1645,  1646,  1647,  1648,
    1649,  1650, -1455,     0,     0,   713,     0,     0,     0,   994,
     995,   996,   997,   998,   999, -1362,     0,     0,  1299,  1300,
     713,     0,     0,   905,     0,     0,  1312, -1362,     0, -1360,
    1315,  1316, -1362,     0,     0,  2051,   903, -1362,   713,     0,
       0,     0,     0,     0,     0,  1352, -1362,  1353,     0, -1362,
       0,     0,     0,     0,     0,  1112,  1112,  1112,     0,     0,
    1364,  1366,   905,     0, -1455, -1455, -1455,     0,  1645,  1646,
    1647,  1648,  1649,  1650,     0,     0,     0, -1362,     0,     0,
    1709,     0,     0,     0,   905,     0,   970,     0,     0,   971,
       0,     0,   904,     0,     0,     0,     0, -1362,     0,     0,
       0,     0,     0,     0,     0,     0, -1360,     0,     0,     0,
       0,     0,     0,   905,     0,   909,     0,     0,   977,     0,
       0,   901,     0,     0,     0, -1455,     0,     0,     0,     0,
   -1360,     0, -1360, -1360,     0,     0,     0,   905, -1362,     0,
       0, -1362,     0,     0,     0,     0,     0, -1362,     0,   979,
       0,   713,   903,     0,   909,     0,     0,     0,     0,   903,
       0,   713,     0,     0,     0,     0,     0,   713, -1360,     0,
     713, -1360, -1360, -1360,     0,     0,   909,   713,   713,   713,
     713,     0,     0,   713,   713,   713,   713,   713,   713,   713,
     713,   713,   713,     0,     0,     0,   713,   713,   904,     0,
       0, -1362,     0,     0,     0,   909,     0,     0,     0,     0,
     713,     0,     0,     0,     0,   903,  1679,   713,     0,     0,
     713,     0,   713,     0,     0,     0,     0,     0,     0,   909,
     713,     0,     0,   713,   713,     0,     0,     0,   713,   713,
       0,     0,  1482,  1482,     0,     0,     0,     0,     0,     0,
       0,     0,  1709,     0,   713,     0,   713,   970, -1455,     0,
     971,     0,   905, -1455,     0,     0,     0,     0,   713,     0,
       0,     0,     0,     0,   713,     0,     0,     0, -1362,     0,
       0,     0,     0,     0,   970,   713,     0,   971,     0,   977,
       0,     0,     0,   858,     0,     0, -1455,     0,     0, -1455,
       0,   713, -1362,   858, -1362, -1362,   858,     0,     0,     0,
       0,     0,     0,     0,   904,     0,   977,     0,     0,     0,
     979,   904,     0, -1455,     0,     0,     0,     0,   623,     0,
     903,  1635,     0,     0,     0,  1636,  1637,  1638,     0,     0,
   -1362,     0,     0, -1362, -1362, -1362,   987,   979,     0,  1112,
       0,     0,  2107,  1112,   909,  1112,     0,     0,     0,     0,
       0,     0,   858,     0,     0,   903,     0,     0,   905,     0,
       0,     0,     0,     0,   696,   696,  1604,   904,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1689,     0,     0,
     903,     0,     0,   903,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   713,     0,     0,  1923,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0, -1455,
       0,     0,     0, -1455, -1455,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   713,   713, -1455,     0,     0,   713,
     909, -1455,     0,     0,   713,     0,     0,   713,   713,     0,
   -1455,     0,   713,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   905,     0,     0,     0,     0,     0,
       0,   905,   904,     0,   713,     0,     0, -1455,   713,     0,
       0,   777,     0,     0,   869,     0,     0,   778,     0,     0,
     713,     0,     0,     0,   790,     0,     0,   987,   713,     0,
       0,   917,     0,     0,     0,   713,  1640,   904,     0, -1455,
       0,     0,  1737,   791,     0,     0,   994,   995,   996,   997,
     998,   999,     0,     0,   987,     0,     0,   905,     0,     0,
       0,   941,   904,     0,     0,   904,     0,     0,  1112,     0,
       0,     0,     0,     0,     0,  1769,  1769,   713,     0,     0,
     957,   958,   959,     0,   961,     0,   909,     0,     0,     0,
       0,     0,   792,   909,     0,     0,     0,     0,  1641,     0,
       0,     0,     0,     0,  1007,     0,     0,     0,     0,   903,
       0,     0,     0,     0, -1455,     0,     0,     0,     0,   779,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,  1029,     0,     0,     0,     0,     0,     0,     0,     0,
       0, -1455,     0, -1376,     0,     0,   713,     0,     0,   909,
       0,     0,     0,     0,     0,     0,     0,     0,   713,   713,
       0,  1135,   713,     0,     0,  1147,  1152,     0,     0,     0,
       0,     0,   905,     0,     0,   713,   793,     0,     0,     0,
     713,     0,     0,     0,     0,   713,     0,     0,   713,   713,
       0,     0,     0,     0,     0,     0,   713,   713,     0,     0,
       0,  1857,  1859,     0,     0,     0,  1866,   905,     0,     0,
   -1455,     0,   713,     0,   713,     0,     0,   994,   995,   996,
     997,   998,   999,     0,   794,     0,     0,   795,     0,     0,
       0,     0,   905, -1376,   713,   905,     0, -1455,   796,     0,
       0,     0,     0,     0,   994,   995,   996,   997,   998,   999,
       0,  1002,     0,     0,     0,     0,     0,     0,     0,   780,
       0,     0,     0,     0,   909,     0,     0,  1112,     0,   797,
       0,   904,     0,     0,     0,     0,     0,   970,     0,     0,
     971,     0,     0, -1376,  1642,  1643,  1644,     0,  1645,  1646,
    1647,  1648,  1649,  1650,   713, -1376,     0,  1002,   713,   909,
   -1376,     0,     0,     0,     0, -1376,     0,     0,   798,   977,
       0,     0,   782,   799, -1376,   713, -1455, -1376,     0,   713,
       0,  1296,     0,     0,   909,     0,     0,   909,   970,   713,
       0,   971,     0,   800,     0,   972,   973,   974,     0,   801,
     979,   713,     0,     0,  1319, -1376,     0,  1336,     0,     0,
    1347,  1112,   975,   802,     0,  1112,   713,  1354,  1359,     0,
     977,     0,     0,     0,     0, -1376,     0,   978,     0,     0,
       0,     0,     0,     0,  1369,  1370,  1371,  1372,     0,     0,
     607,     0,  1379,     0,     0,     0,  1390,     0,     0,     0,
    1393,   979,     0,  1400,  1401,  1402,  1403,  1404,  1405,  1406,
    1407,  1408,     0,   784,  1409,     0, -1376,  1926,     0, -1376,
       0,   696,     0,   869,     0, -1376,     0,   858,     0,     0,
       0,     0,   713,     0,  1002,   713,     0,     0,     0,     0,
       0,     0,     0,     0,   713,     0,     0,     0,     0,     0,
       0,   905,   713,     0,     0,     0,     0,     0,     0, -1455,
       0,   713,     0,     0, -1455,     0,     0,     0,     0,     0,
    2087,     0,     0,     0,     0,     0,     0,     0,     0, -1376,
       0,   713,  1002,     0,     0,     0,  1112,     0,   607,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   -1455,     0,     0,     0,     0,     0,  1002,     0,     0,     0,
     980,  1343,     0,     0,     0,   981,   713,   713,     0,     0,
       0,     0,  1002,  1002,  1002,     0,  1002,     0,     0,     0,
    1709,     0,     0,  1447,     0,     0,   982,   983,     0,     0,
       0,     0,  1112,   909,     0,     0,     0,   987,     0,     0,
       0,   984,     0,     0,     0,   623, -1376,     0,  1635,     0,
     958,   959,  1636,  1637,  1638,     0,     0,     0,     0,     0,
       0,   713,  1002,   713,     0,     0,     0,     0,     0,  2108,
   -1376,   985, -1376, -1376,   986,     0,     0,     0,     0,     0,
       0,     0,     0,     0,  1002,     0,     0,     0,   987,     0,
     970,   988,     0,   971,     0,   607,     0,   972,   973,   974,
       0,     0,     0,     0,     0,     0,     0,     0, -1376,     0,
       0, -1376, -1376, -1376,     0,     0,     0,     0,     0,     0,
       0,     0,   977,     0, -1455,   713,   713,     0,   858,   978,
       0,     0,     0,   858,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1265,  1267,     0,
       0,     0,     0,   979,     0,   969,     0,     0,     0,     0,
     970,     0,     0,   971,     0,     0,     0,   972,   973,   974,
       0,     0,   869,  1593,  1594,   989,     0,     0,     0,     0,
       0,     0,     0,     0,   975,     0,     0,   976,     0,     0,
    1002,     0,   977,     0,     0,  1609,     0,     0,     0,   978,
    1615,     0,  1002,     0,     0,     0,     0,  1002,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   -1455,     0,     0,   979,     0,     0,     0,   994,   995,   996,
     997,   998,   999,     0,     0,     0,     0,     0,     0,     0,
       0,     0,  1634,  1640,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1359,     0,  1359,
    1359,     0,   980,     0,     0,  1672,     0,   981,     0,     0,
       0,   990,     0,     0,   991,   992,   993,     0,   994,   995,
     996,   997,   998,   999,     0,     0,     0,     0, -1455, -1455,
       0,  1626,     0,     0,     0,     0,  1691,     0,  1694,     0,
    1696,     0,     0,   984,     0,  1641,     0,   970,  1265,  1267,
     971,     0,     0,     0,   972,   973,   974,   858,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   975,   980,   869,   869,   869, -1455,   981,     0,   977,
       0,     0,     0,     0,  1739,     0,   978,     0,     0,     0,
     987,  1002,     0,     0,     0,     0,     0,     0,   982,   983,
       0,     0,     0,     0,     0,     0,  1135,     0,     0,     0,
     979,     0,     0,   984,  1002,     0,     0,     0,     0,     0,
       0,  1152,     0,     0,     0,     0,     0,     0,     0,     0,
       0,  1002,     0,  1343,  1343,     0,  1651,     0,  1343,  1777,
       0,     0,  1002,   985,     0,     0,   986,     0,     0,  1002,
       0,     0,     0,     0,  1002,     0,     0,     0,     0,     0,
     987,     0,     0,   988,  1002,  1002,  1002,  1002,     0,     0,
       0,  1343,  1343,   858,  1002,     0,     0,   989,     0,     0,
       0,     0,     0,     0,     0,  1002,     0,     0,  1002,     0,
     970,     0,     0,   971,     0,  1002,  1002,  1002,  1002,  1002,
    1002,  1002,  1002,  1002,  1002,     0,     0,     0,   623,     0,
       0,  1635,     0,     0,     0,  1636,  1637,  1638,     0,   980,
       0,     0,   977,     0,   981,     0,     0,     0,     0, -1455,
       0,  1642,  1643,  1644,     0,  1645,  1646,  1647,  1648,  1649,
    1650,     0,  1002,     0,     0,   982,   983,   989,     0,     0,
       0,     0,  1871,   979,     0,     0,     0,     0,     0,     0,
     984,     0,  1875,     0,     0,     0,     0,     0,  1876,     0,
       0,  1878,     0,   990,     0,     0,   991,   992,   993,     0,
     994,   995,   996,   997,   998,   999,     0,     0,     0,     0,
     985,     0,     0,   986,     0,     0,     0,  1898,  1899,     0,
       0,     0,     0,     0,     0,     0,     0,   987,     0,     0,
     988,     0,     0,     0,     0,     0,     0,     0,  1912,     0,
    1927,  1915,     0,  1917,     0,     0,   858,     0,     0,     0,
       0,  1921,     0,     0,     0,     0,     0,     0,     0,  1928,
    1929,     0,     0,   990,     0,     0,   991,   992,   993,     0,
     994,   995,   996,   997,   998,   999,   623,     0,     0,  1635,
       0,     0, -1455,  1636,  1637,  1638,     0, -1455,     0,  1971,
       0,     0,     0,     0,     0,   869,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,  1983,     0,  1002,  1002,
       0,     0,     0,     0,   989,     0,     0,     0,     0,     0,
       0,     0,  1996, -1455,  1002,     0,  1640,     0,     0,     0,
    1002,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1651,  1651,  1002,
       0,  1343,  1343,  1343,  1343,     0,     0,  1343,  1343,  1343,
    1343,  1343,  1343,  1343,  1343,  1343,  1343,  1651,     0,     0,
     987,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1002,  1641,     0,
       0,     0,  1651,  1651,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,  1002,  1343,  1343,  1002,
     990,  1002,     0,   991,   992,   993,     0,   994,   995,   996,
     997,   998,   999,     0,     0,     0,     0,  1362,     0,     0,
       0,     0,  2091,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,  1002,     0,     0, -1455,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0, -1455,  2101,  2102,     0,     0,     0,
    2103,     0,     0,     0,     0,  2106,     0,     0,  2109,  2110,
       0,   970,  1002,  2114,   971,     0,     0,     0,   972,   973,
     974,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,   975,     0,     0,     0,     0,
       0,     0,     0,   977,     0,     0,     0,     0,     0,     0,
     978,   869,     0,     0,     0,     0,  1641,     0,     0,   869,
       0,     0,     0,     0,     0,     0,   696,     0,     0,     0,
       0,     0,     0, -1455,   979,     0,     0,     0,     0,     0,
     994,   995,   996,   997,   998,   999,     0,     0,     0,     0,
       0,     0,     0,     0,  1642,  1643,  1644,     0,  1645,  1646,
    1647,  1648,  1649,  1650,   970,     0,  1002,   971,  2201,     0,
    1002,  1002,     0,  1002,     0,     0,  1651,  1651,  1651,  1651,
       0,     0,     0,  1651,  1651,  1651,  1651,  1651,  1651,  1651,
    1651,  1651,  1651,  1002,  1002,     0,   977,     0,     0,     0,
       0,     0,     0, -1455,     0,     0,     0,  1002,     0,     0,
    1002,     0,  1002,     0,     0,     0,  1002,     0,     0,  1651,
    1651,     0,     0,  1002,  1002,     0,     0,   979,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   980,     0,     0,     0,     0,   981,  2251,
    2252,     0,     0,  2253,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,  1002,     0,     0,   982,
     983,     0,     0,     0,     0,   432,     0,     0,  1002,     0,
       0,     0,     0,     0,   984,     0,     0,  2282,  2283,   970,
       0,  1002,   971,     0,  2111,     0,   972,   973,   974,     0,
       0,     0,  1642,  1643,  1644,  2296,  1645,  1646,  1647,  1648,
    1649,  1650,     0,   975,   985,     0,     0,   986,     0,     0,
       0,   977,     0,     0,     0,     0,     0,   433,   978,     0,
       0,   987,     0,     0,   988,     0, -1455,     0,     0,     0,
       0, -1455,   434,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   979,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0, -1455,     0,     0,
       0,     0,     0,     0,     0,     0,  1002,     0,     0,     0,
    1343,     0,     0,     0,   435,     0,  1002,  1002,  1002,     0,
       0,  1002,   436,     0,  1002,  1002,  2379,     0,     0,  1002,
       0,     0,     0,     0,   437,     0,     0,     0,   989,     0,
     961,     0,     0,     0,   987,     0,     0,     0,     0,     0,
       0,     0,  2398,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   438,     0,     0,     0,  2412,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   980,     0,     0,     0,     0,   981,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,  1343,     0,
       0,     0,     0,     0,     0,     0,     0,   982,   983,   439,
       0,     0,     0,     0,     0,     0,  1002,     0,     0,     0,
       0,     0,   984,     0,     0,     0,     0,     0,     0,     0,
       0, -1455,     0,     0,   990,     0,     0,   991,   992,   993,
       0,   994,   995,   996,   997,   998,   999,     0,     0,     0,
       0,  1874,   985,  2282,     0,   986,     0,     0,     0,     0,
       0,  1651,  1343,     0,     0,   440,  1002,  1002,  1002,   987,
       0,     0,   988,     0,     0,     0,     0,     0,     0,   441,
       0,     0,  2489,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1002,  1002,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     442,  1002,   443,     0,     0,     0,     0,  2515,  2515,   444,
       0,     0,   445,  1651,     0,     0,     0, -1455,     0,     0,
       0,     0,     0,     0,   994,   995,   996,   997,   998,   999,
       0,   446,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   447,     0,     0,     0,   989,     0,     0,   448,
       0,     0,     0,     0,     0,     0,     0,     0,   449,     0,
       0,     0,     0,     0,  2515,     0,     0,     0,     0,     0,
       0,     0,     0,  1651,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,  1002,     0,     0,     0,   450,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,  1002,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,  1002,     0,     0,
       0,     0,     0,     0,     0,     0,  2515,  2586,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   990,     0,     0,   991,   992,   993,     0,   994,
     995,   996,   997,   998,   999,     0,     0,  1441,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,  1431,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,  1002,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
    1002,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
    1432,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,  1002,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,  1433,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,  1434,     0,     0,     0,     0,
       0,     0,   682,  1435,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,    20,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,    24,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   600,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,    27,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,    28,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,  2390,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,    20,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,    24,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   600,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,    27,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,    28,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,  1355,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,  1356,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,  1357,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,  1358,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,   681,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,  1145,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,  1345,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,  1356,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,  1977,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,  1148,  1149,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,  1480,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,  2278,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,  2512,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,  2513,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,  2514,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,  2513,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,   644,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,   659,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   667,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,  2514,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   678,     0,     0,     0,
       0,     0,     0,   679,   680,     0,     0,     0,     0,     0,
       0,     0,   682,     0,     0,     0,     0,   683,   619,   620,
     467,   621,   622,   623,   624,   625,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,   578,   111,
     112,   113,   114,   626,   579,   627,   628,     0,   118,   119,
     120,   121,   122,   629,   630,   123,   124,   631,   632,   127,
       0,   128,   129,   130,   131,   633,     0,   634,     0,   133,
     134,   135,   136,   137,   581,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,   582,   147,   148,   149,
     635,   636,   637,   638,   639,   640,   641,   150,   151,   152,
     153,   154,   155,   642,   643,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   645,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     646,   186,   187,   188,   647,   648,   190,     0,   191,   192,
     649,   194,     0,   195,     0,   196,   584,     0,   585,   197,
     198,   199,   200,     0,   201,   650,     0,   203,   204,     0,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,   587,
     221,   222,   223,   224,   225,   651,   652,     0,   653,     0,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
       0,     0,   236,   654,   591,   238,   592,     0,   239,   240,
     241,   655,   656,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   657,
     593,   658,   260,   261,   262,   263,     0,   264,   265,   594,
     266,   660,   661,   268,   662,   270,   271,   272,     0,   273,
     274,     0,     0,   663,   276,   277,     0,     0,   278,   279,
     595,   280,   596,   664,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   665,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   666,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,   597,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,   668,   346,   347,   348,   349,   350,
     598,   351,   352,   669,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   670,     0,
     368,   369,     0,   370,   599,   371,   372,   373,   374,   375,
       0,   671,   672,     0,     0,   378,   379,   673,   381,   674,
     675,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,   676,     0,   395,   396,   397,
     398,   399,   400,   677,     0,   402,   601,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,     0,     0,     0,     0,
       0,     0,     0,  1338,  1339,     0,     0,   619,   620,   467,
     621,   622,  1340,   624,   625,     0,     0,   683,     0,     0,
       0,     0,    94,    95,    96,    97,    98,    99,   100,   101,
       0,   103,   104,   105,     0,     0,     0,     0,     0,     0,
       0,   106,   107,     0,   108,   109,   110,   578,   111,   112,
     113,   114,   626,   579,   627,   628,     0,   118,   119,   120,
     121,   122,   629,   630,   123,   124,   631,   632,   127,     0,
     128,   129,   130,   131,   633,     0,   634,     0,   133,   134,
     135,   136,   137,   581,   138,   139,   140,     0,   141,   142,
     143,   144,   145,   146,     0,   582,   147,   148,   149,   635,
     636,   637,   638,   639,   640,   641,   150,   151,   152,   153,
     154,   155,   642,   643,   158,     0,   159,     0,   160,   161,
     162,   163,   164,   165,     0,   166,   167,   168,   169,     0,
       0,   170,   171,   645,   173,   174,     0,   175,   176,   177,
       0,   178,   179,   180,     0,   181,   182,   183,   184,   646,
     186,   187,   188,   647,   648,   190,     0,   191,   192,   649,
     194,     0,   195,     0,   196,   584,     0,   585,   197,   198,
     199,   200,     0,   201,   650,     0,   203,   204,     0,   205,
     206,   207,   208,   209,   586,   210,   211,   212,   213,     0,
     214,   215,   216,   217,   218,   219,     0,   220,   587,   221,
     222,   223,   224,   225,   651,   652,     0,   653,     0,   229,
     588,   589,   230,   590,   231,   232,   233,   234,   235,     0,
       0,   236,   654,   591,   238,   592,     0,   239,   240,   241,
     655,   656,   242,   243,   244,   245,   246,   247,   248,   249,
     250,   251,   252,   253,   254,   255,   256,   257,   657,   593,
     658,   260,   261,   262,   263,     0,   264,   265,   594,   266,
     660,   661,   268,   662,   270,   271,   272,     0,   273,   274,
       0,     0,   275,   276,   277,     0,     0,   278,   279,   595,
     280,   596,   664,   282,   283,   284,   285,   286,   287,   288,
     289,   290,     0,   291,   292,   665,   294,   295,   296,   455,
     298,   299,     0,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   666,   310,   311,   312,   313,     0,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
       0,   326,   327,   597,   328,   329,   330,  1469,  1470,   333,
     334,   335,   336,   337,   338,   339,   340,     0,   341,   342,
     343,   344,   345,   668,   346,   347,   348,   349,   350,   598,
     351,   352,   669,   354,     0,   355,   356,   357,   358,   359,
     360,   361,   362,   363,   364,   365,   366,   670,     0,   368,
     369,     0,   370,   599,   371,   372,   373,   374,   375,     0,
     671,   672,     0,     0,   378,   379,   673,   381,   674,   675,
     383,   384,   385,   386,   387,   388,   389,     0,     0,   390,
     391,   392,   393,   394,   676,     0,   395,   396,   397,   398,
     399,   400,   677,     0,   402,   601,   403,   404,   405,   406,
       0,     0,   407,     0,     0,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427,     0,     0,     0,     0,     0,
       0,     0,  1471,  1472,     0,     0,     0,     0,     0,     0,
       0,  1340,     0,     0,     0,     0,   683,   619,   620,   467,
     621,   622,   623,   624,   625,     0,     0,     0,     0,     0,
       0,     0,    94,    95,    96,    97,    98,    99,   100,   101,
       0,   103,   104,   105,     0,     0,     0,     0,     0,     0,
       0,   106,   107,     0,   108,   109,   110,   578,   111,   112,
     113,   114,   626,   579,   627,   628,     0,   118,   119,   120,
     121,   122,   629,   630,   123,   124,   631,   632,   127,     0,
     128,   129,   130,   131,   633,     0,   634,     0,   133,   134,
     135,   136,   137,   581,   138,   139,   140,     0,   141,   142,
     143,   144,   145,   146,     0,   582,   147,   148,   149,   635,
     636,   637,   638,   639,   640,   641,   150,   151,   152,   153,
     154,   155,   642,   643,   158,     0,   159,     0,   160,   161,
     162,   163,   164,   165,     0,   166,   167,   168,   169,     0,
       0,   170,   171,   645,   173,   174,     0,   175,   176,   177,
       0,   178,   179,   180,     0,   181,   182,   183,   184,   646,
     186,   187,   188,   647,   648,   190,     0,   191,   192,   649,
     194,     0,   195,     0,   196,   584,     0,   585,   197,   198,
     199,   200,     0,   201,   650,     0,   203,   204,     0,   205,
     206,   207,   208,   209,   586,   210,   211,   212,   213,     0,
     214,   215,   216,   217,   218,   219,     0,   220,   587,   221,
     222,   223,   224,   225,   651,   652,     0,   653,     0,   229,
       0,   589,   230,   590,   231,   232,   233,   234,   235,     0,
       0,   236,   654,   591,   238,   592,     0,   239,   240,   241,
     655,   656,   242,   243,   244,   245,   246,   247,   248,   249,
     250,   251,   252,   253,   254,   255,   256,   257,   657,   593,
     658,   260,   261,   262,   263,     0,   264,   265,   594,   266,
     660,   661,   268,   662,   270,   271,   272,     0,   273,   274,
       0,     0,   663,   276,   277,     0,     0,   278,   279,   595,
     280,   596,   664,   282,   283,   284,   285,   286,   287,   288,
     289,   290,     0,   291,   292,   665,   294,   295,   296,   455,
     298,   299,     0,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   666,   310,   311,   312,   313,     0,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
       0,   326,   327,   597,   328,   329,   330,   331,   332,   333,
     334,   335,   336,   337,   338,   339,   340,     0,   341,   342,
     343,   344,   345,   668,   346,   347,   348,   349,   350,   598,
     351,   352,   669,   354,     0,   355,   356,   357,   358,   359,
     360,   361,   362,   363,   364,   365,   366,   670,     0,   368,
     369,     0,   370,   599,   371,   372,   373,   374,   375,     0,
     671,   672,     0,     0,   378,   379,   673,   381,   674,   675,
     383,   384,   385,   386,   387,   388,   389,     0,     0,   390,
     391,   392,   393,   394,   676,     0,   395,   396,   397,   398,
     399,   400,   677,     0,   402,   601,   403,   404,   405,   406,
       0,     0,   407,     0,     0,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427,     0,     0,     0,     0,     0,
       0,     0,  1338,  1339,     0,     0,     0,     0,     0,     0,
       0,  1340,     0,     0,     0,     0,   683,   619,   620,   467,
     621,   622,   623,   624,   625,     0,     0,     0,     0,     0,
       0,     0,    94,    95,    96,    97,    98,    99,   100,   101,
       0,   103,   104,   105,     0,     0,     0,     0,     0,     0,
       0,   106,   107,     0,   108,   109,   110,   578,   111,   112,
     113, -1455,   626,   579,   627,   628,     0,   118,   119,   120,
     121,   122,   629,   630,   123,   124,   631,   632,   127,     0,
     128,   129,   130,   131,   633,     0,   634,     0,   133,   134,
     135,   136,   137,   581,   138,   139,   140,     0,   141,   142,
     143,   144,   145,   146,     0,   582,   147,   148,  2513,   635,
     636,   637,   638,   639,   640,   641,   150,   151,   152,   153,
     154,   155,   642,   643,   158,   644,   159,     0,   160,   161,
     162,   163,   164,   165,     0,   166,   167,   168,   169,     0,
       0,   170,   171,   645,   173,   174,     0,   175,   176,   177,
       0,   178,   179,   180,     0,   181,   182,   183,   184,   646,
     186,   187,   188,   647,   648,   190,     0,   191,   192,   649,
     194,     0,   195,     0,   196,   584,     0,   585,   197,   198,
     199,   200,     0,   201,   650,     0,   203,   204,     0,   205,
     206,   207,   208,   209, -1455,   210,   211,   212,   213,     0,
     214,   215,   216,   217,   218,   219,     0,   220,   587,   221,
     222,   223,   224,   225,   651,   652,     0,   653,     0,   229,
       0,     0,   230,   590,   231,   232,   233,   234,   235,     0,
       0,   236,   654,   591,   238, -1455,     0,   239,   240,   241,
     655,   656,   242,   243,   244,   245,   246,   247,   248,   249,
     250,   251,   252,   253,   254,   255,   256,   257,   657,   593,
     658,   260,   261,   262,   263,     0,   264,   265,     0,   266,
     660,   661,   268,   662,   270,   271,   272,     0,   273,   274,
       0,     0,   663,   276,   277,     0,     0,   278,   279,   595,
     280,   596,   664,   282,   283,   284,   285,   286,   287,   288,
     289,   290,     0,   291,   292,   665,   294,   295,   296,   455,
     298,   299,     0,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   666,   310,   311,   312,   313,     0,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
       0,   326,   327,   597,   328,   329,   330,   667,   332,   333,
     334,   335,   336,   337,   338,   339,   340,     0,   341,   342,
     343,   344,   345,   668,   346,   347,   348,   349,   350, -1455,
     351,   352,   669,   354,     0,   355,   356,   357,   358,   359,
     360,   361,   362,   363,   364,   365,   366,   670,     0,   368,
     369,     0,   370,   599,   371,   372,   373,   374,   375,     0,
     671,   672,     0,     0,   378,   379,   673,   381,   674,   675,
     383,   384,   385,   386,  2514,   388,   389,     0,     0,   390,
     391,   392,   393,   394,   676,     0,   395,   396,   397,   398,
     399,   400,   677,     0,   402,   601,   403,   404,   405,   406,
       0,     0,   407,     0,     0,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427, -1455,     0,     0,     0,     0,
       0,     0,   679,   680,     0,     0,     0,     0,     0,     0,
       0,   682,     0,     0,     0,     0,   683,   619,   620,   467,
     621,   622,   623,   624,   625,     0,     0,     0,     0,     0,
       0,     0,    94,    95,    96,    97,    98,    99,   100,   101,
       0,   103,   104,   105,     0,     0,     0,     0,     0,     0,
       0,   106,   107,     0,   108,   109,   110,   578,   111,   112,
     113,     0,   626,   579,   627,   628,     0,   118,   119,   120,
     121,   122,   629,   630,   123,   124,   631,   632,   127,     0,
     128,   129,   130,   131,   633,     0,   634,     0,   133,   134,
     135,   136,   137,   581,   138,   139,   140,     0,   141,   142,
     143,   144,   145,   146,     0,   582,   147,   148,   149,   635,
     636,   637,   638,   639,   640,   641,   150,   151,   152,   153,
     154,   155,   642,   643,   158,   644,   159,     0,   160,   161,
     162,   163,   164,   165,     0,   166,   167,   168,   169,     0,
       0,   170,   171,   645,   173,   174,     0,   175,   176,   177,
       0,   178,     0,   180,     0,   181,   182,   183,   184,   646,
     186,   187,   188,   647,   648,   190,     0,   191,   192,   649,
     194,     0,   195,     0,   196,   584,     0,   585,   197,   198,
     199,   200,     0,   201,   650,     0,   203,   204,     0,   205,
     206,   207,   208,   209,     0,   210,   211,   212,   213,     0,
     214,   215,   216,   217,   218,   219,     0,   220,   587,   221,
     222,   223,   224,   225,   651,   652,     0,   653,     0,   229,
       0,     0,   230,   590,   231,   232,   233,   234,   235,     0,
       0,   236,   654,   591,   238,     0,     0,   239,   240,   241,
     655,   656,   242,   243,   244,   245,   246,   247,   248,   249,
     250,   251,   252,   253,   254,   255,   256,   257,   657,   593,
     658,   260,   261,   262,   263,     0,   264,   265,     0,   266,
     660,   661,   268,   662,   270,   271,   272,     0,   273,   274,
       0,     0,   663,   276,   277,     0,     0,   278,   279,   595,
     280,   596,   664,   282,   283,   284,   285,   286,   287,   288,
     289,   290,     0,   291,   292,   665,   294,   295,   296,   455,
     298,   299,     0,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   666,   310,   311,   312,   313,     0,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
       0,   326,   327,   597,   328,   329,   330,   667,   332,   333,
     334,   335,   336,   337,   338,   339,   340,     0,   341,   342,
     343,   344,   345,   668,   346,   347,   348,   349,   350,     0,
     351,   352,   669,   354,     0,   355,   356,   357,   358,   359,
     360,   361,   362,   363,   364,   365,   366,   670,     0,   368,
     369,     0,   370,   599,   371,   372,   373,   374,   375,     0,
     671,   672,     0,     0,   378,   379,   673,   381,   674,   675,
     383,   384,   385,   386,   387,   388,   389,     0,     0,   390,
     391,   392,   393,   394,   676,     0,   395,   396,   397,   398,
     399,   400,   677,     0,   402,   601,   403,   404,   405,   406,
       0,     0,   407,     0,     0,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427,     0,     0,     0,     0,     0,
       0,     0,   679,   680,    93,     0,     0,     0,     0,     0,
       0,   682,     0,     0,     0,     0,   683,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,  1949,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,  -550,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,  -550,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     209,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,  -550,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
    -550,   231,   232,   233,   234,   235,     0,     0,   236,   237,
    -550,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,  -550,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
    -550,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,     0,     0,     0,   619,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   748,
      94,    95,    96,    97,    98,    99,   100,   101,     0,   103,
     104,   105,     0,     0,     0,     0,     0,     0,     0,   106,
     107,     0,   108,   109,   110,   578,   111,   112,   113,   114,
     115,   579,   116,   117,     0,   118,   119,   120,   121,   122,
       0,   630,   123,   124,   125,   126,   127,     0,   128,   129,
     130,   131,   633,     0,   634,     0,   133,   134,   135,   136,
     137,   581,   138,   139,   140,     0,   141,   142,   143,   144,
     145,   146,     0,   582,   147,   148,   149,   635,   636,   637,
     638,   639,   640,   641,   150,   151,   152,   153,   154,   155,
     156,   157,   158,     0,   159,     0,   160,   161,   162,   163,
     164,   165,     0,   166,   167,   168,   169,     0,     0,   170,
     171,   172,   173,   174,     0,   175,   176,   177,     0,   178,
     179,   180,     0,   181,   182,   183,   184,   185,   186,   187,
     188,   647,     0,   190,     0,   191,   192,   193,   194,     0,
     195,     0,   196,   584,     0,   585,   197,   198,   199,   200,
       0,   201,   650,     0,   203,   204,     0,   205,   206,   207,
     208,   209,   586,   210,   211,   212,   213,     0,   214,   215,
     216,   217,   218,   219,     0,   220,   587,   221,   222,   223,
     224,   225,   226,   227,     0,   228,     0,   229,   588,   589,
     230,   590,   231,   232,   233,   234,   235,  1713,     0,   236,
     654,   591,   238,   592,     0,   239,   240,   241,   655,   656,
     242,   243,   244,   245,   246,   247,   248,   249,   250,   251,
     252,   253,   254,   255,   256,   257,   258,   593,   259,   260,
     261,   262,   263,     0,   264,   265,   594,   266,     0,   661,
     268,   269,   270,   271,   272,     0,   273,   274,     0,   496,
     275,   276,   277,     0,     0,   278,   279,   595,   280,   596,
     664,   282,   283,   284,   285,   286,   287,   288,   289,   290,
       0,   291,   292,   665,   294,   295,   296,   455,   298,   299,
       0,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,   313,     0,   314,   315,   316,   317,
     318,   319,   320,   321,   322,   323,   324,   325,     0,   326,
     327,   597,   328,   329,   330,   331,  1714,   333,   334,   335,
     336,   337,   338,   339,   340,    20,   341,   342,   343,   344,
     345,   668,   346,   347,   348,   349,   350,   598,   351,   352,
     353,   354,     0,   355,   356,   357,   358,   359,   360,   361,
     362,   363,   364,   365,   366,   670,     0,   368,   369,    24,
     370,   599,   371,   372,   373,   374,   375,     0,   376,   377,
       0,     0,   378,   379,   673,   381,   674,     0,   383,   384,
     385,   386,   387,   388,   389,     0,     0,   390,   391,   392,
     393,   394,   676,     0,   395,   396,   397,   398,   399,   600,
     401,     0,   402,   601,   403,   404,   405,   406,     0,     0,
     407,     0,    27,   408,   409,   410,   411,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,   426,   427,     0,     0,    28,   619,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,  1715,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
     114,   115,   579,   116,   117,     0,   118,   119,   120,   121,
     122,     0,   630,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   633,     0,   634,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,   635,   636,
     637,   638,   639,   640,   641,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   647,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,   650,     0,   203,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,  1713,     0,
     236,   654,   591,   238,   592,     0,   239,   240,   241,   655,
     656,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,   593,   259,
     260,   261,   262,   263,     0,   264,   265,   594,   266,     0,
     661,   268,   269,   270,   271,   272,     0,   273,   274,     0,
     496,   275,   276,   277,     0,     0,   278,   279,   595,   280,
     596,   664,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   665,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,   331,  1714,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,   668,   346,   347,   348,   349,   350,   598,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   670,     0,   368,   369,
       0,   370,   599,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   673,   381,   674,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,   676,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,     0,     0,   619,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
    1715,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
     114,   115,   579,   116,   117,     0,   118,   119,   120,   121,
     122,     0,   630,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   633,     0,   634,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,   635,   636,
     637,   638,   639,   640,   641,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   647,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,   650,     0,   203,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,     0,     0,
     236,   654,   591,   238,   592,     0,   239,   240,   241,   655,
     656,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,   593,   259,
     260,   261,   262,   263,     0,   264,   265,   594,   266,     0,
     661,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,   595,   280,
     596,   664,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   665,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,   331,  1714,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,   668,   346,   347,   348,   349,   350,   598,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   670,     0,   368,   369,
       0,   370,   599,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   673,   381,   674,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,   676,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,     0,     0,   619,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
      29,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
     114,   115,   579,   116,   117,     0,   118,   119,   120,   121,
     122,     0,   630,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   633,     0,   634,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,   635,   636,
     637,   638,   639,   640,   641,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   647,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,   650,     0,   203,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,     0,     0,
     236,   654,   591,   238,   592,     0,   239,   240,   241,   655,
     656,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,   593,   259,
     260,   261,   262,   263,     0,   264,   265,   594,   266,     0,
     661,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,   595,   280,
     596,   664,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   665,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,   668,   346,   347,   348,   349,   350,   598,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   670,     0,   368,   369,
       0,   370,   599,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   673,   381,   674,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,   676,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,     0,     0,   577,   850,   467,     0,
       0,     0,   624,     0,     0,     0,     0,     0,     0,     0,
    2290,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
     114,   115,   579,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,   580,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,     0,     0,
       0,   583,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,   851,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,     0,     0,
     236,   237,   591,   238,   592,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,   593,   259,
     260,   261,   262,   263,     0,   264,   265,   594,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,   852,
       0,   275,   276,   277,     0,     0,   278,   279,   595,   280,
     596,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,   598,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,   599,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,   853,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,     0,     0,   577,     0,     0,     0,
       0,   854,   855,  2426,     0,     0,     0,     0,     0,     0,
    2427,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     3,     4,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
     114,   115,   579,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,   580,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,     0,     0,
       0,   583,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,     0,     0,
     236,   237,   591,   238,   592,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,   593,   259,
     260,   261,   262,   263,     0,   264,   265,   594,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,   595,   280,
     596,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,    20,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,   598,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
      24,   370,   599,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     600,   401,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,    27,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,     0,     0,    28,    93,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
      29,     0,    94,    95,    96,    97,    98,    99,   100,   101,
       0,   103,   104,   105,     0,     0,     0,     0,     0,     0,
       0,   106,   107,     0,   108,   109,   110,     0,   111,   112,
     113,   114,   115,     0,   116,   117,     0,   118,   119,   120,
     121,   122,     0,     0,   123,   124,   125,   126,   127,     0,
     128,   129,   130,   131,   132,     0,     0,     0,   133,   134,
     135,   136,   137,     0,   138,   139,   140,     0,   141,   142,
     143,   144,   145,   146,     0,     0,   147,   148,   149,     0,
       0,     0,     0,     0,     0,     0,   150,   151,   152,   153,
     154,   155,   156,   157,   158,     0,   159,     0,   160,   161,
     162,   163,   164,   165,     0,   166,   167,   168,   169,     0,
       0,   170,   171,   172,   173,   174,     0,   175,   176,   177,
       0,   178,   179,   180,     0,   181,   182,   183,   184,   185,
     186,   187,   188,   189,     0,   190,     0,   191,   192,   193,
     194,     0,   195,     0,   196,     0,     0,     0,   197,   198,
     199,   200,     0,   201,   202,     0,   203,   204,     0,   205,
     206,   207,   208,   209,     0,   210,   211,   212,   213,     0,
     214,   215,   216,   217,   218,   219,     0,   220,     0,   221,
     222,   223,   224,   225,   226,   227,     0,   228,     0,   229,
       0,     0,   230,     0,   231,   232,   233,   234,   235,     0,
       0,   236,   237,     0,   238,     0,     0,   239,   240,   241,
       0,     0,   242,   243,   244,   245,   246,   247,   248,   249,
     250,   251,   252,   253,   254,   255,   256,   257,   258,     0,
     259,   260,   261,   262,   263,     0,   264,   265,     0,   266,
       0,   267,   268,   269,   270,   271,   272,     0,   273,   274,
       0,     0,   275,   276,   277,     0,     0,   278,   279,     0,
     280,     0,   281,   282,   283,   284,   285,   286,   287,   288,
     289,   290,     0,   291,   292,   293,   294,   295,   296,   455,
     298,   299,     0,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,   313,     0,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
       0,   326,   327,     0,   328,   329,   330,   331,   332,   333,
     334,   335,   336,   337,   338,   339,   340,    20,   341,   342,
     343,   344,   345,     0,   346,   347,   348,   349,   350,     0,
     351,   352,   353,   354,     0,   355,   356,   357,   358,   359,
     360,   361,   362,   363,   364,   365,   366,   367,     0,   368,
     369,    24,   370,     0,   371,   372,   373,   374,   375,     0,
     376,   377,     0,     0,   378,   379,   380,   381,   382,     0,
     383,   384,   385,   386,   387,   388,   389,     0,     0,   390,
     391,   392,   393,   394,     0,     0,   395,   396,   397,   398,
     399,   600,   401,     0,   402,     0,   403,   404,   405,   406,
       0,     0,   407,     0,    27,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427,     0,     0,    28,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    29,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,     0,     0,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   726,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,     0,     0,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,  1459,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,     0,     0,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,  1932,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,     0,     0,     0,     0,
       0,   874,   850,   467,     0,     0,  1320,   624,     0,     0,
       0,     0,  2140,  1321,  1322,  1323,    94,    95,    96,    97,
      98,    99,   100,   101,  1032,   103,   104,   105,  1033,  1034,
    1035,  1036,  1037,  1038,  1039,   106,   107,  1040,   108,   109,
     110,   578,   111,   112,   113,     0,   875,   579,   876,   877,
    1041,   118,   119,   120,   121,   122,  1042,  1043,   123,   124,
     878,   879,   127,  1044,   128,   129,   130,   131,     0,  1045,
     580,  1046,   133,   134,   135,   136,   137,   581,   138,   139,
     140,  1047,   141,   142,   143,   144,   145,   146,  1048,   582,
     147,   148,   149,  1049,  1050,  1051,   583,  1052,  1053,  1054,
     150,   151,   152,   153,   154,   155,   880,   881,   158,  1055,
     159,  1056,   160,   161,   162,   163,   164,   165,  1057,   166,
     167,   168,   169,  1058,  1059,   170,   171,   645,   173,   174,
    1060,   175,   176,   177,  1061,   178,   179,   180,  1062,   181,
     182,   183,   184,     0,   186,   187,   188,     0,  1063,   190,
    1064,   191,   192,   882,   194,  1065,   195,  1066,   196,   584,
    1067,   585,   197,   198,   199,   200,  1068,   201,     0,  1069,
       0,   204,  1070,   205,   206,   207,   208,   209,   586,   210,
     211,   212,   213,  1071,   214,   215,   216,   217,   218,   219,
    1072,   220,   587,     0,   222,   223,   224,   225,   883,   884,
    1073,   885,  1074,   229,   588,   589,   230,   590,   231,   232,
     233,   234,   235,  1075,  1076,   236,     0,   591,   238,   592,
    1077,   239,   240,   241,  1078,  1079,   242,   243,   244,   245,
     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,
     256,   257,   886,   593,   887,   260,   261,   262,  2040,  1080,
     264,   265,   594,   266,  1081,     0,   268,   888,   270,   271,
     272,  1082,   273,   274,  1083,  1084,  2041,   276,   277,  1085,
    1086,   278,     0,   595,   280,   596,     0,   282,   283,   284,
     285,   286,   287,   288,   289,   290,  1087,   291,   292,     0,
     294,   295,     0,   455,   298,   299,  1088,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   889,   310,   311,   312,
     313,  1089,   314,   315,   316,   317,   318,   319,   320,   321,
     322,   323,   324,   325,  1090,   326,   327,   597,   328,   329,
     330,     0,   332,   333,   334,   335,   336,   337,   338,   339,
     340,  1091,   341,   342,   343,   344,   345,  1092,   346,  2042,
     348,   349,   350,   598,   351,   352,   891,   354,  1093,   355,
     356,   357,   358,   359,   360,   361,   362,   363,   364,   365,
     366,     0,  1094,   368,   369,  1095,   370,   599,   371,   372,
     373,   374,   375,  1096,   892,   893,  1097,  1098,   378,   379,
       0,   381,     0,  1099,   383,   384,   385,   386,   387,   388,
     389,  1100,  1101,   390,   391,   392,   393,   394,  1102,  1103,
     395,   396,   397,   398,   399,     0,   894,  1104,   402,   601,
     403,   404,   405,   406,  1105,  1106,   407,  1107,  1108,   408,
     409,   410,   411,   412,   413,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,   425,   426,   427,     0,
      93,     0,  1324,  1325,  1326,  1320,  2043,  2044,  1329,  1330,
    1331,  1332,  1321,  1322,  1323,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   209,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,     0,   371,   372,   373,
     374,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,     0,     0,
       0,  1324,  1325,  1326,     0,  1327,  1328,  1329,  1330,  1331,
    1332,   970,     0,     0,   971,     0,     0,     0,   972,   973,
     974,     0,     0,     0,     0,     0,     0,     0,     0,   970,
       0,     0,   971,     0,     0,   975,   972,   973,   974,     0,
       0,     0,     0,   977,     0,     0,     0,     0,   970,     0,
     978,   971,     0,   975,     0,   972,   973,   974,     0,     0,
       0,   977,     0,     0,     0,     0,     0,     0,   978,     0,
       0,     0,   975,     0,   979,     0,     0,     0,     0,     0,
     977,     0,     0,     0,     0,     0,   970,   978,     0,   971,
       0,     0,   979,   972,   973,   974,     0,     0,     0,     0,
       0,     0,     0,     0,     0,   970,     0,     0,   971,     0,
     975,   979,   972,   973,   974,     0,     0,     0,   977,     0,
       0,     0,     0,   970,     0,   978,   971,     0,     0,   975,
     972,   973,   974,     0,     0,     0,     0,   977,     0,     0,
       0,     0,     0,     0,   978,     0,     0,   975,     0,   979,
       0,     0,     0,     0,     0,   977,     0,     0,   970,     0,
       0,   971,   978,     0,     0,   972,   973,   974,   979,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   975,   980,     0,     0,   979,     0,   981,     0,
     977,     0,     0,     0,     0,     0,     0,   978,     0,     0,
       0,   980,     0,     0,     0,     0,   981,     0,     0,   982,
     983,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     980,   979,     0,     0,   984,   981,     0,   982,   983,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   984,     0,     0,     0,   982,   983,     0,     0,
       0,     0,     0,     0,   985,     0,     0,   986,   980,     0,
       0,   984,     0,   981,     0,     0,     0,     0,     0,     0,
       0,   987,   985,     0,   988,   986,     0,   980,     0,     0,
       0,     0,   981,     0,   982,   983,     0,     0,     0,   987,
       0,   985,   988,     0,   986,   980,     0,     0,     0,   984,
     981,     0,     0,   982,   983,     0,     0,     0,   987,     0,
       0,   988,     0,     0,     0,     0,     0,     0,   984,     0,
       0,   982,   983,     0,     0,     0,     0,     0,     0,   985,
     980,     0,   986,     0,     0,   981,   984,     0,     0,     0,
       0,     0,     0,     0,     0,     0,   987,     0,   985,   988,
       0,   986,     0,     0,     0,     0,   982,   983,   989,     0,
       0,     0,     0,     0,     0,   987,   985,     0,   988,   986,
       0,   984,     0,     0,     0,     0,   989,     0,     0,     0,
       0,     0,     0,   987,     0,     0,   988,     0,     0,     0,
     970,     0,     0,   971,     0,   989,     0,   972,   973,   974,
       0,   985,     0,     0,   986,     0,     0,   777,     0,     0,
       0,     0,     0,   778,   975,     0,     0,     0,   987,     0,
     790,   988,   977,     0,     0,     0,     0,     0,     0,   978,
       0,     0,     0,   989,     0,     0,     0,     0,     0,   791,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   989,   979,   990,     0,     0,   991,   992,   993,
       0,   994,   995,   996,   997,   998,   999,     0,     0,     0,
     989,  1909,   990,     0,     0,   991,   992,   993,     0,   994,
     995,   996,   997,   998,   999,     0,     0,     0,   792,  2004,
       0,   990,     0,     0,   991,   992,   993,     0,   994,   995,
     996,   997,   998,   999,     0,   989,     0,     0,  2093,     0,
       0,     0,     0,     0,     0,   779,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   990,
       0,     0,   991,   992,   993,     0,   994,   995,   996,   997,
     998,   999,     0,     0,     0,     0,  2112,     0,   990,     0,
       0,   991,   992,   993,     0,   994,   995,   996,   997,   998,
     999,     0,   980,     0,     0,  2254,   990,   981,     0,   991,
     992,   993,   793,   994,   995,   996,   997,   998,   999,     0,
       0,     0,     0,  2471,     0,     0,     0,     0,   982,   983,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   990,     0,   984,   991,   992,   993,     0,   994,   995,
     996,   997,   998,   999,     0,     0,     0,     0,  2483,     0,
     794,     0,     0,   795,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   985,   796,     0,   986,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     987,     0,     0,   988,     0,   780,     0,     0,     0,     0,
       0,     0,     0,     0,     0,   797,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,  1529,     0,     0,     0,   782,   799,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   800,
       0,     0,     0,     0,     0,  1530,     0,   989,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   802,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   784,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   990,     0,     0,   991,   992,   993,  1031,
     994,   995,   996,   997,   998,   999,     0,     0,     0,     0,
    2592,     0,     0,     0,    94,    95,    96,    97,    98,    99,
     100,   101,  1032,   103,   104,   105,  1033,  1034,  1035,  1036,
    1037,  1038,  1039,   106,   107,  1040,   108,   109,   110,   578,
     111,   112,   113,   114,   115,   579,   116,   117,  1041,   118,
     119,   120,   121,   122,  1042,  1043,   123,   124,   125,   126,
     127,  1044,   128,   129,   130,   131,   132,  1045,   580,  1046,
     133,   134,   135,   136,   137,   581,   138,   139,   140,  1047,
     141,   142,   143,   144,   145,   146,  1048,   582,   147,   148,
     149,  1049,  1050,  1051,   583,  1052,  1053,  1054,   150,   151,
     152,   153,   154,   155,   156,   157,   158,  1055,   159,  1056,
     160,   161,   162,   163,   164,   165,  1057,   166,   167,   168,
     169,  1058,  1059,   170,   171,   172,   173,   174,  1060,   175,
     176,   177,  1061,   178,   179,   180,  1062,   181,   182,   183,
     184,   185,   186,   187,   188,   189,  1063,   190,  1064,   191,
     192,   193,   194,  1065,   195,  1066,   196,   584,  1067,   585,
     197,   198,   199,   200,  1068,   201,   202,  1069,   203,   204,
    1070,   205,   206,   207,   208,   209,   586,   210,   211,   212,
     213,  1071,   214,   215,   216,   217,   218,   219,  1072,   220,
     587,   221,   222,   223,   224,   225,   226,   227,  1073,   228,
    1074,   229,   588,   589,   230,   590,   231,   232,   233,   234,
     235,  1075,  1076,   236,   237,   591,   238,   592,  1077,   239,
     240,   241,  1078,  1079,   242,   243,   244,   245,   246,   247,
     248,   249,   250,   251,   252,   253,   254,   255,   256,   257,
     258,   593,   259,   260,   261,   262,   263,  1080,   264,   265,
     594,   266,  1081,   267,   268,   269,   270,   271,   272,  1082,
     273,   274,  1083,  1084,   275,   276,   277,  1085,  1086,   278,
     279,   595,   280,   596,   281,   282,   283,   284,   285,   286,
     287,   288,   289,   290,  1087,   291,   292,   293,   294,   295,
     296,   455,   298,   299,  1088,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,   313,  1089,
     314,   315,   316,   317,   318,   319,   320,   321,   322,   323,
     324,   325,  1090,   326,   327,   597,   328,   329,   330,   331,
     332,   333,   334,   335,   336,   337,   338,   339,   340,  1091,
     341,   342,   343,   344,   345,  1092,   346,   347,   348,   349,
     350,   598,   351,   352,   353,   354,  1093,   355,   356,   357,
     358,   359,   360,   361,   362,   363,   364,   365,   366,   367,
    1094,   368,   369,  1095,   370,   599,   371,   372,   373,   374,
     375,  1096,   376,   377,  1097,  1098,   378,   379,   380,   381,
     382,  1099,   383,   384,   385,   386,   387,   388,   389,  1100,
    1101,   390,   391,   392,   393,   394,  1102,  1103,   395,   396,
     397,   398,   399,   400,   401,  1104,   402,   601,   403,   404,
     405,   406,  1105,  1106,   407,  1107,  1108,   408,   409,   410,
     411,   412,   413,   414,   415,   416,   417,   418,   419,   420,
     421,   422,   423,   424,   425,   426,   427,    93,     0,     0,
       0,     0,     0,     0,     0,     0,  1109,     0,     0,     0,
       0,     0,    94,    95,    96,    97,    98,    99,   100,   101,
       0,   103,   104,   105,     0,     0,     0,     0,     0,     0,
       0,   106,   107,     0,   108,   109,   110,     0,   111,   112,
     113,   114,   115,     0,   116,   117,     0,   118,   119,   120,
     121,   122,     0,     0,   123,   124,   125,   126,   127,     0,
     128,   129,   130,   131,   132,     0,     0,     0,   133,   134,
     135,   136,   137,     0,   138,   139,   140,     0,   141,   142,
     143,   144,   145,   146,     0,     0,   147,   148,   149,     0,
       0,     0,     0,     0,     0,     0,   150,   151,   152,   153,
     154,   155,   156,   157,   158,     0,   159,     0,   160,   161,
     162,   163,   164,   165,     0,   166,   167,   168,   169,     0,
       0,   170,   171,   172,   173,   174,     0,   175,   176,   177,
       0,   178,   179,   180,     0,   181,   182,   183,   184,   185,
     186,   187,   188,   189,     0,   190,     0,   191,   192,   193,
     194,     0,   195,     0,   196,     0,     0,     0,   197,   198,
     199,   200,     0,   201,   202,     0,   203,   204,     0,   205,
     206,   207,   208,   209,     0,   210,   211,   212,   213,     0,
     214,   215,   216,   217,   218,   219,     0,   220,     0,   221,
     222,   223,   224,   225,   226,   227,     0,   228,     0,   229,
       0,     0,   230,     0,   231,   232,   233,   234,   235,     0,
       0,   236,   237,     0,   238,     0,     0,   239,   240,   241,
       0,     0,   242,   243,   244,   245,   246,   247,   248,   249,
     250,   251,   252,   253,   254,   255,   256,   257,   258,     0,
     259,   260,   261,   262,   263,     0,   264,   265,     0,   266,
       0,   267,   268,   269,   270,   271,   272,     0,   273,   274,
       0,     0,   275,   276,   277,     0,     0,   278,   279,     0,
     280,     0,   281,   282,   283,   284,   285,   286,   287,   288,
     289,   290,     0,   291,   292,   293,   294,   295,   296,   455,
     298,   299,     0,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,   313,     0,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
       0,   326,   327,     0,   328,   329,   330,   331,   332,   333,
     334,   335,   336,   337,   338,   339,   340,     0,   341,   342,
     343,   344,   345,     0,   346,   347,   348,   349,   350,     0,
     351,   352,   353,   354,     0,   355,   356,   357,   358,   359,
     360,   361,   362,   363,   364,   365,   366,   367,     0,   368,
     369,     0,   370,     0,   371,   372,   373,   374,   375,     0,
     376,   377,     0,     0,   378,   379,   380,   381,   382,     0,
     383,   384,   385,   386,   387,   388,   389,     0,     0,   390,
     391,   392,   393,   394,     0,     0,   395,   396,   397,   398,
     399,   400,   401,     0,   402,     0,   403,   404,   405,   406,
       0,     0,   407,     0,     0,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427,   577,   850,   467,     0,     0,
       0,   624,     0,     0,  2499,     0,     0,     0,     0,     0,
      94,    95,    96,    97,    98,    99,   100,   101,     0,   103,
     104,   105,     0,     0,     0,     0,     0,     0,     0,   106,
     107,     0,   108,   109,   110,   578,   111,   112,   113,   114,
     115,   579,   116,   117,     0,   118,   119,   120,   121,   122,
       0,     0,   123,   124,   125,   126,   127,     0,   128,   129,
     130,   131,   132,     0,   580,     0,   133,   134,   135,   136,
     137,   581,   138,   139,   140,     0,   141,   142,   143,   144,
     145,   146,     0,   582,   147,   148,   149,     0,     0,     0,
     583,     0,     0,     0,   150,   151,   152,   153,   154,   155,
     156,   157,   158,  1023,   159,     0,   160,   161,   162,   163,
     164,   165,     0,   166,   167,   168,   169,     0,     0,   170,
     171,   172,   173,   174,     0,   175,   176,   177,     0,   178,
     179,   180,     0,   181,   182,   183,   184,   185,   186,   187,
     188,   189,   851,   190,     0,   191,   192,   193,   194,     0,
     195,     0,   196,   584,     0,   585,   197,   198,   199,   200,
       0,   201,   202,     0,   203,   204,     0,   205,   206,   207,
     208,   209,   586,   210,   211,   212,   213,     0,   214,   215,
     216,   217,   218,   219,     0,   220,   587,   221,   222,   223,
     224,   225,   226,   227,     0,   228,     0,   229,   588,   589,
     230,   590,   231,   232,   233,   234,   235,     0,     0,   236,
     237,   591,   238,   592,     0,   239,   240,   241,     0,     0,
     242,   243,   244,   245,   246,   247,   248,   249,   250,   251,
     252,   253,   254,   255,   256,   257,   258,   593,   259,   260,
     261,   262,   263,     0,   264,   265,   594,   266,     0,   267,
     268,   269,   270,   271,   272,     0,   273,   274,   852,     0,
     275,   276,   277,     0,     0,   278,   279,   595,   280,   596,
     281,   282,   283,   284,   285,   286,   287,   288,   289,   290,
       0,   291,   292,   293,   294,   295,   296,   455,   298,   299,
       0,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,   313,     0,   314,   315,   316,   317,
     318,   319,   320,   321,   322,   323,   324,   325,     0,   326,
     327,   597,   328,   329,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,     0,   341,   342,   343,   344,
     345,     0,   346,   347,   348,   349,   350,   598,   351,   352,
     353,   354,     0,   355,   356,   357,   358,   359,   360,   361,
     362,   363,   364,   365,   366,   367,     0,   368,   369,     0,
     370,   599,   371,   372,   373,   374,   375,     0,   376,   377,
       0,     0,   378,   379,   380,   381,   382,   853,   383,   384,
     385,   386,   387,   388,   389,     0,     0,   390,   391,   392,
     393,   394,     0,     0,   395,   396,   397,   398,   399,   400,
     401,     0,   402,   601,   403,   404,   405,   406,     0,     0,
     407,     0,     0,   408,   409,   410,   411,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,   426,   427,   577,   850,   467,     0,     0,     0,   624,
     854,   855,     0,     0,     0,     0,     0,     0,    94,    95,
      96,    97,    98,    99,   100,   101,     0,   103,   104,   105,
       0,     0,     0,     0,     0,     0,     0,   106,   107,     0,
     108,   109,   110,   578,   111,   112,   113,   114,   115,   579,
     116,   117,     0,   118,   119,   120,   121,   122,     0,     0,
     123,   124,   125,   126,   127,     0,   128,   129,   130,   131,
     132,     0,   580,     0,   133,   134,   135,   136,   137,   581,
     138,   139,   140,     0,   141,   142,   143,   144,   145,   146,
       0,   582,   147,   148,   149,     0,     0,     0,   583,     0,
       0,     0,   150,   151,   152,   153,   154,   155,   156,   157,
     158,  1025,   159,     0,   160,   161,   162,   163,   164,   165,
       0,   166,   167,   168,   169,     0,     0,   170,   171,   172,
     173,   174,     0,   175,   176,   177,     0,   178,   179,   180,
       0,   181,   182,   183,   184,   185,   186,   187,   188,   189,
     851,   190,     0,   191,   192,   193,   194,     0,   195,     0,
     196,   584,     0,   585,   197,   198,   199,   200,     0,   201,
     202,     0,   203,   204,     0,   205,   206,   207,   208,   209,
     586,   210,   211,   212,   213,     0,   214,   215,   216,   217,
     218,   219,     0,   220,   587,   221,   222,   223,   224,   225,
     226,   227,     0,   228,     0,   229,   588,   589,   230,   590,
     231,   232,   233,   234,   235,     0,     0,   236,   237,   591,
     238,   592,     0,   239,   240,   241,     0,     0,   242,   243,
     244,   245,   246,   247,   248,   249,   250,   251,   252,   253,
     254,   255,   256,   257,   258,   593,   259,   260,   261,   262,
     263,     0,   264,   265,   594,   266,     0,   267,   268,   269,
     270,   271,   272,     0,   273,   274,   852,     0,   275,   276,
     277,     0,     0,   278,   279,   595,   280,   596,   281,   282,
     283,   284,   285,   286,   287,   288,   289,   290,     0,   291,
     292,   293,   294,   295,   296,   455,   298,   299,     0,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,   313,     0,   314,   315,   316,   317,   318,   319,
     320,   321,   322,   323,   324,   325,     0,   326,   327,   597,
     328,   329,   330,   331,   332,   333,   334,   335,   336,   337,
     338,   339,   340,     0,   341,   342,   343,   344,   345,     0,
     346,   347,   348,   349,   350,   598,   351,   352,   353,   354,
       0,   355,   356,   357,   358,   359,   360,   361,   362,   363,
     364,   365,   366,   367,     0,   368,   369,     0,   370,   599,
     371,   372,   373,   374,   375,     0,   376,   377,     0,     0,
     378,   379,   380,   381,   382,   853,   383,   384,   385,   386,
     387,   388,   389,     0,     0,   390,   391,   392,   393,   394,
       0,     0,   395,   396,   397,   398,   399,   400,   401,     0,
     402,   601,   403,   404,   405,   406,     0,     0,   407,     0,
       0,   408,   409,   410,   411,   412,   413,   414,   415,   416,
     417,   418,   419,   420,   421,   422,   423,   424,   425,   426,
     427,   577,   850,   467,     0,     0,     0,   624,   854,   855,
       0,     0,     0,     0,     0,     0,    94,    95,    96,    97,
      98,    99,   100,   101,     0,   103,   104,   105,     0,     0,
       0,     0,     0,     0,     0,   106,   107,     0,   108,   109,
     110,   578,   111,   112,   113,   114,   115,   579,   116,   117,
       0,   118,   119,   120,   121,   122,     0,     0,   123,   124,
     125,   126,   127,     0,   128,   129,   130,   131,   132,     0,
     580,     0,   133,   134,   135,   136,   137,   581,   138,   139,
     140,     0,   141,   142,   143,   144,   145,   146,     0,   582,
     147,   148,   149,     0,     0,     0,   583,     0,     0,     0,
     150,   151,   152,   153,   154,   155,   156,   157,   158,     0,
     159,     0,   160,   161,   162,   163,   164,   165,     0,   166,
     167,   168,   169,     0,     0,   170,   171,   172,   173,   174,
       0,   175,   176,   177,     0,   178,   179,   180,     0,   181,
     182,   183,   184,   185,   186,   187,   188,   189,   851,   190,
       0,   191,   192,   193,   194,     0,   195,     0,   196,   584,
       0,   585,   197,   198,   199,   200,     0,   201,   202,     0,
     203,   204,     0,   205,   206,   207,   208,   209,   586,   210,
     211,   212,   213,     0,   214,   215,   216,   217,   218,   219,
       0,   220,   587,   221,   222,   223,   224,   225,   226,   227,
       0,   228,     0,   229,   588,   589,   230,   590,   231,   232,
     233,   234,   235,     0,     0,   236,   237,   591,   238,   592,
       0,   239,   240,   241,     0,     0,   242,   243,   244,   245,
     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,
     256,   257,   258,   593,   259,   260,   261,   262,   263,     0,
     264,   265,   594,   266,     0,   267,   268,   269,   270,   271,
     272,     0,   273,   274,   852,     0,   275,   276,   277,     0,
       0,   278,   279,   595,   280,   596,   281,   282,   283,   284,
     285,   286,   287,   288,   289,   290,     0,   291,   292,   293,
     294,   295,   296,   455,   298,   299,     0,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
     313,     0,   314,   315,   316,   317,   318,   319,   320,   321,
     322,   323,   324,   325,     0,   326,   327,   597,   328,   329,
     330,   331,   332,   333,   334,   335,   336,   337,   338,   339,
     340,     0,   341,   342,   343,   344,   345,     0,   346,   347,
     348,   349,   350,   598,   351,   352,   353,   354,     0,   355,
     356,   357,   358,   359,   360,   361,   362,   363,   364,   365,
     366,   367,     0,   368,   369,     0,   370,   599,   371,   372,
     373,   374,   375,     0,   376,   377,     0,     0,   378,   379,
     380,   381,   382,   853,   383,   384,   385,   386,   387,   388,
     389,     0,     0,   390,   391,   392,   393,   394,     0,     0,
     395,   396,   397,   398,   399,   400,   401,     0,   402,   601,
     403,   404,   405,   406,     0,     0,   407,     0,     0,   408,
     409,   410,   411,   412,   413,   414,   415,   416,   417,   418,
     419,   420,   421,   422,   423,   424,   425,   426,   427,     0,
       0,   970,     0,     0,   971,     0,   854,   855,   972,   973,
     974,     0,     0,     0,   970,     0,     0,   971,     0,     0,
       0,   972,   973,   974,     0,   975,     0,     0,     0,  1465,
       0,     0,     0,   977,     0,     0,     0,     0,   975,     0,
     978,     0,     0,     0,     0,     0,   977,     0,     0,     0,
       0,     0,     0,   978,   970,     0,     0,   971,     0,     0,
       0,   972,   973,   974,   979,     0,     0,     0,     0,     0,
       0,     0,     0,   970,     0,     0,   971,   979,   975,     0,
     972,   973,   974,     0,     0,     0,   977,     0,     0,     0,
       0,     0,     0,   978,     0,     0,     0,   975,     0,     0,
    1613,     0,     0,     0,     0,   977,     0,     0,     0,     0,
       0,   970,   978,  1466,   971,     0,     0,   979,   972,   973,
     974,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     970,     0,     0,   971,     0,   975,   979,   972,   973,   974,
       0,     0,     0,   977,     0,     0,     0,     0,     0,     0,
     978,     0,     0,     0,   975,     0,     0,  1664,     0,     0,
       0,     0,   977,  1655,     0,     0,     0,     0,  1656,   978,
       0,     0,     0,   980,   979,     0,     0,     0,   981,     0,
       0,     0,     0,     0,     0,     0,   980,     0,     0,     0,
       0,   981,     0,   979,     0,     0,     0,     0,     0,   982,
     983,     0,  2553,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   982,   983,   984,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,   980,   984,     0,     0,
       0,   981,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   985,   980,     0,   986,     0,     0,
     981,     0,   982,   983,     0,     0,     0,   985,     0,     0,
     986,   987,     0,     0,   988,     0,     0,   984,     0,     0,
       0,   982,   983,     0,   987,     0,     0,   988,     0,     0,
       0,     0,     0,   980,     0,     0,   984,     0,   981,     0,
       0,     0,     0,     0,     0,     0,     0,   985,     0,     0,
     986,     0,   980,     0,     0,     0,     0,   981,     0,   982,
     983,     0,     0,     0,   987,     0,   985,   988,     0,   986,
       0,     0,     0,     0,   984,     0,     0,     0,   982,   983,
       0,     0,     0,   987,     0,     0,   988,     0,     0,  2554,
       0,     0,     0,   984,     0,     0,     0,     0,   989,     0,
       0,     0,     0,     0,   985,     0,     0,   986,     0,     0,
       0,   989,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   987,     0,   985,   988,     0,   986,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     987,  1629,     0,   988,     0,     0,     0,     0,     0,     0,
       0,   989,     0,     0,  1467,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     989,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   990,     0,     0,   991,   992,   993,
       0,   994,   995,   996,   997,   998,   999,   990,   989,     0,
     991,   992,   993,     0,   994,   995,   996,   997,   998,   999,
       0,   970,     0,     0,   971,     0,     0,   989,   972,   973,
     974,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,   975,     0,   990,     0,     0,
     991,   992,   993,   977,   994,   995,   996,   997,   998,   999,
     978,     0,     0,     0,     0,     0,   990,     0,     0,   991,
     992,   993,     0,   994,   995,   996,   997,   998,   999,     0,
       0,     0,     0,     0,   979,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   990,     0,     0,   991,   992,   993,
       0,   994,   995,   996,   997,   998,   999,     0,     0,     0,
       0,     0,     0,   990,     0,     0,   991,   992,   993,     0,
     994,   995,   996,   997,   998,   999,     0,   970,     0,     0,
     971,     0,     0,     0,   972,   973,   974,     0,     0,     0,
     970,     0,     0,   971,     0,     0,     0,   972,   973,   974,
       0,   975,     0,     0,     0,     0,     0,     0,     0,   977,
       0,     0,     0,     0,   975,  1669,   978,     0,     0,     0,
       0,     0,   977,     0,     0,     0,     0,     0,     0,   978,
       0,     0,     0,   980,     0,     0,     0,     0,   981,     0,
     979,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   979,     0,     0,     0,     0,     0,   982,
     983,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   984,     0,     0,     0,     0,   970,
       0,     0,   971,     0,     0,     0,   972,   973,   974,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   975,   985,     0,     0,   986,     0,     0,
       0,   977,     0,     0,     0,     0,     0,     0,   978,   970,
       0,   987,   971,     0,   988,     0,   972,   973,   974,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   979,     0,     0,     0,     0,     0,     0,   980,
       0,   977,     0,     0,   981,     0,     0,     0,   978,     0,
       0,     0,   980,     0,     0,     0,     0,   981,     0,     0,
       0,     0,     0,     0,     0,   982,   983,     0,     0,     0,
       0,     0,   979,     0,     0,     0,     0,     0,   982,   983,
     984,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   984,     0,     0,     0,     0,   989,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     985,     0,     0,   986,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   985,     0,     0,   986,   987,     0,     0,
     988,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     987,   980,     0,   988,     0,     0,   981,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,   982,   983,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   980,   984,     0,     0,     0,   981,     0,     0,     0,
       0,     0,     0,     0,   990,     0,     0,   991,   992,   993,
       0,   994,   995,   996,   997,   998,   999,   982,   983,     0,
       0,     0,   985,     0,   989,   986,     0,     0,     0,     0,
       0,     0,   984,     0,     0,     0,     0,   989,     0,   987,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,  1870,     0,     0,     0,     0,     0,
       0,     0,   985,     0,     0,   986,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   987,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     990,     0,     0,   991,   992,   993,   989,   994,   995,   996,
     997,   998,   999,   990,     0,     0,   991,   992,   993,     0,
     994,   995,   996,   997,   998,   999,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,   989,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   990,     0,     0,   991,   992,   993,     0,   994,
     995,   996,   997,   998,   999,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
    1031,     0,   990,     0,     0,   991,   992,   993,     0,   994,
     995,   996,   997,   998,   999,    94,    95,    96,    97,    98,
      99,   100,   101,  1032,   103,   104,   105,  1033,  1034,  1035,
    1036,  1037,  1038,  1039,   106,   107,  1040,   108,   109,   110,
     578,   111,   112,   113,   114,   115,   579,   116,   117,  1041,
     118,   119,   120,   121,   122,  1042,  1043,   123,   124,   125,
     126,   127,  1044,   128,   129,   130,   131,   132,  1045,   580,
    1046,   133,   134,   135,   136,   137,   581,   138,   139,   140,
    1047,   141,   142,   143,   144,   145,   146,  1048,   582,   147,
     148,   149,  1049,  1050,  1051,   583,  1052,  1053,  1054,   150,
     151,   152,   153,   154,   155,   156,   157,   158,  1055,   159,
    1056,   160,   161,   162,   163,   164,   165,  1057,   166,   167,
     168,   169,  1058,  1059,   170,   171,   172,   173,   174,  1060,
     175,   176,   177,  1061,   178,   179,   180,  1062,   181,   182,
     183,   184,   185,   186,   187,   188,   189,  1063,   190,  1064,
     191,   192,   193,   194,  1065,   195,  1066,   196,   584,  1067,
     585,   197,   198,   199,   200,  1068,   201,   202,  1069,   203,
     204,  1070,   205,   206,   207,   208,   209,   586,   210,   211,
     212,   213,  1071,   214,   215,   216,   217,   218,   219,  1072,
     220,   587,   221,   222,   223,   224,   225,   226,   227,  1073,
     228,  1074,   229,   588,   589,   230,   590,   231,   232,   233,
     234,   235,  1075,  1076,   236,   237,   591,   238,   592,  1077,
     239,   240,   241,  1078,  1079,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,   593,   259,   260,   261,   262,   263,  1080,   264,
     265,   594,   266,  1081,   267,   268,   269,   270,   271,   272,
    1082,   273,   274,  1083,  1084,   275,   276,   277,  1085,  1086,
     278,   279,   595,   280,   596,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,  1087,   291,   292,   293,   294,
     295,   296,   455,   298,   299,  1088,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
    1089,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,  1090,   326,   327,   597,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
    1091,   341,   342,   343,   344,   345,  1092,   346,   347,   348,
     349,   350,   598,   351,   352,   353,   354,  1093,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,  1094,   368,   369,  1095,   370,   599,   371,   372,   373,
     374,   375,  1096,   376,   377,  1097,  1098,   378,   379,   380,
     381,   382,  1099,   383,   384,   385,   386,   387,   388,   389,
    1100,  1101,   390,   391,   392,   393,   394,  1102,  1103,   395,
     396,   397,   398,   399,   400,   401,  1104,   402,   601,   403,
     404,   405,   406,  1105,  1106,   407,  1107,  1108,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,  1031,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,  1514,    99,   100,
     101,  1032,   103,   104,   105,  1033,  1034,  1035,  1036,  1037,
    1038,  1039,   106,   107,  1040,   108,   109,   110,   578,   111,
     112,   113,   114,   115,   579,   116,   117,  1041,   118,   119,
     120,   121,   122,  1042,  1043,   123,   124,   125,   126,   127,
    1044,   128,   129,   130,   131,   132,  1045,   580,  1046,   133,
     134,   135,   136,   137,   581,   138,   139,   140,  1047,   141,
     142,   143,   144,   145,   146,  1048,   582,   147,   148,   149,
    1049,  1050,  1051,   583,  1052,  1053,  1054,   150,   151,   152,
     153,   154,   155,   156,   157,   158,  1055,   159,  1056,   160,
     161,   162,   163,   164,   165,  1057,   166,   167,   168,   169,
    1058,  1059,   170,   171,   172,  1515,   174,  1060,   175,   176,
     177,  1061,   178,   179,   180,  1062,   181,   182,   183,   184,
     185,   186,   187,   188,   189,  1063,   190,  1064,   191,   192,
     193,   194,  1065,   195,  1066,   196,   584,  1067,   585,   197,
     198,   199,   200,  1068,   201,   202,  1069,   203,   204,  1070,
     205,   206,   207,   208,   209,   586,   210,   211,   212,   213,
    1071,   214,   215,   216,   217,   218,   219,  1072,   220,   587,
     221,   222,   223,   224,   225,   226,   227,  1073,   228,  1074,
     229,   588,   589,   230,   590,   231,   232,   233,   234,   235,
    1075,  1076,   236,   237,   591,   238,   592,  1077,   239,   240,
     241,  1078,  1079,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
     593,   259,   260,   261,   262,   263,  1080,   264,   265,   594,
     266,  1081,   267,   268,   269,   270,   271,   272,  1082,   273,
     274,  1083,  1084,   275,   276,   277,  1085,  1086,   278,   279,
     595,   280,   596,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,  1087,   291,   292,   293,   294,   295,   296,
     455,   298,   299,  1088,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,  1089,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,  1090,   326,   327,   597,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,  1091,   341,
     342,   343,   344,   345,  1092,  1516,   347,   348,   349,   350,
     598,   351,   352,   353,   354,  1093,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,  1094,
     368,   369,  1095,   370,   599,   371,   372,   373,   374,   375,
    1096,   376,   377,  1097,  1098,   378,   379,   380,   381,   382,
    1099,   383,   384,   385,   386,   387,   388,   389,  1100,  1101,
     390,   391,   392,   393,   394,  1102,  1103,   395,   396,   397,
     398,   399,   400,   401,  1104,   402,   601,   403,   404,   405,
     406,  1105,  1106,   407,  1107,  1108,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   619,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
     114,   115,   579,   116,   117,     0,   118,   119,   120,   121,
     122,     0,   630,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   633,     0,   634,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,   635,   636,
     637,   638,   639,   640,   641,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   647,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,   650,     0,   203,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,     0,     0,
     236,   654,   591,   238,   592,     0,   239,   240,   241,   655,
     656,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,   593,   259,
     260,   261,   262,   263,     0,   264,   265,   594,   266,     0,
     661,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,   595,   280,
     596,   664,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   665,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,   668,   346,   347,   348,   349,   350,   598,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   670,     0,   368,   369,
       0,   370,   599,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   673,   381,   674,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,   676,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,   577,     0,   467,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,   578,   111,   112,   113,   114,   115,
     579,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,   580,     0,   133,   134,   135,   136,   137,
     581,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,   582,   147,   148,   149,     0,     0,     0,   583,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,   851,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,   584,     0,   585,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     209,   586,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,   587,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,   588,   589,   230,
     590,   231,   232,   233,   234,   235,     0,     0,   236,   237,
     591,   238,   592,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,   593,   259,   260,   261,
     262,   263,     0,   264,   265,   594,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,   852,     0,   275,
     276,   277,     0,     0,   278,   279,   595,   280,   596,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
     597,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,   598,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
     599,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,   853,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,   601,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,   577,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,     0,   103,   104,   105,     3,
       4,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,   578,   111,   112,   113,   114,   115,   579,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,   580,     0,   133,   134,   135,   136,   137,   581,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
     582,   147,   148,   149,     0,     0,     0,   583,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
     584,     0,   585,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,   209,   586,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,   587,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,   588,   589,   230,   590,   231,
     232,   233,   234,   235,     0,     0,   236,   237,   591,   238,
     592,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   593,   259,   260,   261,   262,   263,
       0,   264,   265,   594,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,   595,   280,   596,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,   597,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     347,   348,   349,   350,   598,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,   599,   371,
     372,   373,   374,   375,     0,   376,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
     601,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
     619,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
     578,   111,   112,   113,   114,   115,   579,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,   580,
       0,   133,   134,   135,   136,   137,   581,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,   582,   147,
     148,   149,     0,     0,     0,   583,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,   584,     0,
     585,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   209,   586,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,   587,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,   588,   589,   230,   590,   231,   232,   233,
     234,   235,     0,     0,   236,   237,   591,   238,   592,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,   593,   259,   260,   261,   262,   263,     0,   264,
     265,   594,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,   595,   280,   596,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,   597,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,   598,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,   599,   371,   372,   373,
     374,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,   601,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
    1169,   128,   129,   130,   131,   132,     0,     0,  1170,   133,
     134,   135,   136,   137,     0,   138,   139,   140,  1171,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,  1172,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,  1173,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,  1174,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,  1175,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,  1169,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,  1171,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,  1172,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   209,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,  1567,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,  1174,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,  1175,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     3,     4,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     209,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,    93,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,   102,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,     0,   111,   112,   113,   114,   115,     0,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,     0,     0,   133,   134,   135,   136,   137,     0,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
       0,   147,   148,   149,     0,     0,     0,     0,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
       0,     0,     0,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,   209,     0,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,     0,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,     0,     0,   230,     0,   231,
     232,   233,   234,   235,     0,     0,   236,   237,     0,   238,
       0,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,     0,   259,   260,   261,   262,   263,
       0,   264,   265,     0,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,     0,   280,     0,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   297,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,     0,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     347,   348,   349,   350,     0,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,     0,   371,
     372,   373,   374,   375,     0,   376,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
       0,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,   472,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   209,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,     0,   371,   372,   373,
     374,   375,     0,   473,   377,     0,     0,   474,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,   491,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   492,   377,     0,     0,   493,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   209,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,     0,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
     496,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     534,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,   496,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,    93,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,   556,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,     0,   111,   112,   113,   114,   115,     0,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,     0,     0,   133,   134,   135,   136,   137,     0,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
       0,   147,   148,   149,     0,     0,     0,     0,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
       0,     0,     0,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,   209,     0,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,     0,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,     0,     0,   230,     0,   231,
     232,   233,   234,   235,     0,     0,   236,   237,     0,   238,
       0,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,     0,   259,   260,   261,   262,   263,
       0,   264,   265,     0,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,     0,   280,     0,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,     0,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     347,   348,   349,   350,     0,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,     0,   371,
     372,   373,   374,   375,     0,   376,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
       0,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,  1420,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   209,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,  1421,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,  1422,   370,     0,   371,  1423,   373,
    1424,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,  1425,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
    1949,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,  1963,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   209,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,     0,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     209,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,    93,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,     0,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,     0,   111,   112,   113,   114,   115,     0,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,     0,     0,   133,   134,   135,   136,   137,     0,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
       0,   147,   148,   149,     0,     0,     0,     0,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
       0,     0,     0,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,   209,     0,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,     0,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,     0,     0,   230,     0,   231,
     232,   233,   234,   235,     0,     0,   236,   237,     0,   238,
       0,     0,   239,   240,   484,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,     0,   259,   260,   261,   262,   263,
       0,   264,   265,     0,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,     0,   280,     0,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,     0,   328,
     329,   330,   331,   332,   333,   334,   485,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   486,     0,   346,
     347,   348,   349,   350,     0,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,     0,   371,
     372,   373,   374,   375,     0,   487,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
       0,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   209,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   504,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,     0,   371,   372,   373,
     374,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   529,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   532,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,     0,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     536,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,    93,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,     0,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,     0,   111,   112,   113,   114,   115,     0,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,     0,     0,   133,   134,   135,   136,   137,     0,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
       0,   147,   148,   149,     0,     0,     0,     0,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
       0,     0,     0,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,   549,     0,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,     0,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,     0,     0,   230,     0,   231,
     232,   233,   234,   235,     0,     0,   236,   237,     0,   238,
       0,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,     0,   259,   260,   261,   262,   263,
       0,   264,   265,     0,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,     0,   280,     0,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,     0,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     347,   348,   349,   350,     0,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,     0,   371,
     372,   373,   374,   375,     0,   376,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
       0,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   564,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,     0,   371,   372,   373,
     374,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   568,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,   571,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,     0,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     209,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,   332,   333,   334,   485,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   487,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,    93,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,     0,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,     0,   111,   112,   113,   114,   115,     0,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,     0,     0,   133,   134,   135,   136,   137,     0,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
       0,   147,   148,   149,     0,     0,     0,     0,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
       0,     0,     0,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,   821,     0,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,     0,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,     0,     0,   230,     0,   231,
     232,   233,   234,   235,     0,     0,   236,   237,     0,   238,
       0,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,     0,   259,   260,   261,   262,   263,
       0,   264,   265,     0,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,     0,   280,     0,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,     0,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     347,   348,   349,   350,     0,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,     0,   371,
     372,   373,   374,   375,     0,   376,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
       0,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,   823,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,     0,   371,   372,   373,
     374,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
    1128,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,   209,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,     0,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,  1246,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,     0,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
    1259,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,    93,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,     0,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,     0,   111,   112,   113,   114,   115,     0,   116,
     117,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   125,   126,   127,     0,   128,   129,   130,   131,   132,
       0,     0,     0,   133,   134,   135,   136,   137,     0,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
       0,   147,   148,   149,     0,     0,     0,     0,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   156,   157,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   172,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,   185,   186,   187,   188,   189,     0,
     190,     0,   191,   192,   193,   194,     0,   195,     0,   196,
       0,     0,     0,   197,   198,   199,   200,     0,   201,   202,
       0,   203,   204,     0,   205,   206,   207,   208,  1498,     0,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,     0,   221,   222,   223,   224,   225,   226,
     227,     0,   228,     0,   229,     0,     0,   230,     0,   231,
     232,   233,   234,   235,     0,     0,   236,   237,     0,   238,
       0,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,     0,   259,   260,   261,   262,   263,
       0,   264,   265,     0,   266,     0,   267,   268,   269,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,   279,     0,   280,     0,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
     293,   294,   295,   296,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,     0,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     347,   348,   349,   350,     0,   351,   352,   353,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,     0,   368,   369,     0,   370,     0,   371,
     372,   373,   374,   375,     0,   376,   377,     0,     0,   378,
     379,   380,   381,   382,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,   400,   401,     0,   402,
       0,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   414,   415,   416,   417,
     418,   419,   420,   421,   422,   423,   424,   425,   426,   427,
      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,    94,    95,    96,    97,    98,
      99,   100,   101,     0,   103,   104,   105,     0,     0,     0,
       0,     0,     0,     0,   106,   107,     0,   108,   109,   110,
       0,   111,   112,   113,   114,   115,     0,   116,   117,     0,
     118,   119,   120,   121,   122,     0,     0,   123,   124,   125,
     126,   127,     0,   128,   129,   130,   131,   132,     0,     0,
       0,   133,   134,   135,   136,   137,     0,   138,   139,   140,
       0,   141,   142,   143,   144,   145,   146,     0,     0,   147,
     148,   149,     0,     0,     0,     0,     0,     0,     0,   150,
     151,   152,   153,   154,   155,   156,   157,   158,     0,   159,
       0,   160,   161,   162,   163,   164,   165,     0,   166,   167,
     168,   169,     0,     0,   170,   171,   172,   173,   174,     0,
     175,   176,   177,     0,   178,   179,   180,     0,   181,   182,
     183,   184,   185,   186,   187,   188,   189,     0,   190,     0,
     191,   192,   193,   194,     0,   195,     0,   196,     0,     0,
       0,   197,   198,   199,   200,     0,   201,   202,     0,   203,
     204,     0,   205,   206,   207,   208,  1510,     0,   210,   211,
     212,   213,     0,   214,   215,   216,   217,   218,   219,     0,
     220,     0,   221,   222,   223,   224,   225,   226,   227,     0,
     228,     0,   229,     0,     0,   230,     0,   231,   232,   233,
     234,   235,     0,     0,   236,   237,     0,   238,     0,     0,
     239,   240,   241,     0,     0,   242,   243,   244,   245,   246,
     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,
     257,   258,     0,   259,   260,   261,   262,   263,     0,   264,
     265,     0,   266,     0,   267,   268,   269,   270,   271,   272,
       0,   273,   274,     0,     0,   275,   276,   277,     0,     0,
     278,   279,     0,   280,     0,   281,   282,   283,   284,   285,
     286,   287,   288,   289,   290,     0,   291,   292,   293,   294,
     295,   296,   455,   298,   299,     0,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
       0,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,     0,   326,   327,     0,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
       0,   341,   342,   343,   344,   345,     0,   346,   347,   348,
     349,   350,     0,   351,   352,   353,   354,     0,   355,   356,
     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
     367,     0,   368,   369,     0,   370,     0,   371,   372,   373,
     374,   375,     0,   376,   377,     0,     0,   378,   379,   380,
     381,   382,     0,   383,   384,   385,   386,   387,   388,   389,
       0,     0,   390,   391,   392,   393,   394,     0,     0,   395,
     396,   397,   398,   399,   400,   401,     0,   402,     0,   403,
     404,   405,   406,     0,     0,   407,     0,     0,   408,   409,
     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
     420,   421,   422,   423,   424,   425,   426,   427,    93,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,    94,    95,    96,    97,    98,    99,   100,
     101,     0,   103,   104,   105,     0,     0,     0,     0,     0,
       0,     0,   106,   107,     0,   108,   109,   110,     0,   111,
     112,   113,   114,   115,     0,   116,   117,     0,   118,   119,
     120,   121,   122,     0,     0,   123,   124,   125,   126,   127,
       0,   128,   129,   130,   131,   132,     0,     0,     0,   133,
     134,   135,   136,   137,     0,   138,   139,   140,     0,   141,
     142,   143,   144,   145,   146,     0,     0,   147,   148,   149,
       0,     0,     0,     0,     0,     0,     0,   150,   151,   152,
     153,   154,   155,   156,   157,   158,     0,   159,     0,   160,
     161,   162,   163,   164,   165,     0,   166,   167,   168,   169,
       0,     0,   170,   171,   172,   173,   174,     0,   175,   176,
     177,     0,   178,   179,   180,     0,   181,   182,   183,   184,
     185,   186,   187,   188,   189,     0,   190,     0,   191,   192,
     193,   194,     0,   195,     0,   196,     0,     0,     0,   197,
     198,   199,   200,     0,   201,   202,     0,   203,   204,     0,
     205,   206,   207,   208,  1512,     0,   210,   211,   212,   213,
       0,   214,   215,   216,   217,   218,   219,     0,   220,     0,
     221,   222,   223,   224,   225,   226,   227,     0,   228,     0,
     229,     0,     0,   230,     0,   231,   232,   233,   234,   235,
       0,     0,   236,   237,     0,   238,     0,     0,   239,   240,
     241,     0,     0,   242,   243,   244,   245,   246,   247,   248,
     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,
       0,   259,   260,   261,   262,   263,     0,   264,   265,     0,
     266,     0,   267,   268,   269,   270,   271,   272,     0,   273,
     274,     0,     0,   275,   276,   277,     0,     0,   278,   279,
       0,   280,     0,   281,   282,   283,   284,   285,   286,   287,
     288,   289,   290,     0,   291,   292,   293,   294,   295,   296,
     455,   298,   299,     0,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,   313,     0,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,     0,   326,   327,     0,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,     0,   341,
     342,   343,   344,   345,     0,   346,   347,   348,   349,   350,
       0,   351,   352,   353,   354,     0,   355,   356,   357,   358,
     359,   360,   361,   362,   363,   364,   365,   366,   367,     0,
     368,   369,     0,   370,     0,   371,   372,   373,   374,   375,
       0,   376,   377,     0,     0,   378,   379,   380,   381,   382,
       0,   383,   384,   385,   386,   387,   388,   389,     0,     0,
     390,   391,   392,   393,   394,     0,     0,   395,   396,   397,
     398,   399,   400,   401,     0,   402,     0,   403,   404,   405,
     406,     0,     0,   407,     0,     0,   408,   409,   410,   411,
     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,    93,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,     0,   111,   112,   113,
     114,   115,     0,   116,   117,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   125,   126,   127,     0,   128,
     129,   130,   131,   132,     0,     0,     0,   133,   134,   135,
     136,   137,     0,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,     0,   147,   148,   149,     0,     0,
       0,     0,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   156,   157,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   172,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,   185,   186,
     187,   188,   189,     0,   190,     0,   191,   192,   193,   194,
       0,   195,     0,   196,     0,     0,     0,   197,   198,   199,
     200,     0,   201,   202,     0,   203,   204,     0,   205,   206,
     207,   208,  2068,     0,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,     0,   221,   222,
     223,   224,   225,   226,   227,     0,   228,     0,   229,     0,
       0,   230,     0,   231,   232,   233,   234,   235,     0,     0,
     236,   237,     0,   238,     0,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   258,     0,   259,
     260,   261,   262,   263,     0,   264,   265,     0,   266,     0,
     267,   268,   269,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,   279,     0,   280,
       0,   281,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,   293,   294,   295,   296,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,     0,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,   347,   348,   349,   350,     0,   351,
     352,   353,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,   367,     0,   368,   369,
       0,   370,     0,   371,   372,   373,   374,   375,     0,   376,
     377,     0,     0,   378,   379,   380,   381,   382,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
     400,   401,     0,   402,     0,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,    93,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
      95,    96,    97,    98,    99,   100,   101,     0,   103,   104,
     105,     0,     0,     0,     0,     0,     0,     0,   106,   107,
       0,   108,   109,   110,     0,   111,   112,   113,   114,   115,
       0,   116,   117,     0,   118,   119,   120,   121,   122,     0,
       0,   123,   124,   125,   126,   127,     0,   128,   129,   130,
     131,   132,     0,     0,     0,   133,   134,   135,   136,   137,
       0,   138,   139,   140,     0,   141,   142,   143,   144,   145,
     146,     0,     0,   147,   148,   149,     0,     0,     0,     0,
       0,     0,     0,   150,   151,   152,   153,   154,   155,   156,
     157,   158,     0,   159,     0,   160,   161,   162,   163,   164,
     165,     0,   166,   167,   168,   169,     0,     0,   170,   171,
     172,   173,   174,     0,   175,   176,   177,     0,   178,   179,
     180,     0,   181,   182,   183,   184,   185,   186,   187,   188,
     189,     0,   190,     0,   191,   192,   193,   194,     0,   195,
       0,   196,     0,     0,     0,   197,   198,   199,   200,     0,
     201,   202,     0,   203,   204,     0,   205,   206,   207,   208,
     209,     0,   210,   211,   212,   213,     0,   214,   215,   216,
     217,   218,   219,     0,   220,     0,   221,   222,   223,   224,
     225,   226,   227,     0,   228,     0,   229,     0,     0,   230,
       0,   231,   232,   233,   234,   235,     0,     0,   236,   237,
       0,   238,     0,     0,   239,   240,   241,     0,     0,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,     0,   259,   260,   261,
     262,   263,     0,   264,   265,     0,   266,     0,   267,   268,
     269,   270,   271,   272,     0,   273,   274,     0,     0,   275,
     276,   277,     0,     0,   278,   279,     0,   280,     0,   281,
     282,   283,   284,   285,   286,   287,     0,   289,   290,     0,
     291,   292,   293,   294,   295,   296,   455,   298,   299,     0,
     300,   301,   302,   303,   304,   305,   306,     0,   308,   309,
     310,   311,   312,   313,     0,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,     0,   326,   327,
       0,   328,   329,   330,   331,     0,   333,   334,   335,   336,
     337,   338,   339,   340,     0,   341,   342,   343,   344,   345,
       0,   346,   347,   348,   349,   350,     0,   351,   352,   353,
     354,     0,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,     0,   368,   369,     0,   370,
       0,   371,   372,   373,   374,   375,     0,   376,   377,     0,
       0,   378,   379,   380,   381,   382,     0,   383,   384,   385,
     386,   387,   388,   389,     0,     0,   390,   391,   392,   393,
     394,     0,     0,   395,   396,   397,   398,   399,   400,   401,
       0,   402,     0,   403,   404,   405,   406,     0,     0,   407,
       0,     0,   408,   409,   410,   411,   412,   413,   414,   415,
     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
     426,   427,   874,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,    94,    95,    96,
      97,    98,    99,   100,   101,     0,   103,   104,   105,     0,
       0,     0,     0,     0,     0,     0,   106,   107,     0,   108,
     109,   110,   578,   111,   112,   113,     0,   875,   579,   876,
     877,     0,   118,   119,   120,   121,   122,     0,     0,   123,
     124,   878,   879,   127,     0,   128,   129,   130,   131,     0,
       0,   580,     0,   133,   134,   135,   136,   137,   581,   138,
     139,   140,     0,   141,   142,   143,   144,   145,   146,     0,
     582,   147,   148,   149,     0,     0,     0,   583,     0,     0,
       0,   150,   151,   152,   153,   154,   155,   880,   881,   158,
       0,   159,     0,   160,   161,   162,   163,   164,   165,     0,
     166,   167,   168,   169,     0,     0,   170,   171,   645,   173,
     174,     0,   175,   176,   177,     0,   178,   179,   180,     0,
     181,   182,   183,   184,     0,   186,   187,   188,     0,     0,
     190,     0,   191,   192,   882,   194,     0,   195,     0,   196,
     584,     0,   585,   197,   198,   199,   200,     0,   201,     0,
       0,     0,   204,     0,   205,   206,   207,   208,   209,   586,
     210,   211,   212,   213,     0,   214,   215,   216,   217,   218,
     219,     0,   220,   587,     0,   222,   223,   224,   225,   883,
     884,     0,   885,     0,   229,   588,   589,   230,   590,   231,
     232,   233,   234,   235,     0,     0,   236,     0,   591,   238,
     592,     0,   239,   240,   241,     0,     0,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   886,   593,   887,   260,   261,   262,     0,
       0,   264,   265,   594,   266,     0,     0,   268,   888,   270,
     271,   272,     0,   273,   274,     0,     0,   275,   276,   277,
       0,     0,   278,     0,   595,   280,   596,     0,   282,   283,
     284,   285,   286,   287,   288,   289,   290,     0,   291,   292,
       0,   294,   295,     0,   455,   298,   299,     0,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   889,   310,   311,
     312,   313,     0,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,     0,   326,   327,   597,   328,
     329,   330,     0,   332,   333,   334,   335,   336,   337,   338,
     339,   340,     0,   341,   342,   343,   344,   345,     0,   346,
     890,   348,   349,   350,   598,   351,   352,   891,   354,     0,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,     0,     0,   368,   369,     0,   370,   599,   371,
     372,   373,   374,   375,     0,   892,   893,     0,     0,   378,
     379,     0,   381,     0,     0,   383,   384,   385,   386,   387,
     388,   389,     0,     0,   390,   391,   392,   393,   394,     0,
       0,   395,   396,   397,   398,   399,     0,   894,     0,   402,
     601,   403,   404,   405,   406,     0,     0,   407,     0,     0,
     408,   409,   410,   411,   412,   413,   874,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,   425,   426,   427,
       0,    94,    95,    96,    97,    98,    99,   100,   101,     0,
     103,   104,   105,     0,     0,     0,     0,     0,     0,     0,
     106,   107,     0,   108,   109,   110,   578,   111,   112,   113,
       0,   875,   579,   876,   877,     0,   118,   119,   120,   121,
     122,     0,     0,   123,   124,   878,   879,   127,     0,   128,
     129,   130,   131,     0,     0,   580,     0,   133,   134,   135,
     136,   137,   581,   138,   139,   140,     0,   141,   142,   143,
     144,   145,   146,     0,   582,   147,   148,   149,     0,     0,
       0,   583,     0,     0,     0,   150,   151,   152,   153,   154,
     155,   880,   881,   158,     0,   159,     0,   160,   161,   162,
     163,   164,   165,     0,   166,   167,   168,   169,     0,     0,
     170,   171,   645,   173,   174,     0,   175,   176,   177,     0,
     178,   179,   180,     0,   181,   182,   183,   184,     0,   186,
     187,   188,     0,     0,   190,     0,   191,   192,   882,   194,
       0,   195,     0,   196,   584,     0,   585,   197,   198,   199,
     200,     0,   201,     0,     0,     0,   204,     0,   205,   206,
     207,   208,   209,   586,   210,   211,   212,   213,     0,   214,
     215,   216,   217,   218,   219,     0,   220,   587,     0,   222,
     223,   224,   225,   883,   884,     0,   885,     0,   229,   588,
     589,   230,   590,   231,   232,   233,   234,   235,     0,     0,
     236,     0,   591,   238,   592,     0,   239,   240,   241,     0,
       0,   242,   243,   244,   245,   246,   247,   248,   249,   250,
     251,   252,   253,   254,   255,   256,   257,   886,   593,   887,
     260,   261,   262,     0,     0,   264,   265,   594,   266,     0,
       0,   268,   888,   270,   271,   272,     0,   273,   274,     0,
       0,   275,   276,   277,     0,     0,   278,     0,   595,   280,
     596,     0,   282,   283,   284,   285,   286,   287,   288,   289,
     290,     0,   291,   292,     0,   294,   295,     0,   455,   298,
     299,     0,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   889,   310,   311,   312,   313,     0,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,     0,
     326,   327,   597,   328,   329,   330,     0,   332,   333,   334,
     335,   336,   337,   338,   339,   340,     0,   341,   342,   343,
     344,   345,     0,   346,     0,   348,   349,   350,   598,   351,
     352,   891,   354,     0,   355,   356,   357,   358,   359,   360,
     361,   362,   363,   364,   365,   366,     0,     0,   368,   369,
       0,   370,   599,   371,   372,   373,   374,   375,     0,   892,
     893,     0,     0,   378,   379,     0,   381,     0,     0,   383,
     384,   385,   386,   387,   388,   389,     0,     0,   390,   391,
     392,   393,   394,     0,     0,   395,   396,   397,   398,   399,
       0,   894,     0,   402,   601,   403,   404,   405,   406,     0,
       0,   407,     0,     0,   408,   409,   410,   411,   412,   413,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,   425,   426,   427
};

static const yytype_int16 yycheck[] =
{
      15,   533,    29,    50,   804,   499,   451,   606,   606,   483,
       0,    10,   730,   944,    13,   503,   543,    16,    17,    18,
     802,   452,    21,    22,   971,    24,   642,   643,    27,    28,
       0,   777,     0,     0,   524,   569,   908,   790,   819,  1437,
     968,   672,   683,     0,  1011,   847,   662,    14,    24,  1270,
      14,   819,   779,   732,   819,   819,  1765,  1514,   457,  1516,
     782,  1508,   775,   910,  1392,  1688,  1813,     9,    52,  1459,
    1847,  1832,     0,    28,    73,    74,    75,    76,    77,     5,
     807,  1840,   459,    82,  1505,   573,    11,    86,  1715,    52,
       5,    81,  1014,   458,     0,    11,  2072,     5,    13,    14,
      76,    10,    49,    56,    13,    13,    14,    56,    17,     9,
    1721,    81,  1149,    81,    81,    40,   459,    22,    27,    28,
    2078,   839,   720,    28,    81,     5,     5,  2075,   839,  1151,
       5,     5,     5,    13,    14,   459,     5,   890,     5,   162,
     118,     5,    56,  1564,     5,     5,    71,     5,    80,   548,
     132,   464,    73,    39,   104,   204,  2142,     5,     4,   163,
       0,    39,    83,     9,  1754,    74,     9,   162,   113,   144,
    2213,   231,    56,  2027,     0,   264,   764,   162,  2345,   533,
     116,   535,    65,   537,    90,    73,   521,    11,    14,  2294,
     122,  1720,     3,   791,   682,    83,   794,   795,   163,    26,
      47,  1657,   272,    29,   111,   613,    33,    11,   188,     3,
       4,     5,  1433,   613,  2243,     9,    40,   711,   266,    30,
      31,   177,     4,   116,    26,   130,    52,     9,   521,   606,
     272,    33,  1179,   156,   611,   914,    40,   333,   104,   252,
     116,   113,   311,  2124,    11,   610,    71,    71,   152,    57,
      90,    11,  1784,  2403,   130,    81,    26,    65,   976,    73,
      36,    75,   893,    77,   880,   881,  2512,    71,    82,  1338,
    1339,  2229,   888,   154,  1343,   114,   159,   337,  2445,   142,
    2161,   237,   606,    26,   963,   964,   774,   611,  2274,   432,
      33,   376,   411,   152,   125,    26,  1919,   427,   297,   826,
    1628,   306,   114,    29,   467,   198,   469,  1376,  1377,  2070,
     453,   456,   720,   390,   324,   746,     5,   111,   222,   284,
    1852,   154,   467,   186,   411,   410,  1953,    53,  2574,   334,
    1957,  2185,  1943,   180,  1013,   249,  1783,     0,   185,  1286,
     350,   471,   181,   467,   120,   722,   723,   407,   467,   256,
     161,   283,   163,   730,   423,   125,   433,   337,   946,  1780,
     266,  1782,  2243,   222,   344,   270,  2471,   248,   343,   181,
     293,   467,   325,   613,   221,  2525,   325,   470,   467,  2546,
     467,   214,   790,   249,   256,   341,   421,  2170,   297,   834,
     790,   356,   837,   388,   125,  1429,   409,   377,   722,   723,
     845,   471,   377,   388,   263,  1995,   730,   467,  2191,   203,
     841,   325,   471,  1942,   319,   298,  1450,   225,   323,   467,
     326,   297,   471,  1879,  1170,   913,   266,   377,   741,   471,
     261,   225,   459,   411,   922,  1472,   350,   772,   926,  2482,
    1240,   325,   417,   423,   426,   350,   934,   935,   471,     8,
     382,  1473,   451,   452,   453,   430,    15,    16,    17,   947,
     948,  1392,   839,   467,  1431,  1432,  2213,   388,   413,  1187,
     485,   456,   849,   409,  2460,  2098,   465,   524,   453,   772,
     469,  2510,   890,   848,   469,   484,   326,   486,   374,  2447,
     890,   458,   467,  2374,   420,   459,   374,   496,  2446,   140,
     388,   321,  2129,   367,   368,   504,   849,  2134,   355,   414,
    2137,  1439,  1733,   456,  2125,   839,   409,   516,   471,  2400,
     467,   404,   471,   513,   430,   849,   469,   511,  2504,   528,
     472,  2314,   188,   360,   979,  1253,  1467,   501,   463,  1461,
     516,   467,  1253,   513,   453,   513,   513,   463,   511,   504,
     790,  1139,   467,   552,   553,   554,   513,  2004,   360,   467,
    2017,   202,   468,   971,   470,   432,   466,  1636,  1637,  1638,
    1639,   971,  2349,  1642,  1643,  1644,  1645,  1646,  1647,  1648,
    1649,  1650,  1651,  2344,   432,   513,   453,   467,   467,  2348,
     430,   606,   467,   467,   467,   504,   611,    90,   467,   976,
     467,  1199,  1449,  1993,   465,   453,   467,   467,   469,   467,
     421,  1209,   458,   459,  1212,   458,   459,   360,   617,   467,
     237,  1630,   125,  1692,  1693,  2248,   231,  1574,   468,  2510,
     470,   272,   458,   459,   458,   459,   460,   461,   462,   463,
     465,  2268,   255,   610,   469,  2066,   111,   113,   430,  1658,
     890,   111,   976,    62,    63,   682,   460,   461,   462,   463,
     236,   103,    22,  1195,   458,   459,  1613,   430,    73,  1997,
     685,   453,  1288,   163,    11,   144,   458,   459,    83,  1713,
     695,  1715,   496,   468,     4,   511,   471,   513,  1635,     9,
     453,  2452,   707,   460,   461,   462,   463,  1628,   458,   459,
     460,   461,   462,   463,   194,   720,   210,   722,   723,   268,
       4,   393,    11,   178,   528,     9,  1250,  1664,    18,   209,
    1254,  1362,    22,  1257,   341,  2172,   192,   726,   210,   219,
    1443,   971,  1532,   167,    71,  2482,   423,     4,   552,   553,
     554,    40,     9,    22,   357,   249,   745,   746,   251,    28,
    1338,  1339,   751,   752,   753,  1343,  1977,   125,   261,    73,
    1205,    91,   403,   467,  1566,  1210,   343,   249,   311,    83,
     130,  1179,    71,   757,   758,   751,   760,   776,   777,  1179,
      13,    14,   150,   249,   610,   251,   251,   340,  1376,  1377,
     789,   225,   231,   235,   757,   758,   238,   760,    13,    14,
     377,   344,   407,   307,  1292,   450,   468,   806,  1185,   471,
    1187,   810,  2573,  1540,  1168,   467,   815,  2526,  2527,   279,
     646,   820,  1463,  1429,  1355,   468,  1357,  1358,   471,   828,
     806,   208,  1231,   163,   377,   834,   745,   469,   837,   329,
     417,  1195,   841,   842,  1450,   844,   845,  2304,   847,   353,
     343,   130,  2299,  1575,   106,   465,   682,   467,  1580,   469,
    1214,  1185,   467,  1187,   194,  1219,  1813,  2576,  1356,   333,
     334,   353,   251,  2475,   343,  2477,  1253,   256,  1286,   209,
     423,   848,  1813,   343,   377,   849,  1286,   106,   256,   219,
     467,  1268,  1380,   261,   266,   454,   455,   456,   337,   458,
     459,   460,   461,   462,   463,   409,   152,     3,   377,     5,
     270,   157,   726,   333,   334,   245,   931,   377,   468,  1953,
     910,   471,    22,  1957,   417,   177,   305,   409,    28,  1253,
    1418,   757,   758,   842,   760,   844,   450,   430,   752,  1179,
     910,   231,   910,   910,  1268,   944,  1436,   381,   417,   383,
    1599,  1600,  1601,   910,    30,    31,  2558,   417,   177,   450,
     453,   430,   776,   323,   324,   432,   468,   231,   407,   471,
     430,   208,   231,   407,   467,   789,   222,  1511,   161,  1513,
     979,   381,  1910,   383,   453,   237,   453,   460,   240,    22,
     350,   270,  1671,   453,  1794,    28,   810,   471,   467,   329,
     467,  2399,  1969,   381,  1019,   383,   820,   467,   432,  1008,
     106,  1793,  1424,  1425,    90,  2436,  2437,   263,   237,  2334,
     467,   240,   848,  2338,   140,  2340,  2095,   395,   467,   453,
     130,  1662,  1663,   847,  1561,  1781,   152,   405,   468,   468,
     319,   157,   471,   467,   323,  1827,  1286,   337,  1636,  1637,
    1638,  1639,  1833,  1855,  1642,  1643,  1644,  1645,  1646,  1647,
    1648,  1649,  1650,  1651,   468,  1833,  1997,   471,  1833,  1833,
    1792,   350,  1794,   337,   468,   468,  2497,   471,   337,   162,
     468,   177,  1761,   471,   910,   204,   202,   152,  2035,   341,
    2124,   430,   157,   432,  1812,  2129,  1814,   130,   468,   468,
    2134,   471,   471,  2137,  1692,  1693,   222,  1713,   231,  1715,
     467,  1752,   469,  2511,  2183,  2562,   462,   407,  1117,   462,
    1119,   467,   341,   469,   467,    53,   469,  2161,    22,  1128,
    2528,  1130,   631,   632,    28,   414,  1126,  1514,  1515,  1516,
     467,   237,  1587,   407,   240,   145,   468,   263,   407,   471,
     468,   319,    22,   471,  1118,   981,   272,   222,    28,   658,
     333,   334,     5,  1162,     7,   468,  1574,   145,   471,    12,
     270,  1170,  1171,   381,  1574,   383,    19,   467,  2247,  2051,
      23,  1669,  1181,  1182,  1183,  1184,  2584,  1186,   333,   334,
    1514,  1515,  1516,  1192,  1008,  1194,   448,   468,   263,   468,
     471,   145,   471,   467,   145,  1613,  1205,  1206,   467,  2243,
     468,  1210,  1211,  1613,   337,  1813,  1215,  1216,  1217,  1218,
      22,  1220,  1221,   323,   125,   468,    28,  1635,   471,   448,
    1229,  1230,  1726,  2033,  2268,  1635,   130,   270,   467,  1729,
    1730,  1731,   251,  1242,   468,   341,   423,   471,   467,   150,
     350,    79,   468,  1268,  1244,   471,  1664,   145,   279,  2005,
     130,   381,  1171,   383,  1664,   468,  2213,   343,   471,   434,
     468,   311,  1181,   471,  1183,   468,   468,  1186,   471,   471,
    1688,   469,  2213,  1192,   407,  1194,   319,   403,  1688,  2042,
     323,  1970,  1704,  1705,  1706,  1707,   468,  1206,   145,   471,
    1126,   377,  1211,  1117,   344,  1119,  1215,  1216,  1217,  1218,
    1989,  1220,  1221,  1340,   414,   468,   468,   350,   471,   471,
    1854,   468,   343,   518,   471,   520,  2273,   468,   130,  2276,
     471,  1958,   145,  1960,  1574,   612,   613,   377,   377,  2211,
    2374,   417,   266,   167,   467,   421,    35,  1953,  1162,    35,
     251,  1957,   448,  1380,   430,   256,   377,   220,   468,   468,
     261,   471,   471,   484,   188,   486,  2400,   468,    54,   468,
     471,   468,   471,  1613,   471,    35,   270,   453,   467,   878,
     879,   414,   468,   423,    26,   471,   468,   468,   887,   471,
     471,   467,     5,  1392,    54,  1635,   417,   722,   723,   468,
     270,   225,   471,     5,   468,  1813,    91,   471,   468,   430,
     467,   471,   467,  1813,   157,  1229,   468,   103,  1244,   471,
     467,   467,   613,  1422,  1664,   319,  2024,  1454,   294,   323,
    1429,  1808,   453,   468,    76,  1812,   471,  1814,  2220,   938,
     939,   467,    84,   103,  2123,   467,   467,   271,  1688,   319,
    1944,  1450,   343,   323,   468,  1454,   350,   471,  1457,  1449,
    1459,   468,   468,   468,   471,   471,   471,     5,   270,   468,
     112,   467,   471,     5,   467,   467,  2510,   467,   163,  1449,
     350,  1449,  1449,   467,  1808,   467,   377,   467,  1812,     5,
    1814,   467,  1449,   467,   395,     5,   467,   467,  2216,   467,
     467,   187,  2036,  2037,   405,  1520,  1505,  2095,   431,   194,
    1984,  1919,   277,   790,  1340,   471,   204,   319,  2124,  1919,
     414,   323,    94,  2129,   209,   220,   417,   187,  2134,    35,
     350,  2137,  2138,   157,   219,  2482,   178,   263,  1553,   430,
     157,   261,   467,   388,   414,   467,    83,   189,   350,   235,
     471,  2482,   238,   388,  1380,  2161,  1555,   381,    53,   383,
     245,  1560,   453,   249,    53,  1564,  1565,  1566,  1567,   388,
     242,  1397,   388,  1813,   388,   235,   467,   430,   238,  1578,
     404,   266,  2300,   407,  1583,   145,    90,  1413,  1587,   249,
     251,   467,   251,    35,   280,  2183,  2212,   469,   471,   790,
    1590,    65,   420,  1429,    34,   467,   467,    71,  1422,   467,
     467,   426,   414,   890,     9,  2213,   386,   386,    11,    83,
     280,   471,   386,  1449,  1450,   467,   256,  2035,  1454,  1628,
     467,   388,   171,   153,  2042,  2035,   162,  2243,   324,   468,
    2017,   473,  2042,   411,   329,   467,    35,   111,   202,   113,
     471,   353,   210,  1700,  2144,   267,   467,   210,   344,  2247,
    1675,  2151,  2268,   471,   324,     8,   251,   210,    11,  1578,
     303,  1698,    15,    16,    17,   264,   423,   467,   364,  1919,
     145,   430,   145,    65,   344,   251,   266,   266,  1715,    32,
    2098,    35,   251,  2017,   971,    34,   388,   388,  2098,   890,
     467,   388,   166,  1702,   364,   465,  2322,  2425,   388,   465,
     468,  1710,  1711,  1712,  1713,   468,  1715,  1716,   468,   162,
     468,  1720,  1721,   468,   366,   469,   411,   369,   192,   111,
    2329,  2329,   468,   468,  1011,   468,  2181,   468,   468,   471,
     450,   450,  2542,   468,   468,   468,  1560,   468,   162,   468,
     468,  1565,  1566,  1567,   450,   467,   388,   276,   427,  1758,
     467,   467,   467,  2481,  1590,   468,  2256,   417,  2374,  1583,
     427,   452,   266,   456,   267,  1774,   267,  1776,   409,   267,
     971,  1780,  1781,  1782,   166,  1784,   230,   251,  2315,   471,
    2278,   388,   256,   251,  2400,  2035,   467,   145,  1813,   270,
    2294,  1800,  2042,  1802,   188,  2213,   388,   145,   468,   145,
     388,   388,   388,  2213,   468,  1830,  1815,  1816,  1817,  1818,
    1819,  1820,  1821,  1822,  1823,  1824,   471,   264,  2427,   430,
    2261,   266,    35,   145,   298,  1834,   145,   465,   341,  2216,
    2248,   240,  1841,  2274,   136,   468,   162,    11,  2248,   313,
     157,   472,   468,  1852,   468,   272,  1855,   468,  2098,   162,
     467,  1851,   468,   206,   427,  2273,   377,  1776,  2276,   251,
     453,   162,  1698,  2273,   256,  2320,  2276,   471,   171,  2406,
     467,   326,   468,  2371,  2482,   466,   416,  1713,    81,  1715,
     267,  1800,  2216,   468,   468,  2383,  1710,  1711,  1712,   467,
     613,   145,  1179,   467,  2510,   166,  1815,  1816,  1817,  1818,
    1819,  1820,  1821,  1822,  1823,  1824,   298,   398,   467,   467,
      35,    77,   466,  2300,   411,   268,   466,  2304,   162,   209,
     275,   313,   468,  1932,    35,   468,  1935,  1936,  1937,  1938,
     404,   468,   467,  1942,  1943,  2544,   468,  1946,   379,  2380,
    1949,   468,  2329,    54,  1953,  2487,  2401,   209,  1957,   467,
    1774,    53,   467,  1978,  1963,  1980,   467,   140,   273,   174,
     468,   468,   468,  2213,   456,   430,  2300,   190,   179,   152,
    2304,   256,   256,   456,   157,   388,   388,   467,  1179,  1988,
      35,   251,   467,  1270,  1993,   104,  1986,  1987,  1997,   266,
     467,   430,   103,   104,    35,  2329,  2005,   466,  2248,  1286,
     111,   162,   285,   467,   467,   209,   467,   429,    83,   126,
    1834,   468,   404,   313,   210,  1851,   467,   467,   111,   202,
      35,  2030,   145,  2273,    71,   145,  2276,   118,    35,   334,
     468,  1855,    53,  1429,    35,   467,   334,   467,  2425,   222,
    2427,   416,   468,   471,    71,   468,    35,   178,   411,    35,
     269,   398,   613,    65,  1450,   166,    65,  2066,    35,   467,
     471,   350,   256,  2072,  2482,   178,   456,   790,   233,   467,
     398,   256,  2482,  2073,  2083,    35,   187,   269,   467,   269,
     263,   467,   249,   468,   467,  1286,   266,   471,   333,   272,
     320,  2425,   190,  2427,  2481,   266,   266,    32,   467,   116,
     409,   454,   455,   456,    21,   458,   459,   460,   461,   462,
     463,  1935,  1936,  1937,  1938,  2124,  2125,  1953,  2127,  1795,
    2129,  1957,  1193,  1808,   235,  2134,  1509,   238,  2137,  2138,
    1758,  2140,   513,  2142,  1988,   167,  2400,  2478,   249,  2157,
     251,  1836,  2029,  2307,  1431,  1432,  1433,  2481,  2484,  2565,
    1986,  1987,  2161,  2541,  2231,     8,   188,  2544,    11,  2529,
     459,  1503,    15,    16,    17,  1515,  1841,   890,   777,   280,
    2481,  1555,  2181,  2182,  2539,  1812,   834,  1500,  2479,  2342,
    2425,  2190,  1559,   482,   483,  2544,  1830,    40,  2213,   745,
     715,  1464,  1165,   225,    47,   767,  1479,  1139,  1736,   766,
    2391,  1979,  1164,   769,   503,  2214,  2215,  1715,  1450,  1943,
    2544,  1959,  2374,   324,  2269,  1713,  2225,  2373,    71,  2228,
     403,  2386,   613,  2223,  2385,  1273,  2153,  2468,  2456,   790,
    2469,  2240,  2482,   344,  2243,  1006,  1467,  2073,  1397,   271,
    1294,  2278,  1442,  1395,  2244,  1009,  1562,  2366,   971,   849,
    1268,   751,  2261,   364,  1118,   366,    -1,  1759,   369,  2268,
    1119,    -1,    -1,  2182,    -1,  2274,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   573,  2284,    -1,    -1,    -1,    -1,
    2289,    -1,   465,    -1,    -1,   468,   469,  1574,    -1,  2298,
      -1,    -1,    -1,  2129,    -1,  2214,  2215,    -1,  2134,    -1,
      -1,  2137,    -1,    -1,  2329,   337,    -1,   606,  2333,  2228,
      -1,  2320,   611,   612,   613,    -1,    -1,  1713,  2343,  1715,
      -1,    -1,    -1,    -1,    -1,    -1,  1613,   180,    -1,   890,
     629,    -1,   185,    -1,    -1,    -1,    -1,  2346,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  2347,  1635,   381,
      -1,   383,    -1,    -1,    -1,     8,   467,    -1,    11,    -1,
     659,    -1,    15,    16,    17,  2374,  2190,    -1,   221,    -1,
    2289,  2380,   404,  1574,    -1,   407,  2385,  1664,    -1,   678,
     679,   680,    -1,   682,    -1,    -1,    -1,  2223,    -1,    -1,
      -1,  2400,  2401,  2402,  2403,    -1,  2396,    -1,    -1,   790,
      -1,  1688,  2427,   702,    -1,    -1,    -1,  2432,  2244,  2434,
     971,    -1,  1613,  2438,  2439,   268,  2240,    -1,    -1,    -1,
      -1,    -1,    -1,   722,   723,    -1,    -1,  2436,  2437,    -1,
     729,   730,  2268,    -1,  1635,    -1,    -1,    -1,    -1,    -1,
       0,    -1,  2278,    -1,    -1,    -1,  1733,    -1,    -1,    -1,
      -1,  2460,    -1,    -1,    -1,    -1,  1179,  2482,    18,  2468,
     759,    -1,    -1,  1664,   763,   764,    -1,    -1,    28,  2478,
      30,    31,    -1,    -1,  2298,   774,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    46,  1688,  2497,    -1,
      -1,   790,    -1,    -1,    -1,  2504,    -1,    -1,    -1,   890,
      -1,  2510,   355,  2503,    -1,    -1,    66,    -1,    -1,    -1,
      -1,  2347,    -1,    -1,    -1,    -1,  2525,    77,    -1,  2544,
      -1,    -1,  2346,    -1,    -1,    -1,  1813,    -1,    88,    -1,
      90,    -1,   185,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     839,    -1,    -1,    -1,    -1,    -1,    -1,   107,    -1,    -1,
     849,    -1,    -1,   206,    -1,    -1,    -1,  1953,    -1,    -1,
    2396,  1957,    -1,  1286,    -1,    -1,    -1,    -1,    -1,    -1,
     130,    -1,    -1,    -1,    -1,    -1,   136,    -1,    -1,    -1,
     971,    -1,    -1,    -1,   144,    -1,   146,    -1,    -1,    -1,
      -1,   890,    -1,    -1,    -1,    -1,    -1,    -1,   451,    -1,
      -1,   454,   455,   456,    -1,   458,   459,   460,   461,   462,
     463,    -1,  1813,    -1,   913,   268,    -1,    -1,  1179,    -1,
     919,    -1,    -1,   922,    -1,    -1,    -1,   926,    -1,    -1,
      -1,    -1,  1919,    -1,    -1,   934,   935,    -1,    -1,    35,
      -1,    -1,    -1,   942,    -1,    -1,   945,   946,   947,   948,
      -1,    -1,    -1,    -1,    -1,    -1,   955,   956,    54,    -1,
      -1,    -1,    -1,    -1,   224,    -1,    -1,  2503,    -1,    -1,
      -1,    -1,   971,   972,   973,   974,   975,   976,    -1,    -1,
      -1,   980,  1969,    -1,    -1,   984,    -1,    -1,    -1,   988,
    1977,    -1,   991,   992,   993,   994,   995,   996,   997,   998,
     999,    -1,    -1,  1002,    49,    -1,     8,   103,    -1,    11,
    1009,    -1,  1011,    15,    16,    17,    -1,    -1,  1919,     8,
      -1,    -1,    11,    -1,    -1,  1286,    -1,    -1,  2124,    -1,
      32,    -1,   292,  2129,    -1,   295,    -1,    -1,  2134,    -1,
      -1,  2137,    -1,    -1,    -1,    -1,    -1,    92,  2035,    -1,
      -1,    40,    -1,    -1,    -1,  2042,    -1,    -1,    47,    -1,
      -1,    -1,    -1,   323,    -1,  2161,    -1,    -1,    -1,    -1,
     166,   331,   117,    -1,    -1,    -1,    -1,    -1,     8,    -1,
      -1,    11,    71,   343,    -1,    15,    16,    17,  1179,   134,
     350,   187,    -1,   138,   354,    -1,    -1,    -1,    -1,    -1,
      -1,   454,   455,   456,   364,   458,   459,   460,   461,   462,
     463,  2098,    -1,   158,    -1,    -1,   161,   377,    -1,    -1,
      -1,    -1,  1121,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     175,    -1,    -1,    -1,  2035,    -1,    -1,    -1,    -1,   235,
    1139,  2042,   238,    -1,    -1,    -1,    -1,  2243,    -1,  1148,
    1149,  1574,   412,   249,    -1,    -1,    -1,   417,    -1,    -1,
     606,    -1,    -1,     0,    -1,   611,    -1,    -1,    -1,    -1,
     430,    -1,  2268,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
    1179,    -1,    -1,    -1,   280,    -1,  1185,    -1,  1187,    -1,
    1613,   180,    -1,   453,    -1,  1286,   185,  2098,    -1,    -1,
      -1,    -1,    -1,    -1,   206,    -1,    -1,   467,    -1,    -1,
     470,   256,  1635,    -1,    -1,    -1,    -1,    -1,    -1,   264,
      -1,    -1,    -1,    -1,    -1,    -1,  2213,    -1,   324,    -1,
      -1,    -1,   221,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,  1664,    -1,    -1,    -1,    -1,    -1,    -1,   344,    -1,
      -1,    -1,    -1,    90,  1253,    -1,    -1,    -1,    -1,    -1,
     305,  2248,    -1,    -1,    -1,  1688,   268,    -1,   364,  1268,
      -1,  1270,  1271,  1272,   720,    -1,   722,   723,  2374,   268,
      -1,    -1,    -1,    -1,    -1,    -1,  2273,  1286,    -1,  2276,
      -1,    -1,    -1,  1292,  1293,    -1,    -1,    -1,    -1,  1298,
      -1,    -1,    -1,   140,  2400,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,  2213,  1574,    -1,   152,    -1,    -1,    -1,    -1,
     157,    -1,    -1,    -1,    -1,   162,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   171,     0,    -1,   174,   268,  1338,
    1339,  1340,    -1,    -1,  1343,   791,    -1,  2248,   794,   795,
      -1,    -1,  1613,    -1,    -1,    -1,  1355,  1356,  1357,  1358,
      -1,    -1,    -1,    -1,  1363,   202,   355,    -1,    -1,    -1,
      -1,    -1,  2273,    -1,  1635,  2276,    -1,  1376,  1377,    -1,
      -1,  1380,    -1,    -1,    -1,   222,    -1,    -1,    -1,    -1,
    1813,    -1,    -1,    -1,    -1,  1394,    -1,  1396,    -1,  1398,
      -1,    -1,    -1,  1664,    -1,    -1,    -1,    -1,   854,   855,
      -1,    -1,    -1,    -1,  2510,    -1,    -1,    -1,    -1,  1418,
      -1,    -1,    -1,    -1,    -1,    90,   263,  1688,    -1,   266,
    1429,    -1,  1431,  1432,  1433,   272,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,  1442,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,  1450,   454,   455,   456,    -1,   458,   459,   460,   461,
     462,   463,   451,    -1,    -1,  1464,    -1,    -1,    -1,   458,
     459,   460,   461,   462,   463,   140,    -1,    -1,   924,   925,
    1479,    -1,    -1,  1574,    -1,    -1,   932,   152,    -1,   326,
     936,   937,   157,    -1,    -1,  2482,  1919,   162,  1497,    -1,
      -1,    -1,    -1,    -1,    -1,   951,   171,   953,    -1,   174,
      -1,    -1,    -1,    -1,    -1,  1514,  1515,  1516,    -1,    -1,
     966,   967,  1613,    -1,   454,   455,   456,    -1,   458,   459,
     460,   461,   462,   463,    -1,    -1,    -1,   202,    -1,    -1,
     377,    -1,    -1,    -1,  1635,    -1,     8,    -1,    -1,    11,
      -1,    -1,  1813,    -1,    -1,    -1,    -1,   222,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   403,    -1,    -1,    -1,
      -1,    -1,    -1,  1664,    -1,  1574,    -1,    -1,    40,    -1,
      -1,  2482,    -1,    -1,    -1,    47,    -1,    -1,    -1,    -1,
     427,    -1,   429,   430,    -1,    -1,    -1,  1688,   263,    -1,
      -1,   266,    -1,    -1,    -1,    -1,    -1,   272,    -1,    71,
      -1,  1610,  2035,    -1,  1613,    -1,    -1,    -1,    -1,  2042,
      -1,  1620,    -1,    -1,    -1,    -1,    -1,  1626,   465,    -1,
    1629,   468,   469,   470,    -1,    -1,  1635,  1636,  1637,  1638,
    1639,    -1,    -1,  1642,  1643,  1644,  1645,  1646,  1647,  1648,
    1649,  1650,  1651,    -1,    -1,    -1,  1655,  1656,  1919,    -1,
      -1,   326,    -1,    -1,    -1,  1664,    -1,    -1,    -1,    -1,
    1669,    -1,    -1,    -1,    -1,  2098,   138,  1676,    -1,    -1,
    1679,    -1,  1681,    -1,    -1,    -1,    -1,    -1,    -1,  1688,
    1689,    -1,    -1,  1692,  1693,    -1,    -1,    -1,  1697,  1698,
      -1,    -1,  1148,  1149,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   377,    -1,  1713,    -1,  1715,     8,   180,    -1,
      11,    -1,  1813,   185,    -1,    -1,    -1,    -1,  1727,    -1,
      -1,    -1,    -1,    -1,  1733,    -1,    -1,    -1,   403,    -1,
      -1,    -1,    -1,    -1,     8,  1744,    -1,    11,    -1,    40,
      -1,    -1,    -1,  1199,    -1,    -1,    47,    -1,    -1,   221,
      -1,  1760,   427,  1209,   429,   430,  1212,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  2035,    -1,    40,    -1,    -1,    -1,
      71,  2042,    -1,    47,    -1,    -1,    -1,    -1,     8,    -1,
    2213,    11,    -1,    -1,    -1,    15,    16,    17,    -1,    -1,
     465,    -1,    -1,   468,   469,   470,   268,    71,    -1,  1808,
      -1,    -1,    32,  1812,  1813,  1814,    -1,    -1,    -1,    -1,
      -1,    -1,  1268,    -1,    -1,  2248,    -1,    -1,  1919,    -1,
      -1,    -1,    -1,    -1,   482,   483,  1282,  2098,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   138,    -1,    -1,
    2273,    -1,    -1,  2276,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,  1870,    -1,    -1,   138,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   180,
      -1,    -1,    -1,   355,   185,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  1913,  1914,   180,    -1,    -1,  1918,
    1919,   185,    -1,    -1,  1923,    -1,    -1,  1926,  1927,    -1,
     221,    -1,  1931,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  2035,    -1,    -1,    -1,    -1,    -1,
      -1,  2042,  2213,    -1,  1953,    -1,    -1,   221,  1957,    -1,
      -1,    22,    -1,    -1,   612,    -1,    -1,    28,    -1,    -1,
    1969,    -1,    -1,    -1,    35,    -1,    -1,   268,  1977,    -1,
      -1,   629,    -1,    -1,    -1,  1984,   206,  2248,    -1,   451,
      -1,    -1,  1438,    54,    -1,    -1,   458,   459,   460,   461,
     462,   463,    -1,    -1,   268,    -1,    -1,  2098,    -1,    -1,
      -1,   659,  2273,    -1,    -1,  2276,    -1,    -1,  2017,    -1,
      -1,    -1,    -1,    -1,    -1,  1471,  1472,  2026,    -1,    -1,
     678,   679,   680,    -1,   682,    -1,  2035,    -1,    -1,    -1,
      -1,    -1,   103,  2042,    -1,    -1,    -1,    -1,   268,    -1,
      -1,    -1,    -1,    -1,   702,    -1,    -1,    -1,    -1,  2482,
      -1,    -1,    -1,    -1,   355,    -1,    -1,    -1,    -1,   130,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   729,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   355,    -1,     0,    -1,    -1,  2095,    -1,    -1,  2098,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,  2107,  2108,
      -1,   759,  2111,    -1,    -1,   763,   764,    -1,    -1,    -1,
      -1,    -1,  2213,    -1,    -1,  2124,   187,    -1,    -1,    -1,
    2129,    -1,    -1,    -1,    -1,  2134,    -1,    -1,  2137,  2138,
      -1,    -1,    -1,    -1,    -1,    -1,  2145,  2146,    -1,    -1,
      -1,  1597,  1598,    -1,    -1,    -1,  1602,  2248,    -1,    -1,
     451,    -1,  2161,    -1,  2163,    -1,    -1,   458,   459,   460,
     461,   462,   463,    -1,   235,    -1,    -1,   238,    -1,    -1,
      -1,    -1,  2273,    90,  2183,  2276,    -1,   451,   249,    -1,
      -1,    -1,    -1,    -1,   458,   459,   460,   461,   462,   463,
      -1,   696,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   270,
      -1,    -1,    -1,    -1,  2213,    -1,    -1,  2216,    -1,   280,
      -1,  2482,    -1,    -1,    -1,    -1,    -1,     8,    -1,    -1,
      11,    -1,    -1,   140,   454,   455,   456,    -1,   458,   459,
     460,   461,   462,   463,  2243,   152,    -1,   742,  2247,  2248,
     157,    -1,    -1,    -1,    -1,   162,    -1,    -1,   319,    40,
      -1,    -1,   323,   324,   171,  2264,    47,   174,    -1,  2268,
      -1,   919,    -1,    -1,  2273,    -1,    -1,  2276,     8,  2278,
      -1,    11,    -1,   344,    -1,    15,    16,    17,    -1,   350,
      71,  2290,    -1,    -1,   942,   202,    -1,   945,    -1,    -1,
     948,  2300,    32,   364,    -1,  2304,  2305,   955,   956,    -1,
      40,    -1,    -1,    -1,    -1,   222,    -1,    47,    -1,    -1,
      -1,    -1,    -1,    -1,   972,   973,   974,   975,    -1,    -1,
    2329,    -1,   980,    -1,    -1,    -1,   984,    -1,    -1,    -1,
     988,    71,    -1,   991,   992,   993,   994,   995,   996,   997,
     998,   999,    -1,   414,  1002,    -1,   263,   138,    -1,   266,
      -1,  1009,    -1,  1011,    -1,   272,    -1,  1813,    -1,    -1,
      -1,    -1,  2371,    -1,   869,  2374,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  2383,    -1,    -1,    -1,    -1,    -1,
      -1,  2482,  2391,    -1,    -1,    -1,    -1,    -1,    -1,   180,
      -1,  2400,    -1,    -1,   185,    -1,    -1,    -1,    -1,    -1,
    1856,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   326,
      -1,  2420,   917,    -1,    -1,    -1,  2425,    -1,  2427,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     221,    -1,    -1,    -1,    -1,    -1,   941,    -1,    -1,    -1,
     180,   946,    -1,    -1,    -1,   185,  2455,  2456,    -1,    -1,
      -1,    -1,   957,   958,   959,    -1,   961,    -1,    -1,    -1,
     377,    -1,    -1,  1121,    -1,    -1,   206,   207,    -1,    -1,
      -1,    -1,  2481,  2482,    -1,    -1,    -1,   268,    -1,    -1,
      -1,   221,    -1,    -1,    -1,     8,   403,    -1,    11,    -1,
    1148,  1149,    15,    16,    17,    -1,    -1,    -1,    -1,    -1,
      -1,  2510,  1007,  2512,    -1,    -1,    -1,    -1,    -1,    32,
     427,   251,   429,   430,   254,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  1029,    -1,    -1,    -1,   268,    -1,
       8,   271,    -1,    11,    -1,  2544,    -1,    15,    16,    17,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   465,    -1,
      -1,   468,   469,   470,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    40,    -1,   355,  2574,  2575,    -1,  2024,    47,
      -1,    -1,    -1,  2029,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  2043,  2044,    -1,
      -1,    -1,    -1,    71,    -1,     3,    -1,    -1,    -1,    -1,
       8,    -1,    -1,    11,    -1,    -1,    -1,    15,    16,    17,
      -1,    -1,  1270,  1271,  1272,   355,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    32,    -1,    -1,    35,    -1,    -1,
    1135,    -1,    40,    -1,    -1,  1293,    -1,    -1,    -1,    47,
    1298,    -1,  1147,    -1,    -1,    -1,    -1,  1152,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     451,    -1,    -1,    71,    -1,    -1,    -1,   458,   459,   460,
     461,   462,   463,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,  1340,   206,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  1355,    -1,  1357,
    1358,    -1,   180,    -1,    -1,  1363,    -1,   185,    -1,    -1,
      -1,   451,    -1,    -1,   454,   455,   456,    -1,   458,   459,
     460,   461,   462,   463,    -1,    -1,    -1,    -1,   206,   207,
      -1,   471,    -1,    -1,    -1,    -1,  1394,    -1,  1396,    -1,
    1398,    -1,    -1,   221,    -1,   268,    -1,     8,  2204,  2205,
      11,    -1,    -1,    -1,    15,    16,    17,  2213,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    32,   180,  1431,  1432,  1433,   254,   185,    -1,    40,
      -1,    -1,    -1,    -1,  1442,    -1,    47,    -1,    -1,    -1,
     268,  1296,    -1,    -1,    -1,    -1,    -1,    -1,   206,   207,
      -1,    -1,    -1,    -1,    -1,    -1,  1464,    -1,    -1,    -1,
      71,    -1,    -1,   221,  1319,    -1,    -1,    -1,    -1,    -1,
      -1,  1479,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,  1336,    -1,  1338,  1339,    -1,  1341,    -1,  1343,  1497,
      -1,    -1,  1347,   251,    -1,    -1,   254,    -1,    -1,  1354,
      -1,    -1,    -1,    -1,  1359,    -1,    -1,    -1,    -1,    -1,
     268,    -1,    -1,   271,  1369,  1370,  1371,  1372,    -1,    -1,
      -1,  1376,  1377,  2329,  1379,    -1,    -1,   355,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,  1390,    -1,    -1,  1393,    -1,
       8,    -1,    -1,    11,    -1,  1400,  1401,  1402,  1403,  1404,
    1405,  1406,  1407,  1408,  1409,    -1,    -1,    -1,     8,    -1,
      -1,    11,    -1,    -1,    -1,    15,    16,    17,    -1,   180,
      -1,    -1,    40,    -1,   185,    -1,    -1,    -1,    -1,    47,
      -1,   454,   455,   456,    -1,   458,   459,   460,   461,   462,
     463,    -1,  1447,    -1,    -1,   206,   207,   355,    -1,    -1,
      -1,    -1,  1610,    71,    -1,    -1,    -1,    -1,    -1,    -1,
     221,    -1,  1620,    -1,    -1,    -1,    -1,    -1,  1626,    -1,
      -1,  1629,    -1,   451,    -1,    -1,   454,   455,   456,    -1,
     458,   459,   460,   461,   462,   463,    -1,    -1,    -1,    -1,
     251,    -1,    -1,   254,    -1,    -1,    -1,  1655,  1656,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   268,    -1,    -1,
     271,    -1,    -1,    -1,    -1,    -1,    -1,    -1,  1676,    -1,
     138,  1679,    -1,  1681,    -1,    -1,  2482,    -1,    -1,    -1,
      -1,  1689,    -1,    -1,    -1,    -1,    -1,    -1,    -1,  1697,
    1698,    -1,    -1,   451,    -1,    -1,   454,   455,   456,    -1,
     458,   459,   460,   461,   462,   463,     8,    -1,    -1,    11,
      -1,    -1,   180,    15,    16,    17,    -1,   185,    -1,  1727,
      -1,    -1,    -1,    -1,    -1,  1733,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,  1744,    -1,  1593,  1594,
      -1,    -1,    -1,    -1,   355,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,  1760,   221,  1609,    -1,   206,    -1,    -1,    -1,
    1615,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  1632,  1633,  1634,
      -1,  1636,  1637,  1638,  1639,    -1,    -1,  1642,  1643,  1644,
    1645,  1646,  1647,  1648,  1649,  1650,  1651,  1652,    -1,    -1,
     268,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  1672,   268,    -1,
      -1,    -1,  1677,  1678,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,  1691,  1692,  1693,  1694,
     451,  1696,    -1,   454,   455,   456,    -1,   458,   459,   460,
     461,   462,   463,    -1,    -1,    -1,    -1,   468,    -1,    -1,
      -1,    -1,  1870,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  1739,    -1,    -1,   355,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   206,  1913,  1914,    -1,    -1,    -1,
    1918,    -1,    -1,    -1,    -1,  1923,    -1,    -1,  1926,  1927,
      -1,     8,  1777,  1931,    11,    -1,    -1,    -1,    15,    16,
      17,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    32,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,
      47,  1969,    -1,    -1,    -1,    -1,   268,    -1,    -1,  1977,
      -1,    -1,    -1,    -1,    -1,    -1,  1984,    -1,    -1,    -1,
      -1,    -1,    -1,   451,    71,    -1,    -1,    -1,    -1,    -1,
     458,   459,   460,   461,   462,   463,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   454,   455,   456,    -1,   458,   459,
     460,   461,   462,   463,     8,    -1,  1871,    11,  2026,    -1,
    1875,  1876,    -1,  1878,    -1,    -1,  1881,  1882,  1883,  1884,
      -1,    -1,    -1,  1888,  1889,  1890,  1891,  1892,  1893,  1894,
    1895,  1896,  1897,  1898,  1899,    -1,    40,    -1,    -1,    -1,
      -1,    -1,    -1,    47,    -1,    -1,    -1,  1912,    -1,    -1,
    1915,    -1,  1917,    -1,    -1,    -1,  1921,    -1,    -1,  1924,
    1925,    -1,    -1,  1928,  1929,    -1,    -1,    71,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   180,    -1,    -1,    -1,    -1,   185,  2107,
    2108,    -1,    -1,  2111,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,  1971,    -1,    -1,   206,
     207,    -1,    -1,    -1,    -1,    20,    -1,    -1,  1983,    -1,
      -1,    -1,    -1,    -1,   221,    -1,    -1,  2145,  2146,     8,
      -1,  1996,    11,    -1,   138,    -1,    15,    16,    17,    -1,
      -1,    -1,   454,   455,   456,  2163,   458,   459,   460,   461,
     462,   463,    -1,    32,   251,    -1,    -1,   254,    -1,    -1,
      -1,    40,    -1,    -1,    -1,    -1,    -1,    72,    47,    -1,
      -1,   268,    -1,    -1,   271,    -1,   180,    -1,    -1,    -1,
      -1,   185,    87,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   221,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,  2091,    -1,    -1,    -1,
    2095,    -1,    -1,    -1,   139,    -1,  2101,  2102,  2103,    -1,
      -1,  2106,   147,    -1,  2109,  2110,  2264,    -1,    -1,  2114,
      -1,    -1,    -1,    -1,   159,    -1,    -1,    -1,   355,    -1,
    2278,    -1,    -1,    -1,   268,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,  2290,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   188,    -1,    -1,    -1,  2305,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   180,    -1,    -1,    -1,    -1,   185,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,  2183,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   206,   207,   234,
      -1,    -1,    -1,    -1,    -1,    -1,  2201,    -1,    -1,    -1,
      -1,    -1,   221,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   355,    -1,    -1,   451,    -1,    -1,   454,   455,   456,
      -1,   458,   459,   460,   461,   462,   463,    -1,    -1,    -1,
      -1,   468,   251,  2391,    -1,   254,    -1,    -1,    -1,    -1,
      -1,  2246,  2247,    -1,    -1,   290,  2251,  2252,  2253,   268,
      -1,    -1,   271,    -1,    -1,    -1,    -1,    -1,    -1,   304,
      -1,    -1,  2420,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  2282,  2283,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     335,  2296,   337,    -1,    -1,    -1,    -1,  2455,  2456,   344,
      -1,    -1,   347,  2308,    -1,    -1,    -1,   451,    -1,    -1,
      -1,    -1,    -1,    -1,   458,   459,   460,   461,   462,   463,
      -1,   366,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   377,    -1,    -1,    -1,   355,    -1,    -1,   384,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   393,    -1,
      -1,    -1,    -1,    -1,  2512,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,  2368,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,  2379,    -1,    -1,    -1,   423,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,  2398,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,  2412,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,  2574,  2575,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   451,    -1,    -1,   454,   455,   456,    -1,   458,
     459,   460,   461,   462,   463,    -1,    -1,   466,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,  2489,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
    2515,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
     125,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,  2586,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,   460,    -1,    -1,    -1,    -1,
      -1,    -1,   467,   468,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,   430,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,   453,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,   468,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,   430,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,   453,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,   162,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,   216,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,   389,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,   460,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,   468,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,   162,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,   451,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,
       5,     6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    72,    -1,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,   161,    -1,   163,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,   194,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,   219,   220,   221,    -1,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,    -1,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,   379,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,   410,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,   421,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   458,   459,    -1,    -1,     3,     4,     5,
       6,     7,   467,     9,    10,    -1,    -1,   472,    -1,    -1,
      -1,    -1,    18,    19,    20,    21,    22,    23,    24,    25,
      -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    37,    38,    -1,    40,    41,    42,    43,    44,    45,
      46,    47,    48,    49,    50,    51,    -1,    53,    54,    55,
      56,    57,    58,    59,    60,    61,    62,    63,    64,    -1,
      66,    67,    68,    69,    70,    -1,    72,    -1,    74,    75,
      76,    77,    78,    79,    80,    81,    82,    -1,    84,    85,
      86,    87,    88,    89,    -1,    91,    92,    93,    94,    95,
      96,    97,    98,    99,   100,   101,   102,   103,   104,   105,
     106,   107,   108,   109,   110,    -1,   112,    -1,   114,   115,
     116,   117,   118,   119,    -1,   121,   122,   123,   124,    -1,
      -1,   127,   128,   129,   130,   131,    -1,   133,   134,   135,
      -1,   137,   138,   139,    -1,   141,   142,   143,   144,   145,
     146,   147,   148,   149,   150,   151,    -1,   153,   154,   155,
     156,    -1,   158,    -1,   160,   161,    -1,   163,   164,   165,
     166,   167,    -1,   169,   170,    -1,   172,   173,    -1,   175,
     176,   177,   178,   179,   180,   181,   182,   183,   184,    -1,
     186,   187,   188,   189,   190,   191,    -1,   193,   194,   195,
     196,   197,   198,   199,   200,   201,    -1,   203,    -1,   205,
     206,   207,   208,   209,   210,   211,   212,   213,   214,    -1,
      -1,   217,   218,   219,   220,   221,    -1,   223,   224,   225,
     226,   227,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,   245,
     246,   247,   248,   249,   250,    -1,   252,   253,   254,   255,
     256,   257,   258,   259,   260,   261,   262,    -1,   264,   265,
      -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,   275,
     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,
     286,   287,    -1,   289,   290,   291,   292,   293,   294,   295,
     296,   297,    -1,   299,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,    -1,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
      -1,   327,   328,   329,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,   341,   342,    -1,   344,   345,
     346,   347,   348,   349,   350,   351,   352,   353,   354,   355,
     356,   357,   358,   359,    -1,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,    -1,   375,
     376,    -1,   378,   379,   380,   381,   382,   383,   384,    -1,
     386,   387,    -1,    -1,   390,   391,   392,   393,   394,   395,
     396,   397,   398,   399,   400,   401,   402,    -1,    -1,   405,
     406,   407,   408,   409,   410,    -1,   412,   413,   414,   415,
     416,   417,   418,    -1,   420,   421,   422,   423,   424,   425,
      -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,   435,
     436,   437,   438,   439,   440,   441,   442,   443,   444,   445,
     446,   447,   448,   449,   450,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,     5,
       6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    18,    19,    20,    21,    22,    23,    24,    25,
      -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    37,    38,    -1,    40,    41,    42,    43,    44,    45,
      46,    47,    48,    49,    50,    51,    -1,    53,    54,    55,
      56,    57,    58,    59,    60,    61,    62,    63,    64,    -1,
      66,    67,    68,    69,    70,    -1,    72,    -1,    74,    75,
      76,    77,    78,    79,    80,    81,    82,    -1,    84,    85,
      86,    87,    88,    89,    -1,    91,    92,    93,    94,    95,
      96,    97,    98,    99,   100,   101,   102,   103,   104,   105,
     106,   107,   108,   109,   110,    -1,   112,    -1,   114,   115,
     116,   117,   118,   119,    -1,   121,   122,   123,   124,    -1,
      -1,   127,   128,   129,   130,   131,    -1,   133,   134,   135,
      -1,   137,   138,   139,    -1,   141,   142,   143,   144,   145,
     146,   147,   148,   149,   150,   151,    -1,   153,   154,   155,
     156,    -1,   158,    -1,   160,   161,    -1,   163,   164,   165,
     166,   167,    -1,   169,   170,    -1,   172,   173,    -1,   175,
     176,   177,   178,   179,   180,   181,   182,   183,   184,    -1,
     186,   187,   188,   189,   190,   191,    -1,   193,   194,   195,
     196,   197,   198,   199,   200,   201,    -1,   203,    -1,   205,
      -1,   207,   208,   209,   210,   211,   212,   213,   214,    -1,
      -1,   217,   218,   219,   220,   221,    -1,   223,   224,   225,
     226,   227,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,   245,
     246,   247,   248,   249,   250,    -1,   252,   253,   254,   255,
     256,   257,   258,   259,   260,   261,   262,    -1,   264,   265,
      -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,   275,
     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,
     286,   287,    -1,   289,   290,   291,   292,   293,   294,   295,
     296,   297,    -1,   299,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,    -1,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
      -1,   327,   328,   329,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,   341,   342,    -1,   344,   345,
     346,   347,   348,   349,   350,   351,   352,   353,   354,   355,
     356,   357,   358,   359,    -1,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,    -1,   375,
     376,    -1,   378,   379,   380,   381,   382,   383,   384,    -1,
     386,   387,    -1,    -1,   390,   391,   392,   393,   394,   395,
     396,   397,   398,   399,   400,   401,   402,    -1,    -1,   405,
     406,   407,   408,   409,   410,    -1,   412,   413,   414,   415,
     416,   417,   418,    -1,   420,   421,   422,   423,   424,   425,
      -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,   435,
     436,   437,   438,   439,   440,   441,   442,   443,   444,   445,
     446,   447,   448,   449,   450,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,     5,
       6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    18,    19,    20,    21,    22,    23,    24,    25,
      -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    37,    38,    -1,    40,    41,    42,    43,    44,    45,
      46,    47,    48,    49,    50,    51,    -1,    53,    54,    55,
      56,    57,    58,    59,    60,    61,    62,    63,    64,    -1,
      66,    67,    68,    69,    70,    -1,    72,    -1,    74,    75,
      76,    77,    78,    79,    80,    81,    82,    -1,    84,    85,
      86,    87,    88,    89,    -1,    91,    92,    93,    94,    95,
      96,    97,    98,    99,   100,   101,   102,   103,   104,   105,
     106,   107,   108,   109,   110,   111,   112,    -1,   114,   115,
     116,   117,   118,   119,    -1,   121,   122,   123,   124,    -1,
      -1,   127,   128,   129,   130,   131,    -1,   133,   134,   135,
      -1,   137,   138,   139,    -1,   141,   142,   143,   144,   145,
     146,   147,   148,   149,   150,   151,    -1,   153,   154,   155,
     156,    -1,   158,    -1,   160,   161,    -1,   163,   164,   165,
     166,   167,    -1,   169,   170,    -1,   172,   173,    -1,   175,
     176,   177,   178,   179,   180,   181,   182,   183,   184,    -1,
     186,   187,   188,   189,   190,   191,    -1,   193,   194,   195,
     196,   197,   198,   199,   200,   201,    -1,   203,    -1,   205,
      -1,    -1,   208,   209,   210,   211,   212,   213,   214,    -1,
      -1,   217,   218,   219,   220,   221,    -1,   223,   224,   225,
     226,   227,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,   245,
     246,   247,   248,   249,   250,    -1,   252,   253,    -1,   255,
     256,   257,   258,   259,   260,   261,   262,    -1,   264,   265,
      -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,   275,
     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,
     286,   287,    -1,   289,   290,   291,   292,   293,   294,   295,
     296,   297,    -1,   299,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,    -1,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
      -1,   327,   328,   329,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,   341,   342,    -1,   344,   345,
     346,   347,   348,   349,   350,   351,   352,   353,   354,   355,
     356,   357,   358,   359,    -1,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,    -1,   375,
     376,    -1,   378,   379,   380,   381,   382,   383,   384,    -1,
     386,   387,    -1,    -1,   390,   391,   392,   393,   394,   395,
     396,   397,   398,   399,   400,   401,   402,    -1,    -1,   405,
     406,   407,   408,   409,   410,    -1,   412,   413,   414,   415,
     416,   417,   418,    -1,   420,   421,   422,   423,   424,   425,
      -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,   435,
     436,   437,   438,   439,   440,   441,   442,   443,   444,   445,
     446,   447,   448,   449,   450,   451,    -1,    -1,    -1,    -1,
      -1,    -1,   458,   459,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   467,    -1,    -1,    -1,    -1,   472,     3,     4,     5,
       6,     7,     8,     9,    10,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    18,    19,    20,    21,    22,    23,    24,    25,
      -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    37,    38,    -1,    40,    41,    42,    43,    44,    45,
      46,    -1,    48,    49,    50,    51,    -1,    53,    54,    55,
      56,    57,    58,    59,    60,    61,    62,    63,    64,    -1,
      66,    67,    68,    69,    70,    -1,    72,    -1,    74,    75,
      76,    77,    78,    79,    80,    81,    82,    -1,    84,    85,
      86,    87,    88,    89,    -1,    91,    92,    93,    94,    95,
      96,    97,    98,    99,   100,   101,   102,   103,   104,   105,
     106,   107,   108,   109,   110,   111,   112,    -1,   114,   115,
     116,   117,   118,   119,    -1,   121,   122,   123,   124,    -1,
      -1,   127,   128,   129,   130,   131,    -1,   133,   134,   135,
      -1,   137,    -1,   139,    -1,   141,   142,   143,   144,   145,
     146,   147,   148,   149,   150,   151,    -1,   153,   154,   155,
     156,    -1,   158,    -1,   160,   161,    -1,   163,   164,   165,
     166,   167,    -1,   169,   170,    -1,   172,   173,    -1,   175,
     176,   177,   178,   179,    -1,   181,   182,   183,   184,    -1,
     186,   187,   188,   189,   190,   191,    -1,   193,   194,   195,
     196,   197,   198,   199,   200,   201,    -1,   203,    -1,   205,
      -1,    -1,   208,   209,   210,   211,   212,   213,   214,    -1,
      -1,   217,   218,   219,   220,    -1,    -1,   223,   224,   225,
     226,   227,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,   245,
     246,   247,   248,   249,   250,    -1,   252,   253,    -1,   255,
     256,   257,   258,   259,   260,   261,   262,    -1,   264,   265,
      -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,   275,
     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,
     286,   287,    -1,   289,   290,   291,   292,   293,   294,   295,
     296,   297,    -1,   299,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,    -1,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
      -1,   327,   328,   329,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,   341,   342,    -1,   344,   345,
     346,   347,   348,   349,   350,   351,   352,   353,   354,    -1,
     356,   357,   358,   359,    -1,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,    -1,   375,
     376,    -1,   378,   379,   380,   381,   382,   383,   384,    -1,
     386,   387,    -1,    -1,   390,   391,   392,   393,   394,   395,
     396,   397,   398,   399,   400,   401,   402,    -1,    -1,   405,
     406,   407,   408,   409,   410,    -1,   412,   413,   414,   415,
     416,   417,   418,    -1,   420,   421,   422,   423,   424,   425,
      -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,   435,
     436,   437,   438,   439,   440,   441,   442,   443,   444,   445,
     446,   447,   448,   449,   450,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   458,   459,     3,    -1,    -1,    -1,    -1,    -1,
      -1,   467,    -1,    -1,    -1,    -1,   472,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    35,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    91,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,   163,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,   194,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
     209,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
     219,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,   245,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,    -1,    -1,    -1,     3,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   468,
      18,    19,    20,    21,    22,    23,    24,    25,    -1,    27,
      28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,
      38,    -1,    40,    41,    42,    43,    44,    45,    46,    47,
      48,    49,    50,    51,    -1,    53,    54,    55,    56,    57,
      -1,    59,    60,    61,    62,    63,    64,    -1,    66,    67,
      68,    69,    70,    -1,    72,    -1,    74,    75,    76,    77,
      78,    79,    80,    81,    82,    -1,    84,    85,    86,    87,
      88,    89,    -1,    91,    92,    93,    94,    95,    96,    97,
      98,    99,   100,   101,   102,   103,   104,   105,   106,   107,
     108,   109,   110,    -1,   112,    -1,   114,   115,   116,   117,
     118,   119,    -1,   121,   122,   123,   124,    -1,    -1,   127,
     128,   129,   130,   131,    -1,   133,   134,   135,    -1,   137,
     138,   139,    -1,   141,   142,   143,   144,   145,   146,   147,
     148,   149,    -1,   151,    -1,   153,   154,   155,   156,    -1,
     158,    -1,   160,   161,    -1,   163,   164,   165,   166,   167,
      -1,   169,   170,    -1,   172,   173,    -1,   175,   176,   177,
     178,   179,   180,   181,   182,   183,   184,    -1,   186,   187,
     188,   189,   190,   191,    -1,   193,   194,   195,   196,   197,
     198,   199,   200,   201,    -1,   203,    -1,   205,   206,   207,
     208,   209,   210,   211,   212,   213,   214,   215,    -1,   217,
     218,   219,   220,   221,    -1,   223,   224,   225,   226,   227,
     228,   229,   230,   231,   232,   233,   234,   235,   236,   237,
     238,   239,   240,   241,   242,   243,   244,   245,   246,   247,
     248,   249,   250,    -1,   252,   253,   254,   255,    -1,   257,
     258,   259,   260,   261,   262,    -1,   264,   265,    -1,   267,
     268,   269,   270,    -1,    -1,   273,   274,   275,   276,   277,
     278,   279,   280,   281,   282,   283,   284,   285,   286,   287,
      -1,   289,   290,   291,   292,   293,   294,   295,   296,   297,
      -1,   299,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,    -1,   314,   315,   316,   317,
     318,   319,   320,   321,   322,   323,   324,   325,    -1,   327,
     328,   329,   330,   331,   332,   333,   334,   335,   336,   337,
     338,   339,   340,   341,   342,   343,   344,   345,   346,   347,
     348,   349,   350,   351,   352,   353,   354,   355,   356,   357,
     358,   359,    -1,   361,   362,   363,   364,   365,   366,   367,
     368,   369,   370,   371,   372,   373,    -1,   375,   376,   377,
     378,   379,   380,   381,   382,   383,   384,    -1,   386,   387,
      -1,    -1,   390,   391,   392,   393,   394,    -1,   396,   397,
     398,   399,   400,   401,   402,    -1,    -1,   405,   406,   407,
     408,   409,   410,    -1,   412,   413,   414,   415,   416,   417,
     418,    -1,   420,   421,   422,   423,   424,   425,    -1,    -1,
     428,    -1,   430,   431,   432,   433,   434,   435,   436,   437,
     438,   439,   440,   441,   442,   443,   444,   445,   446,   447,
     448,   449,   450,    -1,    -1,   453,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   467,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      47,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    59,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    95,    96,
      97,    98,    99,   100,   101,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,   215,    -1,
     217,   218,   219,   220,   221,    -1,   223,   224,   225,   226,
     227,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,   250,    -1,   252,   253,   254,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
     267,   268,   269,   270,    -1,    -1,   273,   274,   275,   276,
     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,   349,   350,   351,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,   410,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,    -1,    -1,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     467,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      47,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    59,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    95,    96,
      97,    98,    99,   100,   101,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,   219,   220,   221,    -1,   223,   224,   225,   226,
     227,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,   250,    -1,   252,   253,   254,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,   275,   276,
     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,   349,   350,   351,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,   410,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,    -1,    -1,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     467,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      47,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    59,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    95,    96,
      97,    98,    99,   100,   101,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,   219,   220,   221,    -1,   223,   224,   225,   226,
     227,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,   250,    -1,   252,   253,   254,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,   275,   276,
     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,   349,   350,   351,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,   410,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,    -1,    -1,     3,     4,     5,    -1,
      -1,    -1,     9,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     467,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      47,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    -1,    -1,
      -1,    98,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,   150,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,   219,   220,   221,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,   250,    -1,   252,   253,   254,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,   266,
      -1,   268,   269,   270,    -1,    -1,   273,   274,   275,   276,
     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,   395,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,    -1,    -1,     3,    -1,    -1,    -1,
      -1,   458,   459,   460,    -1,    -1,    -1,    -1,    -1,    -1,
     467,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    30,    31,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      47,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    -1,    -1,
      -1,    98,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,   219,   220,   221,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,   250,    -1,   252,   253,   254,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,   275,   276,
     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,   343,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
     377,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,   430,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,    -1,    -1,   453,     3,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     467,    -1,    18,    19,    20,    21,    22,    23,    24,    25,
      -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    37,    38,    -1,    40,    41,    42,    -1,    44,    45,
      46,    47,    48,    -1,    50,    51,    -1,    53,    54,    55,
      56,    57,    -1,    -1,    60,    61,    62,    63,    64,    -1,
      66,    67,    68,    69,    70,    -1,    -1,    -1,    74,    75,
      76,    77,    78,    -1,    80,    81,    82,    -1,    84,    85,
      86,    87,    88,    89,    -1,    -1,    92,    93,    94,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,
     106,   107,   108,   109,   110,    -1,   112,    -1,   114,   115,
     116,   117,   118,   119,    -1,   121,   122,   123,   124,    -1,
      -1,   127,   128,   129,   130,   131,    -1,   133,   134,   135,
      -1,   137,   138,   139,    -1,   141,   142,   143,   144,   145,
     146,   147,   148,   149,    -1,   151,    -1,   153,   154,   155,
     156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,
     166,   167,    -1,   169,   170,    -1,   172,   173,    -1,   175,
     176,   177,   178,   179,    -1,   181,   182,   183,   184,    -1,
     186,   187,   188,   189,   190,   191,    -1,   193,    -1,   195,
     196,   197,   198,   199,   200,   201,    -1,   203,    -1,   205,
      -1,    -1,   208,    -1,   210,   211,   212,   213,   214,    -1,
      -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,   225,
      -1,    -1,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,    -1,
     246,   247,   248,   249,   250,    -1,   252,   253,    -1,   255,
      -1,   257,   258,   259,   260,   261,   262,    -1,   264,   265,
      -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,
     276,    -1,   278,   279,   280,   281,   282,   283,   284,   285,
     286,   287,    -1,   289,   290,   291,   292,   293,   294,   295,
     296,   297,    -1,   299,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,    -1,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
      -1,   327,   328,    -1,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,   341,   342,   343,   344,   345,
     346,   347,   348,    -1,   350,   351,   352,   353,   354,    -1,
     356,   357,   358,   359,    -1,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,    -1,   375,
     376,   377,   378,    -1,   380,   381,   382,   383,   384,    -1,
     386,   387,    -1,    -1,   390,   391,   392,   393,   394,    -1,
     396,   397,   398,   399,   400,   401,   402,    -1,    -1,   405,
     406,   407,   408,   409,    -1,    -1,   412,   413,   414,   415,
     416,   417,   418,    -1,   420,    -1,   422,   423,   424,   425,
      -1,    -1,   428,    -1,   430,   431,   432,   433,   434,   435,
     436,   437,   438,   439,   440,   441,   442,   443,   444,   445,
     446,   447,   448,   449,   450,    -1,    -1,   453,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   467,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,    -1,    -1,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,    -1,    -1,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,    -1,    -1,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   467,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,    -1,    -1,    -1,    -1,
      -1,     3,     4,     5,    -1,    -1,     8,     9,    -1,    -1,
      -1,    -1,   467,    15,    16,    17,    18,    19,    20,    21,
      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
      32,    33,    34,    35,    36,    37,    38,    39,    40,    41,
      42,    43,    44,    45,    46,    -1,    48,    49,    50,    51,
      52,    53,    54,    55,    56,    57,    58,    59,    60,    61,
      62,    63,    64,    65,    66,    67,    68,    69,    -1,    71,
      72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
      82,    83,    84,    85,    86,    87,    88,    89,    90,    91,
      92,    93,    94,    95,    96,    97,    98,    99,   100,   101,
     102,   103,   104,   105,   106,   107,   108,   109,   110,   111,
     112,   113,   114,   115,   116,   117,   118,   119,   120,   121,
     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
     132,   133,   134,   135,   136,   137,   138,   139,   140,   141,
     142,   143,   144,    -1,   146,   147,   148,    -1,   150,   151,
     152,   153,   154,   155,   156,   157,   158,   159,   160,   161,
     162,   163,   164,   165,   166,   167,   168,   169,    -1,   171,
      -1,   173,   174,   175,   176,   177,   178,   179,   180,   181,
     182,   183,   184,   185,   186,   187,   188,   189,   190,   191,
     192,   193,   194,    -1,   196,   197,   198,   199,   200,   201,
     202,   203,   204,   205,   206,   207,   208,   209,   210,   211,
     212,   213,   214,   215,   216,   217,    -1,   219,   220,   221,
     222,   223,   224,   225,   226,   227,   228,   229,   230,   231,
     232,   233,   234,   235,   236,   237,   238,   239,   240,   241,
     242,   243,   244,   245,   246,   247,   248,   249,   250,   251,
     252,   253,   254,   255,   256,    -1,   258,   259,   260,   261,
     262,   263,   264,   265,   266,   267,   268,   269,   270,   271,
     272,   273,    -1,   275,   276,   277,    -1,   279,   280,   281,
     282,   283,   284,   285,   286,   287,   288,   289,   290,    -1,
     292,   293,    -1,   295,   296,   297,   298,   299,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,   313,   314,   315,   316,   317,   318,   319,   320,   321,
     322,   323,   324,   325,   326,   327,   328,   329,   330,   331,
     332,    -1,   334,   335,   336,   337,   338,   339,   340,   341,
     342,   343,   344,   345,   346,   347,   348,   349,   350,   351,
     352,   353,   354,   355,   356,   357,   358,   359,   360,   361,
     362,   363,   364,   365,   366,   367,   368,   369,   370,   371,
     372,    -1,   374,   375,   376,   377,   378,   379,   380,   381,
     382,   383,   384,   385,   386,   387,   388,   389,   390,   391,
      -1,   393,    -1,   395,   396,   397,   398,   399,   400,   401,
     402,   403,   404,   405,   406,   407,   408,   409,   410,   411,
     412,   413,   414,   415,   416,    -1,   418,   419,   420,   421,
     422,   423,   424,   425,   426,   427,   428,   429,   430,   431,
     432,   433,   434,   435,   436,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   448,   449,   450,    -1,
       3,    -1,   454,   455,   456,     8,   458,   459,   460,   461,
     462,   463,    15,    16,    17,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,    -1,    -1,
      -1,   454,   455,   456,    -1,   458,   459,   460,   461,   462,
     463,     8,    -1,    -1,    11,    -1,    -1,    -1,    15,    16,
      17,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     8,
      -1,    -1,    11,    -1,    -1,    32,    15,    16,    17,    -1,
      -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,     8,    -1,
      47,    11,    -1,    32,    -1,    15,    16,    17,    -1,    -1,
      -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,    47,    -1,
      -1,    -1,    32,    -1,    71,    -1,    -1,    -1,    -1,    -1,
      40,    -1,    -1,    -1,    -1,    -1,     8,    47,    -1,    11,
      -1,    -1,    71,    15,    16,    17,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,     8,    -1,    -1,    11,    -1,
      32,    71,    15,    16,    17,    -1,    -1,    -1,    40,    -1,
      -1,    -1,    -1,     8,    -1,    47,    11,    -1,    -1,    32,
      15,    16,    17,    -1,    -1,    -1,    -1,    40,    -1,    -1,
      -1,    -1,    -1,    -1,    47,    -1,    -1,    32,    -1,    71,
      -1,    -1,    -1,    -1,    -1,    40,    -1,    -1,     8,    -1,
      -1,    11,    47,    -1,    -1,    15,    16,    17,    71,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    32,   180,    -1,    -1,    71,    -1,   185,    -1,
      40,    -1,    -1,    -1,    -1,    -1,    -1,    47,    -1,    -1,
      -1,   180,    -1,    -1,    -1,    -1,   185,    -1,    -1,   206,
     207,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     180,    71,    -1,    -1,   221,   185,    -1,   206,   207,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   221,    -1,    -1,    -1,   206,   207,    -1,    -1,
      -1,    -1,    -1,    -1,   251,    -1,    -1,   254,   180,    -1,
      -1,   221,    -1,   185,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   268,   251,    -1,   271,   254,    -1,   180,    -1,    -1,
      -1,    -1,   185,    -1,   206,   207,    -1,    -1,    -1,   268,
      -1,   251,   271,    -1,   254,   180,    -1,    -1,    -1,   221,
     185,    -1,    -1,   206,   207,    -1,    -1,    -1,   268,    -1,
      -1,   271,    -1,    -1,    -1,    -1,    -1,    -1,   221,    -1,
      -1,   206,   207,    -1,    -1,    -1,    -1,    -1,    -1,   251,
     180,    -1,   254,    -1,    -1,   185,   221,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   268,    -1,   251,   271,
      -1,   254,    -1,    -1,    -1,    -1,   206,   207,   355,    -1,
      -1,    -1,    -1,    -1,    -1,   268,   251,    -1,   271,   254,
      -1,   221,    -1,    -1,    -1,    -1,   355,    -1,    -1,    -1,
      -1,    -1,    -1,   268,    -1,    -1,   271,    -1,    -1,    -1,
       8,    -1,    -1,    11,    -1,   355,    -1,    15,    16,    17,
      -1,   251,    -1,    -1,   254,    -1,    -1,    22,    -1,    -1,
      -1,    -1,    -1,    28,    32,    -1,    -1,    -1,   268,    -1,
      35,   271,    40,    -1,    -1,    -1,    -1,    -1,    -1,    47,
      -1,    -1,    -1,   355,    -1,    -1,    -1,    -1,    -1,    54,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   355,    71,   451,    -1,    -1,   454,   455,   456,
      -1,   458,   459,   460,   461,   462,   463,    -1,    -1,    -1,
     355,   468,   451,    -1,    -1,   454,   455,   456,    -1,   458,
     459,   460,   461,   462,   463,    -1,    -1,    -1,   103,   468,
      -1,   451,    -1,    -1,   454,   455,   456,    -1,   458,   459,
     460,   461,   462,   463,    -1,   355,    -1,    -1,   468,    -1,
      -1,    -1,    -1,    -1,    -1,   130,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   451,
      -1,    -1,   454,   455,   456,    -1,   458,   459,   460,   461,
     462,   463,    -1,    -1,    -1,    -1,   468,    -1,   451,    -1,
      -1,   454,   455,   456,    -1,   458,   459,   460,   461,   462,
     463,    -1,   180,    -1,    -1,   468,   451,   185,    -1,   454,
     455,   456,   187,   458,   459,   460,   461,   462,   463,    -1,
      -1,    -1,    -1,   468,    -1,    -1,    -1,    -1,   206,   207,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   451,    -1,   221,   454,   455,   456,    -1,   458,   459,
     460,   461,   462,   463,    -1,    -1,    -1,    -1,   468,    -1,
     235,    -1,    -1,   238,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   251,   249,    -1,   254,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     268,    -1,    -1,   271,    -1,   270,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   280,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   319,    -1,    -1,    -1,   323,   324,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   344,
      -1,    -1,    -1,    -1,    -1,   350,    -1,   355,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   364,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   414,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   451,    -1,    -1,   454,   455,   456,     3,
     458,   459,   460,   461,   462,   463,    -1,    -1,    -1,    -1,
     468,    -1,    -1,    -1,    18,    19,    20,    21,    22,    23,
      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
      34,    35,    36,    37,    38,    39,    40,    41,    42,    43,
      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,
      64,    65,    66,    67,    68,    69,    70,    71,    72,    73,
      74,    75,    76,    77,    78,    79,    80,    81,    82,    83,
      84,    85,    86,    87,    88,    89,    90,    91,    92,    93,
      94,    95,    96,    97,    98,    99,   100,   101,   102,   103,
     104,   105,   106,   107,   108,   109,   110,   111,   112,   113,
     114,   115,   116,   117,   118,   119,   120,   121,   122,   123,
     124,   125,   126,   127,   128,   129,   130,   131,   132,   133,
     134,   135,   136,   137,   138,   139,   140,   141,   142,   143,
     144,   145,   146,   147,   148,   149,   150,   151,   152,   153,
     154,   155,   156,   157,   158,   159,   160,   161,   162,   163,
     164,   165,   166,   167,   168,   169,   170,   171,   172,   173,
     174,   175,   176,   177,   178,   179,   180,   181,   182,   183,
     184,   185,   186,   187,   188,   189,   190,   191,   192,   193,
     194,   195,   196,   197,   198,   199,   200,   201,   202,   203,
     204,   205,   206,   207,   208,   209,   210,   211,   212,   213,
     214,   215,   216,   217,   218,   219,   220,   221,   222,   223,
     224,   225,   226,   227,   228,   229,   230,   231,   232,   233,
     234,   235,   236,   237,   238,   239,   240,   241,   242,   243,
     244,   245,   246,   247,   248,   249,   250,   251,   252,   253,
     254,   255,   256,   257,   258,   259,   260,   261,   262,   263,
     264,   265,   266,   267,   268,   269,   270,   271,   272,   273,
     274,   275,   276,   277,   278,   279,   280,   281,   282,   283,
     284,   285,   286,   287,   288,   289,   290,   291,   292,   293,
     294,   295,   296,   297,   298,   299,   300,   301,   302,   303,
     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
     314,   315,   316,   317,   318,   319,   320,   321,   322,   323,
     324,   325,   326,   327,   328,   329,   330,   331,   332,   333,
     334,   335,   336,   337,   338,   339,   340,   341,   342,   343,
     344,   345,   346,   347,   348,   349,   350,   351,   352,   353,
     354,   355,   356,   357,   358,   359,   360,   361,   362,   363,
     364,   365,   366,   367,   368,   369,   370,   371,   372,   373,
     374,   375,   376,   377,   378,   379,   380,   381,   382,   383,
     384,   385,   386,   387,   388,   389,   390,   391,   392,   393,
     394,   395,   396,   397,   398,   399,   400,   401,   402,   403,
     404,   405,   406,   407,   408,   409,   410,   411,   412,   413,
     414,   415,   416,   417,   418,   419,   420,   421,   422,   423,
     424,   425,   426,   427,   428,   429,   430,   431,   432,   433,
     434,   435,   436,   437,   438,   439,   440,   441,   442,   443,
     444,   445,   446,   447,   448,   449,   450,     3,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   460,    -1,    -1,    -1,
      -1,    -1,    18,    19,    20,    21,    22,    23,    24,    25,
      -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    37,    38,    -1,    40,    41,    42,    -1,    44,    45,
      46,    47,    48,    -1,    50,    51,    -1,    53,    54,    55,
      56,    57,    -1,    -1,    60,    61,    62,    63,    64,    -1,
      66,    67,    68,    69,    70,    -1,    -1,    -1,    74,    75,
      76,    77,    78,    -1,    80,    81,    82,    -1,    84,    85,
      86,    87,    88,    89,    -1,    -1,    92,    93,    94,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,
     106,   107,   108,   109,   110,    -1,   112,    -1,   114,   115,
     116,   117,   118,   119,    -1,   121,   122,   123,   124,    -1,
      -1,   127,   128,   129,   130,   131,    -1,   133,   134,   135,
      -1,   137,   138,   139,    -1,   141,   142,   143,   144,   145,
     146,   147,   148,   149,    -1,   151,    -1,   153,   154,   155,
     156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,
     166,   167,    -1,   169,   170,    -1,   172,   173,    -1,   175,
     176,   177,   178,   179,    -1,   181,   182,   183,   184,    -1,
     186,   187,   188,   189,   190,   191,    -1,   193,    -1,   195,
     196,   197,   198,   199,   200,   201,    -1,   203,    -1,   205,
      -1,    -1,   208,    -1,   210,   211,   212,   213,   214,    -1,
      -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,   225,
      -1,    -1,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,    -1,
     246,   247,   248,   249,   250,    -1,   252,   253,    -1,   255,
      -1,   257,   258,   259,   260,   261,   262,    -1,   264,   265,
      -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,
     276,    -1,   278,   279,   280,   281,   282,   283,   284,   285,
     286,   287,    -1,   289,   290,   291,   292,   293,   294,   295,
     296,   297,    -1,   299,   300,   301,   302,   303,   304,   305,
     306,   307,   308,   309,   310,   311,   312,    -1,   314,   315,
     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,
      -1,   327,   328,    -1,   330,   331,   332,   333,   334,   335,
     336,   337,   338,   339,   340,   341,   342,    -1,   344,   345,
     346,   347,   348,    -1,   350,   351,   352,   353,   354,    -1,
     356,   357,   358,   359,    -1,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,    -1,   375,
     376,    -1,   378,    -1,   380,   381,   382,   383,   384,    -1,
     386,   387,    -1,    -1,   390,   391,   392,   393,   394,    -1,
     396,   397,   398,   399,   400,   401,   402,    -1,    -1,   405,
     406,   407,   408,   409,    -1,    -1,   412,   413,   414,   415,
     416,   417,   418,    -1,   420,    -1,   422,   423,   424,   425,
      -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,   435,
     436,   437,   438,   439,   440,   441,   442,   443,   444,   445,
     446,   447,   448,   449,   450,     3,     4,     5,    -1,    -1,
      -1,     9,    -1,    -1,   460,    -1,    -1,    -1,    -1,    -1,
      18,    19,    20,    21,    22,    23,    24,    25,    -1,    27,
      28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,
      38,    -1,    40,    41,    42,    43,    44,    45,    46,    47,
      48,    49,    50,    51,    -1,    53,    54,    55,    56,    57,
      -1,    -1,    60,    61,    62,    63,    64,    -1,    66,    67,
      68,    69,    70,    -1,    72,    -1,    74,    75,    76,    77,
      78,    79,    80,    81,    82,    -1,    84,    85,    86,    87,
      88,    89,    -1,    91,    92,    93,    94,    -1,    -1,    -1,
      98,    -1,    -1,    -1,   102,   103,   104,   105,   106,   107,
     108,   109,   110,   111,   112,    -1,   114,   115,   116,   117,
     118,   119,    -1,   121,   122,   123,   124,    -1,    -1,   127,
     128,   129,   130,   131,    -1,   133,   134,   135,    -1,   137,
     138,   139,    -1,   141,   142,   143,   144,   145,   146,   147,
     148,   149,   150,   151,    -1,   153,   154,   155,   156,    -1,
     158,    -1,   160,   161,    -1,   163,   164,   165,   166,   167,
      -1,   169,   170,    -1,   172,   173,    -1,   175,   176,   177,
     178,   179,   180,   181,   182,   183,   184,    -1,   186,   187,
     188,   189,   190,   191,    -1,   193,   194,   195,   196,   197,
     198,   199,   200,   201,    -1,   203,    -1,   205,   206,   207,
     208,   209,   210,   211,   212,   213,   214,    -1,    -1,   217,
     218,   219,   220,   221,    -1,   223,   224,   225,    -1,    -1,
     228,   229,   230,   231,   232,   233,   234,   235,   236,   237,
     238,   239,   240,   241,   242,   243,   244,   245,   246,   247,
     248,   249,   250,    -1,   252,   253,   254,   255,    -1,   257,
     258,   259,   260,   261,   262,    -1,   264,   265,   266,    -1,
     268,   269,   270,    -1,    -1,   273,   274,   275,   276,   277,
     278,   279,   280,   281,   282,   283,   284,   285,   286,   287,
      -1,   289,   290,   291,   292,   293,   294,   295,   296,   297,
      -1,   299,   300,   301,   302,   303,   304,   305,   306,   307,
     308,   309,   310,   311,   312,    -1,   314,   315,   316,   317,
     318,   319,   320,   321,   322,   323,   324,   325,    -1,   327,
     328,   329,   330,   331,   332,   333,   334,   335,   336,   337,
     338,   339,   340,   341,   342,    -1,   344,   345,   346,   347,
     348,    -1,   350,   351,   352,   353,   354,   355,   356,   357,
     358,   359,    -1,   361,   362,   363,   364,   365,   366,   367,
     368,   369,   370,   371,   372,   373,    -1,   375,   376,    -1,
     378,   379,   380,   381,   382,   383,   384,    -1,   386,   387,
      -1,    -1,   390,   391,   392,   393,   394,   395,   396,   397,
     398,   399,   400,   401,   402,    -1,    -1,   405,   406,   407,
     408,   409,    -1,    -1,   412,   413,   414,   415,   416,   417,
     418,    -1,   420,   421,   422,   423,   424,   425,    -1,    -1,
     428,    -1,    -1,   431,   432,   433,   434,   435,   436,   437,
     438,   439,   440,   441,   442,   443,   444,   445,   446,   447,
     448,   449,   450,     3,     4,     5,    -1,    -1,    -1,     9,
     458,   459,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,
      20,    21,    22,    23,    24,    25,    -1,    27,    28,    29,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,
      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
      50,    51,    -1,    53,    54,    55,    56,    57,    -1,    -1,
      60,    61,    62,    63,    64,    -1,    66,    67,    68,    69,
      70,    -1,    72,    -1,    74,    75,    76,    77,    78,    79,
      80,    81,    82,    -1,    84,    85,    86,    87,    88,    89,
      -1,    91,    92,    93,    94,    -1,    -1,    -1,    98,    -1,
      -1,    -1,   102,   103,   104,   105,   106,   107,   108,   109,
     110,   111,   112,    -1,   114,   115,   116,   117,   118,   119,
      -1,   121,   122,   123,   124,    -1,    -1,   127,   128,   129,
     130,   131,    -1,   133,   134,   135,    -1,   137,   138,   139,
      -1,   141,   142,   143,   144,   145,   146,   147,   148,   149,
     150,   151,    -1,   153,   154,   155,   156,    -1,   158,    -1,
     160,   161,    -1,   163,   164,   165,   166,   167,    -1,   169,
     170,    -1,   172,   173,    -1,   175,   176,   177,   178,   179,
     180,   181,   182,   183,   184,    -1,   186,   187,   188,   189,
     190,   191,    -1,   193,   194,   195,   196,   197,   198,   199,
     200,   201,    -1,   203,    -1,   205,   206,   207,   208,   209,
     210,   211,   212,   213,   214,    -1,    -1,   217,   218,   219,
     220,   221,    -1,   223,   224,   225,    -1,    -1,   228,   229,
     230,   231,   232,   233,   234,   235,   236,   237,   238,   239,
     240,   241,   242,   243,   244,   245,   246,   247,   248,   249,
     250,    -1,   252,   253,   254,   255,    -1,   257,   258,   259,
     260,   261,   262,    -1,   264,   265,   266,    -1,   268,   269,
     270,    -1,    -1,   273,   274,   275,   276,   277,   278,   279,
     280,   281,   282,   283,   284,   285,   286,   287,    -1,   289,
     290,   291,   292,   293,   294,   295,   296,   297,    -1,   299,
     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,
     310,   311,   312,    -1,   314,   315,   316,   317,   318,   319,
     320,   321,   322,   323,   324,   325,    -1,   327,   328,   329,
     330,   331,   332,   333,   334,   335,   336,   337,   338,   339,
     340,   341,   342,    -1,   344,   345,   346,   347,   348,    -1,
     350,   351,   352,   353,   354,   355,   356,   357,   358,   359,
      -1,   361,   362,   363,   364,   365,   366,   367,   368,   369,
     370,   371,   372,   373,    -1,   375,   376,    -1,   378,   379,
     380,   381,   382,   383,   384,    -1,   386,   387,    -1,    -1,
     390,   391,   392,   393,   394,   395,   396,   397,   398,   399,
     400,   401,   402,    -1,    -1,   405,   406,   407,   408,   409,
      -1,    -1,   412,   413,   414,   415,   416,   417,   418,    -1,
     420,   421,   422,   423,   424,   425,    -1,    -1,   428,    -1,
      -1,   431,   432,   433,   434,   435,   436,   437,   438,   439,
     440,   441,   442,   443,   444,   445,   446,   447,   448,   449,
     450,     3,     4,     5,    -1,    -1,    -1,     9,   458,   459,
      -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,
      22,    23,    24,    25,    -1,    27,    28,    29,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,
      42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
      -1,    53,    54,    55,    56,    57,    -1,    -1,    60,    61,
      62,    63,    64,    -1,    66,    67,    68,    69,    70,    -1,
      72,    -1,    74,    75,    76,    77,    78,    79,    80,    81,
      82,    -1,    84,    85,    86,    87,    88,    89,    -1,    91,
      92,    93,    94,    -1,    -1,    -1,    98,    -1,    -1,    -1,
     102,   103,   104,   105,   106,   107,   108,   109,   110,    -1,
     112,    -1,   114,   115,   116,   117,   118,   119,    -1,   121,
     122,   123,   124,    -1,    -1,   127,   128,   129,   130,   131,
      -1,   133,   134,   135,    -1,   137,   138,   139,    -1,   141,
     142,   143,   144,   145,   146,   147,   148,   149,   150,   151,
      -1,   153,   154,   155,   156,    -1,   158,    -1,   160,   161,
      -1,   163,   164,   165,   166,   167,    -1,   169,   170,    -1,
     172,   173,    -1,   175,   176,   177,   178,   179,   180,   181,
     182,   183,   184,    -1,   186,   187,   188,   189,   190,   191,
      -1,   193,   194,   195,   196,   197,   198,   199,   200,   201,
      -1,   203,    -1,   205,   206,   207,   208,   209,   210,   211,
     212,   213,   214,    -1,    -1,   217,   218,   219,   220,   221,
      -1,   223,   224,   225,    -1,    -1,   228,   229,   230,   231,
     232,   233,   234,   235,   236,   237,   238,   239,   240,   241,
     242,   243,   244,   245,   246,   247,   248,   249,   250,    -1,
     252,   253,   254,   255,    -1,   257,   258,   259,   260,   261,
     262,    -1,   264,   265,   266,    -1,   268,   269,   270,    -1,
      -1,   273,   274,   275,   276,   277,   278,   279,   280,   281,
     282,   283,   284,   285,   286,   287,    -1,   289,   290,   291,
     292,   293,   294,   295,   296,   297,    -1,   299,   300,   301,
     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
     312,    -1,   314,   315,   316,   317,   318,   319,   320,   321,
     322,   323,   324,   325,    -1,   327,   328,   329,   330,   331,
     332,   333,   334,   335,   336,   337,   338,   339,   340,   341,
     342,    -1,   344,   345,   346,   347,   348,    -1,   350,   351,
     352,   353,   354,   355,   356,   357,   358,   359,    -1,   361,
     362,   363,   364,   365,   366,   367,   368,   369,   370,   371,
     372,   373,    -1,   375,   376,    -1,   378,   379,   380,   381,
     382,   383,   384,    -1,   386,   387,    -1,    -1,   390,   391,
     392,   393,   394,   395,   396,   397,   398,   399,   400,   401,
     402,    -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,
     412,   413,   414,   415,   416,   417,   418,    -1,   420,   421,
     422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,
     432,   433,   434,   435,   436,   437,   438,   439,   440,   441,
     442,   443,   444,   445,   446,   447,   448,   449,   450,    -1,
      -1,     8,    -1,    -1,    11,    -1,   458,   459,    15,    16,
      17,    -1,    -1,    -1,     8,    -1,    -1,    11,    -1,    -1,
      -1,    15,    16,    17,    -1,    32,    -1,    -1,    -1,    36,
      -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    32,    -1,
      47,    -1,    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,
      -1,    -1,    -1,    47,     8,    -1,    -1,    11,    -1,    -1,
      -1,    15,    16,    17,    71,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,     8,    -1,    -1,    11,    71,    32,    -1,
      15,    16,    17,    -1,    -1,    -1,    40,    -1,    -1,    -1,
      -1,    -1,    -1,    47,    -1,    -1,    -1,    32,    -1,    -1,
      35,    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,
      -1,     8,    47,   120,    11,    -1,    -1,    71,    15,    16,
      17,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       8,    -1,    -1,    11,    -1,    32,    71,    15,    16,    17,
      -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,
      47,    -1,    -1,    -1,    32,    -1,    -1,    35,    -1,    -1,
      -1,    -1,    40,   157,    -1,    -1,    -1,    -1,   162,    47,
      -1,    -1,    -1,   180,    71,    -1,    -1,    -1,   185,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   180,    -1,    -1,    -1,
      -1,   185,    -1,    71,    -1,    -1,    -1,    -1,    -1,   206,
     207,    -1,   156,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   206,   207,   221,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   180,   221,    -1,    -1,
      -1,   185,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   251,   180,    -1,   254,    -1,    -1,
     185,    -1,   206,   207,    -1,    -1,    -1,   251,    -1,    -1,
     254,   268,    -1,    -1,   271,    -1,    -1,   221,    -1,    -1,
      -1,   206,   207,    -1,   268,    -1,    -1,   271,    -1,    -1,
      -1,    -1,    -1,   180,    -1,    -1,   221,    -1,   185,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   251,    -1,    -1,
     254,    -1,   180,    -1,    -1,    -1,    -1,   185,    -1,   206,
     207,    -1,    -1,    -1,   268,    -1,   251,   271,    -1,   254,
      -1,    -1,    -1,    -1,   221,    -1,    -1,    -1,   206,   207,
      -1,    -1,    -1,   268,    -1,    -1,   271,    -1,    -1,   293,
      -1,    -1,    -1,   221,    -1,    -1,    -1,    -1,   355,    -1,
      -1,    -1,    -1,    -1,   251,    -1,    -1,   254,    -1,    -1,
      -1,   355,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   268,    -1,   251,   271,    -1,   254,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     268,   288,    -1,   271,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   355,    -1,    -1,   411,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     355,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   451,    -1,    -1,   454,   455,   456,
      -1,   458,   459,   460,   461,   462,   463,   451,   355,    -1,
     454,   455,   456,    -1,   458,   459,   460,   461,   462,   463,
      -1,     8,    -1,    -1,    11,    -1,    -1,   355,    15,    16,
      17,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    32,    -1,   451,    -1,    -1,
     454,   455,   456,    40,   458,   459,   460,   461,   462,   463,
      47,    -1,    -1,    -1,    -1,    -1,   451,    -1,    -1,   454,
     455,   456,    -1,   458,   459,   460,   461,   462,   463,    -1,
      -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   451,    -1,    -1,   454,   455,   456,
      -1,   458,   459,   460,   461,   462,   463,    -1,    -1,    -1,
      -1,    -1,    -1,   451,    -1,    -1,   454,   455,   456,    -1,
     458,   459,   460,   461,   462,   463,    -1,     8,    -1,    -1,
      11,    -1,    -1,    -1,    15,    16,    17,    -1,    -1,    -1,
       8,    -1,    -1,    11,    -1,    -1,    -1,    15,    16,    17,
      -1,    32,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    40,
      -1,    -1,    -1,    -1,    32,   162,    47,    -1,    -1,    -1,
      -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,    47,
      -1,    -1,    -1,   180,    -1,    -1,    -1,    -1,   185,    -1,
      71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    71,    -1,    -1,    -1,    -1,    -1,   206,
     207,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   221,    -1,    -1,    -1,    -1,     8,
      -1,    -1,    11,    -1,    -1,    -1,    15,    16,    17,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    32,   251,    -1,    -1,   254,    -1,    -1,
      -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,    47,     8,
      -1,   268,    11,    -1,   271,    -1,    15,    16,    17,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    71,    -1,    -1,    -1,    -1,    -1,    -1,   180,
      -1,    40,    -1,    -1,   185,    -1,    -1,    -1,    47,    -1,
      -1,    -1,   180,    -1,    -1,    -1,    -1,   185,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   206,   207,    -1,    -1,    -1,
      -1,    -1,    71,    -1,    -1,    -1,    -1,    -1,   206,   207,
     221,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   221,    -1,    -1,    -1,    -1,   355,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     251,    -1,    -1,   254,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   251,    -1,    -1,   254,   268,    -1,    -1,
     271,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     268,   180,    -1,   271,    -1,    -1,   185,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   206,   207,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   180,   221,    -1,    -1,    -1,   185,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   451,    -1,    -1,   454,   455,   456,
      -1,   458,   459,   460,   461,   462,   463,   206,   207,    -1,
      -1,    -1,   251,    -1,   355,   254,    -1,    -1,    -1,    -1,
      -1,    -1,   221,    -1,    -1,    -1,    -1,   355,    -1,   268,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   385,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   251,    -1,    -1,   254,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   268,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
     451,    -1,    -1,   454,   455,   456,   355,   458,   459,   460,
     461,   462,   463,   451,    -1,    -1,   454,   455,   456,    -1,
     458,   459,   460,   461,   462,   463,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,   355,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   451,    -1,    -1,   454,   455,   456,    -1,   458,
     459,   460,   461,   462,   463,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       3,    -1,   451,    -1,    -1,   454,   455,   456,    -1,   458,
     459,   460,   461,   462,   463,    18,    19,    20,    21,    22,
      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
      33,    34,    35,    36,    37,    38,    39,    40,    41,    42,
      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
      73,    74,    75,    76,    77,    78,    79,    80,    81,    82,
      83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
      93,    94,    95,    96,    97,    98,    99,   100,   101,   102,
     103,   104,   105,   106,   107,   108,   109,   110,   111,   112,
     113,   114,   115,   116,   117,   118,   119,   120,   121,   122,
     123,   124,   125,   126,   127,   128,   129,   130,   131,   132,
     133,   134,   135,   136,   137,   138,   139,   140,   141,   142,
     143,   144,   145,   146,   147,   148,   149,   150,   151,   152,
     153,   154,   155,   156,   157,   158,   159,   160,   161,   162,
     163,   164,   165,   166,   167,   168,   169,   170,   171,   172,
     173,   174,   175,   176,   177,   178,   179,   180,   181,   182,
     183,   184,   185,   186,   187,   188,   189,   190,   191,   192,
     193,   194,   195,   196,   197,   198,   199,   200,   201,   202,
     203,   204,   205,   206,   207,   208,   209,   210,   211,   212,
     213,   214,   215,   216,   217,   218,   219,   220,   221,   222,
     223,   224,   225,   226,   227,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,
     253,   254,   255,   256,   257,   258,   259,   260,   261,   262,
     263,   264,   265,   266,   267,   268,   269,   270,   271,   272,
     273,   274,   275,   276,   277,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,   288,   289,   290,   291,   292,
     293,   294,   295,   296,   297,   298,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
     313,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,   326,   327,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
     343,   344,   345,   346,   347,   348,   349,   350,   351,   352,
     353,   354,   355,   356,   357,   358,   359,   360,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,   374,   375,   376,   377,   378,   379,   380,   381,   382,
     383,   384,   385,   386,   387,   388,   389,   390,   391,   392,
     393,   394,   395,   396,   397,   398,   399,   400,   401,   402,
     403,   404,   405,   406,   407,   408,   409,   410,   411,   412,
     413,   414,   415,   416,   417,   418,   419,   420,   421,   422,
     423,   424,   425,   426,   427,   428,   429,   430,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,
     125,   126,   127,   128,   129,   130,   131,   132,   133,   134,
     135,   136,   137,   138,   139,   140,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,   152,   153,   154,
     155,   156,   157,   158,   159,   160,   161,   162,   163,   164,
     165,   166,   167,   168,   169,   170,   171,   172,   173,   174,
     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,
     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
     195,   196,   197,   198,   199,   200,   201,   202,   203,   204,
     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,
     215,   216,   217,   218,   219,   220,   221,   222,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,
     255,   256,   257,   258,   259,   260,   261,   262,   263,   264,
     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
     385,   386,   387,   388,   389,   390,   391,   392,   393,   394,
     395,   396,   397,   398,   399,   400,   401,   402,   403,   404,
     405,   406,   407,   408,   409,   410,   411,   412,   413,   414,
     415,   416,   417,   418,   419,   420,   421,   422,   423,   424,
     425,   426,   427,   428,   429,   430,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      47,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    59,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    95,    96,
      97,    98,    99,   100,   101,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,   219,   220,   221,    -1,   223,   224,   225,   226,
     227,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,   250,    -1,   252,   253,   254,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,   275,   276,
     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,   349,   350,   351,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,   410,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,     5,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    43,    44,    45,    46,    47,    48,
      49,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    72,    -1,    74,    75,    76,    77,    78,
      79,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    91,    92,    93,    94,    -1,    -1,    -1,    98,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,   150,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,   161,    -1,   163,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,   180,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,   194,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,   206,   207,   208,
     209,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
     219,   220,   221,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,   245,   246,   247,   248,
     249,   250,    -1,   252,   253,   254,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,   266,    -1,   268,
     269,   270,    -1,    -1,   273,   274,   275,   276,   277,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
     329,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,   355,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
     379,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,   395,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,   421,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    -1,    27,    28,    29,    30,
      31,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    72,    -1,    74,    75,    76,    77,    78,    79,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      91,    92,    93,    94,    -1,    -1,    -1,    98,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
     161,    -1,   163,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,   180,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,   194,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,   206,   207,   208,   209,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,   219,   220,
     221,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,   245,   246,   247,   248,   249,   250,
      -1,   252,   253,   254,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,   275,   276,   277,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,   329,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,   355,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,   379,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
     421,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      43,    44,    45,    46,    47,    48,    49,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    72,
      -1,    74,    75,    76,    77,    78,    79,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    91,    92,
      93,    94,    -1,    -1,    -1,    98,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,   161,    -1,
     163,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,   180,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,   194,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,   206,   207,   208,   209,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,   219,   220,   221,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,   245,   246,   247,   248,   249,   250,    -1,   252,
     253,   254,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,   275,   276,   277,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,   329,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,   355,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,   379,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,   421,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      65,    66,    67,    68,    69,    70,    -1,    -1,    73,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    83,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,   159,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,   404,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    65,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    83,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,   159,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,   221,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,   298,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,   404,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    30,    31,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    26,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    -1,    44,    45,    46,    47,    48,    -1,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    -1,    -1,    74,    75,    76,    77,    78,    -1,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      -1,    92,    93,    94,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
      -1,    -1,    -1,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,    -1,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,    -1,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,    -1,    -1,   208,    -1,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,    -1,   220,
      -1,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,    -1,   246,   247,   248,   249,   250,
      -1,   252,   253,    -1,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,    -1,   276,    -1,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,    -1,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,    -1,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,    -1,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
      -1,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    26,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,    -1,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
     267,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,   267,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    26,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    -1,    44,    45,    46,    47,    48,    -1,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    -1,    -1,    74,    75,    76,    77,    78,    -1,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      -1,    92,    93,    94,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
      -1,    -1,    -1,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,    -1,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,    -1,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,    -1,    -1,   208,    -1,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,    -1,   220,
      -1,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,    -1,   246,   247,   248,   249,   250,
      -1,   252,   253,    -1,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,    -1,   276,    -1,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,    -1,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,    -1,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,    -1,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
      -1,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,   377,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      35,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    35,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,    -1,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    -1,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    -1,    44,    45,    46,    47,    48,    -1,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    -1,    -1,    74,    75,    76,    77,    78,    -1,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      -1,    92,    93,    94,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
      -1,    -1,    -1,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,    -1,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,    -1,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,    -1,    -1,   208,    -1,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,    -1,   220,
      -1,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,    -1,   246,   247,   248,   249,   250,
      -1,   252,   253,    -1,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,    -1,   276,    -1,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,    -1,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,    -1,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,    -1,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
      -1,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,    -1,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    -1,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    -1,    44,    45,    46,    47,    48,    -1,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    -1,    -1,    74,    75,    76,    77,    78,    -1,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      -1,    92,    93,    94,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
      -1,    -1,    -1,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,    -1,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,    -1,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,    -1,    -1,   208,    -1,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,    -1,   220,
      -1,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,    -1,   246,   247,   248,   249,   250,
      -1,   252,   253,    -1,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,    -1,   276,    -1,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,    -1,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,    -1,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,    -1,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
      -1,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,    -1,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    -1,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    -1,    44,    45,    46,    47,    48,    -1,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    -1,    -1,    74,    75,    76,    77,    78,    -1,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      -1,    92,    93,    94,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
      -1,    -1,    -1,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,    -1,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,    -1,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,    -1,    -1,   208,    -1,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,    -1,   220,
      -1,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,    -1,   246,   247,   248,   249,   250,
      -1,   252,   253,    -1,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,    -1,   276,    -1,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,    -1,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,    -1,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,    -1,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
      -1,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      35,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,    -1,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,    -1,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,   285,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,   334,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    -1,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    -1,    44,    45,    46,    47,    48,    -1,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    70,
      -1,    -1,    -1,    74,    75,    76,    77,    78,    -1,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      -1,    92,    93,    94,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,   145,   146,   147,   148,   149,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
      -1,    -1,    -1,   164,   165,   166,   167,    -1,   169,   170,
      -1,   172,   173,    -1,   175,   176,   177,   178,   179,    -1,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,    -1,   195,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,    -1,    -1,   208,    -1,   210,
     211,   212,   213,   214,    -1,    -1,   217,   218,    -1,   220,
      -1,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,    -1,   246,   247,   248,   249,   250,
      -1,   252,   253,    -1,   255,    -1,   257,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,   274,    -1,   276,    -1,   278,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
     291,   292,   293,   294,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,    -1,   330,
     331,   332,   333,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,    -1,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,   373,    -1,   375,   376,    -1,   378,    -1,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,   392,   393,   394,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,   417,   418,    -1,   420,
      -1,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,   437,   438,   439,   440,
     441,   442,   443,   444,   445,   446,   447,   448,   449,   450,
       3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    18,    19,    20,    21,    22,
      23,    24,    25,    -1,    27,    28,    29,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
      -1,    44,    45,    46,    47,    48,    -1,    50,    51,    -1,
      53,    54,    55,    56,    57,    -1,    -1,    60,    61,    62,
      63,    64,    -1,    66,    67,    68,    69,    70,    -1,    -1,
      -1,    74,    75,    76,    77,    78,    -1,    80,    81,    82,
      -1,    84,    85,    86,    87,    88,    89,    -1,    -1,    92,
      93,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,
     103,   104,   105,   106,   107,   108,   109,   110,    -1,   112,
      -1,   114,   115,   116,   117,   118,   119,    -1,   121,   122,
     123,   124,    -1,    -1,   127,   128,   129,   130,   131,    -1,
     133,   134,   135,    -1,   137,   138,   139,    -1,   141,   142,
     143,   144,   145,   146,   147,   148,   149,    -1,   151,    -1,
     153,   154,   155,   156,    -1,   158,    -1,   160,    -1,    -1,
      -1,   164,   165,   166,   167,    -1,   169,   170,    -1,   172,
     173,    -1,   175,   176,   177,   178,   179,    -1,   181,   182,
     183,   184,    -1,   186,   187,   188,   189,   190,   191,    -1,
     193,    -1,   195,   196,   197,   198,   199,   200,   201,    -1,
     203,    -1,   205,    -1,    -1,   208,    -1,   210,   211,   212,
     213,   214,    -1,    -1,   217,   218,    -1,   220,    -1,    -1,
     223,   224,   225,    -1,    -1,   228,   229,   230,   231,   232,
     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
     243,   244,    -1,   246,   247,   248,   249,   250,    -1,   252,
     253,    -1,   255,    -1,   257,   258,   259,   260,   261,   262,
      -1,   264,   265,    -1,    -1,   268,   269,   270,    -1,    -1,
     273,   274,    -1,   276,    -1,   278,   279,   280,   281,   282,
     283,   284,   285,   286,   287,    -1,   289,   290,   291,   292,
     293,   294,   295,   296,   297,    -1,   299,   300,   301,   302,
     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
      -1,   314,   315,   316,   317,   318,   319,   320,   321,   322,
     323,   324,   325,    -1,   327,   328,    -1,   330,   331,   332,
     333,   334,   335,   336,   337,   338,   339,   340,   341,   342,
      -1,   344,   345,   346,   347,   348,    -1,   350,   351,   352,
     353,   354,    -1,   356,   357,   358,   359,    -1,   361,   362,
     363,   364,   365,   366,   367,   368,   369,   370,   371,   372,
     373,    -1,   375,   376,    -1,   378,    -1,   380,   381,   382,
     383,   384,    -1,   386,   387,    -1,    -1,   390,   391,   392,
     393,   394,    -1,   396,   397,   398,   399,   400,   401,   402,
      -1,    -1,   405,   406,   407,   408,   409,    -1,    -1,   412,
     413,   414,   415,   416,   417,   418,    -1,   420,    -1,   422,
     423,   424,   425,    -1,    -1,   428,    -1,    -1,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,     3,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
      25,    -1,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    37,    38,    -1,    40,    41,    42,    -1,    44,
      45,    46,    47,    48,    -1,    50,    51,    -1,    53,    54,
      55,    56,    57,    -1,    -1,    60,    61,    62,    63,    64,
      -1,    66,    67,    68,    69,    70,    -1,    -1,    -1,    74,
      75,    76,    77,    78,    -1,    80,    81,    82,    -1,    84,
      85,    86,    87,    88,    89,    -1,    -1,    92,    93,    94,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   102,   103,   104,
     105,   106,   107,   108,   109,   110,    -1,   112,    -1,   114,
     115,   116,   117,   118,   119,    -1,   121,   122,   123,   124,
      -1,    -1,   127,   128,   129,   130,   131,    -1,   133,   134,
     135,    -1,   137,   138,   139,    -1,   141,   142,   143,   144,
     145,   146,   147,   148,   149,    -1,   151,    -1,   153,   154,
     155,   156,    -1,   158,    -1,   160,    -1,    -1,    -1,   164,
     165,   166,   167,    -1,   169,   170,    -1,   172,   173,    -1,
     175,   176,   177,   178,   179,    -1,   181,   182,   183,   184,
      -1,   186,   187,   188,   189,   190,   191,    -1,   193,    -1,
     195,   196,   197,   198,   199,   200,   201,    -1,   203,    -1,
     205,    -1,    -1,   208,    -1,   210,   211,   212,   213,   214,
      -1,    -1,   217,   218,    -1,   220,    -1,    -1,   223,   224,
     225,    -1,    -1,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
      -1,   246,   247,   248,   249,   250,    -1,   252,   253,    -1,
     255,    -1,   257,   258,   259,   260,   261,   262,    -1,   264,
     265,    -1,    -1,   268,   269,   270,    -1,    -1,   273,   274,
      -1,   276,    -1,   278,   279,   280,   281,   282,   283,   284,
     285,   286,   287,    -1,   289,   290,   291,   292,   293,   294,
     295,   296,   297,    -1,   299,   300,   301,   302,   303,   304,
     305,   306,   307,   308,   309,   310,   311,   312,    -1,   314,
     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
     325,    -1,   327,   328,    -1,   330,   331,   332,   333,   334,
     335,   336,   337,   338,   339,   340,   341,   342,    -1,   344,
     345,   346,   347,   348,    -1,   350,   351,   352,   353,   354,
      -1,   356,   357,   358,   359,    -1,   361,   362,   363,   364,
     365,   366,   367,   368,   369,   370,   371,   372,   373,    -1,
     375,   376,    -1,   378,    -1,   380,   381,   382,   383,   384,
      -1,   386,   387,    -1,    -1,   390,   391,   392,   393,   394,
      -1,   396,   397,   398,   399,   400,   401,   402,    -1,    -1,
     405,   406,   407,   408,   409,    -1,    -1,   412,   413,   414,
     415,   416,   417,   418,    -1,   420,    -1,   422,   423,   424,
     425,    -1,    -1,   428,    -1,    -1,   431,   432,   433,   434,
     435,   436,   437,   438,   439,   440,   441,   442,   443,   444,
     445,   446,   447,   448,   449,   450,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    -1,    44,    45,    46,
      47,    48,    -1,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    70,    -1,    -1,    -1,    74,    75,    76,
      77,    78,    -1,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    -1,    92,    93,    94,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,   145,   146,
     147,   148,   149,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,    -1,    -1,    -1,   164,   165,   166,
     167,    -1,   169,   170,    -1,   172,   173,    -1,   175,   176,
     177,   178,   179,    -1,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,    -1,   195,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,    -1,
      -1,   208,    -1,   210,   211,   212,   213,   214,    -1,    -1,
     217,   218,    -1,   220,    -1,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,    -1,   246,
     247,   248,   249,   250,    -1,   252,   253,    -1,   255,    -1,
     257,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,   274,    -1,   276,
      -1,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,   291,   292,   293,   294,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,    -1,   330,   331,   332,   333,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,   351,   352,   353,   354,    -1,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,   373,    -1,   375,   376,
      -1,   378,    -1,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,   392,   393,   394,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
     417,   418,    -1,   420,    -1,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
     437,   438,   439,   440,   441,   442,   443,   444,   445,   446,
     447,   448,   449,   450,     3,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,
      19,    20,    21,    22,    23,    24,    25,    -1,    27,    28,
      29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
      -1,    40,    41,    42,    -1,    44,    45,    46,    47,    48,
      -1,    50,    51,    -1,    53,    54,    55,    56,    57,    -1,
      -1,    60,    61,    62,    63,    64,    -1,    66,    67,    68,
      69,    70,    -1,    -1,    -1,    74,    75,    76,    77,    78,
      -1,    80,    81,    82,    -1,    84,    85,    86,    87,    88,
      89,    -1,    -1,    92,    93,    94,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,   102,   103,   104,   105,   106,   107,   108,
     109,   110,    -1,   112,    -1,   114,   115,   116,   117,   118,
     119,    -1,   121,   122,   123,   124,    -1,    -1,   127,   128,
     129,   130,   131,    -1,   133,   134,   135,    -1,   137,   138,
     139,    -1,   141,   142,   143,   144,   145,   146,   147,   148,
     149,    -1,   151,    -1,   153,   154,   155,   156,    -1,   158,
      -1,   160,    -1,    -1,    -1,   164,   165,   166,   167,    -1,
     169,   170,    -1,   172,   173,    -1,   175,   176,   177,   178,
     179,    -1,   181,   182,   183,   184,    -1,   186,   187,   188,
     189,   190,   191,    -1,   193,    -1,   195,   196,   197,   198,
     199,   200,   201,    -1,   203,    -1,   205,    -1,    -1,   208,
      -1,   210,   211,   212,   213,   214,    -1,    -1,   217,   218,
      -1,   220,    -1,    -1,   223,   224,   225,    -1,    -1,   228,
     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,
     239,   240,   241,   242,   243,   244,    -1,   246,   247,   248,
     249,   250,    -1,   252,   253,    -1,   255,    -1,   257,   258,
     259,   260,   261,   262,    -1,   264,   265,    -1,    -1,   268,
     269,   270,    -1,    -1,   273,   274,    -1,   276,    -1,   278,
     279,   280,   281,   282,   283,   284,    -1,   286,   287,    -1,
     289,   290,   291,   292,   293,   294,   295,   296,   297,    -1,
     299,   300,   301,   302,   303,   304,   305,    -1,   307,   308,
     309,   310,   311,   312,    -1,   314,   315,   316,   317,   318,
     319,   320,   321,   322,   323,   324,   325,    -1,   327,   328,
      -1,   330,   331,   332,   333,    -1,   335,   336,   337,   338,
     339,   340,   341,   342,    -1,   344,   345,   346,   347,   348,
      -1,   350,   351,   352,   353,   354,    -1,   356,   357,   358,
     359,    -1,   361,   362,   363,   364,   365,   366,   367,   368,
     369,   370,   371,   372,   373,    -1,   375,   376,    -1,   378,
      -1,   380,   381,   382,   383,   384,    -1,   386,   387,    -1,
      -1,   390,   391,   392,   393,   394,    -1,   396,   397,   398,
     399,   400,   401,   402,    -1,    -1,   405,   406,   407,   408,
     409,    -1,    -1,   412,   413,   414,   415,   416,   417,   418,
      -1,   420,    -1,   422,   423,   424,   425,    -1,    -1,   428,
      -1,    -1,   431,   432,   433,   434,   435,   436,   437,   438,
     439,   440,   441,   442,   443,   444,   445,   446,   447,   448,
     449,   450,     3,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    18,    19,    20,
      21,    22,    23,    24,    25,    -1,    27,    28,    29,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
      41,    42,    43,    44,    45,    46,    -1,    48,    49,    50,
      51,    -1,    53,    54,    55,    56,    57,    -1,    -1,    60,
      61,    62,    63,    64,    -1,    66,    67,    68,    69,    -1,
      -1,    72,    -1,    74,    75,    76,    77,    78,    79,    80,
      81,    82,    -1,    84,    85,    86,    87,    88,    89,    -1,
      91,    92,    93,    94,    -1,    -1,    -1,    98,    -1,    -1,
      -1,   102,   103,   104,   105,   106,   107,   108,   109,   110,
      -1,   112,    -1,   114,   115,   116,   117,   118,   119,    -1,
     121,   122,   123,   124,    -1,    -1,   127,   128,   129,   130,
     131,    -1,   133,   134,   135,    -1,   137,   138,   139,    -1,
     141,   142,   143,   144,    -1,   146,   147,   148,    -1,    -1,
     151,    -1,   153,   154,   155,   156,    -1,   158,    -1,   160,
     161,    -1,   163,   164,   165,   166,   167,    -1,   169,    -1,
      -1,    -1,   173,    -1,   175,   176,   177,   178,   179,   180,
     181,   182,   183,   184,    -1,   186,   187,   188,   189,   190,
     191,    -1,   193,   194,    -1,   196,   197,   198,   199,   200,
     201,    -1,   203,    -1,   205,   206,   207,   208,   209,   210,
     211,   212,   213,   214,    -1,    -1,   217,    -1,   219,   220,
     221,    -1,   223,   224,   225,    -1,    -1,   228,   229,   230,
     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
     241,   242,   243,   244,   245,   246,   247,   248,   249,    -1,
      -1,   252,   253,   254,   255,    -1,    -1,   258,   259,   260,
     261,   262,    -1,   264,   265,    -1,    -1,   268,   269,   270,
      -1,    -1,   273,    -1,   275,   276,   277,    -1,   279,   280,
     281,   282,   283,   284,   285,   286,   287,    -1,   289,   290,
      -1,   292,   293,    -1,   295,   296,   297,    -1,   299,   300,
     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,
     311,   312,    -1,   314,   315,   316,   317,   318,   319,   320,
     321,   322,   323,   324,   325,    -1,   327,   328,   329,   330,
     331,   332,    -1,   334,   335,   336,   337,   338,   339,   340,
     341,   342,    -1,   344,   345,   346,   347,   348,    -1,   350,
     351,   352,   353,   354,   355,   356,   357,   358,   359,    -1,
     361,   362,   363,   364,   365,   366,   367,   368,   369,   370,
     371,   372,    -1,    -1,   375,   376,    -1,   378,   379,   380,
     381,   382,   383,   384,    -1,   386,   387,    -1,    -1,   390,
     391,    -1,   393,    -1,    -1,   396,   397,   398,   399,   400,
     401,   402,    -1,    -1,   405,   406,   407,   408,   409,    -1,
      -1,   412,   413,   414,   415,   416,    -1,   418,    -1,   420,
     421,   422,   423,   424,   425,    -1,    -1,   428,    -1,    -1,
     431,   432,   433,   434,   435,   436,     3,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   448,   449,   450,
      -1,    18,    19,    20,    21,    22,    23,    24,    25,    -1,
      27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,
      -1,    48,    49,    50,    51,    -1,    53,    54,    55,    56,
      57,    -1,    -1,    60,    61,    62,    63,    64,    -1,    66,
      67,    68,    69,    -1,    -1,    72,    -1,    74,    75,    76,
      77,    78,    79,    80,    81,    82,    -1,    84,    85,    86,
      87,    88,    89,    -1,    91,    92,    93,    94,    -1,    -1,
      -1,    98,    -1,    -1,    -1,   102,   103,   104,   105,   106,
     107,   108,   109,   110,    -1,   112,    -1,   114,   115,   116,
     117,   118,   119,    -1,   121,   122,   123,   124,    -1,    -1,
     127,   128,   129,   130,   131,    -1,   133,   134,   135,    -1,
     137,   138,   139,    -1,   141,   142,   143,   144,    -1,   146,
     147,   148,    -1,    -1,   151,    -1,   153,   154,   155,   156,
      -1,   158,    -1,   160,   161,    -1,   163,   164,   165,   166,
     167,    -1,   169,    -1,    -1,    -1,   173,    -1,   175,   176,
     177,   178,   179,   180,   181,   182,   183,   184,    -1,   186,
     187,   188,   189,   190,   191,    -1,   193,   194,    -1,   196,
     197,   198,   199,   200,   201,    -1,   203,    -1,   205,   206,
     207,   208,   209,   210,   211,   212,   213,   214,    -1,    -1,
     217,    -1,   219,   220,   221,    -1,   223,   224,   225,    -1,
      -1,   228,   229,   230,   231,   232,   233,   234,   235,   236,
     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,
     247,   248,   249,    -1,    -1,   252,   253,   254,   255,    -1,
      -1,   258,   259,   260,   261,   262,    -1,   264,   265,    -1,
      -1,   268,   269,   270,    -1,    -1,   273,    -1,   275,   276,
     277,    -1,   279,   280,   281,   282,   283,   284,   285,   286,
     287,    -1,   289,   290,    -1,   292,   293,    -1,   295,   296,
     297,    -1,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,    -1,   314,   315,   316,
     317,   318,   319,   320,   321,   322,   323,   324,   325,    -1,
     327,   328,   329,   330,   331,   332,    -1,   334,   335,   336,
     337,   338,   339,   340,   341,   342,    -1,   344,   345,   346,
     347,   348,    -1,   350,    -1,   352,   353,   354,   355,   356,
     357,   358,   359,    -1,   361,   362,   363,   364,   365,   366,
     367,   368,   369,   370,   371,   372,    -1,    -1,   375,   376,
      -1,   378,   379,   380,   381,   382,   383,   384,    -1,   386,
     387,    -1,    -1,   390,   391,    -1,   393,    -1,    -1,   396,
     397,   398,   399,   400,   401,   402,    -1,    -1,   405,   406,
     407,   408,   409,    -1,    -1,   412,   413,   414,   415,   416,
      -1,   418,    -1,   420,   421,   422,   423,   424,   425,    -1,
      -1,   428,    -1,    -1,   431,   432,   433,   434,   435,   436,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,   448,   449,   450
};

/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
   symbol of state STATE-NUM.  */
static const yytype_uint16 yystos[] =
{
       0,    18,    28,    30,    31,    46,    66,    77,    88,    90,
     107,   130,   136,   144,   146,   224,   292,   295,   323,   331,
     343,   350,   354,   364,   377,   412,   417,   430,   453,   467,
     475,   476,   477,   478,   489,   490,   492,   496,   510,   511,
     513,   515,   522,   524,   570,   576,   577,   594,   595,   596,
     597,   598,   599,   636,   753,   756,   759,   766,   767,   768,
     775,   779,   785,   787,   792,   796,   797,   800,   802,   804,
     390,   433,   523,   188,   337,   344,   377,   423,   523,   523,
      49,   467,   589,   167,   225,   271,   337,   381,   383,   404,
     407,   568,   765,     3,    18,    19,    20,    21,    22,    23,
      24,    25,    26,    27,    28,    29,    37,    38,    40,    41,
      42,    44,    45,    46,    47,    48,    50,    51,    53,    54,
      55,    56,    57,    60,    61,    62,    63,    64,    66,    67,
      68,    69,    70,    74,    75,    76,    77,    78,    80,    81,
      82,    84,    85,    86,    87,    88,    89,    92,    93,    94,
     102,   103,   104,   105,   106,   107,   108,   109,   110,   112,
     114,   115,   116,   117,   118,   119,   121,   122,   123,   124,
     127,   128,   129,   130,   131,   133,   134,   135,   137,   138,
     139,   141,   142,   143,   144,   145,   146,   147,   148,   149,
     151,   153,   154,   155,   156,   158,   160,   164,   165,   166,
     167,   169,   170,   172,   173,   175,   176,   177,   178,   179,
     181,   182,   183,   184,   186,   187,   188,   189,   190,   191,
     193,   195,   196,   197,   198,   199,   200,   201,   203,   205,
     208,   210,   211,   212,   213,   214,   217,   218,   220,   223,
     224,   225,   228,   229,   230,   231,   232,   233,   234,   235,
     236,   237,   238,   239,   240,   241,   242,   243,   244,   246,
     247,   248,   249,   250,   252,   253,   255,   257,   258,   259,
     260,   261,   262,   264,   265,   268,   269,   270,   273,   274,
     276,   278,   279,   280,   281,   282,   283,   284,   285,   286,
     287,   289,   290,   291,   292,   293,   294,   295,   296,   297,
     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
     309,   310,   311,   312,   314,   315,   316,   317,   318,   319,
     320,   321,   322,   323,   324,   325,   327,   328,   330,   331,
     332,   333,   334,   335,   336,   337,   338,   339,   340,   341,
     342,   344,   345,   346,   347,   348,   350,   351,   352,   353,
     354,   356,   357,   358,   359,   361,   362,   363,   364,   365,
     366,   367,   368,   369,   370,   371,   372,   373,   375,   376,
     378,   380,   381,   382,   383,   384,   386,   387,   390,   391,
     392,   393,   394,   396,   397,   398,   399,   400,   401,   402,
     405,   406,   407,   408,   409,   412,   413,   414,   415,   416,
     417,   418,   420,   422,   423,   424,   425,   428,   431,   432,
     433,   434,   435,   436,   437,   438,   439,   440,   441,   442,
     443,   444,   445,   446,   447,   448,   449,   450,   740,   746,
     807,   808,    20,    72,    87,   139,   147,   159,   188,   234,
     290,   304,   335,   337,   344,   347,   366,   377,   384,   393,
     423,   571,   572,   575,   523,   295,   740,    90,   421,   467,
     492,   576,   594,   771,   775,   792,   804,     5,   745,   786,
     746,   740,    26,   386,   390,   746,   798,   799,   801,   523,
      26,   125,   606,   607,   225,   337,   348,   386,   780,   781,
     801,    26,   386,   390,   801,   523,   267,   647,   738,   746,
     163,   467,   789,   467,   311,   600,   601,   740,   600,   595,
     596,   599,     0,   470,   116,   198,   409,   140,   202,   272,
     403,   608,   609,   595,   597,   598,   471,   421,   769,   179,
     738,   740,   179,   738,   179,   647,   179,   738,   492,   576,
     594,   755,   792,   738,   381,   383,   381,   383,   321,   179,
     746,   311,   344,   377,   423,   188,    26,   740,   236,   393,
     104,   377,   423,   340,   179,   573,   746,   748,   179,   739,
     740,   179,   740,   467,   514,   568,   771,     3,    43,    49,
      72,    79,    91,    98,   161,   163,   180,   194,   206,   207,
     209,   219,   221,   245,   254,   275,   277,   329,   355,   379,
     417,   421,   772,   774,   775,   777,   778,   807,   808,   809,
     769,   456,   467,   467,   754,   450,   208,   469,   266,     3,
       4,     6,     7,     8,     9,    10,    48,    50,    51,    58,
      59,    62,    63,    70,    72,    95,    96,    97,    98,    99,
     100,   101,   108,   109,   111,   129,   145,   149,   150,   155,
     170,   200,   201,   203,   218,   226,   227,   244,   246,   251,
     256,   257,   259,   268,   278,   291,   308,   333,   349,   358,
     373,   386,   387,   392,   394,   395,   410,   418,   451,   458,
     459,   460,   467,   472,   595,   662,   665,   668,   669,   670,
     672,   673,   674,   675,   677,   678,   682,   684,   685,   686,
     688,   701,   705,   723,   728,   735,   736,   742,   743,   744,
     745,   746,   747,   807,   809,   734,   735,   780,   745,   780,
     450,   162,   388,   456,   450,   208,   467,   738,   460,   465,
     469,   729,   731,     3,   161,   163,   421,   775,   788,   790,
     161,   791,   682,   709,   600,   471,   467,   750,   468,   468,
     477,   162,   204,   647,   793,    26,   125,   605,   605,    53,
     605,   152,   157,   222,   263,   614,   616,   617,   629,   631,
     632,   633,   608,   609,   467,   738,   145,    22,    28,   130,
     270,   319,   323,   350,   414,   483,   486,   487,   319,   145,
      35,    54,   103,   187,   235,   238,   249,   280,   319,   324,
     344,   350,   364,   486,   516,   519,   145,   319,   350,   486,
     145,   319,   350,   486,   468,   467,   558,   568,   251,   757,
     423,   179,   738,   179,   738,   806,   738,    79,   762,   434,
      80,   122,   283,   382,   145,    56,   325,   471,   574,   469,
     749,   145,   471,   574,   145,   266,   709,   377,   468,   471,
       4,   150,   266,   395,   458,   459,   518,   521,   744,   745,
     770,   772,   773,   776,   771,   518,   776,   782,   784,   682,
     710,   711,   747,   751,     3,    48,    50,    51,    62,    63,
     108,   109,   155,   200,   201,   203,   244,   246,   259,   308,
     351,   358,   386,   387,   418,   659,   661,   663,   665,   667,
     669,   670,   671,   673,   674,   677,   678,   712,   747,   807,
      35,   220,   746,   467,   732,   420,   676,   682,   727,   467,
     676,   676,   467,   157,   467,   467,   467,   664,   664,   294,
     595,   467,   467,   666,   467,   467,   467,   467,    62,    63,
     676,   682,   467,   664,   467,   467,   467,   467,   467,   432,
     453,   467,   679,   467,   679,   467,   467,   682,   682,   682,
     595,   682,   709,   732,   731,   745,   467,   467,   745,     3,
       8,    11,    15,    16,    17,    32,    35,    40,    47,    71,
     180,   185,   206,   207,   221,   251,   254,   268,   271,   355,
     451,   454,   455,   456,   458,   459,   460,   461,   462,   463,
     703,   704,   705,   707,   431,   689,   277,   682,   204,   471,
     602,   467,   745,   731,   602,     3,   111,   225,   518,   678,
     745,   783,    94,   111,   784,   111,   784,   220,   738,   682,
     730,     3,    26,    30,    31,    32,    33,    34,    35,    36,
      39,    52,    58,    59,    65,    71,    73,    83,    90,    95,
      96,    97,    99,   100,   101,   111,   113,   120,   125,   126,
     132,   136,   140,   150,   152,   157,   159,   162,   168,   171,
     174,   185,   192,   202,   204,   215,   216,   222,   226,   227,
     251,   256,   263,   266,   267,   271,   272,   288,   298,   313,
     326,   343,   349,   360,   374,   377,   385,   388,   389,   395,
     403,   404,   410,   411,   419,   426,   427,   429,   430,   460,
     741,   752,   807,   808,   809,   810,   729,   468,   471,   769,
     468,   471,   601,   739,    35,   793,   494,   738,    35,   746,
     350,   597,   597,   610,   611,   682,   597,   154,   248,   623,
     210,   249,   307,   353,   409,    26,   618,   682,   458,   459,
     619,   620,   682,   684,   629,   630,   617,   616,   614,   615,
     157,   632,   261,   634,   614,   629,   709,   750,   738,    65,
      73,    83,   159,   179,   298,   404,   539,   549,   564,   746,
      73,    83,   491,    83,   491,   467,   388,   467,   537,   231,
     407,   537,    83,   471,   388,   738,   661,   518,    53,   520,
     518,   518,   103,   235,   238,    53,   388,   430,   453,   517,
     242,   337,   517,   519,   647,    83,   388,   491,   337,   738,
     388,   337,   388,   557,   562,   746,   430,   587,   311,   423,
     145,    90,   511,   524,   758,   759,   802,   738,   251,   512,
     516,   251,   467,   558,    35,   558,   179,   552,   746,   763,
     573,   748,   741,   469,   739,   740,   740,   748,   468,   179,
     738,   806,   771,   777,     4,   744,     4,   744,   471,   468,
     471,    13,    14,   661,    34,   660,   106,   177,   237,   240,
     341,   448,   467,   680,   681,   468,   471,   664,   749,   755,
     709,   729,   467,   426,   724,   725,   682,   709,   467,   744,
     744,   709,     3,   106,   177,   237,   240,   341,   448,   713,
     714,   745,   744,   709,   709,   744,   744,   676,   676,   682,
       8,    15,    16,    17,   454,   455,   456,   458,   459,   460,
     461,   462,   463,   703,   708,   746,   682,   715,   458,   459,
     467,   683,   684,   705,   717,   468,   709,   682,   709,   718,
     386,   386,   744,   744,   682,    52,   162,   216,   389,   682,
     709,   721,   468,   471,   744,   472,   744,   680,   659,   682,
     682,   682,   682,   752,   386,    39,   374,   733,   748,   682,
     467,   595,   722,   125,   150,   251,   256,   261,   395,   405,
     682,   256,   467,   682,   388,    47,   180,   185,   221,   355,
     682,   682,   682,   682,   682,   682,   682,   682,   682,   682,
      26,    33,   360,   702,   171,   153,   690,   333,   467,   701,
     167,   225,   377,   381,   383,   407,   603,   738,   736,   162,
     637,    26,   125,   419,   460,   468,   710,   637,   467,   745,
     468,   466,   473,   738,   788,   738,   796,   682,   468,   467,
     411,   795,   111,   279,   467,   493,   594,    35,   746,   467,
     498,   507,   509,   746,   471,    36,   120,   411,   612,   333,
     334,   458,   459,   620,   622,   684,   353,   210,   267,   471,
       4,   621,   744,   621,   333,   334,   622,   737,   738,   255,
     357,   635,   630,   615,   468,   319,   486,   467,   179,   549,
     740,   210,   251,   210,   411,   467,   542,   659,   740,   746,
     179,   740,   179,   746,    22,   130,   350,   482,   485,   532,
     547,   752,   740,   541,   561,   752,   740,   483,   740,   319,
     350,   486,   516,   518,   748,   740,   518,   748,   740,   518,
     319,   350,   486,   740,   740,   740,   740,   319,   350,   486,
     740,   740,   303,   583,   468,   471,   264,   162,   388,   578,
     423,   738,   746,   568,   467,   145,   145,   221,   539,   549,
     553,   556,   565,   567,   746,   430,   432,   544,   144,   594,
     430,   764,   251,   266,   574,   741,   574,   266,   574,   251,
      35,   782,   711,   682,   682,    34,   660,   465,   465,   388,
     388,   388,   467,   388,   744,   659,   664,   468,   709,   682,
     132,   725,   726,    35,   468,   682,   468,   468,   468,   468,
     162,   468,   468,   468,   468,   468,   471,   468,   469,   288,
     716,   468,   683,   683,   682,    11,    15,    16,    17,   185,
     206,   268,   454,   455,   456,   458,   459,   460,   461,   462,
     463,   705,   683,   468,   468,   157,   162,   719,   720,   468,
     450,   450,   468,   468,    35,   721,   709,   721,   721,   162,
     468,   732,   682,   468,   468,   468,   450,   683,   683,   138,
     709,   162,   125,   150,   256,   261,   395,   405,   467,   138,
     708,   682,   374,   733,   682,   722,   682,   388,   467,   595,
     467,   467,   276,   694,   381,   383,   381,   383,   738,   377,
     604,   604,   604,   215,   334,   467,   595,   638,   639,   640,
     647,   650,   685,   687,   688,   742,   746,   427,   655,   710,
     710,   711,   468,   471,   608,   609,   655,   744,   680,   682,
     730,   750,   755,   638,   427,   794,   417,   376,   410,   502,
     497,   506,   746,   266,   499,   746,   503,   509,   471,   637,
     456,   732,   611,   268,   703,   706,   452,   613,     4,   744,
     622,   267,   409,   619,   471,   230,   388,   682,   251,   564,
     467,   145,   467,   542,   188,   562,   525,   270,   535,   525,
      22,   130,   323,   324,   350,   479,   480,   481,   487,   488,
     145,   574,   145,   574,   532,   547,   532,   468,   471,   528,
     745,   468,   471,   456,   469,   388,   337,    83,   388,   491,
     337,   388,   388,   388,   337,   367,   368,   592,   745,   557,
     583,   738,   558,   757,   377,   562,   738,   738,   806,   738,
     468,   471,   264,   537,   264,   266,   536,   740,   430,   805,
     537,    35,   145,   738,   748,   145,   465,   744,   466,   744,
     177,   237,   681,   237,   681,   681,   744,   240,   468,   468,
     385,   682,   136,   659,   468,   682,   682,   708,   682,   719,
     659,   683,   683,   683,   683,   125,   251,   261,   683,   683,
     683,   683,   683,   683,   683,   683,   683,   683,   682,   682,
     720,   719,   679,   679,   659,   468,   468,   468,   709,   468,
     472,   745,   682,    32,    32,   682,   468,   682,   162,   467,
     712,   682,   468,   138,   683,   683,   138,   138,   682,   682,
     609,   427,   467,   695,   746,   604,   604,   604,   604,   738,
     738,   738,   595,   650,   746,   162,   595,   639,   640,    35,
     641,   642,   746,   471,    91,   163,   194,   209,   219,   245,
     329,   644,   642,    35,   641,   643,   746,   453,   654,   467,
     731,   682,   171,   624,   608,   608,   608,   419,   468,   624,
     468,   466,   468,   682,   326,   501,   416,   468,   471,   732,
      81,   501,   468,   471,   498,   794,   682,   467,   613,   154,
     214,   267,   738,   740,   468,   145,   562,   549,   562,   525,
     552,   468,   113,   192,   249,   251,   548,   467,   559,   166,
     111,   178,   251,   537,   517,   104,   111,   166,   251,   366,
     369,   519,   537,   350,   481,   398,   740,   746,   485,   561,
     250,   268,   351,   458,   459,   518,   526,   563,   659,   706,
     745,   747,   810,   752,   740,   740,   740,   740,   740,   740,
     740,   740,   740,   740,   517,   592,   467,   764,   179,   738,
     468,   512,   467,    35,   546,   544,   553,    77,   514,   104,
     249,   594,   552,   411,   761,   574,   806,   744,   466,   466,
     468,   682,   468,   468,   720,   162,   125,   261,   467,   468,
     680,   682,   682,   682,   712,   468,   682,    32,    32,   682,
     682,   138,   468,   468,   682,   696,   746,   738,   738,   738,
     738,   642,   643,   731,   467,   468,   746,   467,   639,   209,
     275,   645,   639,   645,   209,   644,   645,   209,   379,   648,
     467,   746,   467,   273,   710,    53,   174,   628,   468,   468,
     468,   711,   745,   628,   745,   735,   594,   279,   594,   497,
     266,   467,   495,   456,   509,   501,   708,   525,   549,   468,
     468,   430,   555,   114,   181,   190,   113,   413,   532,   550,
      65,    71,    83,   111,   113,   166,   192,   251,   256,   298,
     313,   404,   530,   531,   543,    29,    53,   569,   179,   256,
     518,   682,   569,   256,   458,   459,   521,   746,   659,   574,
     574,   747,   749,   456,   388,   388,   467,   584,   588,   411,
     579,   581,   562,    35,   251,   467,   764,   556,   144,   594,
     142,   186,   536,   116,   130,   297,   805,   104,   430,   803,
     266,   746,   760,   467,    35,   466,   683,   162,   467,   712,
     468,   682,   682,   682,   468,   285,   697,   651,   652,   687,
     641,   467,   739,   639,   266,   411,   646,   639,   209,   639,
     742,   656,   657,   746,   467,   656,   746,   608,   467,   625,
     626,   627,   682,   682,   429,   691,   608,   691,   502,    83,
     467,   500,   508,   687,   746,   126,   682,   468,   313,   555,
     467,   545,   525,   468,   471,   467,   748,   740,   683,   569,
     114,   181,   113,   256,   210,   738,   555,   111,    35,   145,
      71,   658,   749,   462,   526,   740,   740,   586,   593,   752,
      49,    92,   117,   134,   138,   158,   161,   175,   256,   264,
     305,   590,   517,   118,   468,   594,   145,    35,   468,   740,
     805,    26,    76,    84,   112,   178,   189,   366,   369,   540,
     540,   334,   334,    57,    65,   225,   738,   508,   683,   712,
     468,    53,   608,   468,   471,    35,   653,   739,   468,   682,
     467,   639,   646,   467,   468,   471,   659,   656,   468,   468,
     468,   471,   692,   693,   746,   468,   416,   740,   682,   468,
     471,    71,   504,   504,   252,   409,   738,   525,   551,   554,
     752,   532,   682,   251,   531,    35,   555,   558,   178,   748,
     411,   484,   462,   398,   468,   471,   460,   467,   518,   585,
     776,    35,   582,   745,   582,   251,   256,   305,   582,   582,
     584,   745,   764,   803,   738,   594,   544,   514,    65,   269,
      65,   761,   468,   468,   709,   306,   334,   698,   654,   651,
     467,   468,   739,   709,   657,   658,   468,   626,   471,    35,
     594,   468,   655,   500,   748,   505,   748,   505,   350,   558,
     468,   471,   456,   468,   178,   233,   566,   467,   527,   682,
     398,   586,   580,   591,   776,   745,   745,   256,   562,   460,
     562,   745,   745,    35,   467,   803,   536,   805,   269,   269,
     467,   764,    47,    94,   400,   682,   699,   700,   699,   468,
     656,   468,   468,   693,   695,   504,   612,   612,   507,   566,
     554,   526,   249,   538,   527,   163,   284,   356,   266,   533,
     534,   560,   516,   468,   471,   562,   594,   508,   655,   700,
     333,   156,   293,   156,   293,   468,   320,   649,   505,   613,
     613,   655,   534,   190,   116,   409,   266,   560,   266,   533,
     468,   591,   803,   468,    32,   467,   612,   525,    56,   249,
     325,   350,   529,   529,   764,   700,   682,   613,    21,   111,
     256,   655,   468
};

#define yyerrok		(yyerrstatus = 0)
#define yyclearin	(yychar = YYEMPTY)
#define YYEMPTY		(-2)
#define YYEOF		0

#define YYACCEPT	goto yyacceptlab
#define YYABORT		goto yyabortlab
#define YYERROR		goto yyerrorlab


/* Like YYERROR except do call yyerror.  This remains here temporarily
   to ease the transition to the new meaning of YYERROR, for GCC.
   Once GCC version 2 has supplanted version 1, this can go.  */

#define YYFAIL		goto yyerrlab

#define YYRECOVERING()  (!!yyerrstatus)

#define YYBACKUP(Token, Value)					\
do								\
  if (yychar == YYEMPTY && yylen == 1)				\
    {								\
      yychar = (Token);						\
      yylval = (Value);						\
      yytoken = YYTRANSLATE (yychar);				\
      YYPOPSTACK (1);						\
      goto yybackup;						\
    }								\
  else								\
    {								\
      yyerror (&yylloc, yyscanner, YY_("syntax error: cannot back up")); \
      YYERROR;							\
    }								\
while (YYID (0))


#define YYTERROR	1
#define YYERRCODE	256


/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
   If N is 0, then set CURRENT to the empty location which ends
   the previous symbol: RHS[0] (always defined).  */

#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N)				\
    do									\
      if (YYID (N))                                                    \
	{								\
	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
	}								\
      else								\
	{								\
	  (Current).first_line   = (Current).last_line   =		\
	    YYRHSLOC (Rhs, 0).last_line;				\
	  (Current).first_column = (Current).last_column =		\
	    YYRHSLOC (Rhs, 0).last_column;				\
	}								\
    while (YYID (0))
#endif


/* YY_LOCATION_PRINT -- Print the location on the stream.
   This macro was not mandated originally: define only if we know
   we won't break user code: when these are the locations we know.  */

#ifndef YY_LOCATION_PRINT
# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
#  define YY_LOCATION_PRINT(File, Loc)			\
     fprintf (File, "%d.%d-%d.%d",			\
	      (Loc).first_line, (Loc).first_column,	\
	      (Loc).last_line,  (Loc).last_column)
# else
#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
#endif


/* YYLEX -- calling `yylex' with the right arguments.  */

#ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
#else
# define YYLEX yylex (&yylval, &yylloc, yyscanner)
#endif

/* Enable debugging if requested.  */
#if YYDEBUG

# ifndef YYFPRINTF
#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
#  define YYFPRINTF fprintf
# endif

# define YYDPRINTF(Args)			\
do {						\
  if (yydebug)					\
    YYFPRINTF Args;				\
} while (YYID (0))

# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
do {									  \
  if (yydebug)								  \
    {									  \
      YYFPRINTF (stderr, "%s ", Title);					  \
      yy_symbol_print (stderr,						  \
		  Type, Value, Location, yyscanner); \
      YYFPRINTF (stderr, "\n");						  \
    }									  \
} while (YYID (0))


/*--------------------------------.
| Print this symbol on YYOUTPUT.  |
`--------------------------------*/

/*ARGSUSED*/
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static void
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, core_yyscan_t yyscanner)
#else
static void
yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, yyscanner)
    FILE *yyoutput;
    int yytype;
    YYSTYPE const * const yyvaluep;
    YYLTYPE const * const yylocationp;
    core_yyscan_t yyscanner;
#endif
{
  if (!yyvaluep)
    return;
  YYUSE (yylocationp);
  YYUSE (yyscanner);
# ifdef YYPRINT
  if (yytype < YYNTOKENS)
    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
# else
  YYUSE (yyoutput);
# endif
  switch (yytype)
    {
      default:
	break;
    }
}


/*--------------------------------.
| Print this symbol on YYOUTPUT.  |
`--------------------------------*/

#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static void
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, core_yyscan_t yyscanner)
#else
static void
yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, yyscanner)
    FILE *yyoutput;
    int yytype;
    YYSTYPE const * const yyvaluep;
    YYLTYPE const * const yylocationp;
    core_yyscan_t yyscanner;
#endif
{
  if (yytype < YYNTOKENS)
    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
  else
    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);

  YY_LOCATION_PRINT (yyoutput, *yylocationp);
  YYFPRINTF (yyoutput, ": ");
  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, yyscanner);
  YYFPRINTF (yyoutput, ")");
}

/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included).                                                   |
`------------------------------------------------------------------*/

#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static void
yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
yy_stack_print (bottom, top)
    yytype_int16 *bottom;
    yytype_int16 *top;
#endif
{
  YYFPRINTF (stderr, "Stack now");
  for (; bottom <= top; ++bottom)
    YYFPRINTF (stderr, " %d", *bottom);
  YYFPRINTF (stderr, "\n");
}

# define YY_STACK_PRINT(Bottom, Top)				\
do {								\
  if (yydebug)							\
    yy_stack_print ((Bottom), (Top));				\
} while (YYID (0))


/*------------------------------------------------.
| Report that the YYRULE is going to be reduced.  |
`------------------------------------------------*/

#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static void
yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, core_yyscan_t yyscanner)
#else
static void
yy_reduce_print (yyvsp, yylsp, yyrule, yyscanner)
    YYSTYPE *yyvsp;
    YYLTYPE *yylsp;
    int yyrule;
    core_yyscan_t yyscanner;
#endif
{
  int yynrhs = yyr2[yyrule];
  int yyi;
  unsigned long int yylno = yyrline[yyrule];
  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
	     yyrule - 1, yylno);
  /* The symbols being reduced.  */
  for (yyi = 0; yyi < yynrhs; yyi++)
    {
      fprintf (stderr, "   $%d = ", yyi + 1);
      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
		       &(yyvsp[(yyi + 1) - (yynrhs)])
		       , &(yylsp[(yyi + 1) - (yynrhs)])		       , yyscanner);
      fprintf (stderr, "\n");
    }
}

# define YY_REDUCE_PRINT(Rule)		\
do {					\
  if (yydebug)				\
    yy_reduce_print (yyvsp, yylsp, Rule, yyscanner); \
} while (YYID (0))

/* Nonzero means print parse trace.  It is left uninitialized so that
   multiple parsers can coexist.  */
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */


/* YYINITDEPTH -- initial size of the parser's stacks.  */
#ifndef	YYINITDEPTH
# define YYINITDEPTH 200
#endif

/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
   if the built-in stack extension method is used).

   Do not make this value too large; the results are undefined if
   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
   evaluated with infinite-precision integer arithmetic.  */

#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif



#if YYERROR_VERBOSE

# ifndef yystrlen
#  if defined __GLIBC__ && defined _STRING_H
#   define yystrlen strlen
#  else
/* Return the length of YYSTR.  */
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
yystrlen (const char *yystr)
#else
static YYSIZE_T
yystrlen (yystr)
    const char *yystr;
#endif
{
  YYSIZE_T yylen;
  for (yylen = 0; yystr[yylen]; yylen++)
    continue;
  return yylen;
}
#  endif
# endif

# ifndef yystpcpy
#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
#   define yystpcpy stpcpy
#  else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
   YYDEST.  */
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static char *
yystpcpy (char *yydest, const char *yysrc)
#else
static char *
yystpcpy (yydest, yysrc)
    char *yydest;
    const char *yysrc;
#endif
{
  char *yyd = yydest;
  const char *yys = yysrc;

  while ((*yyd++ = *yys++) != '\0')
    continue;

  return yyd - 1;
}
#  endif
# endif

# ifndef yytnamerr
/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
   quotes and backslashes, so that it's suitable for yyerror.  The
   heuristic is that double-quoting is unnecessary unless the string
   contains an apostrophe, a comma, or backslash (other than
   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
   null, do not copy; instead, return the length of what the result
   would have been.  */
static YYSIZE_T
yytnamerr (char *yyres, const char *yystr)
{
  if (*yystr == '"')
    {
      YYSIZE_T yyn = 0;
      char const *yyp = yystr;

      for (;;)
	switch (*++yyp)
	  {
	  case '\'':
	  case ',':
	    goto do_not_strip_quotes;

	  case '\\':
	    if (*++yyp != '\\')
	      goto do_not_strip_quotes;
	    /* Fall through.  */
	  default:
	    if (yyres)
	      yyres[yyn] = *yyp;
	    yyn++;
	    break;

	  case '"':
	    if (yyres)
	      yyres[yyn] = '\0';
	    return yyn;
	  }
    do_not_strip_quotes: ;
    }

  if (! yyres)
    return yystrlen (yystr);

  return yystpcpy (yyres, yystr) - yyres;
}
# endif

/* Copy into YYRESULT an error message about the unexpected token
   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
   including the terminating null byte.  If YYRESULT is null, do not
   copy anything; just return the number of bytes that would be
   copied.  As a special case, return 0 if an ordinary "syntax error"
   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
   size calculation.  */
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
{
  int yyn = yypact[yystate];

  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
    return 0;
  else
    {
      int yytype = YYTRANSLATE (yychar);
      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
      YYSIZE_T yysize = yysize0;
      YYSIZE_T yysize1;
      int yysize_overflow = 0;
      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
      int yyx;

# if 0
      /* This is so xgettext sees the translatable formats that are
	 constructed on the fly.  */
      YY_("syntax error, unexpected %s");
      YY_("syntax error, unexpected %s, expecting %s");
      YY_("syntax error, unexpected %s, expecting %s or %s");
      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
      char *yyfmt;
      char const *yyf;
      static char const yyunexpected[] = "syntax error, unexpected %s";
      static char const yyexpecting[] = ", expecting %s";
      static char const yyor[] = " or %s";
      char yyformat[sizeof yyunexpected
		    + sizeof yyexpecting - 1
		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
		       * (sizeof yyor - 1))];
      char const *yyprefix = yyexpecting;

      /* Start YYX at -YYN if negative to avoid negative indexes in
	 YYCHECK.  */
      int yyxbegin = yyn < 0 ? -yyn : 0;

      /* Stay within bounds of both yycheck and yytname.  */
      int yychecklim = YYLAST - yyn + 1;
      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
      int yycount = 1;

      yyarg[0] = yytname[yytype];
      yyfmt = yystpcpy (yyformat, yyunexpected);

      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
	  {
	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
	      {
		yycount = 1;
		yysize = yysize0;
		yyformat[sizeof yyunexpected - 1] = '\0';
		break;
	      }
	    yyarg[yycount++] = yytname[yyx];
	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
	    yysize_overflow |= (yysize1 < yysize);
	    yysize = yysize1;
	    yyfmt = yystpcpy (yyfmt, yyprefix);
	    yyprefix = yyor;
	  }

      yyf = YY_(yyformat);
      yysize1 = yysize + yystrlen (yyf);
      yysize_overflow |= (yysize1 < yysize);
      yysize = yysize1;

      if (yysize_overflow)
	return YYSIZE_MAXIMUM;

      if (yyresult)
	{
	  /* Avoid sprintf, as that infringes on the user's name space.
	     Don't have undefined behavior even if the translation
	     produced a string with the wrong number of "%s"s.  */
	  char *yyp = yyresult;
	  int yyi = 0;
	  while ((*yyp = *yyf) != '\0')
	    {
	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
		{
		  yyp += yytnamerr (yyp, yyarg[yyi++]);
		  yyf += 2;
		}
	      else
		{
		  yyp++;
		  yyf++;
		}
	    }
	}
      return yysize;
    }
}
#endif /* YYERROR_VERBOSE */


/*-----------------------------------------------.
| Release the memory associated to this symbol.  |
`-----------------------------------------------*/

/*ARGSUSED*/
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, core_yyscan_t yyscanner)
#else
static void
yydestruct (yymsg, yytype, yyvaluep, yylocationp, yyscanner)
    const char *yymsg;
    int yytype;
    YYSTYPE *yyvaluep;
    YYLTYPE *yylocationp;
    core_yyscan_t yyscanner;
#endif
{
  YYUSE (yyvaluep);
  YYUSE (yylocationp);
  YYUSE (yyscanner);

  if (!yymsg)
    yymsg = "Deleting";
  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);

  switch (yytype)
    {

      default:
	break;
    }
}


/* Prevent warnings from -Wmissing-prototypes.  */

#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (core_yyscan_t yyscanner);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */






/*----------.
| yyparse.  |
`----------*/

#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
int
yyparse (void *YYPARSE_PARAM)
#else
int
yyparse (YYPARSE_PARAM)
    void *YYPARSE_PARAM;
#endif
#else /* ! YYPARSE_PARAM */
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
int
yyparse (core_yyscan_t yyscanner)
#else
int
yyparse (yyscanner)
    core_yyscan_t yyscanner;
#endif
#endif
{
  /* The look-ahead symbol.  */
int yychar;

/* The semantic value of the look-ahead symbol.  */
YYSTYPE yylval;

/* Number of syntax errors so far.  */
int yynerrs;
/* Location data for the look-ahead symbol.  */
YYLTYPE yylloc;

  int yystate;
  int yyn;
  int yyresult;
  /* Number of tokens to shift before error messages enabled.  */
  int yyerrstatus;
  /* Look-ahead token as an internal (translated) token number.  */
  int yytoken = 0;
#if YYERROR_VERBOSE
  /* Buffer for error messages, and its allocated size.  */
  char yymsgbuf[128];
  char *yymsg = yymsgbuf;
  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif

  /* Three stacks and their tools:
     `yyss': related to states,
     `yyvs': related to semantic values,
     `yyls': related to locations.

     Refer to the stacks thru separate pointers, to allow yyoverflow
     to reallocate them elsewhere.  */

  /* The state stack.  */
  yytype_int16 yyssa[YYINITDEPTH];
  yytype_int16 *yyss = yyssa;
  yytype_int16 *yyssp;

  /* The semantic value stack.  */
  YYSTYPE yyvsa[YYINITDEPTH];
  YYSTYPE *yyvs = yyvsa;
  YYSTYPE *yyvsp;

  /* The location stack.  */
  YYLTYPE yylsa[YYINITDEPTH];
  YYLTYPE *yyls = yylsa;
  YYLTYPE *yylsp;
  /* The locations where the error started and ended.  */
  YYLTYPE yyerror_range[2];

#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))

  YYSIZE_T yystacksize = YYINITDEPTH;

  /* The variables used to return semantic value and location from the
     action routines.  */
  YYSTYPE yyval;
  YYLTYPE yyloc;

  /* The number of symbols on the RHS of the reduced rule.
     Keep to zero when no symbol should be popped.  */
  int yylen = 0;

  YYDPRINTF ((stderr, "Starting parse\n"));

  yystate = 0;
  yyerrstatus = 0;
  yynerrs = 0;
  yychar = YYEMPTY;		/* Cause a token to be read.  */

  /* Initialize stack pointers.
     Waste one element of value and location stack
     so that they stay on the same level as the state stack.
     The wasted elements are never initialized.  */

  yyssp = yyss;
  yyvsp = yyvs;
  yylsp = yyls;
#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
  /* Initialize the default location before parsing starts.  */
  yylloc.first_line   = yylloc.last_line   = 1;
  yylloc.first_column = yylloc.last_column = 0;
#endif

  goto yysetstate;

/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate.  |
`------------------------------------------------------------*/
 yynewstate:
  /* In all cases, when you get here, the value and location stacks
     have just been pushed.  So pushing a state here evens the stacks.  */
  yyssp++;

 yysetstate:
  *yyssp = yystate;

  if (yyss + yystacksize - 1 <= yyssp)
    {
      /* Get the current used size of the three stacks, in elements.  */
      YYSIZE_T yysize = yyssp - yyss + 1;

#ifdef yyoverflow
      {
	/* Give user a chance to reallocate the stack.  Use copies of
	   these so that the &'s don't force the real ones into
	   memory.  */
	YYSTYPE *yyvs1 = yyvs;
	yytype_int16 *yyss1 = yyss;
	YYLTYPE *yyls1 = yyls;

	/* Each stack pointer address is followed by the size of the
	   data in use in that stack, in bytes.  This used to be a
	   conditional around just the two extra args, but that might
	   be undefined if yyoverflow is a macro.  */
	yyoverflow (YY_("memory exhausted"),
		    &yyss1, yysize * sizeof (*yyssp),
		    &yyvs1, yysize * sizeof (*yyvsp),
		    &yyls1, yysize * sizeof (*yylsp),
		    &yystacksize);
	yyls = yyls1;
	yyss = yyss1;
	yyvs = yyvs1;
      }
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
      goto yyexhaustedlab;
# else
      /* Extend the stack our own way.  */
      if (YYMAXDEPTH <= yystacksize)
	goto yyexhaustedlab;
      yystacksize *= 2;
      if (YYMAXDEPTH < yystacksize)
	yystacksize = YYMAXDEPTH;

      {
	yytype_int16 *yyss1 = yyss;
	union yyalloc *yyptr =
	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
	if (! yyptr)
	  goto yyexhaustedlab;
	YYSTACK_RELOCATE (yyss);
	YYSTACK_RELOCATE (yyvs);
	YYSTACK_RELOCATE (yyls);
#  undef YYSTACK_RELOCATE
	if (yyss1 != yyssa)
	  YYSTACK_FREE (yyss1);
      }
# endif
#endif /* no yyoverflow */

      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;
      yylsp = yyls + yysize - 1;

      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
		  (unsigned long int) yystacksize));

      if (yyss + yystacksize - 1 <= yyssp)
	YYABORT;
    }

  YYDPRINTF ((stderr, "Entering state %d\n", yystate));

  goto yybackup;

/*-----------.
| yybackup.  |
`-----------*/
yybackup:

  /* Do appropriate processing given the current state.  Read a
     look-ahead token if we need one and don't already have one.  */

  /* First try to decide what to do without reference to look-ahead token.  */
  yyn = yypact[yystate];
  if (yyn == YYPACT_NINF)
    goto yydefault;

  /* Not known => get a look-ahead token if don't already have one.  */

  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
  if (yychar == YYEMPTY)
    {
      YYDPRINTF ((stderr, "Reading a token: "));
      yychar = YYLEX;
    }

  if (yychar <= YYEOF)
    {
      yychar = yytoken = YYEOF;
      YYDPRINTF ((stderr, "Now at end of input.\n"));
    }
  else
    {
      yytoken = YYTRANSLATE (yychar);
      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
    }

  /* If the proper action on seeing token YYTOKEN is to reduce or to
     detect an error, take that action.  */
  yyn += yytoken;
  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (yyn == 0 || yyn == YYTABLE_NINF)
	goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }

  if (yyn == YYFINAL)
    YYACCEPT;

  /* Count tokens shifted since error; after three, turn off error
     status.  */
  if (yyerrstatus)
    yyerrstatus--;

  /* Shift the look-ahead token.  */
  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);

  /* Discard the shifted token unless it is eof.  */
  if (yychar != YYEOF)
    yychar = YYEMPTY;

  yystate = yyn;
  *++yyvsp = yylval;
  *++yylsp = yylloc;
  goto yynewstate;


/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state.  |
`-----------------------------------------------------------*/
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;


/*-----------------------------.
| yyreduce -- Do a reduction.  |
`-----------------------------*/
yyreduce:
  /* yyn is the number of a rule to reduce with.  */
  yylen = yyr2[yyn];

  /* If YYLEN is nonzero, implement the default value of the action:
     `$$ = $1'.

     Otherwise, the following line sets YYVAL to garbage.
     This behavior is undocumented and Bison
     users should not rely upon it.  Assigning to YYVAL
     unconditionally makes the parser a bit smaller, and it avoids a
     GCC warning that YYVAL may be used uninitialized.  */
  yyval = yyvsp[1-yylen];

  /* Default location.  */
  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
  YY_REDUCE_PRINT (yyn);
  switch (yyn)
    {
        case 2:
#line 449 "third_party/libpg_query/grammar/grammar.y"
    {
				pg_yyget_extra(yyscanner)->parsetree = (yyvsp[(1) - (1)].list);
			;}
    break;

  case 3:
#line 465 "third_party/libpg_query/grammar/grammar.y"
    {
					if ((yyvsp[(1) - (3)].list) != NIL)
					{
						/* update length of previous stmt */
						updateRawStmtEnd(llast_node(PGRawStmt, (yyvsp[(1) - (3)].list)), (yylsp[(2) - (3)]));
					}
					if ((yyvsp[(3) - (3)].node) != NULL)
						(yyval.list) = lappend((yyvsp[(1) - (3)].list), makeRawStmt((yyvsp[(3) - (3)].node), (yylsp[(2) - (3)]) + 1));
					else
						(yyval.list) = (yyvsp[(1) - (3)].list);
				;}
    break;

  case 4:
#line 477 "third_party/libpg_query/grammar/grammar.y"
    {
					if ((yyvsp[(1) - (1)].node) != NULL)
						(yyval.list) = list_make1(makeRawStmt((yyvsp[(1) - (1)].node), 0));
					else
						(yyval.list) = NIL;
				;}
    break;

  case 34:
#line 515 "third_party/libpg_query/grammar/grammar.y"
    { (yyval.node) = NULL; ;}
    break;

  case 35:
#line 10 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(3) - (4)].range);
					n->cmds = (yyvsp[(4) - (4)].list);
					n->relkind = PG_OBJECT_TABLE;
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 36:
#line 19 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(5) - (6)].range);
					n->cmds = (yyvsp[(6) - (6)].list);
					n->relkind = PG_OBJECT_TABLE;
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 37:
#line 28 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(3) - (4)].range);
					n->cmds = (yyvsp[(4) - (4)].list);
					n->relkind = PG_OBJECT_INDEX;
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 38:
#line 37 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(5) - (6)].range);
					n->cmds = (yyvsp[(6) - (6)].list);
					n->relkind = PG_OBJECT_INDEX;
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 39:
#line 46 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(3) - (4)].range);
					n->cmds = (yyvsp[(4) - (4)].list);
					n->relkind = PG_OBJECT_SEQUENCE;
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 40:
#line 55 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(5) - (6)].range);
					n->cmds = (yyvsp[(6) - (6)].list);
					n->relkind = PG_OBJECT_SEQUENCE;
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 41:
#line 64 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(3) - (4)].range);
					n->cmds = (yyvsp[(4) - (4)].list);
					n->relkind = PG_OBJECT_VIEW;
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 42:
#line 73 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
					n->relation = (yyvsp[(5) - (6)].range);
					n->cmds = (yyvsp[(6) - (6)].list);
					n->relkind = PG_OBJECT_VIEW;
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 43:
#line 86 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;}
    break;

  case 44:
#line 88 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); ;}
    break;

  case 45:
#line 93 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.node) = (yyvsp[(3) - (3)].node); ;}
    break;

  case 46:
#line 94 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.node) = NULL; ;}
    break;

  case 47:
#line 100 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = makeDefElem("restart", NULL, (yylsp[(1) - (1)]));
				;}
    break;

  case 48:
#line 104 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = makeDefElem("restart", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)]));
				;}
    break;

  case 49:
#line 108 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					if (strcmp((yyvsp[(2) - (2)].defelt)->defname, "as") == 0 ||
						strcmp((yyvsp[(2) - (2)].defelt)->defname, "restart") == 0 ||
						strcmp((yyvsp[(2) - (2)].defelt)->defname, "owned_by") == 0)
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("sequence option \"%s\" not supported here", (yyvsp[(2) - (2)].defelt)->defname),
								 parser_errposition((yylsp[(2) - (2)]))));
					(yyval.defelt) = (yyvsp[(2) - (2)].defelt);
				;}
    break;

  case 50:
#line 119 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = makeDefElem("generated", (PGNode *) makeInteger((yyvsp[(3) - (3)].ival)), (yylsp[(1) - (3)]));
				;}
    break;

  case 51:
#line 127 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
				;}
    break;

  case 52:
#line 131 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
				;}
    break;

  case 53:
#line 140 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_AddColumn;
					n->def = (yyvsp[(2) - (2)].node);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 54:
#line 149 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_AddColumn;
					n->def = (yyvsp[(5) - (5)].node);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 55:
#line 158 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_AddColumn;
					n->def = (yyvsp[(3) - (3)].node);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 56:
#line 167 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_AddColumn;
					n->def = (yyvsp[(6) - (6)].node);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 57:
#line 176 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_ColumnDefault;
					n->name = (yyvsp[(3) - (4)].str);
					n->def = (yyvsp[(4) - (4)].node);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 58:
#line 185 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_DropNotNull;
					n->name = (yyvsp[(3) - (6)].str);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 59:
#line 193 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetNotNull;
					n->name = (yyvsp[(3) - (6)].str);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 60:
#line 201 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetStatistics;
					n->name = (yyvsp[(3) - (6)].str);
					n->def = (PGNode *) makeInteger((yyvsp[(6) - (6)].ival));
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 61:
#line 210 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetOptions;
					n->name = (yyvsp[(3) - (5)].str);
					n->def = (PGNode *) (yyvsp[(5) - (5)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 62:
#line 219 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_ResetOptions;
					n->name = (yyvsp[(3) - (5)].str);
					n->def = (PGNode *) (yyvsp[(5) - (5)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 63:
#line 228 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetStorage;
					n->name = (yyvsp[(3) - (6)].str);
					n->def = (PGNode *) makeString((yyvsp[(6) - (6)].str));
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 64:
#line 237 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					PGConstraint *c = makeNode(PGConstraint);

					c->contype = PG_CONSTR_IDENTITY;
					c->generated_when = (yyvsp[(6) - (9)].ival);
					c->options = (yyvsp[(9) - (9)].list);
					c->location = (yylsp[(5) - (9)]);

					n->subtype = PG_AT_AddIdentity;
					n->name = (yyvsp[(3) - (9)].str);
					n->def = (PGNode *) c;

					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 65:
#line 254 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetIdentity;
					n->name = (yyvsp[(3) - (4)].str);
					n->def = (PGNode *) (yyvsp[(4) - (4)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 66:
#line 263 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = AT_DropIdentity;
					n->name = (yyvsp[(3) - (5)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 67:
#line 272 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = AT_DropIdentity;
					n->name = (yyvsp[(3) - (7)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 68:
#line 281 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_DropColumn;
					n->name = (yyvsp[(5) - (6)].str);
					n->behavior = (yyvsp[(6) - (6)].dbehavior);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 69:
#line 291 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_DropColumn;
					n->name = (yyvsp[(3) - (4)].str);
					n->behavior = (yyvsp[(4) - (4)].dbehavior);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 70:
#line 304 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					PGColumnDef *def = makeNode(PGColumnDef);
					n->subtype = PG_AT_AlterColumnType;
					n->name = (yyvsp[(3) - (8)].str);
					n->def = (PGNode *) def;
					/* We only use these fields of the PGColumnDef node */
					def->typeName = (yyvsp[(6) - (8)].typnam);
					def->collClause = (PGCollateClause *) (yyvsp[(7) - (8)].node);
					def->raw_default = (yyvsp[(8) - (8)].node);
					def->location = (yylsp[(3) - (8)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 71:
#line 319 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_AlterColumnGenericOptions;
					n->name = (yyvsp[(3) - (4)].str);
					n->def = (PGNode *) (yyvsp[(4) - (4)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 72:
#line 328 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_AddConstraint;
					n->def = (yyvsp[(2) - (2)].node);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 73:
#line 336 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					PGConstraint *c = makeNode(PGConstraint);
					n->subtype = PG_AT_AlterConstraint;
					n->def = (PGNode *) c;
					c->contype = PG_CONSTR_FOREIGN; /* others not supported, yet */
					c->conname = (yyvsp[(3) - (4)].str);
					processCASbits((yyvsp[(4) - (4)].ival), (yylsp[(4) - (4)]), "ALTER CONSTRAINT statement",
									&c->deferrable,
									&c->initdeferred,
									NULL, NULL, yyscanner);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 74:
#line 351 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_ValidateConstraint;
					n->name = (yyvsp[(3) - (3)].str);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 75:
#line 359 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_DropConstraint;
					n->name = (yyvsp[(5) - (6)].str);
					n->behavior = (yyvsp[(6) - (6)].dbehavior);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 76:
#line 369 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_DropConstraint;
					n->name = (yyvsp[(3) - (4)].str);
					n->behavior = (yyvsp[(4) - (4)].dbehavior);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 77:
#line 379 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetLogged;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 78:
#line 386 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetUnLogged;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 79:
#line 393 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_SetRelOptions;
					n->def = (PGNode *)(yyvsp[(2) - (2)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 80:
#line 401 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_ResetRelOptions;
					n->def = (PGNode *)(yyvsp[(2) - (2)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 81:
#line 408 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
					n->subtype = PG_AT_GenericOptions;
					n->def = (PGNode *)(yyvsp[(1) - (1)].list);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 82:
#line 418 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 83:
#line 419 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.node) = NULL; ;}
    break;

  case 84:
#line 425 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = (yyvsp[(1) - (1)].defelt);
				;}
    break;

  case 85:
#line 429 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = (yyvsp[(2) - (2)].defelt);
					(yyval.defelt)->defaction = PG_DEFELEM_SET;
				;}
    break;

  case 86:
#line 434 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = (yyvsp[(2) - (2)].defelt);
					(yyval.defelt)->defaction = PG_DEFELEM_ADD;
				;}
    break;

  case 87:
#line 439 "third_party/libpg_query/grammar/statements/alter_table.y"
    {
					(yyval.defelt) = makeDefElemExtended(NULL, (yyvsp[(2) - (2)].str), NULL, DEFELEM_DROP, (yylsp[(2) - (2)]));
				;}
    break;

  case 88:
#line 446 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 89:
#line 447 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;}
    break;

  case 90:
#line 452 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 91:
#line 456 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.ival) = 1; ;}
    break;

  case 92:
#line 457 "third_party/libpg_query/grammar/statements/alter_table.y"
    { (yyval.ival) = 0; ;}
    break;

  case 93:
#line 8 "third_party/libpg_query/grammar/statements/deallocate.y"
    {
						PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
						n->name = (yyvsp[(2) - (2)].str);
						(yyval.node) = (PGNode *) n;
					;}
    break;

  case 94:
#line 14 "third_party/libpg_query/grammar/statements/deallocate.y"
    {
						PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
						n->name = (yyvsp[(3) - (3)].str);
						(yyval.node) = (PGNode *) n;
					;}
    break;

  case 95:
#line 20 "third_party/libpg_query/grammar/statements/deallocate.y"
    {
						PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
						n->name = NULL;
						(yyval.node) = (PGNode *) n;
					;}
    break;

  case 96:
#line 26 "third_party/libpg_query/grammar/statements/deallocate.y"
    {
						PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
						n->name = NULL;
						(yyval.node) = (PGNode *) n;
					;}
    break;

  case 97:
#line 7 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_SCHEMA;
					n->subname = (yyvsp[(3) - (6)].str);
					n->newname = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 98:
#line 16 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_TABLE;
					n->relation = (yyvsp[(3) - (6)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 99:
#line 26 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_TABLE;
					n->relation = (yyvsp[(5) - (8)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 100:
#line 36 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_SEQUENCE;
					n->relation = (yyvsp[(3) - (6)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 101:
#line 46 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_SEQUENCE;
					n->relation = (yyvsp[(5) - (8)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 102:
#line 56 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_VIEW;
					n->relation = (yyvsp[(3) - (6)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 103:
#line 66 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_VIEW;
					n->relation = (yyvsp[(5) - (8)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 104:
#line 76 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_INDEX;
					n->relation = (yyvsp[(3) - (6)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 105:
#line 86 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_INDEX;
					n->relation = (yyvsp[(5) - (8)].range);
					n->subname = NULL;
					n->newname = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 106:
#line 96 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_COLUMN;
					n->relationType = PG_OBJECT_TABLE;
					n->relation = (yyvsp[(3) - (8)].range);
					n->subname = (yyvsp[(6) - (8)].str);
					n->newname = (yyvsp[(8) - (8)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 107:
#line 107 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_COLUMN;
					n->relationType = PG_OBJECT_TABLE;
					n->relation = (yyvsp[(5) - (10)].range);
					n->subname = (yyvsp[(8) - (10)].str);
					n->newname = (yyvsp[(10) - (10)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 108:
#line 118 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_TABCONSTRAINT;
					n->relation = (yyvsp[(3) - (8)].range);
					n->subname = (yyvsp[(6) - (8)].str);
					n->newname = (yyvsp[(8) - (8)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 109:
#line 128 "third_party/libpg_query/grammar/statements/rename.y"
    {
					PGRenameStmt *n = makeNode(PGRenameStmt);
					n->renameType = PG_OBJECT_TABCONSTRAINT;
					n->relation = (yyvsp[(5) - (10)].range);
					n->subname = (yyvsp[(8) - (10)].str);
					n->newname = (yyvsp[(10) - (10)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 110:
#line 140 "third_party/libpg_query/grammar/statements/rename.y"
    { (yyval.ival) = COLUMN; ;}
    break;

  case 111:
#line 141 "third_party/libpg_query/grammar/statements/rename.y"
    { (yyval.ival) = 0; ;}
    break;

  case 112:
#line 10 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyvsp[(5) - (7)].istmt)->relation = (yyvsp[(4) - (7)].range);
					(yyvsp[(5) - (7)].istmt)->onConflictClause = (yyvsp[(6) - (7)].onconflict);
					(yyvsp[(5) - (7)].istmt)->returningList = (yyvsp[(7) - (7)].list);
					(yyvsp[(5) - (7)].istmt)->withClause = (yyvsp[(1) - (7)].with);
					(yyval.node) = (PGNode *) (yyvsp[(5) - (7)].istmt);
				;}
    break;

  case 113:
#line 22 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.istmt) = makeNode(PGInsertStmt);
					(yyval.istmt)->cols = NIL;
					(yyval.istmt)->selectStmt = (yyvsp[(1) - (1)].node);
				;}
    break;

  case 114:
#line 28 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.istmt) = makeNode(PGInsertStmt);
					(yyval.istmt)->cols = NIL;
					(yyval.istmt)->override = (yyvsp[(2) - (4)].override);
					(yyval.istmt)->selectStmt = (yyvsp[(4) - (4)].node);
				;}
    break;

  case 115:
#line 35 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.istmt) = makeNode(PGInsertStmt);
					(yyval.istmt)->cols = (yyvsp[(2) - (4)].list);
					(yyval.istmt)->selectStmt = (yyvsp[(4) - (4)].node);
				;}
    break;

  case 116:
#line 41 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.istmt) = makeNode(PGInsertStmt);
					(yyval.istmt)->cols = (yyvsp[(2) - (7)].list);
					(yyval.istmt)->override = (yyvsp[(5) - (7)].override);
					(yyval.istmt)->selectStmt = (yyvsp[(7) - (7)].node);
				;}
    break;

  case 117:
#line 48 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.istmt) = makeNode(PGInsertStmt);
					(yyval.istmt)->cols = NIL;
					(yyval.istmt)->selectStmt = NULL;
				;}
    break;

  case 118:
#line 58 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.range) = (yyvsp[(1) - (1)].range);
				;}
    break;

  case 119:
#line 62 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyvsp[(1) - (3)].range)->alias = makeAlias((yyvsp[(3) - (3)].str), NIL);
					(yyval.range) = (yyvsp[(1) - (3)].range);
				;}
    break;

  case 120:
#line 71 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.infer) = makeNode(PGInferClause);
					(yyval.infer)->indexElems = (yyvsp[(2) - (4)].list);
					(yyval.infer)->whereClause = (yyvsp[(4) - (4)].node);
					(yyval.infer)->conname = NULL;
					(yyval.infer)->location = (yylsp[(1) - (4)]);
				;}
    break;

  case 121:
#line 80 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.infer) = makeNode(PGInferClause);
					(yyval.infer)->indexElems = NIL;
					(yyval.infer)->whereClause = NULL;
					(yyval.infer)->conname = (yyvsp[(3) - (3)].str);
					(yyval.infer)->location = (yylsp[(1) - (3)]);
				;}
    break;

  case 122:
#line 88 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.infer) = NULL;
				;}
    break;

  case 123:
#line 95 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.with) = (yyvsp[(1) - (1)].with); ;}
    break;

  case 124:
#line 96 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.with) = NULL; ;}
    break;

  case 125:
#line 102 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.target) = makeNode(PGResTarget);
					(yyval.target)->name = (yyvsp[(1) - (2)].str);
					(yyval.target)->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner);
					(yyval.target)->val = NULL;
					(yyval.target)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 126:
#line 114 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyvsp[(1) - (3)].target)->val = (PGNode *) (yyvsp[(3) - (3)].node);
					(yyval.list) = list_make1((yyvsp[(1) - (3)].target));
				;}
    break;

  case 127:
#line 119 "third_party/libpg_query/grammar/statements/insert.y"
    {
					int ncolumns = list_length((yyvsp[(2) - (5)].list));
					int i = 1;
					PGListCell *col_cell;

					/* Create a PGMultiAssignRef source for each target */
					foreach(col_cell, (yyvsp[(2) - (5)].list))
					{
						PGResTarget *res_col = (PGResTarget *) lfirst(col_cell);
						PGMultiAssignRef *r = makeNode(PGMultiAssignRef);

						r->source = (PGNode *) (yyvsp[(5) - (5)].node);
						r->colno = i;
						r->ncolumns = ncolumns;
						res_col->val = (PGNode *) r;
						i++;
					}

					(yyval.list) = (yyvsp[(2) - (5)].list);
				;}
    break;

  case 128:
#line 144 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.onconflict) = makeNode(PGOnConflictClause);
					(yyval.onconflict)->action = PG_ONCONFLICT_UPDATE;
					(yyval.onconflict)->infer = (yyvsp[(3) - (8)].infer);
					(yyval.onconflict)->targetList = (yyvsp[(7) - (8)].list);
					(yyval.onconflict)->whereClause = (yyvsp[(8) - (8)].node);
					(yyval.onconflict)->location = (yylsp[(1) - (8)]);
				;}
    break;

  case 129:
#line 154 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.onconflict) = makeNode(PGOnConflictClause);
					(yyval.onconflict)->action = PG_ONCONFLICT_NOTHING;
					(yyval.onconflict)->infer = (yyvsp[(3) - (5)].infer);
					(yyval.onconflict)->targetList = NIL;
					(yyval.onconflict)->whereClause = NULL;
					(yyval.onconflict)->location = (yylsp[(1) - (5)]);
				;}
    break;

  case 130:
#line 163 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.onconflict) = NULL;
				;}
    break;

  case 131:
#line 170 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.ielem) = makeNode(PGIndexElem);
					(yyval.ielem)->name = (yyvsp[(1) - (5)].str);
					(yyval.ielem)->expr = NULL;
					(yyval.ielem)->indexcolname = NULL;
					(yyval.ielem)->collation = (yyvsp[(2) - (5)].list);
					(yyval.ielem)->opclass = (yyvsp[(3) - (5)].list);
					(yyval.ielem)->ordering = (yyvsp[(4) - (5)].sortorder);
					(yyval.ielem)->nulls_ordering = (yyvsp[(5) - (5)].nullorder);
				;}
    break;

  case 132:
#line 181 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.ielem) = makeNode(PGIndexElem);
					(yyval.ielem)->name = NULL;
					(yyval.ielem)->expr = (yyvsp[(1) - (5)].node);
					(yyval.ielem)->indexcolname = NULL;
					(yyval.ielem)->collation = (yyvsp[(2) - (5)].list);
					(yyval.ielem)->opclass = (yyvsp[(3) - (5)].list);
					(yyval.ielem)->ordering = (yyvsp[(4) - (5)].sortorder);
					(yyval.ielem)->nulls_ordering = (yyvsp[(5) - (5)].nullorder);
				;}
    break;

  case 133:
#line 192 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.ielem) = makeNode(PGIndexElem);
					(yyval.ielem)->name = NULL;
					(yyval.ielem)->expr = (yyvsp[(2) - (7)].node);
					(yyval.ielem)->indexcolname = NULL;
					(yyval.ielem)->collation = (yyvsp[(4) - (7)].list);
					(yyval.ielem)->opclass = (yyvsp[(5) - (7)].list);
					(yyval.ielem)->ordering = (yyvsp[(6) - (7)].sortorder);
					(yyval.ielem)->nulls_ordering = (yyvsp[(7) - (7)].nullorder);
				;}
    break;

  case 134:
#line 206 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 135:
#line 207 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = NIL; ;}
    break;

  case 136:
#line 213 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.override) = PG_OVERRIDING_USER_VALUE; ;}
    break;

  case 137:
#line 214 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.override) = OVERRIDING_SYSTEM_VALUE; ;}
    break;

  case 138:
#line 219 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;}
    break;

  case 139:
#line 220 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].target)); ;}
    break;

  case 140:
#line 226 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 141:
#line 227 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = NIL; ;}
    break;

  case 142:
#line 231 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 143:
#line 232 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = NIL; ;}
    break;

  case 144:
#line 238 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;}
    break;

  case 145:
#line 240 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); ;}
    break;

  case 146:
#line 245 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 147:
#line 246 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = list_concat((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].list)); ;}
    break;

  case 148:
#line 250 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].ielem)); ;}
    break;

  case 149:
#line 251 "third_party/libpg_query/grammar/statements/insert.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].ielem)); ;}
    break;

  case 150:
#line 257 "third_party/libpg_query/grammar/statements/insert.y"
    {
					(yyval.target) = makeNode(PGResTarget);
					(yyval.target)->name = (yyvsp[(1) - (2)].str);
					(yyval.target)->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner);
					(yyval.target)->val = NULL;	/* upper production sets this */
					(yyval.target)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 151:
#line 8 "third_party/libpg_query/grammar/statements/pragma.y"
    {
					PGPragmaStmt *n = makeNode(PGPragmaStmt);
					n->kind = PG_PRAGMA_TYPE_NOTHING;
					n->name = (yyvsp[(2) - (2)].str);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 152:
#line 15 "third_party/libpg_query/grammar/statements/pragma.y"
    {
					PGPragmaStmt *n = makeNode(PGPragmaStmt);
					n->kind = PG_PRAGMA_TYPE_ASSIGNMENT;
					n->name = (yyvsp[(2) - (4)].str);
					n->args = (yyvsp[(4) - (4)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 153:
#line 23 "third_party/libpg_query/grammar/statements/pragma.y"
    {
					PGPragmaStmt *n = makeNode(PGPragmaStmt);
					n->kind = PG_PRAGMA_TYPE_CALL;
					n->name = (yyvsp[(2) - (5)].str);
					n->args = (yyvsp[(4) - (5)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 154:
#line 10 "third_party/libpg_query/grammar/statements/create_sequence.y"
    {
					PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt);
					(yyvsp[(4) - (5)].range)->relpersistence = (yyvsp[(2) - (5)].ival);
					n->sequence = (yyvsp[(4) - (5)].range);
					n->options = (yyvsp[(5) - (5)].list);
					n->ownerId = InvalidOid;
					n->if_not_exists = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 155:
#line 20 "third_party/libpg_query/grammar/statements/create_sequence.y"
    {
					PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt);
					(yyvsp[(7) - (8)].range)->relpersistence = (yyvsp[(2) - (8)].ival);
					n->sequence = (yyvsp[(7) - (8)].range);
					n->options = (yyvsp[(8) - (8)].list);
					n->ownerId = InvalidOid;
					n->if_not_exists = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 156:
#line 32 "third_party/libpg_query/grammar/statements/create_sequence.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 157:
#line 33 "third_party/libpg_query/grammar/statements/create_sequence.y"
    { (yyval.list) = NIL; ;}
    break;

  case 158:
#line 8 "third_party/libpg_query/grammar/statements/execute.y"
    {
					PGExecuteStmt *n = makeNode(PGExecuteStmt);
					n->name = (yyvsp[(2) - (3)].str);
					n->params = (yyvsp[(3) - (3)].list);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 159:
#line 16 "third_party/libpg_query/grammar/statements/execute.y"
    {
					PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
					PGExecuteStmt *n = makeNode(PGExecuteStmt);
					n->name = (yyvsp[(7) - (9)].str);
					n->params = (yyvsp[(8) - (9)].list);
					ctas->query = (PGNode *) n;
					ctas->into = (yyvsp[(4) - (9)].into);
					ctas->relkind = PG_OBJECT_TABLE;
					ctas->is_select_into = false;
					ctas->if_not_exists = false;
					/* cram additional flags into the PGIntoClause */
					(yyvsp[(4) - (9)].into)->rel->relpersistence = (yyvsp[(2) - (9)].ival);
					(yyvsp[(4) - (9)].into)->skipData = !((yyvsp[(9) - (9)].boolean));
					(yyval.node) = (PGNode *) ctas;
				;}
    break;

  case 160:
#line 33 "third_party/libpg_query/grammar/statements/execute.y"
    {
					PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
					PGExecuteStmt *n = makeNode(PGExecuteStmt);
					n->name = (yyvsp[(10) - (12)].str);
					n->params = (yyvsp[(11) - (12)].list);
					ctas->query = (PGNode *) n;
					ctas->into = (yyvsp[(7) - (12)].into);
					ctas->relkind = PG_OBJECT_TABLE;
					ctas->is_select_into = false;
					ctas->if_not_exists = true;
					/* cram additional flags into the PGIntoClause */
					(yyvsp[(7) - (12)].into)->rel->relpersistence = (yyvsp[(2) - (12)].ival);
					(yyvsp[(7) - (12)].into)->skipData = !((yyvsp[(12) - (12)].boolean));
					(yyval.node) = (PGNode *) ctas;
				;}
    break;

  case 161:
#line 51 "third_party/libpg_query/grammar/statements/execute.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 162:
#line 52 "third_party/libpg_query/grammar/statements/execute.y"
    { (yyval.list) = NIL; ;}
    break;

  case 163:
#line 10 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					PGAlterSeqStmt *n = makeNode(PGAlterSeqStmt);
					n->sequence = (yyvsp[(3) - (4)].range);
					n->options = (yyvsp[(4) - (4)].list);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 164:
#line 18 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					PGAlterSeqStmt *n = makeNode(PGAlterSeqStmt);
					n->sequence = (yyvsp[(5) - (6)].range);
					n->options = (yyvsp[(6) - (6)].list);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 165:
#line 29 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;}
    break;

  case 166:
#line 30 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); ;}
    break;

  case 167:
#line 34 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {;}
    break;

  case 168:
#line 35 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {;}
    break;

  case 169:
#line 36 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {;}
    break;

  case 170:
#line 41 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.value) = makeFloat((yyvsp[(1) - (1)].str)); ;}
    break;

  case 171:
#line 42 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.value) = makeFloat((yyvsp[(2) - (2)].str)); ;}
    break;

  case 172:
#line 44 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.value) = makeFloat((yyvsp[(2) - (2)].str));
					doNegateFloat((yyval.value));
				;}
    break;

  case 173:
#line 48 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.value) = makeInteger((yyvsp[(1) - (1)].ival)); ;}
    break;

  case 174:
#line 53 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("as", (PGNode *)(yyvsp[(2) - (2)].typnam), (yylsp[(1) - (2)]));
				;}
    break;

  case 175:
#line 57 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("cache", (PGNode *)(yyvsp[(2) - (2)].value), (yylsp[(1) - (2)]));
				;}
    break;

  case 176:
#line 61 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("cycle", (PGNode *)makeInteger(true), (yylsp[(1) - (1)]));
				;}
    break;

  case 177:
#line 65 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("cycle", (PGNode *)makeInteger(false), (yylsp[(1) - (2)]));
				;}
    break;

  case 178:
#line 69 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("increment", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)]));
				;}
    break;

  case 179:
#line 73 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("maxvalue", (PGNode *)(yyvsp[(2) - (2)].value), (yylsp[(1) - (2)]));
				;}
    break;

  case 180:
#line 77 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("minvalue", (PGNode *)(yyvsp[(2) - (2)].value), (yylsp[(1) - (2)]));
				;}
    break;

  case 181:
#line 81 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("maxvalue", NULL, (yylsp[(1) - (2)]));
				;}
    break;

  case 182:
#line 85 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("minvalue", NULL, (yylsp[(1) - (2)]));
				;}
    break;

  case 183:
#line 89 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("owned_by", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)]));
				;}
    break;

  case 184:
#line 93 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					/* not documented, only used by pg_dump */
					(yyval.defelt) = makeDefElem("sequence_name", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)]));
				;}
    break;

  case 185:
#line 98 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("start", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)]));
				;}
    break;

  case 186:
#line 102 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("restart", NULL, (yylsp[(1) - (1)]));
				;}
    break;

  case 187:
#line 106 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {
					(yyval.defelt) = makeDefElem("restart", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)]));
				;}
    break;

  case 188:
#line 112 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {;}
    break;

  case 189:
#line 113 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    {;}
    break;

  case 190:
#line 117 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;}
    break;

  case 191:
#line 118 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.ival) = + (yyvsp[(2) - (2)].ival); ;}
    break;

  case 192:
#line 119 "third_party/libpg_query/grammar/statements/alter_sequence.y"
    { (yyval.ival) = - (yyvsp[(2) - (2)].ival); ;}
    break;

  case 193:
#line 3 "third_party/libpg_query/grammar/statements/transaction.y"
    {
					PGTransactionStmt *n = makeNode(PGTransactionStmt);
					n->kind = PG_TRANS_STMT_ROLLBACK;
					n->options = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 194:
#line 10 "third_party/libpg_query/grammar/statements/transaction.y"
    {
					PGTransactionStmt *n = makeNode(PGTransactionStmt);
					n->kind = PG_TRANS_STMT_BEGIN;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 195:
#line 16 "third_party/libpg_query/grammar/statements/transaction.y"
    {
					PGTransactionStmt *n = makeNode(PGTransactionStmt);
					n->kind = PG_TRANS_STMT_START;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 196:
#line 22 "third_party/libpg_query/grammar/statements/transaction.y"
    {
					PGTransactionStmt *n = makeNode(PGTransactionStmt);
					n->kind = PG_TRANS_STMT_COMMIT;
					n->options = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 197:
#line 29 "third_party/libpg_query/grammar/statements/transaction.y"
    {
					PGTransactionStmt *n = makeNode(PGTransactionStmt);
					n->kind = PG_TRANS_STMT_COMMIT;
					n->options = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 198:
#line 36 "third_party/libpg_query/grammar/statements/transaction.y"
    {
					PGTransactionStmt *n = makeNode(PGTransactionStmt);
					n->kind = PG_TRANS_STMT_ROLLBACK;
					n->options = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 199:
#line 45 "third_party/libpg_query/grammar/statements/transaction.y"
    {;}
    break;

  case 200:
#line 46 "third_party/libpg_query/grammar/statements/transaction.y"
    {;}
    break;

  case 201:
#line 47 "third_party/libpg_query/grammar/statements/transaction.y"
    {;}
    break;

  case 202:
#line 9 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGCreateStmt *n = makeNode(PGCreateStmt);
					(yyvsp[(4) - (9)].range)->relpersistence = (yyvsp[(2) - (9)].ival);
					n->relation = (yyvsp[(4) - (9)].range);
					n->tableElts = (yyvsp[(6) - (9)].list);
					n->ofTypename = NULL;
					n->constraints = NIL;
					n->options = (yyvsp[(8) - (9)].list);
					n->oncommit = (yyvsp[(9) - (9)].oncommit);
					n->if_not_exists = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 203:
#line 24 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGCreateStmt *n = makeNode(PGCreateStmt);
					(yyvsp[(7) - (12)].range)->relpersistence = (yyvsp[(2) - (12)].ival);
					n->relation = (yyvsp[(7) - (12)].range);
					n->tableElts = (yyvsp[(9) - (12)].list);
					n->ofTypename = NULL;
					n->constraints = NIL;
					n->options = (yyvsp[(11) - (12)].list);
					n->oncommit = (yyvsp[(12) - (12)].oncommit);
					n->if_not_exists = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 204:
#line 41 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = 0; ;}
    break;

  case 205:
#line 43 "third_party/libpg_query/grammar/statements/create.y"
    {
					/*
					 * We must complain about conflicting options.
					 * We could, but choose not to, complain about redundant
					 * options (ie, where $2's bit is already set in $1).
					 */
					int		newspec = (yyvsp[(1) - (2)].ival) | (yyvsp[(2) - (2)].ival);

					/* special message for this case */
					if ((newspec & (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) == (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED))
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
								 parser_errposition((yylsp[(2) - (2)]))));
					/* generic message for other conflicts */
					if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) ||
						(newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED))
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("conflicting constraint properties"),
								 parser_errposition((yylsp[(2) - (2)]))));
					(yyval.ival) = newspec;
				;}
    break;

  case 206:
#line 69 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].typnam); ;}
    break;

  case 207:
#line 70 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *)makeString(pstrdup((yyvsp[(1) - (1)].keyword))); ;}
    break;

  case 208:
#line 71 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].list); ;}
    break;

  case 209:
#line 72 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].value); ;}
    break;

  case 210:
#line 73 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *)makeString((yyvsp[(1) - (1)].str)); ;}
    break;

  case 211:
#line 74 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *)makeString(pstrdup((yyvsp[(1) - (1)].keyword))); ;}
    break;

  case 212:
#line 78 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 213:
#line 79 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 214:
#line 84 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;}
    break;

  case 215:
#line 89 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_FKCONSTR_ACTION_NOACTION; ;}
    break;

  case 216:
#line 90 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_FKCONSTR_ACTION_RESTRICT; ;}
    break;

  case 217:
#line 91 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_FKCONSTR_ACTION_CASCADE; ;}
    break;

  case 218:
#line 92 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_FKCONSTR_ACTION_SETNULL; ;}
    break;

  case 219:
#line 93 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_FKCONSTR_ACTION_SETDEFAULT; ;}
    break;

  case 220:
#line 99 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = castNode(PGConstraint, (yyvsp[(3) - (3)].node));
					n->conname = (yyvsp[(2) - (3)].str);
					n->location = (yylsp[(1) - (3)]);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 221:
#line 105 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 222:
#line 106 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 223:
#line 108 "third_party/libpg_query/grammar/statements/create.y"
    {
					/*
					 * Note: the PGCollateClause is momentarily included in
					 * the list built by ColQualList, but we split it out
					 * again in SplitColQualList.
					 */
					PGCollateClause *n = makeNode(PGCollateClause);
					n->arg = NULL;
					n->collname = (yyvsp[(2) - (2)].list);
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 224:
#line 125 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_NOTNULL;
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 225:
#line 132 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_NULL;
					n->location = (yylsp[(1) - (1)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 226:
#line 139 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_UNIQUE;
					n->location = (yylsp[(1) - (2)]);
					n->keys = NULL;
					n->options = (yyvsp[(2) - (2)].list);
					n->indexname = NULL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 227:
#line 149 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_PRIMARY;
					n->location = (yylsp[(1) - (3)]);
					n->keys = NULL;
					n->options = (yyvsp[(3) - (3)].list);
					n->indexname = NULL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 228:
#line 159 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_CHECK;
					n->location = (yylsp[(1) - (5)]);
					n->is_no_inherit = (yyvsp[(5) - (5)].boolean);
					n->raw_expr = (yyvsp[(3) - (5)].node);
					n->cooked_expr = NULL;
					n->skip_validation = false;
					n->initially_valid = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 229:
#line 171 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_DEFAULT;
					n->location = (yylsp[(1) - (2)]);
					n->raw_expr = (yyvsp[(2) - (2)].node);
					n->cooked_expr = NULL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 230:
#line 180 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_IDENTITY;
					n->generated_when = (yyvsp[(2) - (5)].ival);
					n->options = (yyvsp[(5) - (5)].list);
					n->location = (yylsp[(1) - (5)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 231:
#line 189 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_FOREIGN;
					n->location = (yylsp[(1) - (5)]);
					n->pktable			= (yyvsp[(2) - (5)].range);
					n->fk_attrs			= NIL;
					n->pk_attrs			= (yyvsp[(3) - (5)].list);
					n->fk_matchtype		= (yyvsp[(4) - (5)].ival);
					n->fk_upd_action	= (char) ((yyvsp[(5) - (5)].ival) >> 8);
					n->fk_del_action	= (char) ((yyvsp[(5) - (5)].ival) & 0xFF);
					n->skip_validation  = false;
					n->initially_valid  = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 232:
#line 208 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)]));
				;}
    break;

  case 233:
#line 214 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = (yyvsp[(3) - (3)].ival); ;}
    break;

  case 234:
#line 220 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = ((yyvsp[(1) - (1)].ival) << 8) | (PG_FKCONSTR_ACTION_NOACTION & 0xFF); ;}
    break;

  case 235:
#line 222 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = (PG_FKCONSTR_ACTION_NOACTION << 8) | ((yyvsp[(1) - (1)].ival) & 0xFF); ;}
    break;

  case 236:
#line 224 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = ((yyvsp[(1) - (2)].ival) << 8) | ((yyvsp[(2) - (2)].ival) & 0xFF); ;}
    break;

  case 237:
#line 226 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = ((yyvsp[(2) - (2)].ival) << 8) | ((yyvsp[(1) - (2)].ival) & 0xFF); ;}
    break;

  case 238:
#line 228 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = (PG_FKCONSTR_ACTION_NOACTION << 8) | (PG_FKCONSTR_ACTION_NOACTION & 0xFF); ;}
    break;

  case 239:
#line 233 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 240:
#line 234 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 241:
#line 238 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.oncommit) = ONCOMMIT_DROP; ;}
    break;

  case 242:
#line 239 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.oncommit) = PG_ONCOMMIT_DELETE_ROWS; ;}
    break;

  case 243:
#line 240 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.oncommit) = PG_ONCOMMIT_PRESERVE_ROWS; ;}
    break;

  case 244:
#line 241 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.oncommit) = PG_ONCOMMIT_NOOP; ;}
    break;

  case 245:
#line 246 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 246:
#line 250 "third_party/libpg_query/grammar/statements/create.y"
    {  (yyval.boolean) = true; ;}
    break;

  case 247:
#line 251 "third_party/libpg_query/grammar/statements/create.y"
    {  (yyval.boolean) = false; ;}
    break;

  case 248:
#line 257 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = castNode(PGConstraint, (yyvsp[(3) - (3)].node));
					n->conname = (yyvsp[(2) - (3)].str);
					n->location = (yylsp[(1) - (3)]);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 249:
#line 263 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 250:
#line 268 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_COMMENTS; ;}
    break;

  case 251:
#line 269 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_CONSTRAINTS; ;}
    break;

  case 252:
#line 270 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_DEFAULTS; ;}
    break;

  case 253:
#line 271 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_IDENTITY; ;}
    break;

  case 254:
#line 272 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_INDEXES; ;}
    break;

  case 255:
#line 273 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_STATISTICS; ;}
    break;

  case 256:
#line 274 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_STORAGE; ;}
    break;

  case 257:
#line 275 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_CREATE_TABLE_LIKE_ALL; ;}
    break;

  case 258:
#line 281 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;}
    break;

  case 259:
#line 282 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;}
    break;

  case 260:
#line 286 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.str) = (yyvsp[(3) - (3)].str); ;}
    break;

  case 261:
#line 292 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_ATTR_DEFERRABLE;
					n->location = (yylsp[(1) - (1)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 262:
#line 299 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_ATTR_NOT_DEFERRABLE;
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 263:
#line 306 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_ATTR_DEFERRED;
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 264:
#line 313 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_ATTR_IMMEDIATE;
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 265:
#line 324 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 266:
#line 325 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = list_make1(makeDefElem("oids", (PGNode *) makeInteger(true), (yylsp[(1) - (2)]))); ;}
    break;

  case 267:
#line 326 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = list_make1(makeDefElem("oids", (PGNode *) makeInteger(false), (yylsp[(1) - (2)]))); ;}
    break;

  case 268:
#line 327 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 269:
#line 331 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 270:
#line 336 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); ;}
    break;

  case 271:
#line 337 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = (yyvsp[(1) - (3)].ival) & ~(yyvsp[(3) - (3)].ival); ;}
    break;

  case 272:
#line 338 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = 0; ;}
    break;

  case 273:
#line 343 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 274:
#line 348 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = CAS_NOT_DEFERRABLE; ;}
    break;

  case 275:
#line 349 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = CAS_DEFERRABLE; ;}
    break;

  case 276:
#line 350 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = CAS_INITIALLY_IMMEDIATE; ;}
    break;

  case 277:
#line 351 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = CAS_INITIALLY_DEFERRED; ;}
    break;

  case 278:
#line 352 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = CAS_NOT_VALID; ;}
    break;

  case 279:
#line 353 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = CAS_NO_INHERIT; ;}
    break;

  case 280:
#line 359 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGColumnDef *n = makeNode(PGColumnDef);
					n->colname = (yyvsp[(1) - (4)].str);
					n->typeName = (yyvsp[(2) - (4)].typnam);
					n->inhcount = 0;
					n->is_local = true;
					n->is_not_null = false;
					n->is_from_type = false;
					n->storage = 0;
					n->raw_default = NULL;
					n->cooked_default = NULL;
					n->collOid = InvalidOid;
					n->fdwoptions = (yyvsp[(3) - (4)].list);
					SplitColQualList((yyvsp[(4) - (4)].list), &n->constraints, &n->collClause,
									 yyscanner);
					n->location = (yylsp[(1) - (4)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 281:
#line 382 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
				;}
    break;

  case 282:
#line 386 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
				;}
    break;

  case 283:
#line 392 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;}
    break;

  case 284:
#line 393 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;}
    break;

  case 285:
#line 397 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 286:
#line 401 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 287:
#line 402 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 288:
#line 403 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 289:
#line 408 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (PGNode *) (yyvsp[(3) - (3)].node), (yylsp[(1) - (3)]));
				;}
    break;

  case 290:
#line 412 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (1)].str), NULL, (yylsp[(1) - (1)]));
				;}
    break;

  case 291:
#line 419 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 292:
#line 420 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 293:
#line 425 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 294:
#line 426 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 295:
#line 431 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str));
				;}
    break;

  case 296:
#line 438 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 297:
#line 439 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 298:
#line 444 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;}
    break;

  case 299:
#line 445 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = NIL; ;}
    break;

  case 300:
#line 449 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = (yyvsp[(3) - (3)].ival); ;}
    break;

  case 301:
#line 455 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (PGNode *) (yyvsp[(3) - (3)].node), (yylsp[(1) - (3)]));
				;}
    break;

  case 302:
#line 459 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (1)].str), NULL, (yylsp[(1) - (1)]));
				;}
    break;

  case 303:
#line 463 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElemExtended((yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), (PGNode *) (yyvsp[(5) - (5)].node),
											 PG_DEFELEM_UNSPEC, (yylsp[(1) - (5)]));
				;}
    break;

  case 304:
#line 468 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.defelt) = makeDefElemExtended((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str), NULL, PG_DEFELEM_UNSPEC, (yylsp[(1) - (3)]));
				;}
    break;

  case 305:
#line 475 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 306:
#line 476 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;}
    break;

  case 307:
#line 480 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 308:
#line 482 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(1) - (4)].str)), (yyvsp[(2) - (4)].list)));
					(yyval.typnam)->pct_type = true;
					(yyval.typnam)->location = (yylsp[(1) - (4)]);
				;}
    break;

  case 309:
#line 488 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(2) - (5)].str)), (yyvsp[(3) - (5)].list)));
					(yyval.typnam)->pct_type = true;
					(yyval.typnam)->setof = true;
					(yyval.typnam)->location = (yylsp[(2) - (5)]);
				;}
    break;

  case 310:
#line 499 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_CHECK;
					n->location = (yylsp[(1) - (5)]);
					n->raw_expr = (yyvsp[(3) - (5)].node);
					n->cooked_expr = NULL;
					processCASbits((yyvsp[(5) - (5)].ival), (yylsp[(5) - (5)]), "CHECK",
								   NULL, NULL, &n->skip_validation,
								   &n->is_no_inherit, yyscanner);
					n->initially_valid = !n->skip_validation;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 311:
#line 513 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_UNIQUE;
					n->location = (yylsp[(1) - (6)]);
					n->keys = (yyvsp[(3) - (6)].list);
					n->options = (yyvsp[(5) - (6)].list);
					n->indexname = NULL;
					processCASbits((yyvsp[(6) - (6)].ival), (yylsp[(6) - (6)]), "UNIQUE",
								   &n->deferrable, &n->initdeferred, NULL,
								   NULL, yyscanner);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 312:
#line 526 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_UNIQUE;
					n->location = (yylsp[(1) - (3)]);
					n->keys = NIL;
					n->options = NIL;
					n->indexname = (yyvsp[(2) - (3)].str);
					n->indexspace = NULL;
					processCASbits((yyvsp[(3) - (3)].ival), (yylsp[(3) - (3)]), "UNIQUE",
								   &n->deferrable, &n->initdeferred, NULL,
								   NULL, yyscanner);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 313:
#line 541 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_PRIMARY;
					n->location = (yylsp[(1) - (7)]);
					n->keys = (yyvsp[(4) - (7)].list);
					n->options = (yyvsp[(6) - (7)].list);
					n->indexname = NULL;
					processCASbits((yyvsp[(7) - (7)].ival), (yylsp[(7) - (7)]), "PRIMARY KEY",
								   &n->deferrable, &n->initdeferred, NULL,
								   NULL, yyscanner);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 314:
#line 554 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_PRIMARY;
					n->location = (yylsp[(1) - (4)]);
					n->keys = NIL;
					n->options = NIL;
					n->indexname = (yyvsp[(3) - (4)].str);
					n->indexspace = NULL;
					processCASbits((yyvsp[(4) - (4)].ival), (yylsp[(4) - (4)]), "PRIMARY KEY",
								   &n->deferrable, &n->initdeferred, NULL,
								   NULL, yyscanner);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 315:
#line 569 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGConstraint *n = makeNode(PGConstraint);
					n->contype = PG_CONSTR_FOREIGN;
					n->location = (yylsp[(1) - (11)]);
					n->pktable			= (yyvsp[(7) - (11)].range);
					n->fk_attrs			= (yyvsp[(4) - (11)].list);
					n->pk_attrs			= (yyvsp[(8) - (11)].list);
					n->fk_matchtype		= (yyvsp[(9) - (11)].ival);
					n->fk_upd_action	= (char) ((yyvsp[(10) - (11)].ival) >> 8);
					n->fk_del_action	= (char) ((yyvsp[(10) - (11)].ival) & 0xFF);
					processCASbits((yyvsp[(11) - (11)].ival), (yylsp[(11) - (11)]), "FOREIGN KEY",
								   &n->deferrable, &n->initdeferred,
								   &n->skip_validation, NULL,
								   yyscanner);
					n->initially_valid = !n->skip_validation;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 316:
#line 591 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
				;}
    break;

  case 317:
#line 595 "third_party/libpg_query/grammar/statements/create.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 318:
#line 602 "third_party/libpg_query/grammar/statements/create.y"
    {
				(yyval.ival) = PG_FKCONSTR_MATCH_FULL;
			;}
    break;

  case 319:
#line 606 "third_party/libpg_query/grammar/statements/create.y"
    {
				ereport(ERROR,
						(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("MATCH PARTIAL not yet implemented"),
						 parser_errposition((yylsp[(1) - (2)]))));
				(yyval.ival) = PG_FKCONSTR_MATCH_PARTIAL;
			;}
    break;

  case 320:
#line 614 "third_party/libpg_query/grammar/statements/create.y"
    {
				(yyval.ival) = PG_FKCONSTR_MATCH_SIMPLE;
			;}
    break;

  case 321:
#line 618 "third_party/libpg_query/grammar/statements/create.y"
    {
				(yyval.ival) = PG_FKCONSTR_MATCH_SIMPLE;
			;}
    break;

  case 322:
#line 626 "third_party/libpg_query/grammar/statements/create.y"
    {
					PGTableLikeClause *n = makeNode(PGTableLikeClause);
					n->relation = (yyvsp[(2) - (3)].range);
					n->options = (yyvsp[(3) - (3)].ival);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 323:
#line 635 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;}
    break;

  case 324:
#line 636 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;}
    break;

  case 325:
#line 637 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;}
    break;

  case 326:
#line 638 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;}
    break;

  case 327:
#line 640 "third_party/libpg_query/grammar/statements/create.y"
    {
					ereport(PGWARNING,
							(errmsg("GLOBAL is deprecated in temporary table creation"),
							 parser_errposition((yylsp[(1) - (2)]))));
					(yyval.ival) = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 328:
#line 647 "third_party/libpg_query/grammar/statements/create.y"
    {
					ereport(PGWARNING,
							(errmsg("GLOBAL is deprecated in temporary table creation"),
							 parser_errposition((yylsp[(1) - (2)]))));
					(yyval.ival) = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 329:
#line 653 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_RELPERSISTENCE_UNLOGGED; ;}
    break;

  case 330:
#line 654 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = RELPERSISTENCE_PERMANENT; ;}
    break;

  case 331:
#line 659 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = PG_ATTRIBUTE_IDENTITY_ALWAYS; ;}
    break;

  case 332:
#line 660 "third_party/libpg_query/grammar/statements/create.y"
    { (yyval.ival) = ATTRIBUTE_IDENTITY_BY_DEFAULT; ;}
    break;

  case 333:
#line 10 "third_party/libpg_query/grammar/statements/drop.y"
    {
					PGDropStmt *n = makeNode(PGDropStmt);
					n->removeType = (yyvsp[(2) - (6)].objtype);
					n->missing_ok = true;
					n->objects = (yyvsp[(5) - (6)].list);
					n->behavior = (yyvsp[(6) - (6)].dbehavior);
					n->concurrent = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 334:
#line 20 "third_party/libpg_query/grammar/statements/drop.y"
    {
					PGDropStmt *n = makeNode(PGDropStmt);
					n->removeType = (yyvsp[(2) - (4)].objtype);
					n->missing_ok = false;
					n->objects = (yyvsp[(3) - (4)].list);
					n->behavior = (yyvsp[(4) - (4)].dbehavior);
					n->concurrent = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 335:
#line 30 "third_party/libpg_query/grammar/statements/drop.y"
    {
					PGDropStmt *n = makeNode(PGDropStmt);
					n->removeType = (yyvsp[(2) - (6)].objtype);
					n->missing_ok = true;
					n->objects = (yyvsp[(5) - (6)].list);
					n->behavior = (yyvsp[(6) - (6)].dbehavior);
					n->concurrent = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 336:
#line 40 "third_party/libpg_query/grammar/statements/drop.y"
    {
					PGDropStmt *n = makeNode(PGDropStmt);
					n->removeType = (yyvsp[(2) - (4)].objtype);
					n->missing_ok = false;
					n->objects = (yyvsp[(3) - (4)].list);
					n->behavior = (yyvsp[(4) - (4)].dbehavior);
					n->concurrent = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 337:
#line 50 "third_party/libpg_query/grammar/statements/drop.y"
    {
					PGDropStmt *n = makeNode(PGDropStmt);
					n->removeType = (yyvsp[(2) - (6)].objtype);
					n->objects = list_make1(lappend((yyvsp[(5) - (6)].list), makeString((yyvsp[(3) - (6)].str))));
					n->behavior = (yyvsp[(6) - (6)].dbehavior);
					n->missing_ok = false;
					n->concurrent = false;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 338:
#line 60 "third_party/libpg_query/grammar/statements/drop.y"
    {
					PGDropStmt *n = makeNode(PGDropStmt);
					n->removeType = (yyvsp[(2) - (8)].objtype);
					n->objects = list_make1(lappend((yyvsp[(7) - (8)].list), makeString((yyvsp[(5) - (8)].str))));
					n->behavior = (yyvsp[(8) - (8)].dbehavior);
					n->missing_ok = true;
					n->concurrent = false;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 339:
#line 73 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_TABLE; ;}
    break;

  case 340:
#line 74 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_SEQUENCE; ;}
    break;

  case 341:
#line 75 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_VIEW; ;}
    break;

  case 342:
#line 76 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_MATVIEW; ;}
    break;

  case 343:
#line 77 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_INDEX; ;}
    break;

  case 344:
#line 78 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_FOREIGN_TABLE; ;}
    break;

  case 345:
#line 79 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_COLLATION; ;}
    break;

  case 346:
#line 80 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_CONVERSION; ;}
    break;

  case 347:
#line 81 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_STATISTIC_EXT; ;}
    break;

  case 348:
#line 82 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_TSPARSER; ;}
    break;

  case 349:
#line 83 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_TSDICTIONARY; ;}
    break;

  case 350:
#line 84 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_TSTEMPLATE; ;}
    break;

  case 351:
#line 85 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_TSCONFIGURATION; ;}
    break;

  case 352:
#line 90 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_ACCESS_METHOD; ;}
    break;

  case 353:
#line 91 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_EVENT_TRIGGER; ;}
    break;

  case 354:
#line 92 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_EXTENSION; ;}
    break;

  case 355:
#line 93 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_FDW; ;}
    break;

  case 356:
#line 94 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_PUBLICATION; ;}
    break;

  case 357:
#line 95 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_SCHEMA; ;}
    break;

  case 358:
#line 96 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_FOREIGN_SERVER; ;}
    break;

  case 359:
#line 101 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;}
    break;

  case 360:
#line 102 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;}
    break;

  case 361:
#line 107 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.dbehavior) = PG_DROP_CASCADE; ;}
    break;

  case 362:
#line 108 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.dbehavior) = PG_DROP_RESTRICT; ;}
    break;

  case 363:
#line 109 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.dbehavior) = PG_DROP_RESTRICT; /* default */ ;}
    break;

  case 364:
#line 114 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_POLICY; ;}
    break;

  case 365:
#line 115 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_RULE; ;}
    break;

  case 366:
#line 116 "third_party/libpg_query/grammar/statements/drop.y"
    { (yyval.objtype) = PG_OBJECT_TRIGGER; ;}
    break;

  case 367:
#line 12 "third_party/libpg_query/grammar/statements/update.y"
    {
					PGUpdateStmt *n = makeNode(PGUpdateStmt);
					n->relation = (yyvsp[(3) - (8)].range);
					n->targetList = (yyvsp[(5) - (8)].list);
					n->fromClause = (yyvsp[(6) - (8)].list);
					n->whereClause = (yyvsp[(7) - (8)].node);
					n->returningList = (yyvsp[(8) - (8)].list);
					n->withClause = (yyvsp[(1) - (8)].with);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 368:
#line 3 "third_party/libpg_query/grammar/statements/copy.y"
    {
					PGCopyStmt *n = makeNode(PGCopyStmt);
					n->relation = (yyvsp[(3) - (11)].range);
					n->query = NULL;
					n->attlist = (yyvsp[(4) - (11)].list);
					n->is_from = (yyvsp[(6) - (11)].boolean);
					n->is_program = (yyvsp[(7) - (11)].boolean);
					n->filename = (yyvsp[(8) - (11)].str);

					if (n->is_program && n->filename == NULL)
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("STDIN/STDOUT not allowed with PROGRAM"),
								 parser_errposition((yylsp[(8) - (11)]))));

					n->options = NIL;
					/* Concatenate user-supplied flags */
					if ((yyvsp[(2) - (11)].defelt))
						n->options = lappend(n->options, (yyvsp[(2) - (11)].defelt));
					if ((yyvsp[(5) - (11)].defelt))
						n->options = lappend(n->options, (yyvsp[(5) - (11)].defelt));
					if ((yyvsp[(9) - (11)].defelt))
						n->options = lappend(n->options, (yyvsp[(9) - (11)].defelt));
					if ((yyvsp[(11) - (11)].list))
						n->options = list_concat(n->options, (yyvsp[(11) - (11)].list));
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 369:
#line 31 "third_party/libpg_query/grammar/statements/copy.y"
    {
					PGCopyStmt *n = makeNode(PGCopyStmt);
					n->relation = NULL;
					n->query = (yyvsp[(3) - (9)].node);
					n->attlist = NIL;
					n->is_from = false;
					n->is_program = (yyvsp[(6) - (9)].boolean);
					n->filename = (yyvsp[(7) - (9)].str);
					n->options = (yyvsp[(9) - (9)].list);

					if (n->is_program && n->filename == NULL)
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("STDIN/STDOUT not allowed with PROGRAM"),
								 parser_errposition((yylsp[(5) - (9)]))));

					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 370:
#line 53 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.boolean) = true; ;}
    break;

  case 371:
#line 54 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.boolean) = false; ;}
    break;

  case 372:
#line 60 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("delimiter", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(2) - (3)]));
				;}
    break;

  case 373:
#line 63 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.defelt) = NULL; ;}
    break;

  case 374:
#line 69 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
				;}
    break;

  case 375:
#line 73 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 376:
#line 80 "third_party/libpg_query/grammar/statements/copy.y"
    {;}
    break;

  case 377:
#line 81 "third_party/libpg_query/grammar/statements/copy.y"
    {;}
    break;

  case 378:
#line 85 "third_party/libpg_query/grammar/statements/copy.y"
    {;}
    break;

  case 379:
#line 86 "third_party/libpg_query/grammar/statements/copy.y"
    {;}
    break;

  case 380:
#line 91 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.boolean) = true; ;}
    break;

  case 381:
#line 92 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.boolean) = false; ;}
    break;

  case 382:
#line 96 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 383:
#line 97 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 384:
#line 102 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;}
    break;

  case 385:
#line 103 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].value); ;}
    break;

  case 386:
#line 104 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.node) = (PGNode *) makeNode(PGAStar); ;}
    break;

  case 387:
#line 105 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.node) = (PGNode *) (yyvsp[(2) - (3)].list); ;}
    break;

  case 388:
#line 106 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.node) = NULL; ;}
    break;

  case 389:
#line 112 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)]));
				;}
    break;

  case 390:
#line 120 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("oids", (PGNode *)makeInteger(true), (yylsp[(1) - (2)]));
				;}
    break;

  case 391:
#line 123 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.defelt) = NULL; ;}
    break;

  case 392:
#line 128 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); ;}
    break;

  case 393:
#line 129 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.list) = NIL; ;}
    break;

  case 394:
#line 135 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("format", (PGNode *)makeString("binary"), (yylsp[(1) - (1)]));
				;}
    break;

  case 395:
#line 138 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.defelt) = NULL; ;}
    break;

  case 396:
#line 144 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("format", (PGNode *)makeString("binary"), (yylsp[(1) - (1)]));
				;}
    break;

  case 397:
#line 148 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("oids", (PGNode *)makeInteger(true), (yylsp[(1) - (1)]));
				;}
    break;

  case 398:
#line 152 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("freeze", (PGNode *)makeInteger(true), (yylsp[(1) - (1)]));
				;}
    break;

  case 399:
#line 156 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("delimiter", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)]));
				;}
    break;

  case 400:
#line 160 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("null", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)]));
				;}
    break;

  case 401:
#line 164 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("format", (PGNode *)makeString("csv"), (yylsp[(1) - (1)]));
				;}
    break;

  case 402:
#line 168 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("header", (PGNode *)makeInteger(true), (yylsp[(1) - (1)]));
				;}
    break;

  case 403:
#line 172 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("quote", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)]));
				;}
    break;

  case 404:
#line 176 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("escape", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)]));
				;}
    break;

  case 405:
#line 180 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("force_quote", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)]));
				;}
    break;

  case 406:
#line 184 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("force_quote", (PGNode *)makeNode(PGAStar), (yylsp[(1) - (3)]));
				;}
    break;

  case 407:
#line 188 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("force_not_null", (PGNode *)(yyvsp[(4) - (4)].list), (yylsp[(1) - (4)]));
				;}
    break;

  case 408:
#line 192 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("force_null", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)]));
				;}
    break;

  case 409:
#line 196 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.defelt) = makeDefElem("encoding", (PGNode *)makeString((yyvsp[(2) - (2)].str)), (yylsp[(1) - (2)]));
				;}
    break;

  case 410:
#line 203 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;}
    break;

  case 411:
#line 209 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 412:
#line 210 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.str) = NULL; ;}
    break;

  case 413:
#line 211 "third_party/libpg_query/grammar/statements/copy.y"
    { (yyval.str) = NULL; ;}
    break;

  case 414:
#line 217 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
				;}
    break;

  case 415:
#line 221 "third_party/libpg_query/grammar/statements/copy.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
				;}
    break;

  case 418:
#line 52 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (3)].node); ;}
    break;

  case 419:
#line 53 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (3)].node); ;}
    break;

  case 420:
#line 68 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 421:
#line 70 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list), NIL,
										NULL, NULL, NULL,
										yyscanner);
					(yyval.node) = (yyvsp[(1) - (2)].node);
				;}
    break;

  case 422:
#line 77 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].list), (yyvsp[(3) - (4)].list),
										(PGNode*) list_nth((yyvsp[(4) - (4)].list), 0), (PGNode*) list_nth((yyvsp[(4) - (4)].list), 1),
										NULL,
										yyscanner);
					(yyval.node) = (yyvsp[(1) - (4)].node);
				;}
    break;

  case 423:
#line 85 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].list), (yyvsp[(4) - (4)].list),
										(PGNode*) list_nth((yyvsp[(3) - (4)].list), 0), (PGNode*) list_nth((yyvsp[(3) - (4)].list), 1),
										NULL,
										yyscanner);
					(yyval.node) = (yyvsp[(1) - (4)].node);
				;}
    break;

  case 424:
#line 93 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (2)].node), NULL, NIL,
										NULL, NULL,
										(yyvsp[(1) - (2)].with),
										yyscanner);
					(yyval.node) = (yyvsp[(2) - (2)].node);
				;}
    break;

  case 425:
#line 101 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].list), NIL,
										NULL, NULL,
										(yyvsp[(1) - (3)].with),
										yyscanner);
					(yyval.node) = (yyvsp[(2) - (3)].node);
				;}
    break;

  case 426:
#line 109 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (5)].node), (yyvsp[(3) - (5)].list), (yyvsp[(4) - (5)].list),
										(PGNode*) list_nth((yyvsp[(5) - (5)].list), 0), (PGNode*) list_nth((yyvsp[(5) - (5)].list), 1),
										(yyvsp[(1) - (5)].with),
										yyscanner);
					(yyval.node) = (yyvsp[(2) - (5)].node);
				;}
    break;

  case 427:
#line 117 "third_party/libpg_query/grammar/statements/select.y"
    {
					insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (5)].node), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list),
										(PGNode*) list_nth((yyvsp[(4) - (5)].list), 0), (PGNode*) list_nth((yyvsp[(4) - (5)].list), 1),
										(yyvsp[(1) - (5)].with),
										yyscanner);
					(yyval.node) = (yyvsp[(2) - (5)].node);
				;}
    break;

  case 428:
#line 127 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 429:
#line 128 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 430:
#line 158 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSelectStmt *n = makeNode(PGSelectStmt);
					n->targetList = (yyvsp[(3) - (9)].list);
					n->intoClause = (yyvsp[(4) - (9)].into);
					n->fromClause = (yyvsp[(5) - (9)].list);
					n->whereClause = (yyvsp[(6) - (9)].node);
					n->groupClause = (yyvsp[(7) - (9)].list);
					n->havingClause = (yyvsp[(8) - (9)].node);
					n->windowClause = (yyvsp[(9) - (9)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 431:
#line 172 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSelectStmt *n = makeNode(PGSelectStmt);
					n->distinctClause = (yyvsp[(2) - (9)].list);
					n->targetList = (yyvsp[(3) - (9)].list);
					n->intoClause = (yyvsp[(4) - (9)].into);
					n->fromClause = (yyvsp[(5) - (9)].list);
					n->whereClause = (yyvsp[(6) - (9)].node);
					n->groupClause = (yyvsp[(7) - (9)].list);
					n->havingClause = (yyvsp[(8) - (9)].node);
					n->windowClause = (yyvsp[(9) - (9)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 432:
#line 184 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 433:
#line 186 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* same as SELECT * FROM relation_expr */
					PGColumnRef *cr = makeNode(PGColumnRef);
					PGResTarget *rt = makeNode(PGResTarget);
					PGSelectStmt *n = makeNode(PGSelectStmt);

					cr->fields = list_make1(makeNode(PGAStar));
					cr->location = -1;

					rt->name = NULL;
					rt->indirection = NIL;
					rt->val = (PGNode *)cr;
					rt->location = -1;

					n->targetList = list_make1(rt);
					n->fromClause = list_make1((yyvsp[(2) - (2)].range));
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 434:
#line 205 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSetOp(PG_SETOP_UNION, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node));
				;}
    break;

  case 435:
#line 209 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSetOp(PG_SETOP_INTERSECT, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node));
				;}
    break;

  case 436:
#line 213 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSetOp(PG_SETOP_EXCEPT, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node));
				;}
    break;

  case 437:
#line 230 "third_party/libpg_query/grammar/statements/select.y"
    {
				(yyval.with) = makeNode(PGWithClause);
				(yyval.with)->ctes = (yyvsp[(2) - (2)].list);
				(yyval.with)->recursive = false;
				(yyval.with)->location = (yylsp[(1) - (2)]);
			;}
    break;

  case 438:
#line 237 "third_party/libpg_query/grammar/statements/select.y"
    {
				(yyval.with) = makeNode(PGWithClause);
				(yyval.with)->ctes = (yyvsp[(2) - (2)].list);
				(yyval.with)->recursive = false;
				(yyval.with)->location = (yylsp[(1) - (2)]);
			;}
    break;

  case 439:
#line 244 "third_party/libpg_query/grammar/statements/select.y"
    {
				(yyval.with) = makeNode(PGWithClause);
				(yyval.with)->ctes = (yyvsp[(3) - (3)].list);
				(yyval.with)->recursive = true;
				(yyval.with)->location = (yylsp[(1) - (3)]);
			;}
    break;

  case 440:
#line 253 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 441:
#line 254 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;}
    break;

  case 442:
#line 258 "third_party/libpg_query/grammar/statements/select.y"
    {
				PGCommonTableExpr *n = makeNode(PGCommonTableExpr);
				n->ctename = (yyvsp[(1) - (6)].str);
				n->aliascolnames = (yyvsp[(2) - (6)].list);
				n->ctequery = (yyvsp[(5) - (6)].node);
				n->location = (yylsp[(1) - (6)]);
				(yyval.node) = (PGNode *) n;
			;}
    break;

  case 443:
#line 270 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.into) = makeNode(PGIntoClause);
					(yyval.into)->rel = (yyvsp[(2) - (2)].range);
					(yyval.into)->colNames = NIL;
					(yyval.into)->options = NIL;
					(yyval.into)->onCommit = PG_ONCOMMIT_NOOP;
					(yyval.into)->viewQuery = NULL;
					(yyval.into)->skipData = false;
				;}
    break;

  case 444:
#line 280 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.into) = NULL; ;}
    break;

  case 445:
#line 289 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(3) - (3)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 446:
#line 294 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(3) - (3)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 447:
#line 299 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(4) - (4)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 448:
#line 304 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(4) - (4)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 449:
#line 309 "third_party/libpg_query/grammar/statements/select.y"
    {
					ereport(PGWARNING,
							(errmsg("GLOBAL is deprecated in temporary table creation"),
							 parser_errposition((yylsp[(1) - (4)]))));
					(yyval.range) = (yyvsp[(4) - (4)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 450:
#line 317 "third_party/libpg_query/grammar/statements/select.y"
    {
					ereport(PGWARNING,
							(errmsg("GLOBAL is deprecated in temporary table creation"),
							 parser_errposition((yylsp[(1) - (4)]))));
					(yyval.range) = (yyvsp[(4) - (4)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP;
				;}
    break;

  case 451:
#line 325 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(3) - (3)].range);
					(yyval.range)->relpersistence = PG_RELPERSISTENCE_UNLOGGED;
				;}
    break;

  case 452:
#line 330 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(2) - (2)].range);
					(yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT;
				;}
    break;

  case 453:
#line 335 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = (yyvsp[(1) - (1)].range);
					(yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT;
				;}
    break;

  case 454:
#line 341 "third_party/libpg_query/grammar/statements/select.y"
    {;}
    break;

  case 455:
#line 342 "third_party/libpg_query/grammar/statements/select.y"
    {;}
    break;

  case 456:
#line 346 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = true; ;}
    break;

  case 457:
#line 347 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = false; ;}
    break;

  case 458:
#line 348 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = false; ;}
    break;

  case 459:
#line 355 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(NIL); ;}
    break;

  case 460:
#line 356 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(4) - (5)].list); ;}
    break;

  case 461:
#line 360 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL;;}
    break;

  case 462:
#line 361 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 463:
#line 365 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list);;}
    break;

  case 464:
#line 366 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 465:
#line 370 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (3)].list); ;}
    break;

  case 466:
#line 374 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].sortby)); ;}
    break;

  case 467:
#line 375 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].sortby)); ;}
    break;

  case 468:
#line 379 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.sortby) = makeNode(PGSortBy);
					(yyval.sortby)->node = (yyvsp[(1) - (4)].node);
					(yyval.sortby)->sortby_dir = SORTBY_USING;
					(yyval.sortby)->sortby_nulls = (yyvsp[(4) - (4)].nullorder);
					(yyval.sortby)->useOp = (yyvsp[(3) - (4)].list);
					(yyval.sortby)->location = (yylsp[(3) - (4)]);
				;}
    break;

  case 469:
#line 388 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.sortby) = makeNode(PGSortBy);
					(yyval.sortby)->node = (yyvsp[(1) - (3)].node);
					(yyval.sortby)->sortby_dir = (yyvsp[(2) - (3)].sortorder);
					(yyval.sortby)->sortby_nulls = (yyvsp[(3) - (3)].nullorder);
					(yyval.sortby)->useOp = NIL;
					(yyval.sortby)->location = -1;		/* no operator */
				;}
    break;

  case 470:
#line 398 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.sortorder) = PG_SORTBY_ASC; ;}
    break;

  case 471:
#line 399 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.sortorder) = PG_SORTBY_DESC; ;}
    break;

  case 472:
#line 400 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.sortorder) = PG_SORTBY_DEFAULT; ;}
    break;

  case 473:
#line 403 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.nullorder) = PG_SORTBY_NULLS_FIRST; ;}
    break;

  case 474:
#line 404 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.nullorder) = SORTBY_NULLS_LAST; ;}
    break;

  case 475:
#line 405 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.nullorder) = PG_SORTBY_NULLS_DEFAULT; ;}
    break;

  case 476:
#line 409 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].node)); ;}
    break;

  case 477:
#line 410 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ;}
    break;

  case 478:
#line 411 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2(NULL, (yyvsp[(1) - (1)].node)); ;}
    break;

  case 479:
#line 412 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2((yyvsp[(1) - (1)].node), NULL); ;}
    break;

  case 480:
#line 416 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 481:
#line 417 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2(NULL,NULL); ;}
    break;

  case 482:
#line 422 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 483:
#line 424 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* Disabled because it was too confusing, bjm 2002-02-18 */
					ereport(ERROR,
							(errcode(PG_ERRCODE_SYNTAX_ERROR),
							 errmsg("LIMIT #,# syntax is not supported"),
							 errhint("Use separate LIMIT and OFFSET clauses."),
							 parser_errposition((yylsp[(1) - (4)]))));
				;}
    break;

  case 484:
#line 440 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(3) - (5)].node); ;}
    break;

  case 485:
#line 442 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeIntConst(1, -1); ;}
    break;

  case 486:
#line 447 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 487:
#line 450 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (3)].node); ;}
    break;

  case 488:
#line 454 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 489:
#line 456 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* LIMIT ALL is represented as a NULL constant */
					(yyval.node) = makeNullAConst((yylsp[(1) - (1)]));
				;}
    break;

  case 490:
#line 463 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 491:
#line 483 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 492:
#line 485 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 493:
#line 487 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 494:
#line 491 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival),(yylsp[(1) - (1)])); ;}
    break;

  case 495:
#line 492 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str),(yylsp[(1) - (1)])); ;}
    break;

  case 496:
#line 496 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.ival) = 0; ;}
    break;

  case 497:
#line 497 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.ival) = 0; ;}
    break;

  case 498:
#line 500 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.ival) = 0; ;}
    break;

  case 499:
#line 501 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.ival) = 0; ;}
    break;

  case 500:
#line 526 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (3)].list); ;}
    break;

  case 501:
#line 527 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 502:
#line 531 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 503:
#line 532 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].node)); ;}
    break;

  case 504:
#line 536 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 505:
#line 537 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 506:
#line 542 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_EMPTY, NIL, (yylsp[(1) - (2)]));
				;}
    break;

  case 507:
#line 554 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 508:
#line 555 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 509:
#line 559 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 510:
#line 560 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 511:
#line 564 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 512:
#line 565 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 513:
#line 569 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 514:
#line 570 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;}
    break;

  case 515:
#line 575 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGLockingClause *n = makeNode(PGLockingClause);
					n->lockedRels = (yyvsp[(2) - (3)].list);
					n->strength = (yyvsp[(1) - (3)].lockstrength);
					n->waitPolicy = (yyvsp[(3) - (3)].lockwaitpolicy);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 516:
#line 585 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockstrength) = LCS_FORUPDATE; ;}
    break;

  case 517:
#line 586 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockstrength) = PG_LCS_FORNOKEYUPDATE; ;}
    break;

  case 518:
#line 587 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockstrength) = PG_LCS_FORSHARE; ;}
    break;

  case 519:
#line 588 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockstrength) = PG_LCS_FORKEYSHARE; ;}
    break;

  case 520:
#line 592 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 521:
#line 593 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 522:
#line 598 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockwaitpolicy) = LockWaitError; ;}
    break;

  case 523:
#line 599 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockwaitpolicy) = PGLockWaitSkip; ;}
    break;

  case 524:
#line 600 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.lockwaitpolicy) = PGLockWaitBlock; ;}
    break;

  case 525:
#line 610 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSelectStmt *n = makeNode(PGSelectStmt);
					n->valuesLists = list_make1((yyvsp[(3) - (4)].list));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 526:
#line 616 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSelectStmt *n = (PGSelectStmt *) (yyvsp[(1) - (5)].node);
					n->valuesLists = lappend(n->valuesLists, (yyvsp[(4) - (5)].list));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 527:
#line 633 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 528:
#line 634 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 529:
#line 638 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 530:
#line 639 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;}
    break;

  case 531:
#line 646 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyvsp[(1) - (2)].range)->alias = (yyvsp[(2) - (2)].alias);
					(yyval.node) = (PGNode *) (yyvsp[(1) - (2)].range);
				;}
    break;

  case 532:
#line 651 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeTableSample *n = (PGRangeTableSample *) (yyvsp[(3) - (3)].node);
					(yyvsp[(1) - (3)].range)->alias = (yyvsp[(2) - (3)].alias);
					/* relation_expr goes inside the PGRangeTableSample node */
					n->relation = (PGNode *) (yyvsp[(1) - (3)].range);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 533:
#line 659 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeFunction *n = (PGRangeFunction *) (yyvsp[(1) - (2)].node);
					n->alias = (PGAlias*) linitial((yyvsp[(2) - (2)].list));
					n->coldeflist = (PGList*) lsecond((yyvsp[(2) - (2)].list));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 534:
#line 666 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeFunction *n = (PGRangeFunction *) (yyvsp[(2) - (3)].node);
					n->lateral = true;
					n->alias = (PGAlias*) linitial((yyvsp[(3) - (3)].list));
					n->coldeflist = (PGList*) lsecond((yyvsp[(3) - (3)].list));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 535:
#line 674 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeSubselect *n = makeNode(PGRangeSubselect);
					n->lateral = false;
					n->subquery = (yyvsp[(1) - (2)].node);
					n->alias = (yyvsp[(2) - (2)].alias);
					/*
					 * The SQL spec does not permit a subselect
					 * (<derived_table>) without an alias clause,
					 * so we don't either.  This avoids the problem
					 * of needing to invent a unique refname for it.
					 * That could be surmounted if there's sufficient
					 * popular demand, but for now let's just implement
					 * the spec and see if anyone complains.
					 * However, it does seem like a good idea to emit
					 * an error message that's better than "syntax error".
					 */
					if ((yyvsp[(2) - (2)].alias) == NULL)
					{
						if (IsA((yyvsp[(1) - (2)].node), PGSelectStmt) &&
							((PGSelectStmt *) (yyvsp[(1) - (2)].node))->valuesLists)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("VALUES in FROM must have an alias"),
									 errhint("For example, FROM (VALUES ...) [AS] foo."),
									 parser_errposition((yylsp[(1) - (2)]))));
						else
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("subquery in FROM must have an alias"),
									 errhint("For example, FROM (SELECT ...) [AS] foo."),
									 parser_errposition((yylsp[(1) - (2)]))));
					}
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 536:
#line 709 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeSubselect *n = makeNode(PGRangeSubselect);
					n->lateral = true;
					n->subquery = (yyvsp[(2) - (3)].node);
					n->alias = (yyvsp[(3) - (3)].alias);
					/* same comment as above */
					if ((yyvsp[(3) - (3)].alias) == NULL)
					{
						if (IsA((yyvsp[(2) - (3)].node), PGSelectStmt) &&
							((PGSelectStmt *) (yyvsp[(2) - (3)].node))->valuesLists)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("VALUES in FROM must have an alias"),
									 errhint("For example, FROM (VALUES ...) [AS] foo."),
									 parser_errposition((yylsp[(2) - (3)]))));
						else
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("subquery in FROM must have an alias"),
									 errhint("For example, FROM (SELECT ...) [AS] foo."),
									 parser_errposition((yylsp[(2) - (3)]))));
					}
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 537:
#line 734 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) (yyvsp[(1) - (1)].jexpr);
				;}
    break;

  case 538:
#line 738 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyvsp[(2) - (4)].jexpr)->alias = (yyvsp[(4) - (4)].alias);
					(yyval.node) = (PGNode *) (yyvsp[(2) - (4)].jexpr);
				;}
    break;

  case 539:
#line 764 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.jexpr) = (yyvsp[(2) - (3)].jexpr);
				;}
    break;

  case 540:
#line 768 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* CROSS JOIN is same as unqualified inner join */
					PGJoinExpr *n = makeNode(PGJoinExpr);
					n->jointype = PG_JOIN_INNER;
					n->isNatural = false;
					n->larg = (yyvsp[(1) - (4)].node);
					n->rarg = (yyvsp[(4) - (4)].node);
					n->usingClause = NIL;
					n->quals = NULL;
					(yyval.jexpr) = n;
				;}
    break;

  case 541:
#line 780 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGJoinExpr *n = makeNode(PGJoinExpr);
					n->jointype = (yyvsp[(2) - (5)].jtype);
					n->isNatural = false;
					n->larg = (yyvsp[(1) - (5)].node);
					n->rarg = (yyvsp[(4) - (5)].node);
					if ((yyvsp[(5) - (5)].node) != NULL && IsA((yyvsp[(5) - (5)].node), PGList))
						n->usingClause = (PGList *) (yyvsp[(5) - (5)].node); /* USING clause */
					else
						n->quals = (yyvsp[(5) - (5)].node); /* ON clause */
					(yyval.jexpr) = n;
				;}
    break;

  case 542:
#line 793 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* letting join_type reduce to empty doesn't work */
					PGJoinExpr *n = makeNode(PGJoinExpr);
					n->jointype = PG_JOIN_INNER;
					n->isNatural = false;
					n->larg = (yyvsp[(1) - (4)].node);
					n->rarg = (yyvsp[(3) - (4)].node);
					if ((yyvsp[(4) - (4)].node) != NULL && IsA((yyvsp[(4) - (4)].node), PGList))
						n->usingClause = (PGList *) (yyvsp[(4) - (4)].node); /* USING clause */
					else
						n->quals = (yyvsp[(4) - (4)].node); /* ON clause */
					(yyval.jexpr) = n;
				;}
    break;

  case 543:
#line 807 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGJoinExpr *n = makeNode(PGJoinExpr);
					n->jointype = (yyvsp[(3) - (5)].jtype);
					n->isNatural = true;
					n->larg = (yyvsp[(1) - (5)].node);
					n->rarg = (yyvsp[(5) - (5)].node);
					n->usingClause = NIL; /* figure out which columns later... */
					n->quals = NULL; /* fill later */
					(yyval.jexpr) = n;
				;}
    break;

  case 544:
#line 818 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* letting join_type reduce to empty doesn't work */
					PGJoinExpr *n = makeNode(PGJoinExpr);
					n->jointype = PG_JOIN_INNER;
					n->isNatural = true;
					n->larg = (yyvsp[(1) - (4)].node);
					n->rarg = (yyvsp[(4) - (4)].node);
					n->usingClause = NIL; /* figure out which columns later... */
					n->quals = NULL; /* fill later */
					(yyval.jexpr) = n;
				;}
    break;

  case 545:
#line 833 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.alias) = makeNode(PGAlias);
					(yyval.alias)->aliasname = (yyvsp[(2) - (5)].str);
					(yyval.alias)->colnames = (yyvsp[(4) - (5)].list);
				;}
    break;

  case 546:
#line 839 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.alias) = makeNode(PGAlias);
					(yyval.alias)->aliasname = (yyvsp[(2) - (2)].str);
				;}
    break;

  case 547:
#line 844 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.alias) = makeNode(PGAlias);
					(yyval.alias)->aliasname = (yyvsp[(1) - (4)].str);
					(yyval.alias)->colnames = (yyvsp[(3) - (4)].list);
				;}
    break;

  case 548:
#line 850 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.alias) = makeNode(PGAlias);
					(yyval.alias)->aliasname = (yyvsp[(1) - (1)].str);
				;}
    break;

  case 549:
#line 856 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.alias) = (yyvsp[(1) - (1)].alias); ;}
    break;

  case 550:
#line 857 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.alias) = NULL; ;}
    break;

  case 551:
#line 866 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make2((yyvsp[(1) - (1)].alias), NIL);
				;}
    break;

  case 552:
#line 870 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make2(NULL, (yyvsp[(3) - (4)].list));
				;}
    break;

  case 553:
#line 874 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGAlias *a = makeNode(PGAlias);
					a->aliasname = (yyvsp[(2) - (5)].str);
					(yyval.list) = list_make2(a, (yyvsp[(4) - (5)].list));
				;}
    break;

  case 554:
#line 880 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGAlias *a = makeNode(PGAlias);
					a->aliasname = (yyvsp[(1) - (4)].str);
					(yyval.list) = list_make2(a, (yyvsp[(3) - (4)].list));
				;}
    break;

  case 555:
#line 886 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make2(NULL, NIL);
				;}
    break;

  case 556:
#line 891 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.jtype) = PG_JOIN_FULL; ;}
    break;

  case 557:
#line 892 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.jtype) = PG_JOIN_LEFT; ;}
    break;

  case 558:
#line 893 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.jtype) = PG_JOIN_RIGHT; ;}
    break;

  case 559:
#line 894 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.jtype) = PG_JOIN_INNER; ;}
    break;

  case 560:
#line 898 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 561:
#line 899 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 562:
#line 911 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) (yyvsp[(3) - (4)].list); ;}
    break;

  case 563:
#line 912 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 564:
#line 918 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* inheritance query, implicitly */
					(yyval.range) = (yyvsp[(1) - (1)].range);
					(yyval.range)->inh = true;
					(yyval.range)->alias = NULL;
				;}
    break;

  case 565:
#line 925 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* inheritance query, explicitly */
					(yyval.range) = (yyvsp[(1) - (2)].range);
					(yyval.range)->inh = true;
					(yyval.range)->alias = NULL;
				;}
    break;

  case 566:
#line 932 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* no inheritance */
					(yyval.range) = (yyvsp[(2) - (2)].range);
					(yyval.range)->inh = false;
					(yyval.range)->alias = NULL;
				;}
    break;

  case 567:
#line 939 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* no inheritance, SQL99-style syntax */
					(yyval.range) = (yyvsp[(3) - (4)].range);
					(yyval.range)->inh = false;
					(yyval.range)->alias = NULL;
				;}
    break;

  case 568:
#line 962 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeTableSample *n = makeNode(PGRangeTableSample);
					/* n->relation will be filled in later */
					n->method = (yyvsp[(2) - (6)].list);
					n->args = (yyvsp[(4) - (6)].list);
					n->repeatable = (yyvsp[(6) - (6)].node);
					n->location = (yylsp[(2) - (6)]);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 569:
#line 974 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) (yyvsp[(3) - (4)].node); ;}
    break;

  case 570:
#line 975 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 571:
#line 991 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeFunction *n = makeNode(PGRangeFunction);
					n->lateral = false;
					n->ordinality = (yyvsp[(2) - (2)].boolean);
					n->is_rowsfrom = false;
					n->functions = list_make1(list_make2((yyvsp[(1) - (2)].node), NIL));
					/* alias and coldeflist are set by table_ref production */
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 572:
#line 1001 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGRangeFunction *n = makeNode(PGRangeFunction);
					n->lateral = false;
					n->ordinality = (yyvsp[(6) - (6)].boolean);
					n->is_rowsfrom = true;
					n->functions = (yyvsp[(4) - (6)].list);
					/* alias and coldeflist are set by table_ref production */
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 573:
#line 1013 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list)); ;}
    break;

  case 574:
#line 1017 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;}
    break;

  case 575:
#line 1018 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;}
    break;

  case 576:
#line 1021 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 577:
#line 1022 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 578:
#line 1025 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = true; ;}
    break;

  case 579:
#line 1026 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = false; ;}
    break;

  case 580:
#line 1031 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 581:
#line 1032 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 582:
#line 1038 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
				;}
    break;

  case 583:
#line 1042 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 584:
#line 1048 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGColumnDef *n = makeNode(PGColumnDef);
					n->colname = (yyvsp[(1) - (3)].str);
					n->typeName = (yyvsp[(2) - (3)].typnam);
					n->inhcount = 0;
					n->is_local = true;
					n->is_not_null = false;
					n->is_from_type = false;
					n->storage = 0;
					n->raw_default = NULL;
					n->cooked_default = NULL;
					n->collClause = (PGCollateClause *) (yyvsp[(3) - (3)].node);
					n->collOid = InvalidOid;
					n->constraints = NIL;
					n->location = (yylsp[(1) - (3)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 585:
#line 1069 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGCollateClause *n = makeNode(PGCollateClause);
					n->arg = NULL;
					n->collname = (yyvsp[(2) - (2)].list);
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 586:
#line 1076 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 587:
#line 1089 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (2)].typnam);
					(yyval.typnam)->arrayBounds = (yyvsp[(2) - (2)].list);
				;}
    break;

  case 588:
#line 1094 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(2) - (3)].typnam);
					(yyval.typnam)->arrayBounds = (yyvsp[(3) - (3)].list);
					(yyval.typnam)->setof = true;
				;}
    break;

  case 589:
#line 1101 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (5)].typnam);
					(yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(4) - (5)].ival)));
				;}
    break;

  case 590:
#line 1106 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(2) - (6)].typnam);
					(yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(5) - (6)].ival)));
					(yyval.typnam)->setof = true;
				;}
    break;

  case 591:
#line 1112 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (2)].typnam);
					(yyval.typnam)->arrayBounds = list_make1(makeInteger(-1));
				;}
    break;

  case 592:
#line 1117 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(2) - (3)].typnam);
					(yyval.typnam)->arrayBounds = list_make1(makeInteger(-1));
					(yyval.typnam)->setof = true;
				;}
    break;

  case 593:
#line 1126 "third_party/libpg_query/grammar/statements/select.y"
    {  (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeInteger(-1)); ;}
    break;

  case 594:
#line 1128 "third_party/libpg_query/grammar/statements/select.y"
    {  (yyval.list) = lappend((yyvsp[(1) - (4)].list), makeInteger((yyvsp[(3) - (4)].ival))); ;}
    break;

  case 595:
#line 1130 "third_party/libpg_query/grammar/statements/select.y"
    {  (yyval.list) = NIL; ;}
    break;

  case 596:
#line 1134 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 597:
#line 1135 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 598:
#line 1136 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 599:
#line 1137 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 600:
#line 1138 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 601:
#line 1140 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (2)].typnam);
					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
				;}
    break;

  case 602:
#line 1145 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (4)].typnam);
					(yyval.typnam)->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
											 makeIntConst((yyvsp[(3) - (4)].ival), (yylsp[(3) - (4)])));
				;}
    break;

  case 603:
#line 1164 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 604:
#line 1165 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 605:
#line 1166 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 606:
#line 1167 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;}
    break;

  case 607:
#line 1179 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = makeTypeName((yyvsp[(1) - (2)].str));
					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 608:
#line 1185 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(2) - (3)].list)));
					(yyval.typnam)->typmods = (yyvsp[(3) - (3)].list);
					(yyval.typnam)->location = (yylsp[(1) - (3)]);
				;}
    break;

  case 609:
#line 1192 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 610:
#line 1193 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 611:
#line 1200 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("int4");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 612:
#line 1205 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("int4");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 613:
#line 1210 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("int2");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 614:
#line 1215 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("int8");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 615:
#line 1220 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("float4");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 616:
#line 1225 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(2) - (2)].typnam);
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 617:
#line 1230 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("float8");
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 618:
#line 1235 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("numeric");
					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 619:
#line 1241 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("numeric");
					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 620:
#line 1247 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("numeric");
					(yyval.typnam)->typmods = (yyvsp[(2) - (2)].list);
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 621:
#line 1253 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("bool");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 622:
#line 1260 "third_party/libpg_query/grammar/statements/select.y"
    {
					/*
					 * Check FLOAT() precision limits assuming IEEE floating
					 * types - thomas 1997-09-18
					 */
					if ((yyvsp[(2) - (3)].ival) < 1)
						ereport(ERROR,
								(errcode(PG_ERRCODE_INVALID_PARAMETER_VALUE),
								 errmsg("precision for type float must be at least 1 bit"),
								 parser_errposition((yylsp[(2) - (3)]))));
					else if ((yyvsp[(2) - (3)].ival) <= 24)
						(yyval.typnam) = SystemTypeName("float4");
					else if ((yyvsp[(2) - (3)].ival) <= 53)
						(yyval.typnam) = SystemTypeName("float8");
					else
						ereport(ERROR,
								(errcode(PG_ERRCODE_INVALID_PARAMETER_VALUE),
								 errmsg("precision for type float must be less than 54 bits"),
								 parser_errposition((yylsp[(2) - (3)]))));
				;}
    break;

  case 623:
#line 1281 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("float8");
				;}
    break;

  case 624:
#line 1291 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
				;}
    break;

  case 625:
#line 1295 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
				;}
    break;

  case 626:
#line 1303 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
				;}
    break;

  case 627:
#line 1307 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
					(yyval.typnam)->typmods = NIL;
				;}
    break;

  case 628:
#line 1315 "third_party/libpg_query/grammar/statements/select.y"
    {
					const char *typname;

					typname = (yyvsp[(2) - (5)].boolean) ? "varbit" : "bit";
					(yyval.typnam) = SystemTypeName(typname);
					(yyval.typnam)->typmods = (yyvsp[(4) - (5)].list);
					(yyval.typnam)->location = (yylsp[(1) - (5)]);
				;}
    break;

  case 629:
#line 1327 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* bit defaults to bit(1), varbit to no limit */
					if ((yyvsp[(2) - (2)].boolean))
					{
						(yyval.typnam) = SystemTypeName("varbit");
					}
					else
					{
						(yyval.typnam) = SystemTypeName("bit");
						(yyval.typnam)->typmods = list_make1(makeIntConst(1, -1));
					}
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 630:
#line 1348 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
				;}
    break;

  case 631:
#line 1352 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
				;}
    break;

  case 632:
#line 1358 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
				;}
    break;

  case 633:
#line 1362 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* Length was not specified so allow to be unrestricted.
					 * This handles problems with fixed-length (bpchar) strings
					 * which in column definitions must default to a length
					 * of one, but should not be constrained if the length
					 * was not specified.
					 */
					(yyval.typnam) = (yyvsp[(1) - (1)].typnam);
					(yyval.typnam)->typmods = NIL;
				;}
    break;

  case 634:
#line 1375 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName((yyvsp[(1) - (4)].conststr));
					(yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[(3) - (4)].ival), (yylsp[(3) - (4)])));
					(yyval.typnam)->location = (yylsp[(1) - (4)]);
				;}
    break;

  case 635:
#line 1383 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName((yyvsp[(1) - (1)].conststr));
					/* char defaults to char(1), varchar to no limit */
					if (strcmp((yyvsp[(1) - (1)].conststr), "bpchar") == 0)
						(yyval.typnam)->typmods = list_make1(makeIntConst(1, -1));
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 636:
#line 1393 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;}
    break;

  case 637:
#line 1395 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;}
    break;

  case 638:
#line 1397 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "varchar"; ;}
    break;

  case 639:
#line 1399 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;}
    break;

  case 640:
#line 1401 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;}
    break;

  case 641:
#line 1403 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;}
    break;

  case 642:
#line 1407 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = true; ;}
    break;

  case 643:
#line 1408 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = false; ;}
    break;

  case 644:
#line 1416 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(5) - (5)].boolean))
						(yyval.typnam) = SystemTypeName("timestamptz");
					else
						(yyval.typnam) = SystemTypeName("timestamp");
					(yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[(3) - (5)].ival), (yylsp[(3) - (5)])));
					(yyval.typnam)->location = (yylsp[(1) - (5)]);
				;}
    break;

  case 645:
#line 1425 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(2) - (2)].boolean))
						(yyval.typnam) = SystemTypeName("timestamptz");
					else
						(yyval.typnam) = SystemTypeName("timestamp");
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 646:
#line 1433 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(5) - (5)].boolean))
						(yyval.typnam) = SystemTypeName("timetz");
					else
						(yyval.typnam) = SystemTypeName("time");
					(yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[(3) - (5)].ival), (yylsp[(3) - (5)])));
					(yyval.typnam)->location = (yylsp[(1) - (5)]);
				;}
    break;

  case 647:
#line 1442 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(2) - (2)].boolean))
						(yyval.typnam) = SystemTypeName("timetz");
					else
						(yyval.typnam) = SystemTypeName("time");
					(yyval.typnam)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 648:
#line 1453 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.typnam) = SystemTypeName("interval");
					(yyval.typnam)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 649:
#line 1460 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = true; ;}
    break;

  case 650:
#line 1461 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = false; ;}
    break;

  case 651:
#line 1462 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.boolean) = false; ;}
    break;

  case 652:
#line 1467 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR), (yylsp[(1) - (1)]))); ;}
    break;

  case 653:
#line 1469 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MONTH), (yylsp[(1) - (1)]))); ;}
    break;

  case 654:
#line 1471 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY), (yylsp[(1) - (1)]))); ;}
    break;

  case 655:
#line 1473 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR), (yylsp[(1) - (1)]))); ;}
    break;

  case 656:
#line 1475 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), (yylsp[(1) - (1)]))); ;}
    break;

  case 657:
#line 1477 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 658:
#line 1479 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR) |
												 INTERVAL_MASK(MONTH), (yylsp[(1) - (3)])));
				;}
    break;

  case 659:
#line 1484 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
												 INTERVAL_MASK(HOUR), (yylsp[(1) - (3)])));
				;}
    break;

  case 660:
#line 1489 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
												 INTERVAL_MASK(HOUR) |
												 INTERVAL_MASK(MINUTE), (yylsp[(1) - (3)])));
				;}
    break;

  case 661:
#line 1495 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = (yyvsp[(3) - (3)].list);
					linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(DAY) |
												INTERVAL_MASK(HOUR) |
												INTERVAL_MASK(MINUTE) |
												INTERVAL_MASK(SECOND), (yylsp[(1) - (3)]));
				;}
    break;

  case 662:
#line 1503 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) |
												 INTERVAL_MASK(MINUTE), (yylsp[(1) - (3)])));
				;}
    break;

  case 663:
#line 1508 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = (yyvsp[(3) - (3)].list);
					linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(HOUR) |
												INTERVAL_MASK(MINUTE) |
												INTERVAL_MASK(SECOND), (yylsp[(1) - (3)]));
				;}
    break;

  case 664:
#line 1515 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = (yyvsp[(3) - (3)].list);
					linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(MINUTE) |
												INTERVAL_MASK(SECOND), (yylsp[(1) - (3)]));
				;}
    break;

  case 665:
#line 1521 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 666:
#line 1526 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (1)])));
				;}
    break;

  case 667:
#line 1530 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make2(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (4)])),
									makeIntConst((yyvsp[(3) - (4)].ival), (yylsp[(3) - (4)])));
				;}
    break;

  case 668:
#line 1565 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 669:
#line 1567 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeTypeCast((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].typnam), (yylsp[(2) - (3)])); ;}
    break;

  case 670:
#line 1569 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGCollateClause *n = makeNode(PGCollateClause);
					n->arg = (yyvsp[(1) - (3)].node);
					n->collname = (yyvsp[(3) - (3)].list);
					n->location = (yylsp[(2) - (3)]);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 671:
#line 1577 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("timezone"),
											   list_make2((yyvsp[(5) - (5)].node), (yyvsp[(1) - (5)].node)),
											   (yylsp[(2) - (5)]));
				;}
    break;

  case 672:
#line 1592 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 673:
#line 1594 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 674:
#line 1596 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 675:
#line 1598 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "-", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 676:
#line 1600 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 677:
#line 1602 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "/", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 678:
#line 1604 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "%", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 679:
#line 1606 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "^", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 680:
#line 1608 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 681:
#line 1610 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 682:
#line 1612 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 683:
#line 1614 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 684:
#line 1616 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 685:
#line 1618 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<>", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 686:
#line 1621 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (3)].list), (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 687:
#line 1623 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(1) - (2)].list), NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 688:
#line 1625 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (2)].list), (yyvsp[(1) - (2)].node), NULL, (yylsp[(2) - (2)])); ;}
    break;

  case 689:
#line 1628 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeAndExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 690:
#line 1630 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeOrExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 691:
#line 1632 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 692:
#line 1634 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 693:
#line 1637 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "~~",
												   (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)]));
				;}
    break;

  case 694:
#line 1642 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
											   list_make2((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)),
											   (yylsp[(2) - (5)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "~~",
												   (yyvsp[(1) - (5)].node), (PGNode *) n, (yylsp[(2) - (5)]));
				;}
    break;

  case 695:
#line 1650 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "!~~",
												   (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)]));
				;}
    break;

  case 696:
#line 1655 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
											   list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)),
											   (yylsp[(2) - (6)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "!~~",
												   (yyvsp[(1) - (6)].node), (PGNode *) n, (yylsp[(2) - (6)]));
				;}
    break;

  case 697:
#line 1663 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "~~*",
												   (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)]));
				;}
    break;

  case 698:
#line 1668 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
											   list_make2((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)),
											   (yylsp[(2) - (5)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "~~*",
												   (yyvsp[(1) - (5)].node), (PGNode *) n, (yylsp[(2) - (5)]));
				;}
    break;

  case 699:
#line 1676 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "!~~*",
												   (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)]));
				;}
    break;

  case 700:
#line 1681 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
											   list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)),
											   (yylsp[(2) - (6)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "!~~*",
												   (yyvsp[(1) - (6)].node), (PGNode *) n, (yylsp[(2) - (6)]));
				;}
    break;

  case 701:
#line 1690 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
											   list_make2((yyvsp[(4) - (4)].node), makeNullAConst(-1)),
											   (yylsp[(2) - (4)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_SIMILAR, "~",
												   (yyvsp[(1) - (4)].node), (PGNode *) n, (yylsp[(2) - (4)]));
				;}
    break;

  case 702:
#line 1698 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
											   list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)),
											   (yylsp[(2) - (6)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_SIMILAR, "~",
												   (yyvsp[(1) - (6)].node), (PGNode *) n, (yylsp[(2) - (6)]));
				;}
    break;

  case 703:
#line 1706 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
											   list_make2((yyvsp[(5) - (5)].node), makeNullAConst(-1)),
											   (yylsp[(2) - (5)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_SIMILAR, "!~",
												   (yyvsp[(1) - (5)].node), (PGNode *) n, (yylsp[(2) - (5)]));
				;}
    break;

  case 704:
#line 1714 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
											   list_make2((yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)),
											   (yylsp[(2) - (7)]));
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_SIMILAR, "!~",
												   (yyvsp[(1) - (7)].node), (PGNode *) n, (yylsp[(2) - (7)]));
				;}
    break;

  case 705:
#line 1732 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNullTest *n = makeNode(PGNullTest);
					n->arg = (PGExpr *) (yyvsp[(1) - (3)].node);
					n->nulltesttype = PG_IS_NULL;
					n->location = (yylsp[(2) - (3)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 706:
#line 1740 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNullTest *n = makeNode(PGNullTest);
					n->arg = (PGExpr *) (yyvsp[(1) - (2)].node);
					n->nulltesttype = PG_IS_NULL;
					n->location = (yylsp[(2) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 707:
#line 1748 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNullTest *n = makeNode(PGNullTest);
					n->arg = (PGExpr *) (yyvsp[(1) - (4)].node);
					n->nulltesttype = IS_NOT_NULL;
					n->location = (yylsp[(2) - (4)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 708:
#line 1756 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNullTest *n = makeNode(PGNullTest);
					n->arg = (PGExpr *) (yyvsp[(1) - (3)].node);
					n->nulltesttype = IS_NOT_NULL;
					n->location = (yylsp[(2) - (3)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 709:
#line 1764 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNullTest *n = makeNode(PGNullTest);
					n->arg = (PGExpr *) (yyvsp[(1) - (2)].node);
					n->nulltesttype = IS_NOT_NULL;
					n->location = (yylsp[(2) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 710:
#line 1772 "third_party/libpg_query/grammar/statements/select.y"
    {
					if (list_length((yyvsp[(1) - (3)].list)) != 2)
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("wrong number of parameters on left side of OVERLAPS expression"),
								 parser_errposition((yylsp[(1) - (3)]))));
					if (list_length((yyvsp[(3) - (3)].list)) != 2)
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
								 errmsg("wrong number of parameters on right side of OVERLAPS expression"),
								 parser_errposition((yylsp[(3) - (3)]))));
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("overlaps"),
											   list_concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)),
											   (yylsp[(2) - (3)]));
				;}
    break;

  case 711:
#line 1788 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGBooleanTest *b = makeNode(PGBooleanTest);
					b->arg = (PGExpr *) (yyvsp[(1) - (3)].node);
					b->booltesttype = PG_IS_TRUE;
					b->location = (yylsp[(2) - (3)]);
					(yyval.node) = (PGNode *)b;
				;}
    break;

  case 712:
#line 1796 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGBooleanTest *b = makeNode(PGBooleanTest);
					b->arg = (PGExpr *) (yyvsp[(1) - (4)].node);
					b->booltesttype = IS_NOT_TRUE;
					b->location = (yylsp[(2) - (4)]);
					(yyval.node) = (PGNode *)b;
				;}
    break;

  case 713:
#line 1804 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGBooleanTest *b = makeNode(PGBooleanTest);
					b->arg = (PGExpr *) (yyvsp[(1) - (3)].node);
					b->booltesttype = IS_FALSE;
					b->location = (yylsp[(2) - (3)]);
					(yyval.node) = (PGNode *)b;
				;}
    break;

  case 714:
#line 1812 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGBooleanTest *b = makeNode(PGBooleanTest);
					b->arg = (PGExpr *) (yyvsp[(1) - (4)].node);
					b->booltesttype = IS_NOT_FALSE;
					b->location = (yylsp[(2) - (4)]);
					(yyval.node) = (PGNode *)b;
				;}
    break;

  case 715:
#line 1820 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGBooleanTest *b = makeNode(PGBooleanTest);
					b->arg = (PGExpr *) (yyvsp[(1) - (3)].node);
					b->booltesttype = IS_UNKNOWN;
					b->location = (yylsp[(2) - (3)]);
					(yyval.node) = (PGNode *)b;
				;}
    break;

  case 716:
#line 1828 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGBooleanTest *b = makeNode(PGBooleanTest);
					b->arg = (PGExpr *) (yyvsp[(1) - (4)].node);
					b->booltesttype = IS_NOT_UNKNOWN;
					b->location = (yylsp[(2) - (4)]);
					(yyval.node) = (PGNode *)b;
				;}
    break;

  case 717:
#line 1836 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_DISTINCT, "=", (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node), (yylsp[(2) - (5)]));
				;}
    break;

  case 718:
#line 1840 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_DISTINCT, "=", (yyvsp[(1) - (6)].node), (yyvsp[(6) - (6)].node), (yylsp[(2) - (6)]));
				;}
    break;

  case 719:
#line 1844 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "=", (yyvsp[(1) - (6)].node), (PGNode *) (yyvsp[(5) - (6)].list), (yylsp[(2) - (6)]));
				;}
    break;

  case 720:
#line 1848 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "<>", (yyvsp[(1) - (7)].node), (PGNode *) (yyvsp[(6) - (7)].list), (yylsp[(2) - (7)]));
				;}
    break;

  case 721:
#line 1852 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN,
												   "BETWEEN",
												   (yyvsp[(1) - (6)].node),
												   (PGNode *) list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)),
												   (yylsp[(2) - (6)]));
				;}
    break;

  case 722:
#line 1860 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN,
												   "NOT BETWEEN",
												   (yyvsp[(1) - (7)].node),
												   (PGNode *) list_make2((yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)),
												   (yylsp[(2) - (7)]));
				;}
    break;

  case 723:
#line 1868 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN_SYM,
												   "BETWEEN SYMMETRIC",
												   (yyvsp[(1) - (6)].node),
												   (PGNode *) list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)),
												   (yylsp[(2) - (6)]));
				;}
    break;

  case 724:
#line 1876 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN_SYM,
												   "NOT BETWEEN SYMMETRIC",
												   (yyvsp[(1) - (7)].node),
												   (PGNode *) list_make2((yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)),
												   (yylsp[(2) - (7)]));
				;}
    break;

  case 725:
#line 1884 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* in_expr returns a PGSubLink or a list of a_exprs */
					if (IsA((yyvsp[(3) - (3)].node), PGSubLink))
					{
						/* generate foo = ANY (subquery) */
						PGSubLink *n = (PGSubLink *) (yyvsp[(3) - (3)].node);
						n->subLinkType = PG_ANY_SUBLINK;
						n->subLinkId = 0;
						n->testexpr = (yyvsp[(1) - (3)].node);
						n->operName = NIL;		/* show it's IN not = ANY */
						n->location = (yylsp[(2) - (3)]);
						(yyval.node) = (PGNode *)n;
					}
					else
					{
						/* generate scalar IN expression */
						(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_IN, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)]));
					}
				;}
    break;

  case 726:
#line 1904 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* in_expr returns a PGSubLink or a list of a_exprs */
					if (IsA((yyvsp[(4) - (4)].node), PGSubLink))
					{
						/* generate NOT (foo = ANY (subquery)) */
						/* Make an = ANY node */
						PGSubLink *n = (PGSubLink *) (yyvsp[(4) - (4)].node);
						n->subLinkType = PG_ANY_SUBLINK;
						n->subLinkId = 0;
						n->testexpr = (yyvsp[(1) - (4)].node);
						n->operName = NIL;		/* show it's IN not = ANY */
						n->location = (yylsp[(2) - (4)]);
						/* Stick a NOT on top; must have same parse location */
						(yyval.node) = makeNotExpr((PGNode *) n, (yylsp[(2) - (4)]));
					}
					else
					{
						/* generate scalar NOT IN expression */
						(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_IN, "<>", (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)]));
					}
				;}
    break;

  case 727:
#line 1926 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSubLink *n = makeNode(PGSubLink);
					n->subLinkType = (yyvsp[(3) - (4)].subquerytype);
					n->subLinkId = 0;
					n->testexpr = (yyvsp[(1) - (4)].node);
					n->operName = (yyvsp[(2) - (4)].list);
					n->subselect = (yyvsp[(4) - (4)].node);
					n->location = (yylsp[(2) - (4)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 728:
#line 1937 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(3) - (6)].subquerytype) == PG_ANY_SUBLINK)
						(yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP_ANY, (yyvsp[(2) - (6)].list), (yyvsp[(1) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(2) - (6)]));
					else
						(yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP_ALL, (yyvsp[(2) - (6)].list), (yyvsp[(1) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(2) - (6)]));
				;}
    break;

  case 729:
#line 1944 "third_party/libpg_query/grammar/statements/select.y"
    {
					/*
					 * The SQL spec only allows DEFAULT in "contextually typed
					 * expressions", but for us, it's easier to allow it in
					 * any a_expr and then throw error during parse analysis
					 * if it's in an inappropriate context.  This way also
					 * lets us say something smarter than "syntax error".
					 */
					PGSetToDefault *n = makeNode(PGSetToDefault);
					/* parse analysis will fill in the rest */
					n->location = (yylsp[(1) - (1)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 730:
#line 1969 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 731:
#line 1971 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeTypeCast((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].typnam), (yylsp[(2) - (3)])); ;}
    break;

  case 732:
#line 1973 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 733:
#line 1975 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 734:
#line 1977 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 735:
#line 1979 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "-", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 736:
#line 1981 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 737:
#line 1983 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "/", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 738:
#line 1985 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "%", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 739:
#line 1987 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "^", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 740:
#line 1989 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 741:
#line 1991 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 742:
#line 1993 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 743:
#line 1995 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 744:
#line 1997 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 745:
#line 1999 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<>", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 746:
#line 2001 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (3)].list), (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;}
    break;

  case 747:
#line 2003 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(1) - (2)].list), NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;}
    break;

  case 748:
#line 2005 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (2)].list), (yyvsp[(1) - (2)].node), NULL, (yylsp[(2) - (2)])); ;}
    break;

  case 749:
#line 2007 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_DISTINCT, "=", (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node), (yylsp[(2) - (5)]));
				;}
    break;

  case 750:
#line 2011 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_DISTINCT, "=", (yyvsp[(1) - (6)].node), (yyvsp[(6) - (6)].node), (yylsp[(2) - (6)]));
				;}
    break;

  case 751:
#line 2015 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "=", (yyvsp[(1) - (6)].node), (PGNode *) (yyvsp[(5) - (6)].list), (yylsp[(2) - (6)]));
				;}
    break;

  case 752:
#line 2019 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "<>", (yyvsp[(1) - (7)].node), (PGNode *) (yyvsp[(6) - (7)].list), (yylsp[(2) - (7)]));
				;}
    break;

  case 753:
#line 2032 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 754:
#line 2033 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 755:
#line 2035 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(2) - (2)].list))
					{
						PGAIndirection *n = makeNode(PGAIndirection);
						n->arg = makeParamRef(0, (yylsp[(1) - (2)]));
						n->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner);
						(yyval.node) = (PGNode *) n;
					}
					else
						(yyval.node) = makeParamRef(0, (yylsp[(1) - (2)]));
				;}
    break;

  case 756:
#line 2047 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGParamRef *p = makeNode(PGParamRef);
					p->number = (yyvsp[(1) - (2)].ival);
					p->location = (yylsp[(1) - (2)]);
					if ((yyvsp[(2) - (2)].list))
					{
						PGAIndirection *n = makeNode(PGAIndirection);
						n->arg = (PGNode *) p;
						n->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner);
						(yyval.node) = (PGNode *) n;
					}
					else
						(yyval.node) = (PGNode *) p;
				;}
    break;

  case 757:
#line 2062 "third_party/libpg_query/grammar/statements/select.y"
    {
					if ((yyvsp[(4) - (4)].list))
					{
						PGAIndirection *n = makeNode(PGAIndirection);
						n->arg = (yyvsp[(2) - (4)].node);
						n->indirection = check_indirection((yyvsp[(4) - (4)].list), yyscanner);
						(yyval.node) = (PGNode *)n;
					}
					else
						(yyval.node) = (yyvsp[(2) - (4)].node);
				;}
    break;

  case 758:
#line 2074 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 759:
#line 2076 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 760:
#line 2078 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSubLink *n = makeNode(PGSubLink);
					n->subLinkType = PG_EXPR_SUBLINK;
					n->subLinkId = 0;
					n->testexpr = NULL;
					n->operName = NIL;
					n->subselect = (yyvsp[(1) - (1)].node);
					n->location = (yylsp[(1) - (1)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 761:
#line 2089 "third_party/libpg_query/grammar/statements/select.y"
    {
					/*
					 * Because the select_with_parens nonterminal is designed
					 * to "eat" as many levels of parens as possible, the
					 * '(' a_expr ')' opt_indirection production above will
					 * fail to match a sub-SELECT with indirection decoration;
					 * the sub-SELECT won't be regarded as an a_expr as long
					 * as there are parens around it.  To support applying
					 * subscripting or field selection to a sub-SELECT result,
					 * we need this redundant-looking production.
					 */
					PGSubLink *n = makeNode(PGSubLink);
					PGAIndirection *a = makeNode(PGAIndirection);
					n->subLinkType = PG_EXPR_SUBLINK;
					n->subLinkId = 0;
					n->testexpr = NULL;
					n->operName = NIL;
					n->subselect = (yyvsp[(1) - (2)].node);
					n->location = (yylsp[(1) - (2)]);
					a->arg = (PGNode *)n;
					a->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner);
					(yyval.node) = (PGNode *)a;
				;}
    break;

  case 762:
#line 2113 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSubLink *n = makeNode(PGSubLink);
					n->subLinkType = PG_EXISTS_SUBLINK;
					n->subLinkId = 0;
					n->testexpr = NULL;
					n->operName = NIL;
					n->subselect = (yyvsp[(2) - (2)].node);
					n->location = (yylsp[(1) - (2)]);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 763:
#line 2126 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall((yyvsp[(1) - (3)].list), NIL, (yylsp[(1) - (3)]));
				;}
    break;

  case 764:
#line 2130 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall((yyvsp[(1) - (5)].list), (yyvsp[(3) - (5)].list), (yylsp[(1) - (5)]));
					n->agg_order = (yyvsp[(4) - (5)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 765:
#line 2136 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), list_make1((yyvsp[(4) - (6)].node)), (yylsp[(1) - (6)]));
					n->func_variadic = true;
					n->agg_order = (yyvsp[(5) - (6)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 766:
#line 2143 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall((yyvsp[(1) - (8)].list), lappend((yyvsp[(3) - (8)].list), (yyvsp[(6) - (8)].node)), (yylsp[(1) - (8)]));
					n->func_variadic = true;
					n->agg_order = (yyvsp[(7) - (8)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 767:
#line 2150 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(4) - (6)].list), (yylsp[(1) - (6)]));
					n->agg_order = (yyvsp[(5) - (6)].list);
					/* Ideally we'd mark the PGFuncCall node to indicate
					 * "must be an aggregate", but there's no provision
					 * for that in PGFuncCall at the moment.
					 */
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 768:
#line 2160 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(4) - (6)].list), (yylsp[(1) - (6)]));
					n->agg_order = (yyvsp[(5) - (6)].list);
					n->agg_distinct = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 769:
#line 2167 "third_party/libpg_query/grammar/statements/select.y"
    {
					/*
					 * We consider AGGREGATE(*) to invoke a parameterless
					 * aggregate.  This does the right thing for COUNT(*),
					 * and there are no other aggregates in SQL that accept
					 * '*' as parameter.
					 *
					 * The PGFuncCall node is also marked agg_star = true,
					 * so that later processing can detect what the argument
					 * really was.
					 */
					PGFuncCall *n = makeFuncCall((yyvsp[(1) - (4)].list), NIL, (yylsp[(1) - (4)]));
					n->agg_star = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 770:
#line 2195 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGFuncCall *n = (PGFuncCall *) (yyvsp[(1) - (4)].node);
					/*
					 * The order clause for WITHIN GROUP and the one for
					 * plain-aggregate ORDER BY share a field, so we have to
					 * check here that at most one is present.  We also check
					 * for DISTINCT and VARIADIC here to give a better error
					 * location.  Other consistency checks are deferred to
					 * parse analysis.
					 */
					if ((yyvsp[(2) - (4)].list) != NIL)
					{
						if (n->agg_order != NIL)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("cannot use multiple ORDER BY clauses with WITHIN GROUP"),
									 parser_errposition((yylsp[(2) - (4)]))));
						if (n->agg_distinct)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("cannot use DISTINCT with WITHIN GROUP"),
									 parser_errposition((yylsp[(2) - (4)]))));
						if (n->func_variadic)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("cannot use VARIADIC with WITHIN GROUP"),
									 parser_errposition((yylsp[(2) - (4)]))));
						n->agg_order = (yyvsp[(2) - (4)].list);
						n->agg_within_group = true;
					}
					n->agg_filter = (yyvsp[(3) - (4)].node);
					n->over = (yyvsp[(4) - (4)].windef);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 771:
#line 2230 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 772:
#line 2240 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 773:
#line 2241 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 774:
#line 2249 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("pg_collation_for"),
											   list_make1((yyvsp[(4) - (5)].node)),
											   (yylsp[(1) - (5)]));
				;}
    break;

  case 775:
#line 2255 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_DATE, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 776:
#line 2259 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIME, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 777:
#line 2263 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIME_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)]));
				;}
    break;

  case 778:
#line 2267 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIMESTAMP, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 779:
#line 2271 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIMESTAMP_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)]));
				;}
    break;

  case 780:
#line 2275 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIME, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 781:
#line 2279 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIME_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)]));
				;}
    break;

  case 782:
#line 2283 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIMESTAMP, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 783:
#line 2287 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIMESTAMP_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)]));
				;}
    break;

  case 784:
#line 2291 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_ROLE, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 785:
#line 2295 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_USER, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 786:
#line 2299 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_SESSION_USER, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 787:
#line 2303 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_USER, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 788:
#line 2307 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_CATALOG, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 789:
#line 2311 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_SCHEMA, -1, (yylsp[(1) - (1)]));
				;}
    break;

  case 790:
#line 2315 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = makeTypeCast((yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].typnam), (yylsp[(1) - (6)])); ;}
    break;

  case 791:
#line 2317 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("date_part"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)]));
				;}
    break;

  case 792:
#line 2321 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* overlay(A PLACING B FROM C FOR D) is converted to
					 * overlay(A, B, C, D)
					 * overlay(A PLACING B FROM C) is converted to
					 * overlay(A, B, C)
					 */
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("overlay"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)]));
				;}
    break;

  case 793:
#line 2330 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* position(A in B) is converted to position(B, A) */
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("position"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)]));
				;}
    break;

  case 794:
#line 2335 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* substring(A from B for C) is converted to
					 * substring(A, B, C) - thomas 2000-11-28
					 */
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("substring"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)]));
				;}
    break;

  case 795:
#line 2342 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* TREAT(expr AS target) converts expr of a particular type to target,
					 * which is defined to be a subtype of the original expression.
					 * In SQL99, this is intended for use with structured UDTs,
					 * but let's make this a generally useful form allowing stronger
					 * coercions than are handled by implicit casting.
					 *
					 * Convert SystemTypeName() to SystemFuncName() even though
					 * at the moment they result in the same thing.
					 */
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName(((PGValue *)llast((yyvsp[(5) - (6)].typnam)->names))->val.str),
												list_make1((yyvsp[(3) - (6)].node)),
												(yylsp[(1) - (6)]));
				;}
    break;

  case 796:
#line 2357 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* various trim expressions are defined in SQL
					 * - thomas 1997-07-19
					 */
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("btrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)]));
				;}
    break;

  case 797:
#line 2364 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("ltrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)]));
				;}
    break;

  case 798:
#line 2368 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("rtrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)]));
				;}
    break;

  case 799:
#line 2372 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("btrim"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)]));
				;}
    break;

  case 800:
#line 2376 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NULLIF, "=", (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(1) - (6)]));
				;}
    break;

  case 801:
#line 2380 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGCoalesceExpr *c = makeNode(PGCoalesceExpr);
					c->args = (yyvsp[(3) - (4)].list);
					c->location = (yylsp[(1) - (4)]);
					(yyval.node) = (PGNode *)c;
				;}
    break;

  case 802:
#line 2387 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGMinMaxExpr *v = makeNode(PGMinMaxExpr);
					v->args = (yyvsp[(3) - (4)].list);
					v->op = PG_IS_GREATEST;
					v->location = (yylsp[(1) - (4)]);
					(yyval.node) = (PGNode *)v;
				;}
    break;

  case 803:
#line 2395 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGMinMaxExpr *v = makeNode(PGMinMaxExpr);
					v->args = (yyvsp[(3) - (4)].list);
					v->op = IS_LEAST;
					v->location = (yylsp[(1) - (4)]);
					(yyval.node) = (PGNode *)v;
				;}
    break;

  case 804:
#line 2409 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(4) - (5)].list); ;}
    break;

  case 805:
#line 2410 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 806:
#line 2414 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(4) - (5)].node); ;}
    break;

  case 807:
#line 2415 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 808:
#line 2423 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 809:
#line 2424 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 810:
#line 2428 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].windef)); ;}
    break;

  case 811:
#line 2430 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].windef)); ;}
    break;

  case 812:
#line 2435 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = (yyvsp[(3) - (3)].windef);
					n->name = (yyvsp[(1) - (3)].str);
					(yyval.windef) = n;
				;}
    break;

  case 813:
#line 2443 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.windef) = (yyvsp[(2) - (2)].windef); ;}
    break;

  case 814:
#line 2445 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->name = (yyvsp[(2) - (2)].str);
					n->refname = NULL;
					n->partitionClause = NIL;
					n->orderClause = NIL;
					n->frameOptions = FRAMEOPTION_DEFAULTS;
					n->startOffset = NULL;
					n->endOffset = NULL;
					n->location = (yylsp[(2) - (2)]);
					(yyval.windef) = n;
				;}
    break;

  case 815:
#line 2458 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.windef) = NULL; ;}
    break;

  case 816:
#line 2463 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->name = NULL;
					n->refname = (yyvsp[(2) - (6)].str);
					n->partitionClause = (yyvsp[(3) - (6)].list);
					n->orderClause = (yyvsp[(4) - (6)].list);
					/* copy relevant fields of opt_frame_clause */
					n->frameOptions = (yyvsp[(5) - (6)].windef)->frameOptions;
					n->startOffset = (yyvsp[(5) - (6)].windef)->startOffset;
					n->endOffset = (yyvsp[(5) - (6)].windef)->endOffset;
					n->location = (yylsp[(1) - (6)]);
					(yyval.windef) = n;
				;}
    break;

  case 817:
#line 2488 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 818:
#line 2489 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = NULL; ;}
    break;

  case 819:
#line 2492 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (3)].list); ;}
    break;

  case 820:
#line 2493 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 821:
#line 2505 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = (yyvsp[(2) - (2)].windef);
					n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE;
					if (n->frameOptions & (FRAMEOPTION_START_VALUE_PRECEDING |
										   FRAMEOPTION_END_VALUE_PRECEDING))
						ereport(ERROR,
								(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("RANGE PRECEDING is only supported with UNBOUNDED"),
								 parser_errposition((yylsp[(1) - (2)]))));
					if (n->frameOptions & (FRAMEOPTION_START_VALUE_FOLLOWING |
										   FRAMEOPTION_END_VALUE_FOLLOWING))
						ereport(ERROR,
								(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("RANGE FOLLOWING is only supported with UNBOUNDED"),
								 parser_errposition((yylsp[(1) - (2)]))));
					(yyval.windef) = n;
				;}
    break;

  case 822:
#line 2523 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = (yyvsp[(2) - (2)].windef);
					n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS;
					(yyval.windef) = n;
				;}
    break;

  case 823:
#line 2529 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->frameOptions = FRAMEOPTION_DEFAULTS;
					n->startOffset = NULL;
					n->endOffset = NULL;
					(yyval.windef) = n;
				;}
    break;

  case 824:
#line 2539 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = (yyvsp[(1) - (1)].windef);
					/* reject invalid cases */
					if (n->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
						ereport(ERROR,
								(errcode(PG_ERRCODE_WINDOWING_ERROR),
								 errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
								 parser_errposition((yylsp[(1) - (1)]))));
					if (n->frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING)
						ereport(ERROR,
								(errcode(PG_ERRCODE_WINDOWING_ERROR),
								 errmsg("frame starting from following row cannot end with current row"),
								 parser_errposition((yylsp[(1) - (1)]))));
					n->frameOptions |= FRAMEOPTION_END_CURRENT_ROW;
					(yyval.windef) = n;
				;}
    break;

  case 825:
#line 2556 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n1 = (yyvsp[(2) - (4)].windef);
					PGWindowDef *n2 = (yyvsp[(4) - (4)].windef);
					/* form merged options */
					int		frameOptions = n1->frameOptions;
					/* shift converts START_ options to END_ options */
					frameOptions |= n2->frameOptions << 1;
					frameOptions |= FRAMEOPTION_BETWEEN;
					/* reject invalid cases */
					if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
						ereport(ERROR,
								(errcode(PG_ERRCODE_WINDOWING_ERROR),
								 errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
								 parser_errposition((yylsp[(2) - (4)]))));
					if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING)
						ereport(ERROR,
								(errcode(PG_ERRCODE_WINDOWING_ERROR),
								 errmsg("frame end cannot be UNBOUNDED PRECEDING"),
								 parser_errposition((yylsp[(4) - (4)]))));
					if ((frameOptions & FRAMEOPTION_START_CURRENT_ROW) &&
						(frameOptions & FRAMEOPTION_END_VALUE_PRECEDING))
						ereport(ERROR,
								(errcode(PG_ERRCODE_WINDOWING_ERROR),
								 errmsg("frame starting from current row cannot have preceding rows"),
								 parser_errposition((yylsp[(4) - (4)]))));
					if ((frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING) &&
						(frameOptions & (FRAMEOPTION_END_VALUE_PRECEDING |
										 FRAMEOPTION_END_CURRENT_ROW)))
						ereport(ERROR,
								(errcode(PG_ERRCODE_WINDOWING_ERROR),
								 errmsg("frame starting from following row cannot have preceding rows"),
								 parser_errposition((yylsp[(4) - (4)]))));
					n1->frameOptions = frameOptions;
					n1->endOffset = n2->startOffset;
					(yyval.windef) = n1;
				;}
    break;

  case 826:
#line 2601 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING;
					n->startOffset = NULL;
					n->endOffset = NULL;
					(yyval.windef) = n;
				;}
    break;

  case 827:
#line 2609 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING;
					n->startOffset = NULL;
					n->endOffset = NULL;
					(yyval.windef) = n;
				;}
    break;

  case 828:
#line 2617 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->frameOptions = FRAMEOPTION_START_CURRENT_ROW;
					n->startOffset = NULL;
					n->endOffset = NULL;
					(yyval.windef) = n;
				;}
    break;

  case 829:
#line 2625 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->frameOptions = FRAMEOPTION_START_VALUE_PRECEDING;
					n->startOffset = (yyvsp[(1) - (2)].node);
					n->endOffset = NULL;
					(yyval.windef) = n;
				;}
    break;

  case 830:
#line 2633 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGWindowDef *n = makeNode(PGWindowDef);
					n->frameOptions = FRAMEOPTION_START_VALUE_FOLLOWING;
					n->startOffset = (yyvsp[(1) - (2)].node);
					n->endOffset = NULL;
					(yyval.windef) = n;
				;}
    break;

  case 831:
#line 2653 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 832:
#line 2654 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 833:
#line 2655 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(2) - (5)].list), (yyvsp[(4) - (5)].node)); ;}
    break;

  case 834:
#line 2658 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.subquerytype) = PG_ANY_SUBLINK; ;}
    break;

  case 835:
#line 2659 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.subquerytype) = PG_ANY_SUBLINK; ;}
    break;

  case 836:
#line 2660 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.subquerytype) = PG_ALL_SUBLINK; ;}
    break;

  case 837:
#line 2663 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 838:
#line 2664 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) (yyvsp[(1) - (1)].conststr); ;}
    break;

  case 839:
#line 2667 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "+"; ;}
    break;

  case 840:
#line 2668 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "-"; ;}
    break;

  case 841:
#line 2669 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "*"; ;}
    break;

  case 842:
#line 2670 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "/"; ;}
    break;

  case 843:
#line 2671 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "%"; ;}
    break;

  case 844:
#line 2672 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "^"; ;}
    break;

  case 845:
#line 2673 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "<"; ;}
    break;

  case 846:
#line 2674 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = ">"; ;}
    break;

  case 847:
#line 2675 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "="; ;}
    break;

  case 848:
#line 2676 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "<="; ;}
    break;

  case 849:
#line 2677 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = ">="; ;}
    break;

  case 850:
#line 2678 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.conststr) = "<>"; ;}
    break;

  case 851:
#line 2682 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 852:
#line 2684 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 853:
#line 2689 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 854:
#line 2691 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 855:
#line 2696 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 856:
#line 2698 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(3) - (4)].list); ;}
    break;

  case 857:
#line 2700 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString("~~")); ;}
    break;

  case 858:
#line 2702 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString("!~~")); ;}
    break;

  case 859:
#line 2704 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString("~~*")); ;}
    break;

  case 860:
#line 2706 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString("!~~*")); ;}
    break;

  case 861:
#line 2720 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 862:
#line 2722 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(3) - (3)].list)); ;}
    break;

  case 863:
#line 2726 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
				;}
    break;

  case 864:
#line 2730 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 865:
#line 2737 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].node));
				;}
    break;

  case 866:
#line 2741 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 867:
#line 2747 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (yyvsp[(1) - (1)].node);
				;}
    break;

  case 868:
#line 2751 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNamedArgExpr *na = makeNode(PGNamedArgExpr);
					na->name = (yyvsp[(1) - (3)].str);
					na->arg = (PGExpr *) (yyvsp[(3) - (3)].node);
					na->argnumber = -1;		/* until determined */
					na->location = (yylsp[(1) - (3)]);
					(yyval.node) = (PGNode *) na;
				;}
    break;

  case 869:
#line 2760 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGNamedArgExpr *na = makeNode(PGNamedArgExpr);
					na->name = (yyvsp[(1) - (3)].str);
					na->arg = (PGExpr *) (yyvsp[(3) - (3)].node);
					na->argnumber = -1;		/* until determined */
					na->location = (yylsp[(1) - (3)]);
					(yyval.node) = (PGNode *) na;
				;}
    break;

  case 870:
#line 2770 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].typnam)); ;}
    break;

  case 871:
#line 2771 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].typnam)); ;}
    break;

  case 872:
#line 2776 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make2(makeStringConst((yyvsp[(1) - (3)].str), (yylsp[(1) - (3)])), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 873:
#line 2779 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 874:
#line 2786 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 875:
#line 2787 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) "year"; ;}
    break;

  case 876:
#line 2788 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) "month"; ;}
    break;

  case 877:
#line 2789 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) "day"; ;}
    break;

  case 878:
#line 2790 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) "hour"; ;}
    break;

  case 879:
#line 2791 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) "minute"; ;}
    break;

  case 880:
#line 2792 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (char*) "second"; ;}
    break;

  case 881:
#line 2793 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 882:
#line 2804 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make4((yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].node), (yyvsp[(3) - (4)].node), (yyvsp[(4) - (4)].node));
				;}
    break;

  case 883:
#line 2808 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 884:
#line 2815 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 885:
#line 2821 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make2((yyvsp[(3) - (3)].node), (yyvsp[(1) - (3)].node)); ;}
    break;

  case 886:
#line 2822 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 887:
#line 2839 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].node));
				;}
    break;

  case 888:
#line 2843 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* not legal per SQL99, but might as well allow it */
					(yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].node));
				;}
    break;

  case 889:
#line 2848 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
				;}
    break;

  case 890:
#line 2852 "third_party/libpg_query/grammar/statements/select.y"
    {
					/*
					 * Since there are no cases where this syntax allows
					 * a textual FOR value, we forcibly cast the argument
					 * to int4.  The possible matches in pg_proc are
					 * substring(text,int4) and substring(text,text),
					 * and we don't want the parser to choose the latter,
					 * which it is likely to do if the second argument
					 * is unknown or doesn't have an implicit cast to int4.
					 */
					(yyval.list) = list_make3((yyvsp[(1) - (2)].node), makeIntConst(1, -1),
									makeTypeCast((yyvsp[(2) - (2)].node),
												 SystemTypeName("int4"), -1));
				;}
    break;

  case 891:
#line 2867 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.list) = (yyvsp[(1) - (1)].list);
				;}
    break;

  case 892:
#line 2871 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 893:
#line 2875 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 894:
#line 2878 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 895:
#line 2881 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(3) - (3)].list), (yyvsp[(1) - (3)].node)); ;}
    break;

  case 896:
#line 2882 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 897:
#line 2883 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 898:
#line 2887 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGSubLink *n = makeNode(PGSubLink);
					n->subselect = (yyvsp[(1) - (1)].node);
					/* other fields will be filled later */
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 899:
#line 2893 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (PGNode *)(yyvsp[(2) - (3)].list); ;}
    break;

  case 900:
#line 2904 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGCaseExpr *c = makeNode(PGCaseExpr);
					c->casetype = InvalidOid; /* not analyzed yet */
					c->arg = (PGExpr *) (yyvsp[(2) - (5)].node);
					c->args = (yyvsp[(3) - (5)].list);
					c->defresult = (PGExpr *) (yyvsp[(4) - (5)].node);
					c->location = (yylsp[(1) - (5)]);
					(yyval.node) = (PGNode *)c;
				;}
    break;

  case 901:
#line 2917 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 902:
#line 2918 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;}
    break;

  case 903:
#line 2923 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGCaseWhen *w = makeNode(PGCaseWhen);
					w->expr = (PGExpr *) (yyvsp[(2) - (4)].node);
					w->result = (PGExpr *) (yyvsp[(4) - (4)].node);
					w->location = (yylsp[(1) - (4)]);
					(yyval.node) = (PGNode *)w;
				;}
    break;

  case 904:
#line 2933 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 905:
#line 2934 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 906:
#line 2937 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 907:
#line 2938 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 908:
#line 2942 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeColumnRef((yyvsp[(1) - (1)].str), NIL, (yylsp[(1) - (1)]), yyscanner);
				;}
    break;

  case 909:
#line 2946 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeColumnRef((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].list), (yylsp[(1) - (2)]), yyscanner);
				;}
    break;

  case 910:
#line 2953 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeString((yyvsp[(2) - (2)].str));
				;}
    break;

  case 911:
#line 2957 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = (PGNode *) makeNode(PGAStar);
				;}
    break;

  case 912:
#line 2961 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGAIndices *ai = makeNode(PGAIndices);
					ai->is_slice = false;
					ai->lidx = NULL;
					ai->uidx = (yyvsp[(2) - (3)].node);
					(yyval.node) = (PGNode *) ai;
				;}
    break;

  case 913:
#line 2969 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGAIndices *ai = makeNode(PGAIndices);
					ai->is_slice = true;
					ai->lidx = (yyvsp[(2) - (5)].node);
					ai->uidx = (yyvsp[(4) - (5)].node);
					(yyval.node) = (PGNode *) ai;
				;}
    break;

  case 914:
#line 2979 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
    break;

  case 915:
#line 2980 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.node) = NULL; ;}
    break;

  case 916:
#line 2984 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 917:
#line 2985 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;}
    break;

  case 918:
#line 2989 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 919:
#line 2990 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;}
    break;

  case 922:
#line 3004 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(1) - (1)].list); ;}
    break;

  case 923:
#line 3005 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 924:
#line 3009 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;}
    break;

  case 925:
#line 3010 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); ;}
    break;

  case 926:
#line 3014 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.target) = makeNode(PGResTarget);
					(yyval.target)->name = (yyvsp[(3) - (3)].str);
					(yyval.target)->indirection = NIL;
					(yyval.target)->val = (PGNode *)(yyvsp[(1) - (3)].node);
					(yyval.target)->location = (yylsp[(1) - (3)]);
				;}
    break;

  case 927:
#line 3030 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.target) = makeNode(PGResTarget);
					(yyval.target)->name = (yyvsp[(2) - (2)].str);
					(yyval.target)->indirection = NIL;
					(yyval.target)->val = (PGNode *)(yyvsp[(1) - (2)].node);
					(yyval.target)->location = (yylsp[(1) - (2)]);
				;}
    break;

  case 928:
#line 3038 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.target) = makeNode(PGResTarget);
					(yyval.target)->name = NULL;
					(yyval.target)->indirection = NIL;
					(yyval.target)->val = (PGNode *)(yyvsp[(1) - (1)].node);
					(yyval.target)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 929:
#line 3046 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGColumnRef *n = makeNode(PGColumnRef);
					n->fields = list_make1(makeNode(PGAStar));
					n->location = (yylsp[(1) - (1)]);

					(yyval.target) = makeNode(PGResTarget);
					(yyval.target)->name = NULL;
					(yyval.target)->indirection = NIL;
					(yyval.target)->val = (PGNode *)n;
					(yyval.target)->location = (yylsp[(1) - (1)]);
				;}
    break;

  case 930:
#line 3067 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].range)); ;}
    break;

  case 931:
#line 3068 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].range)); ;}
    break;

  case 932:
#line 3080 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.range) = makeRangeVar(NULL, (yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 933:
#line 3084 "third_party/libpg_query/grammar/statements/select.y"
    {
					check_qualified_name((yyvsp[(2) - (2)].list), yyscanner);
					(yyval.range) = makeRangeVar(NULL, NULL, (yylsp[(1) - (2)]));
					switch (list_length((yyvsp[(2) - (2)].list)))
					{
						case 1:
							(yyval.range)->catalogname = NULL;
							(yyval.range)->schemaname = (yyvsp[(1) - (2)].str);
							(yyval.range)->relname = strVal(linitial((yyvsp[(2) - (2)].list)));
							break;
						case 2:
							(yyval.range)->catalogname = (yyvsp[(1) - (2)].str);
							(yyval.range)->schemaname = strVal(linitial((yyvsp[(2) - (2)].list)));
							(yyval.range)->relname = strVal(lsecond((yyvsp[(2) - (2)].list)));
							break;
						default:
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("improper qualified name (too many dotted names): %s",
											NameListToString(lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)))),
									 parser_errposition((yylsp[(1) - (2)]))));
							break;
					}
				;}
    break;

  case 934:
#line 3111 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 935:
#line 3113 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;}
    break;

  case 936:
#line 3117 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 937:
#line 3119 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 938:
#line 3130 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 939:
#line 3132 "third_party/libpg_query/grammar/statements/select.y"
    {
						(yyval.list) = check_func_name(lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)),
											 yyscanner);
					;}
    break;

  case 940:
#line 3143 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival), (yylsp[(1) - (1)]));
				;}
    break;

  case 941:
#line 3147 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 942:
#line 3151 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 943:
#line 3155 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeBitStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 944:
#line 3159 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* This is a bit constant per SQL99:
					 * Without Feature F511, "BIT data type",
					 * a <general literal> shall not be a
					 * <bit string literal> or a <hex string literal>.
					 */
					(yyval.node) = makeBitStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 945:
#line 3168 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* generic type 'literal' syntax */
					PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (2)].list));
					t->location = (yylsp[(1) - (2)]);
					(yyval.node) = makeStringConstCast((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)]), t);
				;}
    break;

  case 946:
#line 3175 "third_party/libpg_query/grammar/statements/select.y"
    {
					/* generic syntax with a type modifier */
					PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (6)].list));
					PGListCell *lc;

					/*
					 * We must use func_arg_list and opt_sort_clause in the
					 * production to avoid reduce/reduce conflicts, but we
					 * don't actually wish to allow PGNamedArgExpr in this
					 * context, nor ORDER BY.
					 */
					foreach(lc, (yyvsp[(3) - (6)].list))
					{
						PGNamedArgExpr *arg = (PGNamedArgExpr *) lfirst(lc);

						if (IsA(arg, PGNamedArgExpr))
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("type modifier cannot have parameter name"),
									 parser_errposition(arg->location)));
					}
					if ((yyvsp[(4) - (6)].list) != NIL)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("type modifier cannot have ORDER BY"),
									 parser_errposition((yylsp[(4) - (6)]))));

					t->typmods = (yyvsp[(3) - (6)].list);
					t->location = (yylsp[(1) - (6)]);
					(yyval.node) = makeStringConstCast((yyvsp[(6) - (6)].str), (yylsp[(6) - (6)]), t);
				;}
    break;

  case 947:
#line 3207 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeStringConstCast((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)]), (yyvsp[(1) - (2)].typnam));
				;}
    break;

  case 948:
#line 3211 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGTypeName *t = (yyvsp[(1) - (3)].typnam);
					t->typmods = (yyvsp[(3) - (3)].list);
					(yyval.node) = makeStringConstCast((yyvsp[(2) - (3)].str), (yylsp[(2) - (3)]), t);
				;}
    break;

  case 949:
#line 3217 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGTypeName *t = (yyvsp[(1) - (5)].typnam);
					t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
											makeIntConst((yyvsp[(3) - (5)].ival), (yylsp[(3) - (5)])));
					(yyval.node) = makeStringConstCast((yyvsp[(5) - (5)].str), (yylsp[(5) - (5)]), t);
				;}
    break;

  case 950:
#line 3225 "third_party/libpg_query/grammar/statements/select.y"
    {
					PGTypeName *t = (yyvsp[(1) - (6)].typnam);
					if ((yyvsp[(6) - (6)].list) != NIL)
					{
						t->typmods = lappend((yyvsp[(6) - (6)].list), makeParamRef(0, (yylsp[(3) - (6)])));
					}
					else
						t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
												makeParamRef(0, (yylsp[(3) - (6)])));
					(yyval.node) = makeParamRefCast(0, (yylsp[(5) - (6)]), t);
				;}
    break;

  case 951:
#line 3237 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeBoolAConst(true, (yylsp[(1) - (1)]));
				;}
    break;

  case 952:
#line 3241 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeBoolAConst(false, (yylsp[(1) - (1)]));
				;}
    break;

  case 953:
#line 3245 "third_party/libpg_query/grammar/statements/select.y"
    {
					(yyval.node) = makeNullAConst((yylsp[(1) - (1)]));
				;}
    break;

  case 954:
#line 3250 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;}
    break;

  case 955:
#line 3251 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 956:
#line 3267 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 957:
#line 3268 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 958:
#line 3269 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 959:
#line 3274 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 960:
#line 3275 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 961:
#line 3276 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 962:
#line 3279 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;}
    break;

  case 963:
#line 3280 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)); ;}
    break;

  case 964:
#line 3284 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;}
    break;

  case 965:
#line 3286 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;}
    break;

  case 966:
#line 3290 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 967:
#line 3291 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.list) = NIL; ;}
    break;

  case 969:
#line 3302 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 970:
#line 3303 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 971:
#line 3304 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 972:
#line 3305 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 973:
#line 3306 "third_party/libpg_query/grammar/statements/select.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 974:
#line 8 "third_party/libpg_query/grammar/statements/prepare.y"
    {
					PGPrepareStmt *n = makeNode(PGPrepareStmt);
					n->name = (yyvsp[(2) - (5)].str);
					n->argtypes = (yyvsp[(3) - (5)].list);
					n->query = (yyvsp[(5) - (5)].node);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 975:
#line 18 "third_party/libpg_query/grammar/statements/prepare.y"
    { (yyval.list) = (yyvsp[(2) - (3)].list); ;}
    break;

  case 976:
#line 19 "third_party/libpg_query/grammar/statements/prepare.y"
    { (yyval.list) = NIL; ;}
    break;

  case 981:
#line 8 "third_party/libpg_query/grammar/statements/create_schema.y"
    {
					PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt);
					/* ...but not both */
					n->schemaname = (yyvsp[(3) - (4)].str);
					n->schemaElts = (yyvsp[(4) - (4)].list);
					n->if_not_exists = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 982:
#line 17 "third_party/libpg_query/grammar/statements/create_schema.y"
    {
					PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt);
					/* ...but not here */
					n->schemaname = (yyvsp[(6) - (7)].str);
					if ((yyvsp[(7) - (7)].list) != NIL)
						ereport(ERROR,
								(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"),
								 parser_errposition((yylsp[(7) - (7)]))));
					n->schemaElts = (yyvsp[(7) - (7)].list);
					n->if_not_exists = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 983:
#line 35 "third_party/libpg_query/grammar/statements/create_schema.y"
    {
					if ((yyloc) < 0)			/* see comments for YYLLOC_DEFAULT */
						(yyloc) = (yylsp[(2) - (2)]);
					(yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
				;}
    break;

  case 984:
#line 41 "third_party/libpg_query/grammar/statements/create_schema.y"
    { (yyval.list) = NIL; ;}
    break;

  case 989:
#line 11 "third_party/libpg_query/grammar/statements/index.y"
    {
					PGIndexStmt *n = makeNode(PGIndexStmt);
					n->unique = (yyvsp[(2) - (13)].boolean);
					n->concurrent = (yyvsp[(4) - (13)].boolean);
					n->idxname = (yyvsp[(5) - (13)].str);
					n->relation = (yyvsp[(7) - (13)].range);
					n->accessMethod = (yyvsp[(8) - (13)].str);
					n->indexParams = (yyvsp[(10) - (13)].list);
					n->options = (yyvsp[(12) - (13)].list);
					n->whereClause = (yyvsp[(13) - (13)].node);
					n->excludeOpNames = NIL;
					n->idxcomment = NULL;
					n->indexOid = InvalidOid;
					n->oldNode = InvalidOid;
					n->primary = false;
					n->isconstraint = false;
					n->deferrable = false;
					n->initdeferred = false;
					n->transformed = false;
					n->if_not_exists = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 990:
#line 36 "third_party/libpg_query/grammar/statements/index.y"
    {
					PGIndexStmt *n = makeNode(PGIndexStmt);
					n->unique = (yyvsp[(2) - (16)].boolean);
					n->concurrent = (yyvsp[(4) - (16)].boolean);
					n->idxname = (yyvsp[(8) - (16)].str);
					n->relation = (yyvsp[(10) - (16)].range);
					n->accessMethod = (yyvsp[(11) - (16)].str);
					n->indexParams = (yyvsp[(13) - (16)].list);
					n->options = (yyvsp[(15) - (16)].list);
					n->whereClause = (yyvsp[(16) - (16)].node);
					n->excludeOpNames = NIL;
					n->idxcomment = NULL;
					n->indexOid = InvalidOid;
					n->oldNode = InvalidOid;
					n->primary = false;
					n->isconstraint = false;
					n->deferrable = false;
					n->initdeferred = false;
					n->transformed = false;
					n->if_not_exists = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 991:
#line 62 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 992:
#line 66 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.str) = (yyvsp[(2) - (2)].str); ;}
    break;

  case 993:
#line 67 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.str) = (char*) DEFAULT_INDEX_TYPE; ;}
    break;

  case 994:
#line 72 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.boolean) = true; ;}
    break;

  case 995:
#line 73 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.boolean) = false; ;}
    break;

  case 996:
#line 78 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 997:
#line 79 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.str) = NULL; ;}
    break;

  case 998:
#line 83 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 999:
#line 84 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.list) = NIL; ;}
    break;

  case 1000:
#line 89 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.boolean) = true; ;}
    break;

  case 1001:
#line 90 "third_party/libpg_query/grammar/statements/index.y"
    { (yyval.boolean) = false; ;}
    break;

  case 1002:
#line 8 "third_party/libpg_query/grammar/statements/alter_schema.y"
    {
					PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
					n->objectType = PG_OBJECT_TABLE;
					n->relation = (yyvsp[(3) - (6)].range);
					n->newschema = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1003:
#line 17 "third_party/libpg_query/grammar/statements/alter_schema.y"
    {
					PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
					n->objectType = PG_OBJECT_TABLE;
					n->relation = (yyvsp[(5) - (8)].range);
					n->newschema = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1004:
#line 26 "third_party/libpg_query/grammar/statements/alter_schema.y"
    {
					PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
					n->objectType = PG_OBJECT_SEQUENCE;
					n->relation = (yyvsp[(3) - (6)].range);
					n->newschema = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1005:
#line 35 "third_party/libpg_query/grammar/statements/alter_schema.y"
    {
					PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
					n->objectType = PG_OBJECT_SEQUENCE;
					n->relation = (yyvsp[(5) - (8)].range);
					n->newschema = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1006:
#line 44 "third_party/libpg_query/grammar/statements/alter_schema.y"
    {
					PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
					n->objectType = PG_OBJECT_VIEW;
					n->relation = (yyvsp[(3) - (6)].range);
					n->newschema = (yyvsp[(6) - (6)].str);
					n->missing_ok = false;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1007:
#line 53 "third_party/libpg_query/grammar/statements/alter_schema.y"
    {
					PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
					n->objectType = PG_OBJECT_VIEW;
					n->relation = (yyvsp[(5) - (8)].range);
					n->newschema = (yyvsp[(8) - (8)].str);
					n->missing_ok = true;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1008:
#line 6 "third_party/libpg_query/grammar/statements/checkpoint.y"
    {
					PGCheckPointStmt *n = makeNode(PGCheckPointStmt);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1009:
#line 10 "third_party/libpg_query/grammar/statements/explain.y"
    {
					PGExplainStmt *n = makeNode(PGExplainStmt);
					n->query = (yyvsp[(2) - (2)].node);
					n->options = NIL;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1010:
#line 17 "third_party/libpg_query/grammar/statements/explain.y"
    {
					PGExplainStmt *n = makeNode(PGExplainStmt);
					n->query = (yyvsp[(4) - (4)].node);
					n->options = list_make1(makeDefElem("analyze", NULL, (yylsp[(2) - (4)])));
					if ((yyvsp[(3) - (4)].boolean))
						n->options = lappend(n->options,
											 makeDefElem("verbose", NULL, (yylsp[(3) - (4)])));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1011:
#line 27 "third_party/libpg_query/grammar/statements/explain.y"
    {
					PGExplainStmt *n = makeNode(PGExplainStmt);
					n->query = (yyvsp[(3) - (3)].node);
					n->options = list_make1(makeDefElem("verbose", NULL, (yylsp[(2) - (3)])));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1012:
#line 34 "third_party/libpg_query/grammar/statements/explain.y"
    {
					PGExplainStmt *n = makeNode(PGExplainStmt);
					n->query = (yyvsp[(5) - (5)].node);
					n->options = (yyvsp[(3) - (5)].list);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1013:
#line 44 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.boolean) = true; ;}
    break;

  case 1014:
#line 45 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.boolean) = false; ;}
    break;

  case 1015:
#line 50 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;}
    break;

  case 1016:
#line 51 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].value); ;}
    break;

  case 1017:
#line 52 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.node) = NULL; ;}
    break;

  case 1023:
#line 65 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1024:
#line 66 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 1025:
#line 67 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 1026:
#line 68 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;}
    break;

  case 1027:
#line 73 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1028:
#line 74 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1029:
#line 80 "third_party/libpg_query/grammar/statements/explain.y"
    {
					(yyval.list) = list_make1((yyvsp[(1) - (1)].defelt));
				;}
    break;

  case 1030:
#line 84 "third_party/libpg_query/grammar/statements/explain.y"
    {
					(yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt));
				;}
    break;

  case 1031:
#line 91 "third_party/libpg_query/grammar/statements/explain.y"
    {;}
    break;

  case 1032:
#line 92 "third_party/libpg_query/grammar/statements/explain.y"
    {;}
    break;

  case 1033:
#line 97 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (char*) "true"; ;}
    break;

  case 1034:
#line 98 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (char*) "false"; ;}
    break;

  case 1035:
#line 99 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (char*) "on"; ;}
    break;

  case 1036:
#line 105 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1037:
#line 111 "third_party/libpg_query/grammar/statements/explain.y"
    {
					(yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)]));
				;}
    break;

  case 1038:
#line 118 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1039:
#line 119 "third_party/libpg_query/grammar/statements/explain.y"
    { (yyval.str) = (char*) "analyze"; ;}
    break;

  case 1040:
#line 11 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = (yyvsp[(2) - (2)].vsetstmt);
					n->is_local = false;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1041:
#line 17 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt);
					n->is_local = true;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1042:
#line 23 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt);
					n->is_local = false;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1043:
#line 32 "third_party/libpg_query/grammar/statements/variable_set.y"
    {(yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt);;}
    break;

  case 1044:
#line 34 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_CURRENT;
					n->name = (yyvsp[(1) - (3)].str);
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1045:
#line 42 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_VALUE;
					n->name = (char*) "timezone";
					if ((yyvsp[(3) - (3)].node) != NULL)
						n->args = list_make1((yyvsp[(3) - (3)].node));
					else
						n->kind = VAR_SET_DEFAULT;
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1046:
#line 53 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_VALUE;
					n->name = (char*) "search_path";
					n->args = list_make1(makeStringConst((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)])));
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1047:
#line 65 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_VALUE;
					n->name = (yyvsp[(1) - (3)].str);
					n->args = (yyvsp[(3) - (3)].list);
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1048:
#line 73 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_VALUE;
					n->name = (yyvsp[(1) - (3)].str);
					n->args = (yyvsp[(3) - (3)].list);
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1049:
#line 81 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_DEFAULT;
					n->name = (yyvsp[(1) - (3)].str);
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1050:
#line 88 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_SET_DEFAULT;
					n->name = (yyvsp[(1) - (3)].str);
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1051:
#line 98 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;}
    break;

  case 1052:
#line 100 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;}
    break;

  case 1053:
#line 106 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					(yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 1054:
#line 110 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					(yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]));
				;}
    break;

  case 1055:
#line 114 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGTypeName *t = (yyvsp[(1) - (3)].typnam);
					if ((yyvsp[(3) - (3)].list) != NIL)
					{
						PGAConst *n = (PGAConst *) linitial((yyvsp[(3) - (3)].list));
						if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
							ereport(ERROR,
									(errcode(PG_ERRCODE_SYNTAX_ERROR),
									 errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
									 parser_errposition((yylsp[(3) - (3)]))));
					}
					t->typmods = (yyvsp[(3) - (3)].list);
					(yyval.node) = makeStringConstCast((yyvsp[(2) - (3)].str), (yylsp[(2) - (3)]), t);
				;}
    break;

  case 1056:
#line 129 "third_party/libpg_query/grammar/statements/variable_set.y"
    {
					PGTypeName *t = (yyvsp[(1) - (5)].typnam);
					t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
											makeIntConst((yyvsp[(3) - (5)].ival), (yylsp[(3) - (5)])));
					(yyval.node) = makeStringConstCast((yyvsp[(5) - (5)].str), (yylsp[(5) - (5)]), t);
				;}
    break;

  case 1057:
#line 135 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;}
    break;

  case 1058:
#line 136 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.node) = NULL; ;}
    break;

  case 1059:
#line 137 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.node) = NULL; ;}
    break;

  case 1060:
#line 141 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;}
    break;

  case 1061:
#line 142 "third_party/libpg_query/grammar/statements/variable_set.y"
    { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;}
    break;

  case 1062:
#line 8 "third_party/libpg_query/grammar/statements/load.y"
    {
					PGLoadStmt *n = makeNode(PGLoadStmt);
					n->filename = (yyvsp[(2) - (2)].str);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1063:
#line 16 "third_party/libpg_query/grammar/statements/load.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1064:
#line 9 "third_party/libpg_query/grammar/statements/vacuum.y"
    {
					PGVacuumStmt *n = makeNode(PGVacuumStmt);
					n->options = PG_VACOPT_VACUUM;
					if ((yyvsp[(2) - (4)].boolean))
						n->options |= PG_VACOPT_FULL;
					if ((yyvsp[(3) - (4)].boolean))
						n->options |= PG_VACOPT_FREEZE;
					if ((yyvsp[(4) - (4)].boolean))
						n->options |= PG_VACOPT_VERBOSE;
					n->relation = NULL;
					n->va_cols = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1065:
#line 23 "third_party/libpg_query/grammar/statements/vacuum.y"
    {
					PGVacuumStmt *n = makeNode(PGVacuumStmt);
					n->options = PG_VACOPT_VACUUM;
					if ((yyvsp[(2) - (5)].boolean))
						n->options |= PG_VACOPT_FULL;
					if ((yyvsp[(3) - (5)].boolean))
						n->options |= PG_VACOPT_FREEZE;
					if ((yyvsp[(4) - (5)].boolean))
						n->options |= PG_VACOPT_VERBOSE;
					n->relation = (yyvsp[(5) - (5)].range);
					n->va_cols = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1066:
#line 37 "third_party/libpg_query/grammar/statements/vacuum.y"
    {
					PGVacuumStmt *n = (PGVacuumStmt *) (yyvsp[(5) - (5)].node);
					n->options |= PG_VACOPT_VACUUM;
					if ((yyvsp[(2) - (5)].boolean))
						n->options |= PG_VACOPT_FULL;
					if ((yyvsp[(3) - (5)].boolean))
						n->options |= PG_VACOPT_FREEZE;
					if ((yyvsp[(4) - (5)].boolean))
						n->options |= PG_VACOPT_VERBOSE;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1067:
#line 49 "third_party/libpg_query/grammar/statements/vacuum.y"
    {
					PGVacuumStmt *n = makeNode(PGVacuumStmt);
					n->options = PG_VACOPT_VACUUM | (yyvsp[(3) - (4)].ival);
					n->relation = NULL;
					n->va_cols = NIL;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1068:
#line 57 "third_party/libpg_query/grammar/statements/vacuum.y"
    {
					PGVacuumStmt *n = makeNode(PGVacuumStmt);
					n->options = PG_VACOPT_VACUUM | (yyvsp[(3) - (6)].ival);
					n->relation = (yyvsp[(5) - (6)].range);
					n->va_cols = (yyvsp[(6) - (6)].list);
					if (n->va_cols != NIL)	/* implies analyze */
						n->options |= PG_VACOPT_ANALYZE;
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1069:
#line 70 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.ival) = PG_VACOPT_ANALYZE; ;}
    break;

  case 1070:
#line 71 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.ival) = PG_VACOPT_VERBOSE; ;}
    break;

  case 1071:
#line 72 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.ival) = PG_VACOPT_FREEZE; ;}
    break;

  case 1072:
#line 73 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.ival) = PG_VACOPT_FULL; ;}
    break;

  case 1073:
#line 75 "third_party/libpg_query/grammar/statements/vacuum.y"
    {
					if (strcmp((yyvsp[(1) - (1)].str), "disable_page_skipping") == 0)
						(yyval.ival) = PG_VACOPT_DISABLE_PAGE_SKIPPING;
					else
						ereport(ERROR,
								(errcode(PG_ERRCODE_SYNTAX_ERROR),
							 errmsg("unrecognized VACUUM option \"%s\"", (yyvsp[(1) - (1)].str)),
									 parser_errposition((yylsp[(1) - (1)]))));
				;}
    break;

  case 1074:
#line 87 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.boolean) = true; ;}
    break;

  case 1075:
#line 88 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.boolean) = false; ;}
    break;

  case 1076:
#line 93 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;}
    break;

  case 1077:
#line 94 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); ;}
    break;

  case 1078:
#line 98 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.boolean) = true; ;}
    break;

  case 1079:
#line 99 "third_party/libpg_query/grammar/statements/vacuum.y"
    { (yyval.boolean) = false; ;}
    break;

  case 1080:
#line 9 "third_party/libpg_query/grammar/statements/delete.y"
    {
					PGDeleteStmt *n = makeNode(PGDeleteStmt);
					n->relation = (yyvsp[(4) - (7)].range);
					n->usingClause = (yyvsp[(5) - (7)].list);
					n->whereClause = (yyvsp[(6) - (7)].node);
					n->returningList = (yyvsp[(7) - (7)].list);
					n->withClause = (yyvsp[(1) - (7)].with);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1081:
#line 22 "third_party/libpg_query/grammar/statements/delete.y"
    {
					(yyval.range) = (yyvsp[(1) - (1)].range);
				;}
    break;

  case 1082:
#line 26 "third_party/libpg_query/grammar/statements/delete.y"
    {
					PGAlias *alias = makeNode(PGAlias);
					alias->aliasname = (yyvsp[(2) - (2)].str);
					(yyvsp[(1) - (2)].range)->alias = alias;
					(yyval.range) = (yyvsp[(1) - (2)].range);
				;}
    break;

  case 1083:
#line 33 "third_party/libpg_query/grammar/statements/delete.y"
    {
					PGAlias *alias = makeNode(PGAlias);
					alias->aliasname = (yyvsp[(3) - (3)].str);
					(yyvsp[(1) - (3)].range)->alias = alias;
					(yyval.range) = (yyvsp[(1) - (3)].range);
				;}
    break;

  case 1084:
#line 43 "third_party/libpg_query/grammar/statements/delete.y"
    { (yyval.node) = (yyvsp[(2) - (2)].node); ;}
    break;

  case 1085:
#line 44 "third_party/libpg_query/grammar/statements/delete.y"
    { (yyval.node) = NULL; ;}
    break;

  case 1086:
#line 50 "third_party/libpg_query/grammar/statements/delete.y"
    { (yyval.list) = (yyvsp[(2) - (2)].list); ;}
    break;

  case 1087:
#line 51 "third_party/libpg_query/grammar/statements/delete.y"
    { (yyval.list) = NIL; ;}
    break;

  case 1088:
#line 10 "third_party/libpg_query/grammar/statements/analyze.y"
    {
					PGVacuumStmt *n = makeNode(PGVacuumStmt);
					n->options = PG_VACOPT_ANALYZE;
					if ((yyvsp[(2) - (2)].boolean))
						n->options |= PG_VACOPT_VERBOSE;
					n->relation = NULL;
					n->va_cols = NIL;
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1089:
#line 20 "third_party/libpg_query/grammar/statements/analyze.y"
    {
					PGVacuumStmt *n = makeNode(PGVacuumStmt);
					n->options = PG_VACOPT_ANALYZE;
					if ((yyvsp[(2) - (4)].boolean))
						n->options |= PG_VACOPT_VERBOSE;
					n->relation = (yyvsp[(3) - (4)].range);
					n->va_cols = (yyvsp[(4) - (4)].list);
					(yyval.node) = (PGNode *)n;
				;}
    break;

  case 1090:
#line 2 "third_party/libpg_query/grammar/statements/variable_reset.y"
    { (yyval.node) = (PGNode *) (yyvsp[(2) - (2)].vsetstmt); ;}
    break;

  case 1091:
#line 8 "third_party/libpg_query/grammar/statements/variable_reset.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_RESET;
					n->name = (yyvsp[(1) - (1)].str);
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1092:
#line 15 "third_party/libpg_query/grammar/statements/variable_reset.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_RESET_ALL;
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1093:
#line 24 "third_party/libpg_query/grammar/statements/variable_reset.y"
    { (yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt); ;}
    break;

  case 1094:
#line 26 "third_party/libpg_query/grammar/statements/variable_reset.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_RESET;
					n->name = (char*) "timezone";
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1095:
#line 33 "third_party/libpg_query/grammar/statements/variable_reset.y"
    {
					PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
					n->kind = VAR_RESET;
					n->name = (char*) "transaction_isolation";
					(yyval.vsetstmt) = n;
				;}
    break;

  case 1096:
#line 4 "third_party/libpg_query/grammar/statements/variable_show.y"
    {
					PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
					n->name = (yyvsp[(2) - (2)].str);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1097:
#line 10 "third_party/libpg_query/grammar/statements/variable_show.y"
    {
					PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
					n->name = (char*) "timezone";
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1098:
#line 16 "third_party/libpg_query/grammar/statements/variable_show.y"
    {
					PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
					n->name = (char*) "transaction_isolation";
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1099:
#line 22 "third_party/libpg_query/grammar/statements/variable_show.y"
    {
					PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
					n->name = (char*) "all";
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1100:
#line 30 "third_party/libpg_query/grammar/statements/variable_show.y"
    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
    break;

  case 1101:
#line 32 "third_party/libpg_query/grammar/statements/variable_show.y"
    { (yyval.str) = psprintf("%s.%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)); ;}
    break;

  case 1102:
#line 10 "third_party/libpg_query/grammar/statements/view.y"
    {
					PGViewStmt *n = makeNode(PGViewStmt);
					n->view = (yyvsp[(4) - (9)].range);
					n->view->relpersistence = (yyvsp[(2) - (9)].ival);
					n->aliases = (yyvsp[(5) - (9)].list);
					n->query = (yyvsp[(8) - (9)].node);
					n->replace = false;
					n->options = (yyvsp[(6) - (9)].list);
					n->withCheckOption = (yyvsp[(9) - (9)].viewcheckoption);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1103:
#line 23 "third_party/libpg_query/grammar/statements/view.y"
    {
					PGViewStmt *n = makeNode(PGViewStmt);
					n->view = (yyvsp[(6) - (11)].range);
					n->view->relpersistence = (yyvsp[(4) - (11)].ival);
					n->aliases = (yyvsp[(7) - (11)].list);
					n->query = (yyvsp[(10) - (11)].node);
					n->replace = true;
					n->options = (yyvsp[(8) - (11)].list);
					n->withCheckOption = (yyvsp[(11) - (11)].viewcheckoption);
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1104:
#line 36 "third_party/libpg_query/grammar/statements/view.y"
    {
					PGViewStmt *n = makeNode(PGViewStmt);
					n->view = (yyvsp[(5) - (12)].range);
					n->view->relpersistence = (yyvsp[(2) - (12)].ival);
					n->aliases = (yyvsp[(7) - (12)].list);
					n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, (yyvsp[(11) - (12)].node));
					n->replace = false;
					n->options = (yyvsp[(9) - (12)].list);
					n->withCheckOption = (yyvsp[(12) - (12)].viewcheckoption);
					if (n->withCheckOption != PG_NO_CHECK_OPTION)
						ereport(ERROR,
								(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("WITH CHECK OPTION not supported on recursive views"),
								 parser_errposition((yylsp[(12) - (12)]))));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1105:
#line 54 "third_party/libpg_query/grammar/statements/view.y"
    {
					PGViewStmt *n = makeNode(PGViewStmt);
					n->view = (yyvsp[(7) - (14)].range);
					n->view->relpersistence = (yyvsp[(4) - (14)].ival);
					n->aliases = (yyvsp[(9) - (14)].list);
					n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, (yyvsp[(13) - (14)].node));
					n->replace = true;
					n->options = (yyvsp[(11) - (14)].list);
					n->withCheckOption = (yyvsp[(14) - (14)].viewcheckoption);
					if (n->withCheckOption != PG_NO_CHECK_OPTION)
						ereport(ERROR,
								(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("WITH CHECK OPTION not supported on recursive views"),
								 parser_errposition((yylsp[(14) - (14)]))));
					(yyval.node) = (PGNode *) n;
				;}
    break;

  case 1106:
#line 74 "third_party/libpg_query/grammar/statements/view.y"
    { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;}
    break;

  case 1107:
#line 75 "third_party/libpg_query/grammar/statements/view.y"
    { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;}
    break;

  case 1108:
#line 76 "third_party/libpg_query/grammar/statements/view.y"
    { (yyval.viewcheckoption) = PG_LOCAL_CHECK_OPTION; ;}
    break;

  case 1109:
#line 77 "third_party/libpg_query/grammar/statements/view.y"
    { (yyval.viewcheckoption) = PG_NO_CHECK_OPTION; ;}
    break;

  case 1110:
#line 12 "third_party/libpg_query/grammar/statements/create_as.y"
    {
					PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
					ctas->query = (yyvsp[(6) - (7)].node);
					ctas->into = (yyvsp[(4) - (7)].into);
					ctas->relkind = PG_OBJECT_TABLE;
					ctas->is_select_into = false;
					ctas->if_not_exists = false;
					/* cram additional flags into the PGIntoClause */
					(yyvsp[(4) - (7)].into)->rel->relpersistence = (yyvsp[(2) - (7)].ival);
					(yyvsp[(4) - (7)].into)->skipData = !((yyvsp[(7) - (7)].boolean));
					(yyval.node) = (PGNode *) ctas;
				;}
    break;

  case 1111:
#line 25 "third_party/libpg_query/grammar/statements/create_as.y"
    {
					PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
					ctas->query = (yyvsp[(9) - (10)].node);
					ctas->into = (yyvsp[(7) - (10)].into);
					ctas->relkind = PG_OBJECT_TABLE;
					ctas->is_select_into = false;
					ctas->if_not_exists = true;
					/* cram additional flags into the PGIntoClause */
					(yyvsp[(7) - (10)].into)->rel->relpersistence = (yyvsp[(2) - (10)].ival);
					(yyvsp[(7) - (10)].into)->skipData = !((yyvsp[(10) - (10)].boolean));
					(yyval.node) = (PGNode *) ctas;
				;}
    break;

  case 1112:
#line 41 "third_party/libpg_query/grammar/statements/create_as.y"
    { (yyval.boolean) = true; ;}
    break;

  case 1113:
#line 42 "third_party/libpg_query/grammar/statements/create_as.y"
    { (yyval.boolean) = false; ;}
    break;

  case 1114:
#line 43 "third_party/libpg_query/grammar/statements/create_as.y"
    { (yyval.boolean) = true; ;}
    break;

  case 1115:
#line 49 "third_party/libpg_query/grammar/statements/create_as.y"
    {
					(yyval.into) = makeNode(PGIntoClause);
					(yyval.into)->rel = (yyvsp[(1) - (4)].range);
					(yyval.into)->colNames = (yyvsp[(2) - (4)].list);
					(yyval.into)->options = (yyvsp[(3) - (4)].list);
					(yyval.into)->onCommit = (yyvsp[(4) - (4)].oncommit);
					(yyval.into)->viewQuery = NULL;
					(yyval.into)->skipData = false;		/* might get changed later */
				;}
    break;


/* Line 1267 of yacc.c.  */
#line 21790 "third_party/libpg_query/grammar/grammar_out.cpp"
      default: break;
    }
  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);

  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);

  *++yyvsp = yyval;
  *++yylsp = yyloc;

  /* Now `shift' the result of the reduction.  Determine what state
     that goes to, based on the state we popped back to and the rule
     number reduced by.  */

  yyn = yyr1[yyn];

  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
    yystate = yytable[yystate];
  else
    yystate = yydefgoto[yyn - YYNTOKENS];

  goto yynewstate;


/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
  /* If not already recovering from an error, report this error.  */
  if (!yyerrstatus)
    {
      ++yynerrs;
#if ! YYERROR_VERBOSE
      yyerror (&yylloc, yyscanner, YY_("syntax error"));
#else
      {
	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
	  {
	    YYSIZE_T yyalloc = 2 * yysize;
	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
	    if (yymsg != yymsgbuf)
	      YYSTACK_FREE (yymsg);
	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
	    if (yymsg)
	      yymsg_alloc = yyalloc;
	    else
	      {
		yymsg = yymsgbuf;
		yymsg_alloc = sizeof yymsgbuf;
	      }
	  }

	if (0 < yysize && yysize <= yymsg_alloc)
	  {
	    (void) yysyntax_error (yymsg, yystate, yychar);
	    yyerror (&yylloc, yyscanner, yymsg);
	  }
	else
	  {
	    yyerror (&yylloc, yyscanner, YY_("syntax error"));
	    if (yysize != 0)
	      goto yyexhaustedlab;
	  }
      }
#endif
    }

  yyerror_range[0] = yylloc;

  if (yyerrstatus == 3)
    {
      /* If just tried and failed to reuse look-ahead token after an
	 error, discard it.  */

      if (yychar <= YYEOF)
	{
	  /* Return failure if at end of input.  */
	  if (yychar == YYEOF)
	    YYABORT;
	}
      else
	{
	  yydestruct ("Error: discarding",
		      yytoken, &yylval, &yylloc, yyscanner);
	  yychar = YYEMPTY;
	}
    }

  /* Else will try to reuse look-ahead token after shifting the error
     token.  */
  goto yyerrlab1;


/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR.  |
`---------------------------------------------------*/
yyerrorlab:

  /* Pacify compilers like GCC when the user code never invokes
     YYERROR and the label yyerrorlab therefore never appears in user
     code.  */
  if (/*CONSTCOND*/ 0)
     goto yyerrorlab;

  yyerror_range[0] = yylsp[1-yylen];
  /* Do not reclaim the symbols of the rule which action triggered
     this YYERROR.  */
  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);
  yystate = *yyssp;
  goto yyerrlab1;


/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR.  |
`-------------------------------------------------------------*/
yyerrlab1:
  yyerrstatus = 3;	/* Each real token shifted decrements this.  */

  for (;;)
    {
      yyn = yypact[yystate];
      if (yyn != YYPACT_NINF)
	{
	  yyn += YYTERROR;
	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
	    {
	      yyn = yytable[yyn];
	      if (0 < yyn)
		break;
	    }
	}

      /* Pop the current state because it cannot handle the error token.  */
      if (yyssp == yyss)
	YYABORT;

      yyerror_range[0] = *yylsp;
      yydestruct ("Error: popping",
		  yystos[yystate], yyvsp, yylsp, yyscanner);
      YYPOPSTACK (1);
      yystate = *yyssp;
      YY_STACK_PRINT (yyss, yyssp);
    }

  if (yyn == YYFINAL)
    YYACCEPT;

  *++yyvsp = yylval;

  yyerror_range[1] = yylloc;
  /* Using YYLLOC is tempting, but would change the location of
     the look-ahead.  YYLOC is available though.  */
  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
  *++yylsp = yyloc;

  /* Shift the error token.  */
  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);

  yystate = yyn;
  goto yynewstate;


/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here.  |
`-------------------------------------*/
yyacceptlab:
  yyresult = 0;
  goto yyreturn;

/*-----------------------------------.
| yyabortlab -- YYABORT comes here.  |
`-----------------------------------*/
yyabortlab:
  yyresult = 1;
  goto yyreturn;

#ifndef yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here.  |
`-------------------------------------------------*/
yyexhaustedlab:
  yyerror (&yylloc, yyscanner, YY_("memory exhausted"));
  yyresult = 2;
  /* Fall through.  */
#endif

yyreturn:
  if (yychar != YYEOF && yychar != YYEMPTY)
     yydestruct ("Cleanup: discarding lookahead",
		 yytoken, &yylval, &yylloc, yyscanner);
  /* Do not reclaim the symbols of the rule which action triggered
     this YYABORT or YYACCEPT.  */
  YYPOPSTACK (yylen);
  YY_STACK_PRINT (yyss, yyssp);
  while (yyssp != yyss)
    {
      yydestruct ("Cleanup: popping",
		  yystos[*yyssp], yyvsp, yylsp, yyscanner);
      YYPOPSTACK (1);
    }
#ifndef yyoverflow
  if (yyss != yyssa)
    YYSTACK_FREE (yyss);
#endif
#if YYERROR_VERBOSE
  if (yymsg != yymsgbuf)
    YYSTACK_FREE (yymsg);
#endif
  /* Make sure YYID is used.  */
  return YYID (yyresult);
}


#line 67 "third_party/libpg_query/grammar/statements/create_as.y"


#line 1 "third_party/libpg_query/grammar/grammar.cpp"
/*
 * The signature of this function is required by bison.  However, we
 * ignore the passed yylloc and instead use the last token position
 * available from the scanner.
 */
static void
base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg)
{
	parser_yyerror(msg);
}

static PGRawStmt *
makeRawStmt(PGNode *stmt, int stmt_location)
{
	PGRawStmt    *rs = makeNode(PGRawStmt);

	rs->stmt = stmt;
	rs->stmt_location = stmt_location;
	rs->stmt_len = 0;			/* might get changed later */
	return rs;
}

/* Adjust a PGRawStmt to reflect that it doesn't run to the end of the string */
static void
updateRawStmtEnd(PGRawStmt *rs, int end_location)
{
	/*
	 * If we already set the length, don't change it.  This is for situations
	 * like "select foo ;; select bar" where the same statement will be last
	 * in the string for more than one semicolon.
	 */
	if (rs->stmt_len > 0)
		return;

	/* OK, update length of PGRawStmt */
	rs->stmt_len = end_location - rs->stmt_location;
}

static PGNode *
makeColumnRef(char *colname, PGList *indirection,
			  int location, core_yyscan_t yyscanner)
{
	/*
	 * Generate a PGColumnRef node, with an PGAIndirection node added if there
	 * is any subscripting in the specified indirection list.  However,
	 * any field selection at the start of the indirection list must be
	 * transposed into the "fields" part of the PGColumnRef node.
	 */
	PGColumnRef  *c = makeNode(PGColumnRef);
	int		nfields = 0;
	PGListCell *l;

	c->location = location;
	foreach(l, indirection)
	{
		if (IsA(lfirst(l), PGAIndices))
		{
			PGAIndirection *i = makeNode(PGAIndirection);

			if (nfields == 0)
			{
				/* easy case - all indirection goes to PGAIndirection */
				c->fields = list_make1(makeString(colname));
				i->indirection = check_indirection(indirection, yyscanner);
			}
			else
			{
				/* got to split the list in two */
				i->indirection = check_indirection(list_copy_tail(indirection,
																  nfields),
												   yyscanner);
				indirection = list_truncate(indirection, nfields);
				c->fields = lcons(makeString(colname), indirection);
			}
			i->arg = (PGNode *) c;
			return (PGNode *) i;
		}
		else if (IsA(lfirst(l), PGAStar))
		{
			/* We only allow '*' at the end of a PGColumnRef */
			if (lnext(l) != NULL)
				parser_yyerror("improper use of \"*\"");
		}
		nfields++;
	}
	/* No subscripting, so all indirection gets added to field list */
	c->fields = lcons(makeString(colname), indirection);
	return (PGNode *) c;
}

static PGNode *
makeTypeCast(PGNode *arg, PGTypeName *tpname, int location)
{
	PGTypeCast *n = makeNode(PGTypeCast);
	n->arg = arg;
	n->typeName = tpname;
	n->location = location;
	return (PGNode *) n;
}

static PGNode *
makeStringConst(char *str, int location)
{
	PGAConst *n = makeNode(PGAConst);

	n->val.type = T_PGString;
	n->val.val.str = str;
	n->location = location;

	return (PGNode *)n;
}

static PGNode *
makeStringConstCast(char *str, int location, PGTypeName *tpname)
{
	PGNode *s = makeStringConst(str, location);

	return makeTypeCast(s, tpname, -1);
}

static PGNode *
makeIntConst(int val, int location)
{
	PGAConst *n = makeNode(PGAConst);

	n->val.type = T_PGInteger;
	n->val.val.ival = val;
	n->location = location;

	return (PGNode *)n;
}

static PGNode *
makeFloatConst(char *str, int location)
{
	PGAConst *n = makeNode(PGAConst);

	n->val.type = T_PGFloat;
	n->val.val.str = str;
	n->location = location;

	return (PGNode *)n;
}

static PGNode *
makeBitStringConst(char *str, int location)
{
	PGAConst *n = makeNode(PGAConst);

	n->val.type = T_PGBitString;
	n->val.val.str = str;
	n->location = location;

	return (PGNode *)n;
}

static PGNode *
makeNullAConst(int location)
{
	PGAConst *n = makeNode(PGAConst);

	n->val.type = T_PGNull;
	n->location = location;

	return (PGNode *)n;
}

static PGNode *
makeAConst(PGValue *v, int location)
{
	PGNode *n;

	switch (v->type)
	{
		case T_PGFloat:
			n = makeFloatConst(v->val.str, location);
			break;

		case T_PGInteger:
			n = makeIntConst(v->val.ival, location);
			break;

		case T_PGString:
		default:
			n = makeStringConst(v->val.str, location);
			break;
	}

	return n;
}

/* makeBoolAConst()
 * Create an PGAConst string node and put it inside a boolean cast.
 */
static PGNode *
makeBoolAConst(bool state, int location)
{
	PGAConst *n = makeNode(PGAConst);

	n->val.type = T_PGString;
	n->val.val.str = (state ? (char*) "t" : (char*) "f");
	n->location = location;

	return makeTypeCast((PGNode *)n, SystemTypeName("bool"), -1);
}

/* check_qualified_name --- check the result of qualified_name production
 *
 * It's easiest to let the grammar production for qualified_name allow
 * subscripts and '*', which we then must reject here.
 */
static void
check_qualified_name(PGList *names, core_yyscan_t yyscanner)
{
	PGListCell   *i;

	foreach(i, names)
	{
		if (!IsA(lfirst(i), PGString))
			parser_yyerror("syntax error");
	}
}

/* check_func_name --- check the result of func_name production
 *
 * It's easiest to let the grammar production for func_name allow subscripts
 * and '*', which we then must reject here.
 */
static PGList *
check_func_name(PGList *names, core_yyscan_t yyscanner)
{
	PGListCell   *i;

	foreach(i, names)
	{
		if (!IsA(lfirst(i), PGString))
			parser_yyerror("syntax error");
	}
	return names;
}

/* check_indirection --- check the result of indirection production
 *
 * We only allow '*' at the end of the list, but it's hard to enforce that
 * in the grammar, so do it here.
 */
static PGList *
check_indirection(PGList *indirection, core_yyscan_t yyscanner)
{
	PGListCell *l;

	foreach(l, indirection)
	{
		if (IsA(lfirst(l), PGAStar))
		{
			if (lnext(l) != NULL)
				parser_yyerror("improper use of \"*\"");
		}
	}
	return indirection;
}

/* makeParamRef
 * Creates a new PGParamRef node
 */
static PGNode* makeParamRef(int number, int location)
{
	PGParamRef *p = makeNode(PGParamRef);
	p->number = number;
	p->location = location;
	return (PGNode *) p;
}

static PGNode *
makeParamRefCast(int number, int location, PGTypeName *tpname)
{
	PGNode *p = makeParamRef(number, location);
	return makeTypeCast(p, tpname, -1);
}

/* insertSelectOptions()
 * Insert ORDER BY, etc into an already-constructed SelectStmt.
 *
 * This routine is just to avoid duplicating code in PGSelectStmt productions.
 */
static void
insertSelectOptions(PGSelectStmt *stmt,
					PGList *sortClause, PGList *lockingClause,
					PGNode *limitOffset, PGNode *limitCount,
					PGWithClause *withClause,
					core_yyscan_t yyscanner)
{
	Assert(IsA(stmt, PGSelectStmt));

	/*
	 * Tests here are to reject constructs like
	 *	(SELECT foo ORDER BY bar) ORDER BY baz
	 */
	if (sortClause)
	{
		if (stmt->sortClause)
			ereport(ERROR,
					(errcode(PG_ERRCODE_SYNTAX_ERROR),
					 errmsg("multiple ORDER BY clauses not allowed"),
					 parser_errposition(exprLocation((PGNode *) sortClause))));
		stmt->sortClause = sortClause;
	}
	/* We can handle multiple locking clauses, though */
	stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause);
	if (limitOffset)
	{
		if (stmt->limitOffset)
			ereport(ERROR,
					(errcode(PG_ERRCODE_SYNTAX_ERROR),
					 errmsg("multiple OFFSET clauses not allowed"),
					 parser_errposition(exprLocation(limitOffset))));
		stmt->limitOffset = limitOffset;
	}
	if (limitCount)
	{
		if (stmt->limitCount)
			ereport(ERROR,
					(errcode(PG_ERRCODE_SYNTAX_ERROR),
					 errmsg("multiple LIMIT clauses not allowed"),
					 parser_errposition(exprLocation(limitCount))));
		stmt->limitCount = limitCount;
	}
	if (withClause)
	{
		if (stmt->withClause)
			ereport(ERROR,
					(errcode(PG_ERRCODE_SYNTAX_ERROR),
					 errmsg("multiple WITH clauses not allowed"),
					 parser_errposition(exprLocation((PGNode *) withClause))));
		stmt->withClause = withClause;
	}
}

static PGNode *
makeSetOp(PGSetOperation op, bool all, PGNode *larg, PGNode *rarg)
{
	PGSelectStmt *n = makeNode(PGSelectStmt);

	n->op = op;
	n->all = all;
	n->larg = (PGSelectStmt *) larg;
	n->rarg = (PGSelectStmt *) rarg;
	return (PGNode *) n;
}

/* SystemFuncName()
 * Build a properly-qualified reference to a built-in function.
 */
PGList *
SystemFuncName(const char *name)
{
	return list_make2(makeString(DEFAULT_SCHEMA), makeString(name));
}

/* SystemTypeName()
 * Build a properly-qualified reference to a built-in type.
 *
 * typmod is defaulted, but may be changed afterwards by caller.
 * Likewise for the location.
 */
PGTypeName *
SystemTypeName(const char *name)
{
	return makeTypeNameFromNameList(list_make2(makeString(DEFAULT_SCHEMA),
											   makeString(name)));
}

/* doNegate()
 * Handle negation of a numeric constant.
 *
 * Formerly, we did this here because the optimizer couldn't cope with
 * indexquals that looked like "var = -4" --- it wants "var = const"
 * and a unary minus operator applied to a constant didn't qualify.
 * As of Postgres 7.0, that problem doesn't exist anymore because there
 * is a constant-subexpression simplifier in the optimizer.  However,
 * there's still a good reason for doing this here, which is that we can
 * postpone committing to a particular internal representation for simple
 * negative constants.	It's better to leave "-123.456" in string form
 * until we know what the desired type is.
 */
static PGNode *
doNegate(PGNode *n, int location)
{
	if (IsA(n, PGAConst))
	{
		PGAConst *con = (PGAConst *)n;

		/* report the constant's location as that of the '-' sign */
		con->location = location;

		if (con->val.type == T_PGInteger)
		{
			con->val.val.ival = -con->val.val.ival;
			return n;
		}
		if (con->val.type == T_PGFloat)
		{
			doNegateFloat(&con->val);
			return n;
		}
	}

	return (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "-", NULL, n, location);
}

static void
doNegateFloat(PGValue *v)
{
	char   *oldval = v->val.str;

	Assert(IsA(v, PGFloat));
	if (*oldval == '+')
		oldval++;
	if (*oldval == '-')
		v->val.str = oldval+1;	/* just strip the '-' */
	else
		v->val.str = psprintf("-%s", oldval);
}

static PGNode *
makeAndExpr(PGNode *lexpr, PGNode *rexpr, int location)
{
	PGNode	   *lexp = lexpr;

	/* Look through AEXPR_PAREN nodes so they don't affect flattening */
	while (IsA(lexp, PGAExpr) &&
		   ((PGAExpr *) lexp)->kind == AEXPR_PAREN)
		lexp = ((PGAExpr *) lexp)->lexpr;
	/* Flatten "a AND b AND c ..." to a single PGBoolExpr on sight */
	if (IsA(lexp, PGBoolExpr))
	{
		PGBoolExpr *blexpr = (PGBoolExpr *) lexp;

		if (blexpr->boolop == PG_AND_EXPR)
		{
			blexpr->args = lappend(blexpr->args, rexpr);
			return (PGNode *) blexpr;
		}
	}
	return (PGNode *) makeBoolExpr(PG_AND_EXPR, list_make2(lexpr, rexpr), location);
}

static PGNode *
makeOrExpr(PGNode *lexpr, PGNode *rexpr, int location)
{
	PGNode	   *lexp = lexpr;

	/* Look through AEXPR_PAREN nodes so they don't affect flattening */
	while (IsA(lexp, PGAExpr) &&
		   ((PGAExpr *) lexp)->kind == AEXPR_PAREN)
		lexp = ((PGAExpr *) lexp)->lexpr;
	/* Flatten "a OR b OR c ..." to a single PGBoolExpr on sight */
	if (IsA(lexp, PGBoolExpr))
	{
		PGBoolExpr *blexpr = (PGBoolExpr *) lexp;

		if (blexpr->boolop == PG_OR_EXPR)
		{
			blexpr->args = lappend(blexpr->args, rexpr);
			return (PGNode *) blexpr;
		}
	}
	return (PGNode *) makeBoolExpr(PG_OR_EXPR, list_make2(lexpr, rexpr), location);
}

static PGNode *
makeNotExpr(PGNode *expr, int location)
{
	return (PGNode *) makeBoolExpr(PG_NOT_EXPR, list_make1(expr), location);
}

static PGNode *
makeSQLValueFunction(PGSQLValueFunctionOp op, int32_t typmod, int location)
{
	PGSQLValueFunction *svf = makeNode(PGSQLValueFunction);

	svf->op = op;
	/* svf->type will be filled during parse analysis */
	svf->typmod = typmod;
	svf->location = location;
	return (PGNode *) svf;
}

/* Separate PGConstraint nodes from COLLATE clauses in a */
static void
SplitColQualList(PGList *qualList,
				 PGList **constraintList, PGCollateClause **collClause,
				 core_yyscan_t yyscanner)
{
	PGListCell   *cell;
	PGListCell   *prev;
	PGListCell   *next;

	*collClause = NULL;
	prev = NULL;
	for (cell = list_head(qualList); cell; cell = next)
	{
		PGNode   *n = (PGNode *) lfirst(cell);

		next = lnext(cell);
		if (IsA(n, PGConstraint))
		{
			/* keep it in list */
			prev = cell;
			continue;
		}
		if (IsA(n, PGCollateClause))
		{
			PGCollateClause *c = (PGCollateClause *) n;

			if (*collClause)
				ereport(ERROR,
						(errcode(PG_ERRCODE_SYNTAX_ERROR),
						 errmsg("multiple COLLATE clauses not allowed"),
						 parser_errposition(c->location)));
			*collClause = c;
		}
		else
			elog(ERROR, "unexpected node type %d", (int) n->type);
		/* remove non-Constraint nodes from qualList */
		qualList = list_delete_cell(qualList, cell, prev);
	}
	*constraintList = qualList;
}

/*
 * Process result of ConstraintAttributeSpec, and set appropriate bool flags
 * in the output command node.  Pass NULL for any flags the particular
 * command doesn't support.
 */
static void
processCASbits(int cas_bits, int location, const char *constrType,
			   bool *deferrable, bool *initdeferred, bool *not_valid,
			   bool *no_inherit, core_yyscan_t yyscanner)
{
	/* defaults */
	if (deferrable)
		*deferrable = false;
	if (initdeferred)
		*initdeferred = false;
	if (not_valid)
		*not_valid = false;

	if (cas_bits & (CAS_DEFERRABLE | CAS_INITIALLY_DEFERRED))
	{
		if (deferrable)
			*deferrable = true;
		else
			ereport(ERROR,
					(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
					 /* translator: %s is CHECK, UNIQUE, or similar */
					 errmsg("%s constraints cannot be marked DEFERRABLE",
							constrType),
					 parser_errposition(location)));
	}

	if (cas_bits & CAS_INITIALLY_DEFERRED)
	{
		if (initdeferred)
			*initdeferred = true;
		else
			ereport(ERROR,
					(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
					 /* translator: %s is CHECK, UNIQUE, or similar */
					 errmsg("%s constraints cannot be marked DEFERRABLE",
							constrType),
					 parser_errposition(location)));
	}

	if (cas_bits & CAS_NOT_VALID)
	{
		if (not_valid)
			*not_valid = true;
		else
			ereport(ERROR,
					(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
					 /* translator: %s is CHECK, UNIQUE, or similar */
					 errmsg("%s constraints cannot be marked NOT VALID",
							constrType),
					 parser_errposition(location)));
	}

	if (cas_bits & CAS_NO_INHERIT)
	{
		if (no_inherit)
			*no_inherit = true;
		else
			ereport(ERROR,
					(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
					 /* translator: %s is CHECK, UNIQUE, or similar */
					 errmsg("%s constraints cannot be marked NO INHERIT",
							constrType),
					 parser_errposition(location)));
	}
}

/*----------
 * Recursive view transformation
 *
 * Convert
 *
 *     CREATE RECURSIVE VIEW relname (aliases) AS query
 *
 * to
 *
 *     CREATE VIEW relname (aliases) AS
 *         WITH RECURSIVE relname (aliases) AS (query)
 *         SELECT aliases FROM relname
 *
 * Actually, just the WITH ... part, which is then inserted into the original
 * view as the query.
 * ----------
 */
static PGNode *
makeRecursiveViewSelect(char *relname, PGList *aliases, PGNode *query)
{
	PGSelectStmt *s = makeNode(PGSelectStmt);
	PGWithClause *w = makeNode(PGWithClause);
	PGCommonTableExpr *cte = makeNode(PGCommonTableExpr);
	PGList	   *tl = NIL;
	PGListCell   *lc;

	/* create common table expression */
	cte->ctename = relname;
	cte->aliascolnames = aliases;
	cte->ctequery = query;
	cte->location = -1;

	/* create WITH clause and attach CTE */
	w->recursive = true;
	w->ctes = list_make1(cte);
	w->location = -1;

	/* create target list for the new SELECT from the alias list of the
	 * recursive view specification */
	foreach (lc, aliases)
	{
		PGResTarget *rt = makeNode(PGResTarget);

		rt->name = NULL;
		rt->indirection = NIL;
		rt->val = makeColumnRef(strVal(lfirst(lc)), NIL, -1, 0);
		rt->location = -1;

		tl = lappend(tl, rt);
	}

	/* create new SELECT combining WITH clause, target list, and fake FROM
	 * clause */
	s->withClause = w;
	s->targetList = tl;
	s->fromClause = list_make1(makeRangeVar(NULL, relname, -1));

	return (PGNode *) s;
}

/* parser_init()
 * Initialize to parse one query string
 */
void
parser_init(base_yy_extra_type *yyext)
{
	yyext->parsetree = NIL;		/* in case grammar forgets to set it */
}

/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - raw_parser
 * - base_yylex
 * - raw_parser
 *--------------------------------------------------------------------
 */

/*-------------------------------------------------------------------------
 *
 * parser.c
 *		Main entry point/driver for PostgreSQL grammar
 *
 * Note that the grammar is not allowed to perform any table access
 * (since we need to be able to do basic parsing even while inside an
 * aborted transaction).  Therefore, the data structures returned by
 * the grammar are "raw" parsetrees that still need to be analyzed by
 * analyze.c and related files.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/parser/parser.c
 *
 *-------------------------------------------------------------------------
 */







/*
 * raw_parser
 *		Given a query in string form, do lexical and grammatical analysis.
 *
 * Returns a list of raw (un-analyzed) parse trees.  The immediate elements
 * of the list are always PGRawStmt nodes.
 */
PGList *
raw_parser(const char *str)
{
	core_yyscan_t yyscanner;
	base_yy_extra_type yyextra;
	int			yyresult;

	/* initialize the flex scanner */
	yyscanner = scanner_init(str, &yyextra.core_yy_extra,
							 ScanKeywords, NumScanKeywords);

	/* base_yylex() only needs this much initialization */
	yyextra.have_lookahead = false;

	/* initialize the bison parser */
	parser_init(&yyextra);

	/* Parse! */
	yyresult = base_yyparse(yyscanner);

	/* Clean up (release memory) */
	scanner_finish(yyscanner);

	if (yyresult)				/* error */
		return NIL;

	return yyextra.parsetree;
}


/*
 * Intermediate filter between parser and core lexer (core_yylex in scan.l).
 *
 * This filter is needed because in some cases the standard SQL grammar
 * requires more than one token lookahead.  We reduce these cases to one-token
 * lookahead by replacing tokens here, in order to keep the grammar LALR(1).
 *
 * Using a filter is simpler than trying to recognize multiword tokens
 * directly in scan.l, because we'd have to allow for comments between the
 * words.  Furthermore it's not clear how to do that without re-introducing
 * scanner backtrack, which would cost more performance than this filter
 * layer does.
 *
 * The filter also provides a convenient place to translate between
 * the core_YYSTYPE and YYSTYPE representations (which are really the
 * same thing anyway, but notationally they're different).
 */
int
base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner)
{
	base_yy_extra_type *yyextra = pg_yyget_extra(yyscanner);
	int			cur_token;
	int			next_token;
	int			cur_token_length;
	YYLTYPE		cur_yylloc;

	/* Get next token --- we might already have it */
	if (yyextra->have_lookahead)
	{
		cur_token = yyextra->lookahead_token;
		lvalp->core_yystype = yyextra->lookahead_yylval;
		*llocp = yyextra->lookahead_yylloc;
		*(yyextra->lookahead_end) = yyextra->lookahead_hold_char;
		yyextra->have_lookahead = false;
	}
	else
		cur_token = core_yylex(&(lvalp->core_yystype), llocp, yyscanner);

	/*
	 * If this token isn't one that requires lookahead, just return it.  If it
	 * does, determine the token length.  (We could get that via strlen(), but
	 * since we have such a small set of possibilities, hardwiring seems
	 * feasible and more efficient.)
	 */
	switch (cur_token)
	{
		case NOT:
			cur_token_length = 3;
			break;
		case NULLS_P:
			cur_token_length = 5;
			break;
		case WITH:
			cur_token_length = 4;
			break;
		default:
			return cur_token;
	}

	/*
	 * Identify end+1 of current token.  core_yylex() has temporarily stored a
	 * '\0' here, and will undo that when we call it again.  We need to redo
	 * it to fully revert the lookahead call for error reporting purposes.
	 */
	yyextra->lookahead_end = yyextra->core_yy_extra.scanbuf +
		*llocp + cur_token_length;
	Assert(*(yyextra->lookahead_end) == '\0');

	/*
	 * Save and restore *llocp around the call.  It might look like we could
	 * avoid this by just passing &lookahead_yylloc to core_yylex(), but that
	 * does not work because flex actually holds onto the last-passed pointer
	 * internally, and will use that for error reporting.  We need any error
	 * reports to point to the current token, not the next one.
	 */
	cur_yylloc = *llocp;

	/* Get next token, saving outputs into lookahead variables */
	next_token = core_yylex(&(yyextra->lookahead_yylval), llocp, yyscanner);
	yyextra->lookahead_token = next_token;
	yyextra->lookahead_yylloc = *llocp;

	*llocp = cur_yylloc;

	/* Now revert the un-truncation of the current token */
	yyextra->lookahead_hold_char = *(yyextra->lookahead_end);
	*(yyextra->lookahead_end) = '\0';

	yyextra->have_lookahead = true;

	/* Replace cur_token if needed, based on lookahead */
	switch (cur_token)
	{
		case NOT:
			/* Replace NOT by NOT_LA if it's followed by BETWEEN, IN, etc */
			switch (next_token)
			{
				case BETWEEN:
				case IN_P:
				case LIKE:
				case ILIKE:
				case SIMILAR:
					cur_token = NOT_LA;
					break;
			}
			break;

		case NULLS_P:
			/* Replace NULLS_P by NULLS_LA if it's followed by FIRST or LAST */
			switch (next_token)
			{
				case FIRST_P:
				case LAST_P:
					cur_token = NULLS_LA;
					break;
			}
			break;

		case WITH:
			/* Replace WITH by WITH_LA if it's followed by TIME or ORDINALITY */
			switch (next_token)
			{
				case TIME:
				case ORDINALITY:
					cur_token = WITH_LA;
					break;
			}
			break;
	}

	return cur_token;
}
/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - scanner_init
 * - core_yylex_init
 * - core_yyalloc
 * - yy_init_globals
 * - core_yyset_extra
 * - backslash_quote
 * - escape_string_warning
 * - standard_conforming_strings
 * - core_yy_scan_buffer
 * - core_yy_switch_to_buffer
 * - core_yyensure_buffer_stack
 * - core_yyrealloc
 * - core_yy_load_buffer_state
 * - yy_fatal_error
 * - fprintf_to_ereport
 * - core_yylex
 * - core_yy_create_buffer
 * - core_yy_init_buffer
 * - core_yy_flush_buffer
 * - core_yyrestart
 * - yy_start_state_list
 * - yy_transition
 * - addlitchar
 * - litbufdup
 * - addlit
 * - litbuf_udeescape
 * - hexval
 * - check_unicode_value
 * - check_uescapechar
 * - check_escape_warning
 * - is_utf16_surrogate_first
 * - is_utf16_surrogate_second
 * - addunicode
 * - surrogate_pair_to_codepoint
 * - check_string_escape_warning
 * - unescape_single_char
 * - process_integer_literal
 * - yy_get_previous_state
 * - yy_try_NUL_trans
 * - yy_get_next_buffer
 * - scanner_errposition
 * - scanner_yyerror
 * - scanner_finish
 *--------------------------------------------------------------------
 */



/*-------------------------------------------------------------------------
 *
 * scan.l
 *	  lexical scanner for PostgreSQL
 *
 * NOTE NOTE NOTE:
 *
 * The rules in this file must be kept in sync with src/fe_utils/psqlscan.l!
 *
 * The rules are designed so that the scanner never has to backtrack,
 * in the sense that there is always a rule that can match the input
 * consumed so far (the rule action may internally throw back some input
 * with yyless(), however).  As explained in the flex manual, this makes
 * for a useful speed increase --- about a third faster than a plain -CF
 * lexer, in simple testing.  The extra complexity is mostly in the rules
 * for handling float numbers and continued string literals.  If you change
 * the lexical rules, verify that you haven't broken the no-backtrack
 * property by running flex with the "-b" option and checking that the
 * resulting "lex.backup" file says that no backing up is needed.  (As of
 * Postgres 9.2, this check is made automatically by the Makefile.)
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/parser/scan.l
 *
 *-------------------------------------------------------------------------
 */
#include <ctype.h>
//#include <unistd.h>



		/* only needed for GUC variables */
/*-------------------------------------------------------------------------
 *
 * scansup.h
 *	  scanner support routines.  used by both the bootstrap lexer
 * as well as the normal lexer
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/parser/scansup.h
 *
 *-------------------------------------------------------------------------
 */



extern char *scanstr(const char *s);

extern char *downcase_truncate_identifier(const char *ident, int len,
							 bool warn);

extern char *downcase_identifier(const char *ident, int len,
					bool warn, bool truncate);

extern void truncate_identifier(char *ident, int len, bool warn);

extern bool scanner_isspace(char ch);

/*-------------------------------------------------------------------------
 *
 * pg_wchar.h
 *	  multibyte-character support
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/mb/pg_wchar.h
 *
 *	NOTES
 *		This is used both by the backend and by libpq, but should not be
 *		included by libpq client programs.  In particular, a libpq client
 *		should not assume that the encoding IDs used by the version of libpq
 *		it's linked to match up with the IDs declared here.
 *
 *-------------------------------------------------------------------------
 */


#include <cstdint>

/*
 * The pg_wchar type
 */
typedef unsigned int pg_wchar;






#define  YY_INT_ALIGNED short int

/* A lexical scanner generated by flex */

#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 35
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif

/* First, we deal with  platform-specific or compiler-specific issues. */

/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

/* end standard C headers. */

/* flex integer type definitions */

#ifndef FLEXINT_H
#define FLEXINT_H

/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */

#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L

/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
 * if you want the limit (max/min) macros for int types.
 */
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif

#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
#endif /* ! C99 */

/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN               (-128)
#endif
#ifndef INT16_MIN
#define INT16_MIN              (-32767-1)
#endif
#ifndef INT32_MIN
#define INT32_MIN              (-2147483647-1)
#endif
#ifndef INT8_MAX
#define INT8_MAX               (127)
#endif
#ifndef INT16_MAX
#define INT16_MAX              (32767)
#endif
#ifndef INT32_MAX
#define INT32_MAX              (2147483647)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX              (255U)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX             (65535U)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX             (4294967295U)
#endif

#endif /* ! FLEXINT_H */

#ifdef __cplusplus

/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST

#else	/* ! __cplusplus */

/* C99 requires __STDC__ to be defined as 1. */
#if defined (__STDC__)

#define YY_USE_CONST

#endif	/* defined (__STDC__) */
#endif	/* ! __cplusplus */

#ifdef YY_USE_CONST
#define yyconst const
#else
#define yyconst
#endif

/* Returned upon end-of-file. */
#define YY_NULL 0

/* Promotes a possibly negative, possibly signed char to an unsigned
 * integer for use as an array index.  If the signed char is negative,
 * we want to instead treat it as an 8-bit unsigned char, hence the
 * double cast.
 */
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)

/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif

/* For convenience, these vars (plus the bison vars far below)
   are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
#define yyout yyg->yyout_r
#define yyextra yyg->yyextra_r
#define yyleng yyg->yyleng_r
#define yytext yyg->yytext_r
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r

/* Enter a start condition.  This macro really ought to take a parameter,
 * but we do it the disgusting crufty way forced on us by the ()-less
 * definition of BEGIN.
 */
#define BEGIN yyg->yy_start = 1 + 2 *

/* Translate the current start state into a value that can be later handed
 * to BEGIN to return to the state.  The YYSTATE alias is for lex
 * compatibility.
 */
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START

/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)

/* Special action meaning "start processing a new file". */
#define YY_NEW_FILE core_yyrestart(yyin ,yyscanner )

#define YY_END_OF_BUFFER_CHAR 0

/* PGSize of default input buffer. */
#ifndef YY_BUF_SIZE
#define YY_BUF_SIZE 16384
#endif

/* The state buf must be large enough to hold one state per character in the main buffer.
 */
#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))

#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif

#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif

#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2

    #define YY_LESS_LINENO(n)

/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
	do \
		{ \
		/* Undo effects of setting up yytext. */ \
        int yyless_macro_arg = (n); \
        YY_LESS_LINENO(yyless_macro_arg);\
		*yy_cp = yyg->yy_hold_char; \
		YY_RESTORE_YY_MORE_OFFSET \
		yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
		} \
	while ( 0 )

#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )

#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
	{
	FILE *yy_input_file;

	char *yy_ch_buf;		/* input buffer */
	char *yy_buf_pos;		/* current position in input buffer */

	/* PGSize of input buffer in bytes, not including room for EOB
	 * characters.
	 */
	yy_size_t yy_buf_size;

	/* Number of characters read into yy_ch_buf, not including EOB
	 * characters.
	 */
	yy_size_t yy_n_chars;

	/* Whether we "own" the buffer - i.e., we know we created it,
	 * and can realloc() it to grow it, and should free() it to
	 * delete it.
	 */
	int yy_is_our_buffer;

	/* Whether this is an "interactive" input source; if so, and
	 * if we're using stdio for input, then we want to use getc()
	 * instead of fread(), to make sure we stop fetching input after
	 * each newline.
	 */
	int yy_is_interactive;

	/* Whether we're considered to be at the beginning of a line.
	 * If so, '^' rules will be active on the next match, otherwise
	 * not.
	 */
	int yy_at_bol;

    int yy_bs_lineno; /**< The line count. */
    int yy_bs_column; /**< The column count. */

	/* Whether to try to fill the input buffer when we reach the
	 * end of it.
	 */
	int yy_fill_buffer;

	int yy_buffer_status;

#define YY_BUFFER_NEW 0
#define YY_BUFFER_NORMAL 1
	/* When an EOF's been seen but there's still some text to process
	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
	 * shouldn't try reading from the input source any more.  We might
	 * still have a bunch of tokens to match, though, because of
	 * possible backing-up.
	 *
	 * When we actually see the EOF, we change the status to "new"
	 * (via core_yyrestart()), so that the user can continue scanning by
	 * just pointing yyin at a new input file.
	 */
#define YY_BUFFER_EOF_PENDING 2

	};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */

/* We provide macros for accessing buffer states in case in the
 * future we want to put the buffer states in a more general
 * "scanner state".
 *
 * Returns the top of the stack, or NULL.
 */
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
                          : NULL)

/* Same as previous macro, but useful when we know that the buffer stack is not
 * NULL or when we need an lvalue. For internal use only.
 */
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]

void core_yyrestart (FILE *input_file ,yyscan_t yyscanner );
void core_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
YY_BUFFER_STATE core_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
void core_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
void core_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
void core_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
void core_yypop_buffer_state (yyscan_t yyscanner );

static void core_yyensure_buffer_stack (yyscan_t yyscanner );
static void core_yy_load_buffer_state (yyscan_t yyscanner );
static void core_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );

#define YY_FLUSH_BUFFER core_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)

YY_BUFFER_STATE core_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE core_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );

void *core_yyalloc (yy_size_t ,yyscan_t yyscanner );
void *core_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
void core_yyfree (void * ,yyscan_t yyscanner );

#define yy_new_buffer core_yy_create_buffer

#define yy_set_interactive(is_interactive) \
	{ \
	if ( ! YY_CURRENT_BUFFER ){ \
        core_yyensure_buffer_stack (yyscanner); \
		YY_CURRENT_BUFFER_LVALUE =    \
            core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
	} \
	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
	}

#define yy_set_bol(at_bol) \
	{ \
	if ( ! YY_CURRENT_BUFFER ){\
        core_yyensure_buffer_stack (yyscanner); \
		YY_CURRENT_BUFFER_LVALUE =    \
            core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
	} \
	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
	}

#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)

/* Begin user sect3 */

#define core_yywrap(n) 1
#define YY_SKIP_YYWRAP

typedef unsigned char YY_CHAR;

typedef yyconst struct yy_trans_info *yy_state_type;

#define yytext_ptr yytext_r

static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
static int yy_get_next_buffer (yyscan_t yyscanner );
static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );

/* Done after the current pattern has been matched and before the
 * corresponding action - sets up yytext.
 */
#define YY_DO_BEFORE_ACTION \
	yyg->yytext_ptr = yy_bp; \
	yyleng = (yy_size_t) (yy_cp - yy_bp); \
	yyg->yy_hold_char = *yy_cp; \
	*yy_cp = '\0'; \
	yyg->yy_c_buf_p = yy_cp;

#define YY_NUM_RULES 80
#define YY_END_OF_BUFFER 81
struct yy_trans_info
	{
	flex_int32_t yy_verify;
	flex_int32_t yy_nxt;
	};
static yyconst struct yy_trans_info yy_transition[37005] =
    {
 {   0,   0 }, {   0,36749 }, {   0,   0 }, {   0,36747 }, {   1,6708 },
 {   2,6708 }, {   3,6708 }, {   4,6708 }, {   5,6708 }, {   6,6708 },
 {   7,6708 }, {   8,6708 }, {   9,6710 }, {  10,6715 }, {  11,6708 },
 {  12,6710 }, {  13,6710 }, {  14,6708 }, {  15,6708 }, {  16,6708 },
 {  17,6708 }, {  18,6708 }, {  19,6708 }, {  20,6708 }, {  21,6708 },
 {  22,6708 }, {  23,6708 }, {  24,6708 }, {  25,6708 }, {  26,6708 },
 {  27,6708 }, {  28,6708 }, {  29,6708 }, {  30,6708 }, {  31,6708 },
 {  32,6710 }, {  33,6717 }, {  34,6712 }, {  35,6757 }, {  36,6823 },
 {  37,7080 }, {  38,6757 }, {  39,6730 }, {  40,6732 }, {  41,6732 },
 {  42,7080 }, {  43,7080 }, {  44,6732 }, {  45,7091 }, {  46,7110 },

 {  47,7181 }, {  48,7183 }, {  49,7183 }, {  50,7183 }, {  51,7183 },
 {  52,7183 }, {  53,7183 }, {  54,7183 }, {  55,7183 }, {  56,7183 },
 {  57,7183 }, {  58,6735 }, {  59,6732 }, {  60,7248 }, {  61,7259 },
 {  62,7326 }, {  63,7080 }, {  64,6757 }, {  65,7358 }, {  66,7615 },
 {  67,7358 }, {  68,7358 }, {  69,7872 }, {  70,7358 }, {  71,7358 },
 {  72,7358 }, {  73,7358 }, {  74,7358 }, {  75,7358 }, {  76,7358 },
 {  77,7358 }, {  78,8129 }, {  79,7358 }, {  80,7358 }, {  81,7358 },
 {  82,7358 }, {  83,7358 }, {  84,7358 }, {  85,8386 }, {  86,7358 },
 {  87,7358 }, {  88,8643 }, {  89,7358 }, {  90,7358 }, {  91,6732 },
 {  92,6708 }, {  93,6732 }, {  94,7080 }, {  95,7358 }, {  96,6757 },

 {  97,7358 }, {  98,7615 }, {  99,7358 }, { 100,7358 }, { 101,7872 },
 { 102,7358 }, { 103,7358 }, { 104,7358 }, { 105,7358 }, { 106,7358 },
 { 107,7358 }, { 108,7358 }, { 109,7358 }, { 110,8129 }, { 111,7358 },
 { 112,7358 }, { 113,7358 }, { 114,7358 }, { 115,7358 }, { 116,7358 },
 { 117,8386 }, { 118,7358 }, { 119,7358 }, { 120,8643 }, { 121,7358 },
 { 122,7358 }, { 123,6708 }, { 124,6757 }, { 125,6708 }, { 126,6757 },
 { 127,6708 }, { 128,7358 }, { 129,7358 }, { 130,7358 }, { 131,7358 },
 { 132,7358 }, { 133,7358 }, { 134,7358 }, { 135,7358 }, { 136,7358 },
 { 137,7358 }, { 138,7358 }, { 139,7358 }, { 140,7358 }, { 141,7358 },
 { 142,7358 }, { 143,7358 }, { 144,7358 }, { 145,7358 }, { 146,7358 },

 { 147,7358 }, { 148,7358 }, { 149,7358 }, { 150,7358 }, { 151,7358 },
 { 152,7358 }, { 153,7358 }, { 154,7358 }, { 155,7358 }, { 156,7358 },
 { 157,7358 }, { 158,7358 }, { 159,7358 }, { 160,7358 }, { 161,7358 },
 { 162,7358 }, { 163,7358 }, { 164,7358 }, { 165,7358 }, { 166,7358 },
 { 167,7358 }, { 168,7358 }, { 169,7358 }, { 170,7358 }, { 171,7358 },
 { 172,7358 }, { 173,7358 }, { 174,7358 }, { 175,7358 }, { 176,7358 },
 { 177,7358 }, { 178,7358 }, { 179,7358 }, { 180,7358 }, { 181,7358 },
 { 182,7358 }, { 183,7358 }, { 184,7358 }, { 185,7358 }, { 186,7358 },
 { 187,7358 }, { 188,7358 }, { 189,7358 }, { 190,7358 }, { 191,7358 },
 { 192,7358 }, { 193,7358 }, { 194,7358 }, { 195,7358 }, { 196,7358 },

 { 197,7358 }, { 198,7358 }, { 199,7358 }, { 200,7358 }, { 201,7358 },
 { 202,7358 }, { 203,7358 }, { 204,7358 }, { 205,7358 }, { 206,7358 },
 { 207,7358 }, { 208,7358 }, { 209,7358 }, { 210,7358 }, { 211,7358 },
 { 212,7358 }, { 213,7358 }, { 214,7358 }, { 215,7358 }, { 216,7358 },
 { 217,7358 }, { 218,7358 }, { 219,7358 }, { 220,7358 }, { 221,7358 },
 { 222,7358 }, { 223,7358 }, { 224,7358 }, { 225,7358 }, { 226,7358 },
 { 227,7358 }, { 228,7358 }, { 229,7358 }, { 230,7358 }, { 231,7358 },
 { 232,7358 }, { 233,7358 }, { 234,7358 }, { 235,7358 }, { 236,7358 },
 { 237,7358 }, { 238,7358 }, { 239,7358 }, { 240,7358 }, { 241,7358 },
 { 242,7358 }, { 243,7358 }, { 244,7358 }, { 245,7358 }, { 246,7358 },

 { 247,7358 }, { 248,7358 }, { 249,7358 }, { 250,7358 }, { 251,7358 },
 { 252,7358 }, { 253,7358 }, { 254,7358 }, { 255,7358 }, { 256,6708 },
 {   0,   0 }, {   0,36489 }, {   1,6450 }, {   2,6450 }, {   3,6450 },
 {   4,6450 }, {   5,6450 }, {   6,6450 }, {   7,6450 }, {   8,6450 },
 {   9,6452 }, {  10,6457 }, {  11,6450 }, {  12,6452 }, {  13,6452 },
 {  14,6450 }, {  15,6450 }, {  16,6450 }, {  17,6450 }, {  18,6450 },
 {  19,6450 }, {  20,6450 }, {  21,6450 }, {  22,6450 }, {  23,6450 },
 {  24,6450 }, {  25,6450 }, {  26,6450 }, {  27,6450 }, {  28,6450 },
 {  29,6450 }, {  30,6450 }, {  31,6450 }, {  32,6452 }, {  33,6459 },
 {  34,6454 }, {  35,6499 }, {  36,6565 }, {  37,6822 }, {  38,6499 },

 {  39,6472 }, {  40,6474 }, {  41,6474 }, {  42,6822 }, {  43,6822 },
 {  44,6474 }, {  45,6833 }, {  46,6852 }, {  47,6923 }, {  48,6925 },
 {  49,6925 }, {  50,6925 }, {  51,6925 }, {  52,6925 }, {  53,6925 },
 {  54,6925 }, {  55,6925 }, {  56,6925 }, {  57,6925 }, {  58,6477 },
 {  59,6474 }, {  60,6990 }, {  61,7001 }, {  62,7068 }, {  63,6822 },
 {  64,6499 }, {  65,7100 }, {  66,7357 }, {  67,7100 }, {  68,7100 },
 {  69,7614 }, {  70,7100 }, {  71,7100 }, {  72,7100 }, {  73,7100 },
 {  74,7100 }, {  75,7100 }, {  76,7100 }, {  77,7100 }, {  78,7871 },
 {  79,7100 }, {  80,7100 }, {  81,7100 }, {  82,7100 }, {  83,7100 },
 {  84,7100 }, {  85,8128 }, {  86,7100 }, {  87,7100 }, {  88,8385 },

 {  89,7100 }, {  90,7100 }, {  91,6474 }, {  92,6450 }, {  93,6474 },
 {  94,6822 }, {  95,7100 }, {  96,6499 }, {  97,7100 }, {  98,7357 },
 {  99,7100 }, { 100,7100 }, { 101,7614 }, { 102,7100 }, { 103,7100 },
 { 104,7100 }, { 105,7100 }, { 106,7100 }, { 107,7100 }, { 108,7100 },
 { 109,7100 }, { 110,7871 }, { 111,7100 }, { 112,7100 }, { 113,7100 },
 { 114,7100 }, { 115,7100 }, { 116,7100 }, { 117,8128 }, { 118,7100 },
 { 119,7100 }, { 120,8385 }, { 121,7100 }, { 122,7100 }, { 123,6450 },
 { 124,6499 }, { 125,6450 }, { 126,6499 }, { 127,6450 }, { 128,7100 },
 { 129,7100 }, { 130,7100 }, { 131,7100 }, { 132,7100 }, { 133,7100 },
 { 134,7100 }, { 135,7100 }, { 136,7100 }, { 137,7100 }, { 138,7100 },

 { 139,7100 }, { 140,7100 }, { 141,7100 }, { 142,7100 }, { 143,7100 },
 { 144,7100 }, { 145,7100 }, { 146,7100 }, { 147,7100 }, { 148,7100 },
 { 149,7100 }, { 150,7100 }, { 151,7100 }, { 152,7100 }, { 153,7100 },
 { 154,7100 }, { 155,7100 }, { 156,7100 }, { 157,7100 }, { 158,7100 },
 { 159,7100 }, { 160,7100 }, { 161,7100 }, { 162,7100 }, { 163,7100 },
 { 164,7100 }, { 165,7100 }, { 166,7100 }, { 167,7100 }, { 168,7100 },
 { 169,7100 }, { 170,7100 }, { 171,7100 }, { 172,7100 }, { 173,7100 },
 { 174,7100 }, { 175,7100 }, { 176,7100 }, { 177,7100 }, { 178,7100 },
 { 179,7100 }, { 180,7100 }, { 181,7100 }, { 182,7100 }, { 183,7100 },
 { 184,7100 }, { 185,7100 }, { 186,7100 }, { 187,7100 }, { 188,7100 },

 { 189,7100 }, { 190,7100 }, { 191,7100 }, { 192,7100 }, { 193,7100 },
 { 194,7100 }, { 195,7100 }, { 196,7100 }, { 197,7100 }, { 198,7100 },
 { 199,7100 }, { 200,7100 }, { 201,7100 }, { 202,7100 }, { 203,7100 },
 { 204,7100 }, { 205,7100 }, { 206,7100 }, { 207,7100 }, { 208,7100 },
 { 209,7100 }, { 210,7100 }, { 211,7100 }, { 212,7100 }, { 213,7100 },
 { 214,7100 }, { 215,7100 }, { 216,7100 }, { 217,7100 }, { 218,7100 },
 { 219,7100 }, { 220,7100 }, { 221,7100 }, { 222,7100 }, { 223,7100 },
 { 224,7100 }, { 225,7100 }, { 226,7100 }, { 227,7100 }, { 228,7100 },
 { 229,7100 }, { 230,7100 }, { 231,7100 }, { 232,7100 }, { 233,7100 },
 { 234,7100 }, { 235,7100 }, { 236,7100 }, { 237,7100 }, { 238,7100 },

 { 239,7100 }, { 240,7100 }, { 241,7100 }, { 242,7100 }, { 243,7100 },
 { 244,7100 }, { 245,7100 }, { 246,7100 }, { 247,7100 }, { 248,7100 },
 { 249,7100 }, { 250,7100 }, { 251,7100 }, { 252,7100 }, { 253,7100 },
 { 254,7100 }, { 255,7100 }, { 256,6450 }, {   0,  12 }, {   0,36231 },
 {   1,8384 }, {   2,8384 }, {   3,8384 }, {   4,8384 }, {   5,8384 },
 {   6,8384 }, {   7,8384 }, {   8,8384 }, {   9,8384 }, {  10,8384 },
 {  11,8384 }, {  12,8384 }, {  13,8384 }, {  14,8384 }, {  15,8384 },
 {  16,8384 }, {  17,8384 }, {  18,8384 }, {  19,8384 }, {  20,8384 },
 {  21,8384 }, {  22,8384 }, {  23,8384 }, {  24,8384 }, {  25,8384 },
 {  26,8384 }, {  27,8384 }, {  28,8384 }, {  29,8384 }, {  30,8384 },

 {  31,8384 }, {  32,8384 }, {  33,8384 }, {  34,8384 }, {  35,8384 },
 {  36,8384 }, {  37,8384 }, {  38,8384 }, {  39,8642 }, {  40,8384 },
 {  41,8384 }, {  42,8384 }, {  43,8384 }, {  44,8384 }, {  45,8384 },
 {  46,8384 }, {  47,8384 }, {  48,8384 }, {  49,8384 }, {  50,8384 },
 {  51,8384 }, {  52,8384 }, {  53,8384 }, {  54,8384 }, {  55,8384 },
 {  56,8384 }, {  57,8384 }, {  58,8384 }, {  59,8384 }, {  60,8384 },
 {  61,8384 }, {  62,8384 }, {  63,8384 }, {  64,8384 }, {  65,8384 },
 {  66,8384 }, {  67,8384 }, {  68,8384 }, {  69,8384 }, {  70,8384 },
 {  71,8384 }, {  72,8384 }, {  73,8384 }, {  74,8384 }, {  75,8384 },
 {  76,8384 }, {  77,8384 }, {  78,8384 }, {  79,8384 }, {  80,8384 },

 {  81,8384 }, {  82,8384 }, {  83,8384 }, {  84,8384 }, {  85,8384 },
 {  86,8384 }, {  87,8384 }, {  88,8384 }, {  89,8384 }, {  90,8384 },
 {  91,8384 }, {  92,8384 }, {  93,8384 }, {  94,8384 }, {  95,8384 },
 {  96,8384 }, {  97,8384 }, {  98,8384 }, {  99,8384 }, { 100,8384 },
 { 101,8384 }, { 102,8384 }, { 103,8384 }, { 104,8384 }, { 105,8384 },
 { 106,8384 }, { 107,8384 }, { 108,8384 }, { 109,8384 }, { 110,8384 },
 { 111,8384 }, { 112,8384 }, { 113,8384 }, { 114,8384 }, { 115,8384 },
 { 116,8384 }, { 117,8384 }, { 118,8384 }, { 119,8384 }, { 120,8384 },
 { 121,8384 }, { 122,8384 }, { 123,8384 }, { 124,8384 }, { 125,8384 },
 { 126,8384 }, { 127,8384 }, { 128,8384 }, { 129,8384 }, { 130,8384 },

 { 131,8384 }, { 132,8384 }, { 133,8384 }, { 134,8384 }, { 135,8384 },
 { 136,8384 }, { 137,8384 }, { 138,8384 }, { 139,8384 }, { 140,8384 },
 { 141,8384 }, { 142,8384 }, { 143,8384 }, { 144,8384 }, { 145,8384 },
 { 146,8384 }, { 147,8384 }, { 148,8384 }, { 149,8384 }, { 150,8384 },
 { 151,8384 }, { 152,8384 }, { 153,8384 }, { 154,8384 }, { 155,8384 },
 { 156,8384 }, { 157,8384 }, { 158,8384 }, { 159,8384 }, { 160,8384 },
 { 161,8384 }, { 162,8384 }, { 163,8384 }, { 164,8384 }, { 165,8384 },
 { 166,8384 }, { 167,8384 }, { 168,8384 }, { 169,8384 }, { 170,8384 },
 { 171,8384 }, { 172,8384 }, { 173,8384 }, { 174,8384 }, { 175,8384 },
 { 176,8384 }, { 177,8384 }, { 178,8384 }, { 179,8384 }, { 180,8384 },

 { 181,8384 }, { 182,8384 }, { 183,8384 }, { 184,8384 }, { 185,8384 },
 { 186,8384 }, { 187,8384 }, { 188,8384 }, { 189,8384 }, { 190,8384 },
 { 191,8384 }, { 192,8384 }, { 193,8384 }, { 194,8384 }, { 195,8384 },
 { 196,8384 }, { 197,8384 }, { 198,8384 }, { 199,8384 }, { 200,8384 },
 { 201,8384 }, { 202,8384 }, { 203,8384 }, { 204,8384 }, { 205,8384 },
 { 206,8384 }, { 207,8384 }, { 208,8384 }, { 209,8384 }, { 210,8384 },
 { 211,8384 }, { 212,8384 }, { 213,8384 }, { 214,8384 }, { 215,8384 },
 { 216,8384 }, { 217,8384 }, { 218,8384 }, { 219,8384 }, { 220,8384 },
 { 221,8384 }, { 222,8384 }, { 223,8384 }, { 224,8384 }, { 225,8384 },
 { 226,8384 }, { 227,8384 }, { 228,8384 }, { 229,8384 }, { 230,8384 },

 { 231,8384 }, { 232,8384 }, { 233,8384 }, { 234,8384 }, { 235,8384 },
 { 236,8384 }, { 237,8384 }, { 238,8384 }, { 239,8384 }, { 240,8384 },
 { 241,8384 }, { 242,8384 }, { 243,8384 }, { 244,8384 }, { 245,8384 },
 { 246,8384 }, { 247,8384 }, { 248,8384 }, { 249,8384 }, { 250,8384 },
 { 251,8384 }, { 252,8384 }, { 253,8384 }, { 254,8384 }, { 255,8384 },
 { 256,8384 }, {   0,  12 }, {   0,35973 }, {   1,8126 }, {   2,8126 },
 {   3,8126 }, {   4,8126 }, {   5,8126 }, {   6,8126 }, {   7,8126 },
 {   8,8126 }, {   9,8126 }, {  10,8126 }, {  11,8126 }, {  12,8126 },
 {  13,8126 }, {  14,8126 }, {  15,8126 }, {  16,8126 }, {  17,8126 },
 {  18,8126 }, {  19,8126 }, {  20,8126 }, {  21,8126 }, {  22,8126 },

 {  23,8126 }, {  24,8126 }, {  25,8126 }, {  26,8126 }, {  27,8126 },
 {  28,8126 }, {  29,8126 }, {  30,8126 }, {  31,8126 }, {  32,8126 },
 {  33,8126 }, {  34,8126 }, {  35,8126 }, {  36,8126 }, {  37,8126 },
 {  38,8126 }, {  39,8384 }, {  40,8126 }, {  41,8126 }, {  42,8126 },
 {  43,8126 }, {  44,8126 }, {  45,8126 }, {  46,8126 }, {  47,8126 },
 {  48,8126 }, {  49,8126 }, {  50,8126 }, {  51,8126 }, {  52,8126 },
 {  53,8126 }, {  54,8126 }, {  55,8126 }, {  56,8126 }, {  57,8126 },
 {  58,8126 }, {  59,8126 }, {  60,8126 }, {  61,8126 }, {  62,8126 },
 {  63,8126 }, {  64,8126 }, {  65,8126 }, {  66,8126 }, {  67,8126 },
 {  68,8126 }, {  69,8126 }, {  70,8126 }, {  71,8126 }, {  72,8126 },

 {  73,8126 }, {  74,8126 }, {  75,8126 }, {  76,8126 }, {  77,8126 },
 {  78,8126 }, {  79,8126 }, {  80,8126 }, {  81,8126 }, {  82,8126 },
 {  83,8126 }, {  84,8126 }, {  85,8126 }, {  86,8126 }, {  87,8126 },
 {  88,8126 }, {  89,8126 }, {  90,8126 }, {  91,8126 }, {  92,8126 },
 {  93,8126 }, {  94,8126 }, {  95,8126 }, {  96,8126 }, {  97,8126 },
 {  98,8126 }, {  99,8126 }, { 100,8126 }, { 101,8126 }, { 102,8126 },
 { 103,8126 }, { 104,8126 }, { 105,8126 }, { 106,8126 }, { 107,8126 },
 { 108,8126 }, { 109,8126 }, { 110,8126 }, { 111,8126 }, { 112,8126 },
 { 113,8126 }, { 114,8126 }, { 115,8126 }, { 116,8126 }, { 117,8126 },
 { 118,8126 }, { 119,8126 }, { 120,8126 }, { 121,8126 }, { 122,8126 },

 { 123,8126 }, { 124,8126 }, { 125,8126 }, { 126,8126 }, { 127,8126 },
 { 128,8126 }, { 129,8126 }, { 130,8126 }, { 131,8126 }, { 132,8126 },
 { 133,8126 }, { 134,8126 }, { 135,8126 }, { 136,8126 }, { 137,8126 },
 { 138,8126 }, { 139,8126 }, { 140,8126 }, { 141,8126 }, { 142,8126 },
 { 143,8126 }, { 144,8126 }, { 145,8126 }, { 146,8126 }, { 147,8126 },
 { 148,8126 }, { 149,8126 }, { 150,8126 }, { 151,8126 }, { 152,8126 },
 { 153,8126 }, { 154,8126 }, { 155,8126 }, { 156,8126 }, { 157,8126 },
 { 158,8126 }, { 159,8126 }, { 160,8126 }, { 161,8126 }, { 162,8126 },
 { 163,8126 }, { 164,8126 }, { 165,8126 }, { 166,8126 }, { 167,8126 },
 { 168,8126 }, { 169,8126 }, { 170,8126 }, { 171,8126 }, { 172,8126 },

 { 173,8126 }, { 174,8126 }, { 175,8126 }, { 176,8126 }, { 177,8126 },
 { 178,8126 }, { 179,8126 }, { 180,8126 }, { 181,8126 }, { 182,8126 },
 { 183,8126 }, { 184,8126 }, { 185,8126 }, { 186,8126 }, { 187,8126 },
 { 188,8126 }, { 189,8126 }, { 190,8126 }, { 191,8126 }, { 192,8126 },
 { 193,8126 }, { 194,8126 }, { 195,8126 }, { 196,8126 }, { 197,8126 },
 { 198,8126 }, { 199,8126 }, { 200,8126 }, { 201,8126 }, { 202,8126 },
 { 203,8126 }, { 204,8126 }, { 205,8126 }, { 206,8126 }, { 207,8126 },
 { 208,8126 }, { 209,8126 }, { 210,8126 }, { 211,8126 }, { 212,8126 },
 { 213,8126 }, { 214,8126 }, { 215,8126 }, { 216,8126 }, { 217,8126 },
 { 218,8126 }, { 219,8126 }, { 220,8126 }, { 221,8126 }, { 222,8126 },

 { 223,8126 }, { 224,8126 }, { 225,8126 }, { 226,8126 }, { 227,8126 },
 { 228,8126 }, { 229,8126 }, { 230,8126 }, { 231,8126 }, { 232,8126 },
 { 233,8126 }, { 234,8126 }, { 235,8126 }, { 236,8126 }, { 237,8126 },
 { 238,8126 }, { 239,8126 }, { 240,8126 }, { 241,8126 }, { 242,8126 },
 { 243,8126 }, { 244,8126 }, { 245,8126 }, { 246,8126 }, { 247,8126 },
 { 248,8126 }, { 249,8126 }, { 250,8126 }, { 251,8126 }, { 252,8126 },
 { 253,8126 }, { 254,8126 }, { 255,8126 }, { 256,8126 }, {   0,   0 },
 {   0,35715 }, {   1,8173 }, {   2,8173 }, {   3,8173 }, {   4,8173 },
 {   5,8173 }, {   6,8173 }, {   7,8173 }, {   8,8173 }, {   9,8173 },
 {  10,8173 }, {  11,8173 }, {  12,8173 }, {  13,8173 }, {  14,8173 },

 {  15,8173 }, {  16,8173 }, {  17,8173 }, {  18,8173 }, {  19,8173 },
 {  20,8173 }, {  21,8173 }, {  22,8173 }, {  23,8173 }, {  24,8173 },
 {  25,8173 }, {  26,8173 }, {  27,8173 }, {  28,8173 }, {  29,8173 },
 {  30,8173 }, {  31,8173 }, {  32,8173 }, {  33,8431 }, {  34,8173 },
 {  35,8431 }, {  36,8173 }, {  37,8431 }, {  38,8431 }, {  39,8173 },
 {  40,8173 }, {  41,8173 }, {  42,5708 }, {  43,8431 }, {  44,8173 },
 {  45,8431 }, {  46,8173 }, {  47,5712 }, {  48,8173 }, {  49,8173 },
 {  50,8173 }, {  51,8173 }, {  52,8173 }, {  53,8173 }, {  54,8173 },
 {  55,8173 }, {  56,8173 }, {  57,8173 }, {  58,8173 }, {  59,8173 },
 {  60,8431 }, {  61,8431 }, {  62,8431 }, {  63,8431 }, {  64,8431 },

 {  65,8173 }, {  66,8173 }, {  67,8173 }, {  68,8173 }, {  69,8173 },
 {  70,8173 }, {  71,8173 }, {  72,8173 }, {  73,8173 }, {  74,8173 },
 {  75,8173 }, {  76,8173 }, {  77,8173 }, {  78,8173 }, {  79,8173 },
 {  80,8173 }, {  81,8173 }, {  82,8173 }, {  83,8173 }, {  84,8173 },
 {  85,8173 }, {  86,8173 }, {  87,8173 }, {  88,8173 }, {  89,8173 },
 {  90,8173 }, {  91,8173 }, {  92,8173 }, {  93,8173 }, {  94,8431 },
 {  95,8173 }, {  96,8431 }, {  97,8173 }, {  98,8173 }, {  99,8173 },
 { 100,8173 }, { 101,8173 }, { 102,8173 }, { 103,8173 }, { 104,8173 },
 { 105,8173 }, { 106,8173 }, { 107,8173 }, { 108,8173 }, { 109,8173 },
 { 110,8173 }, { 111,8173 }, { 112,8173 }, { 113,8173 }, { 114,8173 },

 { 115,8173 }, { 116,8173 }, { 117,8173 }, { 118,8173 }, { 119,8173 },
 { 120,8173 }, { 121,8173 }, { 122,8173 }, { 123,8173 }, { 124,8431 },
 { 125,8173 }, { 126,8431 }, { 127,8173 }, { 128,8173 }, { 129,8173 },
 { 130,8173 }, { 131,8173 }, { 132,8173 }, { 133,8173 }, { 134,8173 },
 { 135,8173 }, { 136,8173 }, { 137,8173 }, { 138,8173 }, { 139,8173 },
 { 140,8173 }, { 141,8173 }, { 142,8173 }, { 143,8173 }, { 144,8173 },
 { 145,8173 }, { 146,8173 }, { 147,8173 }, { 148,8173 }, { 149,8173 },
 { 150,8173 }, { 151,8173 }, { 152,8173 }, { 153,8173 }, { 154,8173 },
 { 155,8173 }, { 156,8173 }, { 157,8173 }, { 158,8173 }, { 159,8173 },
 { 160,8173 }, { 161,8173 }, { 162,8173 }, { 163,8173 }, { 164,8173 },

 { 165,8173 }, { 166,8173 }, { 167,8173 }, { 168,8173 }, { 169,8173 },
 { 170,8173 }, { 171,8173 }, { 172,8173 }, { 173,8173 }, { 174,8173 },
 { 175,8173 }, { 176,8173 }, { 177,8173 }, { 178,8173 }, { 179,8173 },
 { 180,8173 }, { 181,8173 }, { 182,8173 }, { 183,8173 }, { 184,8173 },
 { 185,8173 }, { 186,8173 }, { 187,8173 }, { 188,8173 }, { 189,8173 },
 { 190,8173 }, { 191,8173 }, { 192,8173 }, { 193,8173 }, { 194,8173 },
 { 195,8173 }, { 196,8173 }, { 197,8173 }, { 198,8173 }, { 199,8173 },
 { 200,8173 }, { 201,8173 }, { 202,8173 }, { 203,8173 }, { 204,8173 },
 { 205,8173 }, { 206,8173 }, { 207,8173 }, { 208,8173 }, { 209,8173 },
 { 210,8173 }, { 211,8173 }, { 212,8173 }, { 213,8173 }, { 214,8173 },

 { 215,8173 }, { 216,8173 }, { 217,8173 }, { 218,8173 }, { 219,8173 },
 { 220,8173 }, { 221,8173 }, { 222,8173 }, { 223,8173 }, { 224,8173 },
 { 225,8173 }, { 226,8173 }, { 227,8173 }, { 228,8173 }, { 229,8173 },
 { 230,8173 }, { 231,8173 }, { 232,8173 }, { 233,8173 }, { 234,8173 },
 { 235,8173 }, { 236,8173 }, { 237,8173 }, { 238,8173 }, { 239,8173 },
 { 240,8173 }, { 241,8173 }, { 242,8173 }, { 243,8173 }, { 244,8173 },
 { 245,8173 }, { 246,8173 }, { 247,8173 }, { 248,8173 }, { 249,8173 },
 { 250,8173 }, { 251,8173 }, { 252,8173 }, { 253,8173 }, { 254,8173 },
 { 255,8173 }, { 256,8173 }, {   0,   0 }, {   0,35457 }, {   1,7915 },
 {   2,7915 }, {   3,7915 }, {   4,7915 }, {   5,7915 }, {   6,7915 },

 {   7,7915 }, {   8,7915 }, {   9,7915 }, {  10,7915 }, {  11,7915 },
 {  12,7915 }, {  13,7915 }, {  14,7915 }, {  15,7915 }, {  16,7915 },
 {  17,7915 }, {  18,7915 }, {  19,7915 }, {  20,7915 }, {  21,7915 },
 {  22,7915 }, {  23,7915 }, {  24,7915 }, {  25,7915 }, {  26,7915 },
 {  27,7915 }, {  28,7915 }, {  29,7915 }, {  30,7915 }, {  31,7915 },
 {  32,7915 }, {  33,8173 }, {  34,7915 }, {  35,8173 }, {  36,7915 },
 {  37,8173 }, {  38,8173 }, {  39,7915 }, {  40,7915 }, {  41,7915 },
 {  42,5450 }, {  43,8173 }, {  44,7915 }, {  45,8173 }, {  46,7915 },
 {  47,5454 }, {  48,7915 }, {  49,7915 }, {  50,7915 }, {  51,7915 },
 {  52,7915 }, {  53,7915 }, {  54,7915 }, {  55,7915 }, {  56,7915 },

 {  57,7915 }, {  58,7915 }, {  59,7915 }, {  60,8173 }, {  61,8173 },
 {  62,8173 }, {  63,8173 }, {  64,8173 }, {  65,7915 }, {  66,7915 },
 {  67,7915 }, {  68,7915 }, {  69,7915 }, {  70,7915 }, {  71,7915 },
 {  72,7915 }, {  73,7915 }, {  74,7915 }, {  75,7915 }, {  76,7915 },
 {  77,7915 }, {  78,7915 }, {  79,7915 }, {  80,7915 }, {  81,7915 },
 {  82,7915 }, {  83,7915 }, {  84,7915 }, {  85,7915 }, {  86,7915 },
 {  87,7915 }, {  88,7915 }, {  89,7915 }, {  90,7915 }, {  91,7915 },
 {  92,7915 }, {  93,7915 }, {  94,8173 }, {  95,7915 }, {  96,8173 },
 {  97,7915 }, {  98,7915 }, {  99,7915 }, { 100,7915 }, { 101,7915 },
 { 102,7915 }, { 103,7915 }, { 104,7915 }, { 105,7915 }, { 106,7915 },

 { 107,7915 }, { 108,7915 }, { 109,7915 }, { 110,7915 }, { 111,7915 },
 { 112,7915 }, { 113,7915 }, { 114,7915 }, { 115,7915 }, { 116,7915 },
 { 117,7915 }, { 118,7915 }, { 119,7915 }, { 120,7915 }, { 121,7915 },
 { 122,7915 }, { 123,7915 }, { 124,8173 }, { 125,7915 }, { 126,8173 },
 { 127,7915 }, { 128,7915 }, { 129,7915 }, { 130,7915 }, { 131,7915 },
 { 132,7915 }, { 133,7915 }, { 134,7915 }, { 135,7915 }, { 136,7915 },
 { 137,7915 }, { 138,7915 }, { 139,7915 }, { 140,7915 }, { 141,7915 },
 { 142,7915 }, { 143,7915 }, { 144,7915 }, { 145,7915 }, { 146,7915 },
 { 147,7915 }, { 148,7915 }, { 149,7915 }, { 150,7915 }, { 151,7915 },
 { 152,7915 }, { 153,7915 }, { 154,7915 }, { 155,7915 }, { 156,7915 },

 { 157,7915 }, { 158,7915 }, { 159,7915 }, { 160,7915 }, { 161,7915 },
 { 162,7915 }, { 163,7915 }, { 164,7915 }, { 165,7915 }, { 166,7915 },
 { 167,7915 }, { 168,7915 }, { 169,7915 }, { 170,7915 }, { 171,7915 },
 { 172,7915 }, { 173,7915 }, { 174,7915 }, { 175,7915 }, { 176,7915 },
 { 177,7915 }, { 178,7915 }, { 179,7915 }, { 180,7915 }, { 181,7915 },
 { 182,7915 }, { 183,7915 }, { 184,7915 }, { 185,7915 }, { 186,7915 },
 { 187,7915 }, { 188,7915 }, { 189,7915 }, { 190,7915 }, { 191,7915 },
 { 192,7915 }, { 193,7915 }, { 194,7915 }, { 195,7915 }, { 196,7915 },
 { 197,7915 }, { 198,7915 }, { 199,7915 }, { 200,7915 }, { 201,7915 },
 { 202,7915 }, { 203,7915 }, { 204,7915 }, { 205,7915 }, { 206,7915 },

 { 207,7915 }, { 208,7915 }, { 209,7915 }, { 210,7915 }, { 211,7915 },
 { 212,7915 }, { 213,7915 }, { 214,7915 }, { 215,7915 }, { 216,7915 },
 { 217,7915 }, { 218,7915 }, { 219,7915 }, { 220,7915 }, { 221,7915 },
 { 222,7915 }, { 223,7915 }, { 224,7915 }, { 225,7915 }, { 226,7915 },
 { 227,7915 }, { 228,7915 }, { 229,7915 }, { 230,7915 }, { 231,7915 },
 { 232,7915 }, { 233,7915 }, { 234,7915 }, { 235,7915 }, { 236,7915 },
 { 237,7915 }, { 238,7915 }, { 239,7915 }, { 240,7915 }, { 241,7915 },
 { 242,7915 }, { 243,7915 }, { 244,7915 }, { 245,7915 }, { 246,7915 },
 { 247,7915 }, { 248,7915 }, { 249,7915 }, { 250,7915 }, { 251,7915 },
 { 252,7915 }, { 253,7915 }, { 254,7915 }, { 255,7915 }, { 256,7915 },

 {   0,   0 }, {   0,35199 }, {   1,8173 }, {   2,8173 }, {   3,8173 },
 {   4,8173 }, {   5,8173 }, {   6,8173 }, {   7,8173 }, {   8,8173 },
 {   9,8173 }, {  10,8173 }, {  11,8173 }, {  12,8173 }, {  13,8173 },
 {  14,8173 }, {  15,8173 }, {  16,8173 }, {  17,8173 }, {  18,8173 },
 {  19,8173 }, {  20,8173 }, {  21,8173 }, {  22,8173 }, {  23,8173 },
 {  24,8173 }, {  25,8173 }, {  26,8173 }, {  27,8173 }, {  28,8173 },
 {  29,8173 }, {  30,8173 }, {  31,8173 }, {  32,8173 }, {  33,8173 },
 {  34,5201 }, {  35,8173 }, {  36,8173 }, {  37,8173 }, {  38,8173 },
 {  39,8173 }, {  40,8173 }, {  41,8173 }, {  42,8173 }, {  43,8173 },
 {  44,8173 }, {  45,8173 }, {  46,8173 }, {  47,8173 }, {  48,8173 },

 {  49,8173 }, {  50,8173 }, {  51,8173 }, {  52,8173 }, {  53,8173 },
 {  54,8173 }, {  55,8173 }, {  56,8173 }, {  57,8173 }, {  58,8173 },
 {  59,8173 }, {  60,8173 }, {  61,8173 }, {  62,8173 }, {  63,8173 },
 {  64,8173 }, {  65,8173 }, {  66,8173 }, {  67,8173 }, {  68,8173 },
 {  69,8173 }, {  70,8173 }, {  71,8173 }, {  72,8173 }, {  73,8173 },
 {  74,8173 }, {  75,8173 }, {  76,8173 }, {  77,8173 }, {  78,8173 },
 {  79,8173 }, {  80,8173 }, {  81,8173 }, {  82,8173 }, {  83,8173 },
 {  84,8173 }, {  85,8173 }, {  86,8173 }, {  87,8173 }, {  88,8173 },
 {  89,8173 }, {  90,8173 }, {  91,8173 }, {  92,8173 }, {  93,8173 },
 {  94,8173 }, {  95,8173 }, {  96,8173 }, {  97,8173 }, {  98,8173 },

 {  99,8173 }, { 100,8173 }, { 101,8173 }, { 102,8173 }, { 103,8173 },
 { 104,8173 }, { 105,8173 }, { 106,8173 }, { 107,8173 }, { 108,8173 },
 { 109,8173 }, { 110,8173 }, { 111,8173 }, { 112,8173 }, { 113,8173 },
 { 114,8173 }, { 115,8173 }, { 116,8173 }, { 117,8173 }, { 118,8173 },
 { 119,8173 }, { 120,8173 }, { 121,8173 }, { 122,8173 }, { 123,8173 },
 { 124,8173 }, { 125,8173 }, { 126,8173 }, { 127,8173 }, { 128,8173 },
 { 129,8173 }, { 130,8173 }, { 131,8173 }, { 132,8173 }, { 133,8173 },
 { 134,8173 }, { 135,8173 }, { 136,8173 }, { 137,8173 }, { 138,8173 },
 { 139,8173 }, { 140,8173 }, { 141,8173 }, { 142,8173 }, { 143,8173 },
 { 144,8173 }, { 145,8173 }, { 146,8173 }, { 147,8173 }, { 148,8173 },

 { 149,8173 }, { 150,8173 }, { 151,8173 }, { 152,8173 }, { 153,8173 },
 { 154,8173 }, { 155,8173 }, { 156,8173 }, { 157,8173 }, { 158,8173 },
 { 159,8173 }, { 160,8173 }, { 161,8173 }, { 162,8173 }, { 163,8173 },
 { 164,8173 }, { 165,8173 }, { 166,8173 }, { 167,8173 }, { 168,8173 },
 { 169,8173 }, { 170,8173 }, { 171,8173 }, { 172,8173 }, { 173,8173 },
 { 174,8173 }, { 175,8173 }, { 176,8173 }, { 177,8173 }, { 178,8173 },
 { 179,8173 }, { 180,8173 }, { 181,8173 }, { 182,8173 }, { 183,8173 },
 { 184,8173 }, { 185,8173 }, { 186,8173 }, { 187,8173 }, { 188,8173 },
 { 189,8173 }, { 190,8173 }, { 191,8173 }, { 192,8173 }, { 193,8173 },
 { 194,8173 }, { 195,8173 }, { 196,8173 }, { 197,8173 }, { 198,8173 },

 { 199,8173 }, { 200,8173 }, { 201,8173 }, { 202,8173 }, { 203,8173 },
 { 204,8173 }, { 205,8173 }, { 206,8173 }, { 207,8173 }, { 208,8173 },
 { 209,8173 }, { 210,8173 }, { 211,8173 }, { 212,8173 }, { 213,8173 },
 { 214,8173 }, { 215,8173 }, { 216,8173 }, { 217,8173 }, { 218,8173 },
 { 219,8173 }, { 220,8173 }, { 221,8173 }, { 222,8173 }, { 223,8173 },
 { 224,8173 }, { 225,8173 }, { 226,8173 }, { 227,8173 }, { 228,8173 },
 { 229,8173 }, { 230,8173 }, { 231,8173 }, { 232,8173 }, { 233,8173 },
 { 234,8173 }, { 235,8173 }, { 236,8173 }, { 237,8173 }, { 238,8173 },
 { 239,8173 }, { 240,8173 }, { 241,8173 }, { 242,8173 }, { 243,8173 },
 { 244,8173 }, { 245,8173 }, { 246,8173 }, { 247,8173 }, { 248,8173 },

 { 249,8173 }, { 250,8173 }, { 251,8173 }, { 252,8173 }, { 253,8173 },
 { 254,8173 }, { 255,8173 }, { 256,8173 }, {   0,   0 }, {   0,34941 },
 {   1,7915 }, {   2,7915 }, {   3,7915 }, {   4,7915 }, {   5,7915 },
 {   6,7915 }, {   7,7915 }, {   8,7915 }, {   9,7915 }, {  10,7915 },
 {  11,7915 }, {  12,7915 }, {  13,7915 }, {  14,7915 }, {  15,7915 },
 {  16,7915 }, {  17,7915 }, {  18,7915 }, {  19,7915 }, {  20,7915 },
 {  21,7915 }, {  22,7915 }, {  23,7915 }, {  24,7915 }, {  25,7915 },
 {  26,7915 }, {  27,7915 }, {  28,7915 }, {  29,7915 }, {  30,7915 },
 {  31,7915 }, {  32,7915 }, {  33,7915 }, {  34,4943 }, {  35,7915 },
 {  36,7915 }, {  37,7915 }, {  38,7915 }, {  39,7915 }, {  40,7915 },

 {  41,7915 }, {  42,7915 }, {  43,7915 }, {  44,7915 }, {  45,7915 },
 {  46,7915 }, {  47,7915 }, {  48,7915 }, {  49,7915 }, {  50,7915 },
 {  51,7915 }, {  52,7915 }, {  53,7915 }, {  54,7915 }, {  55,7915 },
 {  56,7915 }, {  57,7915 }, {  58,7915 }, {  59,7915 }, {  60,7915 },
 {  61,7915 }, {  62,7915 }, {  63,7915 }, {  64,7915 }, {  65,7915 },
 {  66,7915 }, {  67,7915 }, {  68,7915 }, {  69,7915 }, {  70,7915 },
 {  71,7915 }, {  72,7915 }, {  73,7915 }, {  74,7915 }, {  75,7915 },
 {  76,7915 }, {  77,7915 }, {  78,7915 }, {  79,7915 }, {  80,7915 },
 {  81,7915 }, {  82,7915 }, {  83,7915 }, {  84,7915 }, {  85,7915 },
 {  86,7915 }, {  87,7915 }, {  88,7915 }, {  89,7915 }, {  90,7915 },

 {  91,7915 }, {  92,7915 }, {  93,7915 }, {  94,7915 }, {  95,7915 },
 {  96,7915 }, {  97,7915 }, {  98,7915 }, {  99,7915 }, { 100,7915 },
 { 101,7915 }, { 102,7915 }, { 103,7915 }, { 104,7915 }, { 105,7915 },
 { 106,7915 }, { 107,7915 }, { 108,7915 }, { 109,7915 }, { 110,7915 },
 { 111,7915 }, { 112,7915 }, { 113,7915 }, { 114,7915 }, { 115,7915 },
 { 116,7915 }, { 117,7915 }, { 118,7915 }, { 119,7915 }, { 120,7915 },
 { 121,7915 }, { 122,7915 }, { 123,7915 }, { 124,7915 }, { 125,7915 },
 { 126,7915 }, { 127,7915 }, { 128,7915 }, { 129,7915 }, { 130,7915 },
 { 131,7915 }, { 132,7915 }, { 133,7915 }, { 134,7915 }, { 135,7915 },
 { 136,7915 }, { 137,7915 }, { 138,7915 }, { 139,7915 }, { 140,7915 },

 { 141,7915 }, { 142,7915 }, { 143,7915 }, { 144,7915 }, { 145,7915 },
 { 146,7915 }, { 147,7915 }, { 148,7915 }, { 149,7915 }, { 150,7915 },
 { 151,7915 }, { 152,7915 }, { 153,7915 }, { 154,7915 }, { 155,7915 },
 { 156,7915 }, { 157,7915 }, { 158,7915 }, { 159,7915 }, { 160,7915 },
 { 161,7915 }, { 162,7915 }, { 163,7915 }, { 164,7915 }, { 165,7915 },
 { 166,7915 }, { 167,7915 }, { 168,7915 }, { 169,7915 }, { 170,7915 },
 { 171,7915 }, { 172,7915 }, { 173,7915 }, { 174,7915 }, { 175,7915 },
 { 176,7915 }, { 177,7915 }, { 178,7915 }, { 179,7915 }, { 180,7915 },
 { 181,7915 }, { 182,7915 }, { 183,7915 }, { 184,7915 }, { 185,7915 },
 { 186,7915 }, { 187,7915 }, { 188,7915 }, { 189,7915 }, { 190,7915 },

 { 191,7915 }, { 192,7915 }, { 193,7915 }, { 194,7915 }, { 195,7915 },
 { 196,7915 }, { 197,7915 }, { 198,7915 }, { 199,7915 }, { 200,7915 },
 { 201,7915 }, { 202,7915 }, { 203,7915 }, { 204,7915 }, { 205,7915 },
 { 206,7915 }, { 207,7915 }, { 208,7915 }, { 209,7915 }, { 210,7915 },
 { 211,7915 }, { 212,7915 }, { 213,7915 }, { 214,7915 }, { 215,7915 },
 { 216,7915 }, { 217,7915 }, { 218,7915 }, { 219,7915 }, { 220,7915 },
 { 221,7915 }, { 222,7915 }, { 223,7915 }, { 224,7915 }, { 225,7915 },
 { 226,7915 }, { 227,7915 }, { 228,7915 }, { 229,7915 }, { 230,7915 },
 { 231,7915 }, { 232,7915 }, { 233,7915 }, { 234,7915 }, { 235,7915 },
 { 236,7915 }, { 237,7915 }, { 238,7915 }, { 239,7915 }, { 240,7915 },

 { 241,7915 }, { 242,7915 }, { 243,7915 }, { 244,7915 }, { 245,7915 },
 { 246,7915 }, { 247,7915 }, { 248,7915 }, { 249,7915 }, { 250,7915 },
 { 251,7915 }, { 252,7915 }, { 253,7915 }, { 254,7915 }, { 255,7915 },
 { 256,7915 }, {   0,  11 }, {   0,34683 }, {   1,7915 }, {   2,7915 },
 {   3,7915 }, {   4,7915 }, {   5,7915 }, {   6,7915 }, {   7,7915 },
 {   8,7915 }, {   9,7915 }, {  10,7915 }, {  11,7915 }, {  12,7915 },
 {  13,7915 }, {  14,7915 }, {  15,7915 }, {  16,7915 }, {  17,7915 },
 {  18,7915 }, {  19,7915 }, {  20,7915 }, {  21,7915 }, {  22,7915 },
 {  23,7915 }, {  24,7915 }, {  25,7915 }, {  26,7915 }, {  27,7915 },
 {  28,7915 }, {  29,7915 }, {  30,7915 }, {  31,7915 }, {  32,7915 },

 {  33,7915 }, {  34,7915 }, {  35,7915 }, {  36,7915 }, {  37,7915 },
 {  38,7915 }, {  39,8173 }, {  40,7915 }, {  41,7915 }, {  42,7915 },
 {  43,7915 }, {  44,7915 }, {  45,7915 }, {  46,7915 }, {  47,7915 },
 {  48,7915 }, {  49,7915 }, {  50,7915 }, {  51,7915 }, {  52,7915 },
 {  53,7915 }, {  54,7915 }, {  55,7915 }, {  56,7915 }, {  57,7915 },
 {  58,7915 }, {  59,7915 }, {  60,7915 }, {  61,7915 }, {  62,7915 },
 {  63,7915 }, {  64,7915 }, {  65,7915 }, {  66,7915 }, {  67,7915 },
 {  68,7915 }, {  69,7915 }, {  70,7915 }, {  71,7915 }, {  72,7915 },
 {  73,7915 }, {  74,7915 }, {  75,7915 }, {  76,7915 }, {  77,7915 },
 {  78,7915 }, {  79,7915 }, {  80,7915 }, {  81,7915 }, {  82,7915 },

 {  83,7915 }, {  84,7915 }, {  85,7915 }, {  86,7915 }, {  87,7915 },
 {  88,7915 }, {  89,7915 }, {  90,7915 }, {  91,7915 }, {  92,7915 },
 {  93,7915 }, {  94,7915 }, {  95,7915 }, {  96,7915 }, {  97,7915 },
 {  98,7915 }, {  99,7915 }, { 100,7915 }, { 101,7915 }, { 102,7915 },
 { 103,7915 }, { 104,7915 }, { 105,7915 }, { 106,7915 }, { 107,7915 },
 { 108,7915 }, { 109,7915 }, { 110,7915 }, { 111,7915 }, { 112,7915 },
 { 113,7915 }, { 114,7915 }, { 115,7915 }, { 116,7915 }, { 117,7915 },
 { 118,7915 }, { 119,7915 }, { 120,7915 }, { 121,7915 }, { 122,7915 },
 { 123,7915 }, { 124,7915 }, { 125,7915 }, { 126,7915 }, { 127,7915 },
 { 128,7915 }, { 129,7915 }, { 130,7915 }, { 131,7915 }, { 132,7915 },

 { 133,7915 }, { 134,7915 }, { 135,7915 }, { 136,7915 }, { 137,7915 },
 { 138,7915 }, { 139,7915 }, { 140,7915 }, { 141,7915 }, { 142,7915 },
 { 143,7915 }, { 144,7915 }, { 145,7915 }, { 146,7915 }, { 147,7915 },
 { 148,7915 }, { 149,7915 }, { 150,7915 }, { 151,7915 }, { 152,7915 },
 { 153,7915 }, { 154,7915 }, { 155,7915 }, { 156,7915 }, { 157,7915 },
 { 158,7915 }, { 159,7915 }, { 160,7915 }, { 161,7915 }, { 162,7915 },
 { 163,7915 }, { 164,7915 }, { 165,7915 }, { 166,7915 }, { 167,7915 },
 { 168,7915 }, { 169,7915 }, { 170,7915 }, { 171,7915 }, { 172,7915 },
 { 173,7915 }, { 174,7915 }, { 175,7915 }, { 176,7915 }, { 177,7915 },
 { 178,7915 }, { 179,7915 }, { 180,7915 }, { 181,7915 }, { 182,7915 },

 { 183,7915 }, { 184,7915 }, { 185,7915 }, { 186,7915 }, { 187,7915 },
 { 188,7915 }, { 189,7915 }, { 190,7915 }, { 191,7915 }, { 192,7915 },
 { 193,7915 }, { 194,7915 }, { 195,7915 }, { 196,7915 }, { 197,7915 },
 { 198,7915 }, { 199,7915 }, { 200,7915 }, { 201,7915 }, { 202,7915 },
 { 203,7915 }, { 204,7915 }, { 205,7915 }, { 206,7915 }, { 207,7915 },
 { 208,7915 }, { 209,7915 }, { 210,7915 }, { 211,7915 }, { 212,7915 },
 { 213,7915 }, { 214,7915 }, { 215,7915 }, { 216,7915 }, { 217,7915 },
 { 218,7915 }, { 219,7915 }, { 220,7915 }, { 221,7915 }, { 222,7915 },
 { 223,7915 }, { 224,7915 }, { 225,7915 }, { 226,7915 }, { 227,7915 },
 { 228,7915 }, { 229,7915 }, { 230,7915 }, { 231,7915 }, { 232,7915 },

 { 233,7915 }, { 234,7915 }, { 235,7915 }, { 236,7915 }, { 237,7915 },
 { 238,7915 }, { 239,7915 }, { 240,7915 }, { 241,7915 }, { 242,7915 },
 { 243,7915 }, { 244,7915 }, { 245,7915 }, { 246,7915 }, { 247,7915 },
 { 248,7915 }, { 249,7915 }, { 250,7915 }, { 251,7915 }, { 252,7915 },
 { 253,7915 }, { 254,7915 }, { 255,7915 }, { 256,7915 }, {   0,  11 },
 {   0,34425 }, {   1,7657 }, {   2,7657 }, {   3,7657 }, {   4,7657 },
 {   5,7657 }, {   6,7657 }, {   7,7657 }, {   8,7657 }, {   9,7657 },
 {  10,7657 }, {  11,7657 }, {  12,7657 }, {  13,7657 }, {  14,7657 },
 {  15,7657 }, {  16,7657 }, {  17,7657 }, {  18,7657 }, {  19,7657 },
 {  20,7657 }, {  21,7657 }, {  22,7657 }, {  23,7657 }, {  24,7657 },

 {  25,7657 }, {  26,7657 }, {  27,7657 }, {  28,7657 }, {  29,7657 },
 {  30,7657 }, {  31,7657 }, {  32,7657 }, {  33,7657 }, {  34,7657 },
 {  35,7657 }, {  36,7657 }, {  37,7657 }, {  38,7657 }, {  39,7915 },
 {  40,7657 }, {  41,7657 }, {  42,7657 }, {  43,7657 }, {  44,7657 },
 {  45,7657 }, {  46,7657 }, {  47,7657 }, {  48,7657 }, {  49,7657 },
 {  50,7657 }, {  51,7657 }, {  52,7657 }, {  53,7657 }, {  54,7657 },
 {  55,7657 }, {  56,7657 }, {  57,7657 }, {  58,7657 }, {  59,7657 },
 {  60,7657 }, {  61,7657 }, {  62,7657 }, {  63,7657 }, {  64,7657 },
 {  65,7657 }, {  66,7657 }, {  67,7657 }, {  68,7657 }, {  69,7657 },
 {  70,7657 }, {  71,7657 }, {  72,7657 }, {  73,7657 }, {  74,7657 },

 {  75,7657 }, {  76,7657 }, {  77,7657 }, {  78,7657 }, {  79,7657 },
 {  80,7657 }, {  81,7657 }, {  82,7657 }, {  83,7657 }, {  84,7657 },
 {  85,7657 }, {  86,7657 }, {  87,7657 }, {  88,7657 }, {  89,7657 },
 {  90,7657 }, {  91,7657 }, {  92,7657 }, {  93,7657 }, {  94,7657 },
 {  95,7657 }, {  96,7657 }, {  97,7657 }, {  98,7657 }, {  99,7657 },
 { 100,7657 }, { 101,7657 }, { 102,7657 }, { 103,7657 }, { 104,7657 },
 { 105,7657 }, { 106,7657 }, { 107,7657 }, { 108,7657 }, { 109,7657 },
 { 110,7657 }, { 111,7657 }, { 112,7657 }, { 113,7657 }, { 114,7657 },
 { 115,7657 }, { 116,7657 }, { 117,7657 }, { 118,7657 }, { 119,7657 },
 { 120,7657 }, { 121,7657 }, { 122,7657 }, { 123,7657 }, { 124,7657 },

 { 125,7657 }, { 126,7657 }, { 127,7657 }, { 128,7657 }, { 129,7657 },
 { 130,7657 }, { 131,7657 }, { 132,7657 }, { 133,7657 }, { 134,7657 },
 { 135,7657 }, { 136,7657 }, { 137,7657 }, { 138,7657 }, { 139,7657 },
 { 140,7657 }, { 141,7657 }, { 142,7657 }, { 143,7657 }, { 144,7657 },
 { 145,7657 }, { 146,7657 }, { 147,7657 }, { 148,7657 }, { 149,7657 },
 { 150,7657 }, { 151,7657 }, { 152,7657 }, { 153,7657 }, { 154,7657 },
 { 155,7657 }, { 156,7657 }, { 157,7657 }, { 158,7657 }, { 159,7657 },
 { 160,7657 }, { 161,7657 }, { 162,7657 }, { 163,7657 }, { 164,7657 },
 { 165,7657 }, { 166,7657 }, { 167,7657 }, { 168,7657 }, { 169,7657 },
 { 170,7657 }, { 171,7657 }, { 172,7657 }, { 173,7657 }, { 174,7657 },

 { 175,7657 }, { 176,7657 }, { 177,7657 }, { 178,7657 }, { 179,7657 },
 { 180,7657 }, { 181,7657 }, { 182,7657 }, { 183,7657 }, { 184,7657 },
 { 185,7657 }, { 186,7657 }, { 187,7657 }, { 188,7657 }, { 189,7657 },
 { 190,7657 }, { 191,7657 }, { 192,7657 }, { 193,7657 }, { 194,7657 },
 { 195,7657 }, { 196,7657 }, { 197,7657 }, { 198,7657 }, { 199,7657 },
 { 200,7657 }, { 201,7657 }, { 202,7657 }, { 203,7657 }, { 204,7657 },
 { 205,7657 }, { 206,7657 }, { 207,7657 }, { 208,7657 }, { 209,7657 },
 { 210,7657 }, { 211,7657 }, { 212,7657 }, { 213,7657 }, { 214,7657 },
 { 215,7657 }, { 216,7657 }, { 217,7657 }, { 218,7657 }, { 219,7657 },
 { 220,7657 }, { 221,7657 }, { 222,7657 }, { 223,7657 }, { 224,7657 },

 { 225,7657 }, { 226,7657 }, { 227,7657 }, { 228,7657 }, { 229,7657 },
 { 230,7657 }, { 231,7657 }, { 232,7657 }, { 233,7657 }, { 234,7657 },
 { 235,7657 }, { 236,7657 }, { 237,7657 }, { 238,7657 }, { 239,7657 },
 { 240,7657 }, { 241,7657 }, { 242,7657 }, { 243,7657 }, { 244,7657 },
 { 245,7657 }, { 246,7657 }, { 247,7657 }, { 248,7657 }, { 249,7657 },
 { 250,7657 }, { 251,7657 }, { 252,7657 }, { 253,7657 }, { 254,7657 },
 { 255,7657 }, { 256,7657 }, {   0,   0 }, {   0,34167 }, {   1,7704 },
 {   2,7704 }, {   3,7704 }, {   4,7704 }, {   5,7704 }, {   6,7704 },
 {   7,7704 }, {   8,7704 }, {   9,7704 }, {  10,7962 }, {  11,7704 },
 {  12,7704 }, {  13,7704 }, {  14,7704 }, {  15,7704 }, {  16,7704 },

 {  17,7704 }, {  18,7704 }, {  19,7704 }, {  20,7704 }, {  21,7704 },
 {  22,7704 }, {  23,7704 }, {  24,7704 }, {  25,7704 }, {  26,7704 },
 {  27,7704 }, {  28,7704 }, {  29,7704 }, {  30,7704 }, {  31,7704 },
 {  32,7704 }, {  33,7704 }, {  34,7704 }, {  35,7704 }, {  36,7704 },
 {  37,7704 }, {  38,7704 }, {  39,8220 }, {  40,7704 }, {  41,7704 },
 {  42,7704 }, {  43,7704 }, {  44,7704 }, {  45,7704 }, {  46,7704 },
 {  47,7704 }, {  48,7704 }, {  49,7704 }, {  50,7704 }, {  51,7704 },
 {  52,7704 }, {  53,7704 }, {  54,7704 }, {  55,7704 }, {  56,7704 },
 {  57,7704 }, {  58,7704 }, {  59,7704 }, {  60,7704 }, {  61,7704 },
 {  62,7704 }, {  63,7704 }, {  64,7704 }, {  65,7704 }, {  66,7704 },

 {  67,7704 }, {  68,7704 }, {  69,7704 }, {  70,7704 }, {  71,7704 },
 {  72,7704 }, {  73,7704 }, {  74,7704 }, {  75,7704 }, {  76,7704 },
 {  77,7704 }, {  78,7704 }, {  79,7704 }, {  80,7704 }, {  81,7704 },
 {  82,7704 }, {  83,7704 }, {  84,7704 }, {  85,7704 }, {  86,7704 },
 {  87,7704 }, {  88,7704 }, {  89,7704 }, {  90,7704 }, {  91,7704 },
 {  92,8267 }, {  93,7704 }, {  94,7704 }, {  95,7704 }, {  96,7704 },
 {  97,7704 }, {  98,7704 }, {  99,7704 }, { 100,7704 }, { 101,7704 },
 { 102,7704 }, { 103,7704 }, { 104,7704 }, { 105,7704 }, { 106,7704 },
 { 107,7704 }, { 108,7704 }, { 109,7704 }, { 110,7704 }, { 111,7704 },
 { 112,7704 }, { 113,7704 }, { 114,7704 }, { 115,7704 }, { 116,7704 },

 { 117,7704 }, { 118,7704 }, { 119,7704 }, { 120,7704 }, { 121,7704 },
 { 122,7704 }, { 123,7704 }, { 124,7704 }, { 125,7704 }, { 126,7704 },
 { 127,7704 }, { 128,7704 }, { 129,7704 }, { 130,7704 }, { 131,7704 },
 { 132,7704 }, { 133,7704 }, { 134,7704 }, { 135,7704 }, { 136,7704 },
 { 137,7704 }, { 138,7704 }, { 139,7704 }, { 140,7704 }, { 141,7704 },
 { 142,7704 }, { 143,7704 }, { 144,7704 }, { 145,7704 }, { 146,7704 },
 { 147,7704 }, { 148,7704 }, { 149,7704 }, { 150,7704 }, { 151,7704 },
 { 152,7704 }, { 153,7704 }, { 154,7704 }, { 155,7704 }, { 156,7704 },
 { 157,7704 }, { 158,7704 }, { 159,7704 }, { 160,7704 }, { 161,7704 },
 { 162,7704 }, { 163,7704 }, { 164,7704 }, { 165,7704 }, { 166,7704 },

 { 167,7704 }, { 168,7704 }, { 169,7704 }, { 170,7704 }, { 171,7704 },
 { 172,7704 }, { 173,7704 }, { 174,7704 }, { 175,7704 }, { 176,7704 },
 { 177,7704 }, { 178,7704 }, { 179,7704 }, { 180,7704 }, { 181,7704 },
 { 182,7704 }, { 183,7704 }, { 184,7704 }, { 185,7704 }, { 186,7704 },
 { 187,7704 }, { 188,7704 }, { 189,7704 }, { 190,7704 }, { 191,7704 },
 { 192,7704 }, { 193,7704 }, { 194,7704 }, { 195,7704 }, { 196,7704 },
 { 197,7704 }, { 198,7704 }, { 199,7704 }, { 200,7704 }, { 201,7704 },
 { 202,7704 }, { 203,7704 }, { 204,7704 }, { 205,7704 }, { 206,7704 },
 { 207,7704 }, { 208,7704 }, { 209,7704 }, { 210,7704 }, { 211,7704 },
 { 212,7704 }, { 213,7704 }, { 214,7704 }, { 215,7704 }, { 216,7704 },

 { 217,7704 }, { 218,7704 }, { 219,7704 }, { 220,7704 }, { 221,7704 },
 { 222,7704 }, { 223,7704 }, { 224,7704 }, { 225,7704 }, { 226,7704 },
 { 227,7704 }, { 228,7704 }, { 229,7704 }, { 230,7704 }, { 231,7704 },
 { 232,7704 }, { 233,7704 }, { 234,7704 }, { 235,7704 }, { 236,7704 },
 { 237,7704 }, { 238,7704 }, { 239,7704 }, { 240,7704 }, { 241,7704 },
 { 242,7704 }, { 243,7704 }, { 244,7704 }, { 245,7704 }, { 246,7704 },
 { 247,7704 }, { 248,7704 }, { 249,7704 }, { 250,7704 }, { 251,7704 },
 { 252,7704 }, { 253,7704 }, { 254,7704 }, { 255,7704 }, { 256,7704 },
 {   0,   0 }, {   0,33909 }, {   1,7446 }, {   2,7446 }, {   3,7446 },
 {   4,7446 }, {   5,7446 }, {   6,7446 }, {   7,7446 }, {   8,7446 },

 {   9,7446 }, {  10,7704 }, {  11,7446 }, {  12,7446 }, {  13,7446 },
 {  14,7446 }, {  15,7446 }, {  16,7446 }, {  17,7446 }, {  18,7446 },
 {  19,7446 }, {  20,7446 }, {  21,7446 }, {  22,7446 }, {  23,7446 },
 {  24,7446 }, {  25,7446 }, {  26,7446 }, {  27,7446 }, {  28,7446 },
 {  29,7446 }, {  30,7446 }, {  31,7446 }, {  32,7446 }, {  33,7446 },
 {  34,7446 }, {  35,7446 }, {  36,7446 }, {  37,7446 }, {  38,7446 },
 {  39,7962 }, {  40,7446 }, {  41,7446 }, {  42,7446 }, {  43,7446 },
 {  44,7446 }, {  45,7446 }, {  46,7446 }, {  47,7446 }, {  48,7446 },
 {  49,7446 }, {  50,7446 }, {  51,7446 }, {  52,7446 }, {  53,7446 },
 {  54,7446 }, {  55,7446 }, {  56,7446 }, {  57,7446 }, {  58,7446 },

 {  59,7446 }, {  60,7446 }, {  61,7446 }, {  62,7446 }, {  63,7446 },
 {  64,7446 }, {  65,7446 }, {  66,7446 }, {  67,7446 }, {  68,7446 },
 {  69,7446 }, {  70,7446 }, {  71,7446 }, {  72,7446 }, {  73,7446 },
 {  74,7446 }, {  75,7446 }, {  76,7446 }, {  77,7446 }, {  78,7446 },
 {  79,7446 }, {  80,7446 }, {  81,7446 }, {  82,7446 }, {  83,7446 },
 {  84,7446 }, {  85,7446 }, {  86,7446 }, {  87,7446 }, {  88,7446 },
 {  89,7446 }, {  90,7446 }, {  91,7446 }, {  92,8009 }, {  93,7446 },
 {  94,7446 }, {  95,7446 }, {  96,7446 }, {  97,7446 }, {  98,7446 },
 {  99,7446 }, { 100,7446 }, { 101,7446 }, { 102,7446 }, { 103,7446 },
 { 104,7446 }, { 105,7446 }, { 106,7446 }, { 107,7446 }, { 108,7446 },

 { 109,7446 }, { 110,7446 }, { 111,7446 }, { 112,7446 }, { 113,7446 },
 { 114,7446 }, { 115,7446 }, { 116,7446 }, { 117,7446 }, { 118,7446 },
 { 119,7446 }, { 120,7446 }, { 121,7446 }, { 122,7446 }, { 123,7446 },
 { 124,7446 }, { 125,7446 }, { 126,7446 }, { 127,7446 }, { 128,7446 },
 { 129,7446 }, { 130,7446 }, { 131,7446 }, { 132,7446 }, { 133,7446 },
 { 134,7446 }, { 135,7446 }, { 136,7446 }, { 137,7446 }, { 138,7446 },
 { 139,7446 }, { 140,7446 }, { 141,7446 }, { 142,7446 }, { 143,7446 },
 { 144,7446 }, { 145,7446 }, { 146,7446 }, { 147,7446 }, { 148,7446 },
 { 149,7446 }, { 150,7446 }, { 151,7446 }, { 152,7446 }, { 153,7446 },
 { 154,7446 }, { 155,7446 }, { 156,7446 }, { 157,7446 }, { 158,7446 },

 { 159,7446 }, { 160,7446 }, { 161,7446 }, { 162,7446 }, { 163,7446 },
 { 164,7446 }, { 165,7446 }, { 166,7446 }, { 167,7446 }, { 168,7446 },
 { 169,7446 }, { 170,7446 }, { 171,7446 }, { 172,7446 }, { 173,7446 },
 { 174,7446 }, { 175,7446 }, { 176,7446 }, { 177,7446 }, { 178,7446 },
 { 179,7446 }, { 180,7446 }, { 181,7446 }, { 182,7446 }, { 183,7446 },
 { 184,7446 }, { 185,7446 }, { 186,7446 }, { 187,7446 }, { 188,7446 },
 { 189,7446 }, { 190,7446 }, { 191,7446 }, { 192,7446 }, { 193,7446 },
 { 194,7446 }, { 195,7446 }, { 196,7446 }, { 197,7446 }, { 198,7446 },
 { 199,7446 }, { 200,7446 }, { 201,7446 }, { 202,7446 }, { 203,7446 },
 { 204,7446 }, { 205,7446 }, { 206,7446 }, { 207,7446 }, { 208,7446 },

 { 209,7446 }, { 210,7446 }, { 211,7446 }, { 212,7446 }, { 213,7446 },
 { 214,7446 }, { 215,7446 }, { 216,7446 }, { 217,7446 }, { 218,7446 },
 { 219,7446 }, { 220,7446 }, { 221,7446 }, { 222,7446 }, { 223,7446 },
 { 224,7446 }, { 225,7446 }, { 226,7446 }, { 227,7446 }, { 228,7446 },
 { 229,7446 }, { 230,7446 }, { 231,7446 }, { 232,7446 }, { 233,7446 },
 { 234,7446 }, { 235,7446 }, { 236,7446 }, { 237,7446 }, { 238,7446 },
 { 239,7446 }, { 240,7446 }, { 241,7446 }, { 242,7446 }, { 243,7446 },
 { 244,7446 }, { 245,7446 }, { 246,7446 }, { 247,7446 }, { 248,7446 },
 { 249,7446 }, { 250,7446 }, { 251,7446 }, { 252,7446 }, { 253,7446 },
 { 254,7446 }, { 255,7446 }, { 256,7446 }, {   0,   0 }, {   0,33651 },

 {   1,8009 }, {   2,8009 }, {   3,8009 }, {   4,8009 }, {   5,8009 },
 {   6,8009 }, {   7,8009 }, {   8,8009 }, {   9,8009 }, {  10,8009 },
 {  11,8009 }, {  12,8009 }, {  13,8009 }, {  14,8009 }, {  15,8009 },
 {  16,8009 }, {  17,8009 }, {  18,8009 }, {  19,8009 }, {  20,8009 },
 {  21,8009 }, {  22,8009 }, {  23,8009 }, {  24,8009 }, {  25,8009 },
 {  26,8009 }, {  27,8009 }, {  28,8009 }, {  29,8009 }, {  30,8009 },
 {  31,8009 }, {  32,8009 }, {  33,8009 }, {  34,8009 }, {  35,8009 },
 {  36,8009 }, {  37,8009 }, {  38,8009 }, {  39,8267 }, {  40,8009 },
 {  41,8009 }, {  42,8009 }, {  43,8009 }, {  44,8009 }, {  45,8009 },
 {  46,8009 }, {  47,8009 }, {  48,8009 }, {  49,8009 }, {  50,8009 },

 {  51,8009 }, {  52,8009 }, {  53,8009 }, {  54,8009 }, {  55,8009 },
 {  56,8009 }, {  57,8009 }, {  58,8009 }, {  59,8009 }, {  60,8009 },
 {  61,8009 }, {  62,8009 }, {  63,8009 }, {  64,8009 }, {  65,8009 },
 {  66,8009 }, {  67,8009 }, {  68,8009 }, {  69,8009 }, {  70,8009 },
 {  71,8009 }, {  72,8009 }, {  73,8009 }, {  74,8009 }, {  75,8009 },
 {  76,8009 }, {  77,8009 }, {  78,8009 }, {  79,8009 }, {  80,8009 },
 {  81,8009 }, {  82,8009 }, {  83,8009 }, {  84,8009 }, {  85,8009 },
 {  86,8009 }, {  87,8009 }, {  88,8009 }, {  89,8009 }, {  90,8009 },
 {  91,8009 }, {  92,8009 }, {  93,8009 }, {  94,8009 }, {  95,8009 },
 {  96,8009 }, {  97,8009 }, {  98,8009 }, {  99,8009 }, { 100,8009 },

 { 101,8009 }, { 102,8009 }, { 103,8009 }, { 104,8009 }, { 105,8009 },
 { 106,8009 }, { 107,8009 }, { 108,8009 }, { 109,8009 }, { 110,8009 },
 { 111,8009 }, { 112,8009 }, { 113,8009 }, { 114,8009 }, { 115,8009 },
 { 116,8009 }, { 117,8009 }, { 118,8009 }, { 119,8009 }, { 120,8009 },
 { 121,8009 }, { 122,8009 }, { 123,8009 }, { 124,8009 }, { 125,8009 },
 { 126,8009 }, { 127,8009 }, { 128,8009 }, { 129,8009 }, { 130,8009 },
 { 131,8009 }, { 132,8009 }, { 133,8009 }, { 134,8009 }, { 135,8009 },
 { 136,8009 }, { 137,8009 }, { 138,8009 }, { 139,8009 }, { 140,8009 },
 { 141,8009 }, { 142,8009 }, { 143,8009 }, { 144,8009 }, { 145,8009 },
 { 146,8009 }, { 147,8009 }, { 148,8009 }, { 149,8009 }, { 150,8009 },

 { 151,8009 }, { 152,8009 }, { 153,8009 }, { 154,8009 }, { 155,8009 },
 { 156,8009 }, { 157,8009 }, { 158,8009 }, { 159,8009 }, { 160,8009 },
 { 161,8009 }, { 162,8009 }, { 163,8009 }, { 164,8009 }, { 165,8009 },
 { 166,8009 }, { 167,8009 }, { 168,8009 }, { 169,8009 }, { 170,8009 },
 { 171,8009 }, { 172,8009 }, { 173,8009 }, { 174,8009 }, { 175,8009 },
 { 176,8009 }, { 177,8009 }, { 178,8009 }, { 179,8009 }, { 180,8009 },
 { 181,8009 }, { 182,8009 }, { 183,8009 }, { 184,8009 }, { 185,8009 },
 { 186,8009 }, { 187,8009 }, { 188,8009 }, { 189,8009 }, { 190,8009 },
 { 191,8009 }, { 192,8009 }, { 193,8009 }, { 194,8009 }, { 195,8009 },
 { 196,8009 }, { 197,8009 }, { 198,8009 }, { 199,8009 }, { 200,8009 },

 { 201,8009 }, { 202,8009 }, { 203,8009 }, { 204,8009 }, { 205,8009 },
 { 206,8009 }, { 207,8009 }, { 208,8009 }, { 209,8009 }, { 210,8009 },
 { 211,8009 }, { 212,8009 }, { 213,8009 }, { 214,8009 }, { 215,8009 },
 { 216,8009 }, { 217,8009 }, { 218,8009 }, { 219,8009 }, { 220,8009 },
 { 221,8009 }, { 222,8009 }, { 223,8009 }, { 224,8009 }, { 225,8009 },
 { 226,8009 }, { 227,8009 }, { 228,8009 }, { 229,8009 }, { 230,8009 },
 { 231,8009 }, { 232,8009 }, { 233,8009 }, { 234,8009 }, { 235,8009 },
 { 236,8009 }, { 237,8009 }, { 238,8009 }, { 239,8009 }, { 240,8009 },
 { 241,8009 }, { 242,8009 }, { 243,8009 }, { 244,8009 }, { 245,8009 },
 { 246,8009 }, { 247,8009 }, { 248,8009 }, { 249,8009 }, { 250,8009 },

 { 251,8009 }, { 252,8009 }, { 253,8009 }, { 254,8009 }, { 255,8009 },
 { 256,8009 }, {   0,   0 }, {   0,33393 }, {   1,7751 }, {   2,7751 },
 {   3,7751 }, {   4,7751 }, {   5,7751 }, {   6,7751 }, {   7,7751 },
 {   8,7751 }, {   9,7751 }, {  10,7751 }, {  11,7751 }, {  12,7751 },
 {  13,7751 }, {  14,7751 }, {  15,7751 }, {  16,7751 }, {  17,7751 },
 {  18,7751 }, {  19,7751 }, {  20,7751 }, {  21,7751 }, {  22,7751 },
 {  23,7751 }, {  24,7751 }, {  25,7751 }, {  26,7751 }, {  27,7751 },
 {  28,7751 }, {  29,7751 }, {  30,7751 }, {  31,7751 }, {  32,7751 },
 {  33,7751 }, {  34,7751 }, {  35,7751 }, {  36,7751 }, {  37,7751 },
 {  38,7751 }, {  39,8009 }, {  40,7751 }, {  41,7751 }, {  42,7751 },

 {  43,7751 }, {  44,7751 }, {  45,7751 }, {  46,7751 }, {  47,7751 },
 {  48,7751 }, {  49,7751 }, {  50,7751 }, {  51,7751 }, {  52,7751 },
 {  53,7751 }, {  54,7751 }, {  55,7751 }, {  56,7751 }, {  57,7751 },
 {  58,7751 }, {  59,7751 }, {  60,7751 }, {  61,7751 }, {  62,7751 },
 {  63,7751 }, {  64,7751 }, {  65,7751 }, {  66,7751 }, {  67,7751 },
 {  68,7751 }, {  69,7751 }, {  70,7751 }, {  71,7751 }, {  72,7751 },
 {  73,7751 }, {  74,7751 }, {  75,7751 }, {  76,7751 }, {  77,7751 },
 {  78,7751 }, {  79,7751 }, {  80,7751 }, {  81,7751 }, {  82,7751 },
 {  83,7751 }, {  84,7751 }, {  85,7751 }, {  86,7751 }, {  87,7751 },
 {  88,7751 }, {  89,7751 }, {  90,7751 }, {  91,7751 }, {  92,7751 },

 {  93,7751 }, {  94,7751 }, {  95,7751 }, {  96,7751 }, {  97,7751 },
 {  98,7751 }, {  99,7751 }, { 100,7751 }, { 101,7751 }, { 102,7751 },
 { 103,7751 }, { 104,7751 }, { 105,7751 }, { 106,7751 }, { 107,7751 },
 { 108,7751 }, { 109,7751 }, { 110,7751 }, { 111,7751 }, { 112,7751 },
 { 113,7751 }, { 114,7751 }, { 115,7751 }, { 116,7751 }, { 117,7751 },
 { 118,7751 }, { 119,7751 }, { 120,7751 }, { 121,7751 }, { 122,7751 },
 { 123,7751 }, { 124,7751 }, { 125,7751 }, { 126,7751 }, { 127,7751 },
 { 128,7751 }, { 129,7751 }, { 130,7751 }, { 131,7751 }, { 132,7751 },
 { 133,7751 }, { 134,7751 }, { 135,7751 }, { 136,7751 }, { 137,7751 },
 { 138,7751 }, { 139,7751 }, { 140,7751 }, { 141,7751 }, { 142,7751 },

 { 143,7751 }, { 144,7751 }, { 145,7751 }, { 146,7751 }, { 147,7751 },
 { 148,7751 }, { 149,7751 }, { 150,7751 }, { 151,7751 }, { 152,7751 },
 { 153,7751 }, { 154,7751 }, { 155,7751 }, { 156,7751 }, { 157,7751 },
 { 158,7751 }, { 159,7751 }, { 160,7751 }, { 161,7751 }, { 162,7751 },
 { 163,7751 }, { 164,7751 }, { 165,7751 }, { 166,7751 }, { 167,7751 },
 { 168,7751 }, { 169,7751 }, { 170,7751 }, { 171,7751 }, { 172,7751 },
 { 173,7751 }, { 174,7751 }, { 175,7751 }, { 176,7751 }, { 177,7751 },
 { 178,7751 }, { 179,7751 }, { 180,7751 }, { 181,7751 }, { 182,7751 },
 { 183,7751 }, { 184,7751 }, { 185,7751 }, { 186,7751 }, { 187,7751 },
 { 188,7751 }, { 189,7751 }, { 190,7751 }, { 191,7751 }, { 192,7751 },

 { 193,7751 }, { 194,7751 }, { 195,7751 }, { 196,7751 }, { 197,7751 },
 { 198,7751 }, { 199,7751 }, { 200,7751 }, { 201,7751 }, { 202,7751 },
 { 203,7751 }, { 204,7751 }, { 205,7751 }, { 206,7751 }, { 207,7751 },
 { 208,7751 }, { 209,7751 }, { 210,7751 }, { 211,7751 }, { 212,7751 },
 { 213,7751 }, { 214,7751 }, { 215,7751 }, { 216,7751 }, { 217,7751 },
 { 218,7751 }, { 219,7751 }, { 220,7751 }, { 221,7751 }, { 222,7751 },
 { 223,7751 }, { 224,7751 }, { 225,7751 }, { 226,7751 }, { 227,7751 },
 { 228,7751 }, { 229,7751 }, { 230,7751 }, { 231,7751 }, { 232,7751 },
 { 233,7751 }, { 234,7751 }, { 235,7751 }, { 236,7751 }, { 237,7751 },
 { 238,7751 }, { 239,7751 }, { 240,7751 }, { 241,7751 }, { 242,7751 },

 { 243,7751 }, { 244,7751 }, { 245,7751 }, { 246,7751 }, { 247,7751 },
 { 248,7751 }, { 249,7751 }, { 250,7751 }, { 251,7751 }, { 252,7751 },
 { 253,7751 }, { 254,7751 }, { 255,7751 }, { 256,7751 }, {   0,   0 },
 {   0,33135 }, {   1,7798 }, {   2,7798 }, {   3,7798 }, {   4,7798 },
 {   5,7798 }, {   6,7798 }, {   7,7798 }, {   8,7798 }, {   9,7798 },
 {  10,8056 }, {  11,7798 }, {  12,7798 }, {  13,7798 }, {  14,7798 },
 {  15,7798 }, {  16,7798 }, {  17,7798 }, {  18,7798 }, {  19,7798 },
 {  20,7798 }, {  21,7798 }, {  22,7798 }, {  23,7798 }, {  24,7798 },
 {  25,7798 }, {  26,7798 }, {  27,7798 }, {  28,7798 }, {  29,7798 },
 {  30,7798 }, {  31,7798 }, {  32,7798 }, {  33,7798 }, {  34,7798 },

 {  35,7798 }, {  36,8314 }, {  37,7798 }, {  38,7798 }, {  39,7798 },
 {  40,7798 }, {  41,7798 }, {  42,7798 }, {  43,7798 }, {  44,7798 },
 {  45,7798 }, {  46,7798 }, {  47,7798 }, {  48,7798 }, {  49,7798 },
 {  50,7798 }, {  51,7798 }, {  52,7798 }, {  53,7798 }, {  54,7798 },
 {  55,7798 }, {  56,7798 }, {  57,7798 }, {  58,7798 }, {  59,7798 },
 {  60,7798 }, {  61,7798 }, {  62,7798 }, {  63,7798 }, {  64,7798 },
 {  65,7798 }, {  66,7798 }, {  67,7798 }, {  68,7798 }, {  69,7798 },
 {  70,7798 }, {  71,7798 }, {  72,7798 }, {  73,7798 }, {  74,7798 },
 {  75,7798 }, {  76,7798 }, {  77,7798 }, {  78,7798 }, {  79,7798 },
 {  80,7798 }, {  81,7798 }, {  82,7798 }, {  83,7798 }, {  84,7798 },

 {  85,7798 }, {  86,7798 }, {  87,7798 }, {  88,7798 }, {  89,7798 },
 {  90,7798 }, {  91,7798 }, {  92,7798 }, {  93,7798 }, {  94,7798 },
 {  95,7798 }, {  96,7798 }, {  97,7798 }, {  98,7798 }, {  99,7798 },
 { 100,7798 }, { 101,7798 }, { 102,7798 }, { 103,7798 }, { 104,7798 },
 { 105,7798 }, { 106,7798 }, { 107,7798 }, { 108,7798 }, { 109,7798 },
 { 110,7798 }, { 111,7798 }, { 112,7798 }, { 113,7798 }, { 114,7798 },
 { 115,7798 }, { 116,7798 }, { 117,7798 }, { 118,7798 }, { 119,7798 },
 { 120,7798 }, { 121,7798 }, { 122,7798 }, { 123,7798 }, { 124,7798 },
 { 125,7798 }, { 126,7798 }, { 127,7798 }, { 128,7798 }, { 129,7798 },
 { 130,7798 }, { 131,7798 }, { 132,7798 }, { 133,7798 }, { 134,7798 },

 { 135,7798 }, { 136,7798 }, { 137,7798 }, { 138,7798 }, { 139,7798 },
 { 140,7798 }, { 141,7798 }, { 142,7798 }, { 143,7798 }, { 144,7798 },
 { 145,7798 }, { 146,7798 }, { 147,7798 }, { 148,7798 }, { 149,7798 },
 { 150,7798 }, { 151,7798 }, { 152,7798 }, { 153,7798 }, { 154,7798 },
 { 155,7798 }, { 156,7798 }, { 157,7798 }, { 158,7798 }, { 159,7798 },
 { 160,7798 }, { 161,7798 }, { 162,7798 }, { 163,7798 }, { 164,7798 },
 { 165,7798 }, { 166,7798 }, { 167,7798 }, { 168,7798 }, { 169,7798 },
 { 170,7798 }, { 171,7798 }, { 172,7798 }, { 173,7798 }, { 174,7798 },
 { 175,7798 }, { 176,7798 }, { 177,7798 }, { 178,7798 }, { 179,7798 },
 { 180,7798 }, { 181,7798 }, { 182,7798 }, { 183,7798 }, { 184,7798 },

 { 185,7798 }, { 186,7798 }, { 187,7798 }, { 188,7798 }, { 189,7798 },
 { 190,7798 }, { 191,7798 }, { 192,7798 }, { 193,7798 }, { 194,7798 },
 { 195,7798 }, { 196,7798 }, { 197,7798 }, { 198,7798 }, { 199,7798 },
 { 200,7798 }, { 201,7798 }, { 202,7798 }, { 203,7798 }, { 204,7798 },
 { 205,7798 }, { 206,7798 }, { 207,7798 }, { 208,7798 }, { 209,7798 },
 { 210,7798 }, { 211,7798 }, { 212,7798 }, { 213,7798 }, { 214,7798 },
 { 215,7798 }, { 216,7798 }, { 217,7798 }, { 218,7798 }, { 219,7798 },
 { 220,7798 }, { 221,7798 }, { 222,7798 }, { 223,7798 }, { 224,7798 },
 { 225,7798 }, { 226,7798 }, { 227,7798 }, { 228,7798 }, { 229,7798 },
 { 230,7798 }, { 231,7798 }, { 232,7798 }, { 233,7798 }, { 234,7798 },

 { 235,7798 }, { 236,7798 }, { 237,7798 }, { 238,7798 }, { 239,7798 },
 { 240,7798 }, { 241,7798 }, { 242,7798 }, { 243,7798 }, { 244,7798 },
 { 245,7798 }, { 246,7798 }, { 247,7798 }, { 248,7798 }, { 249,7798 },
 { 250,7798 }, { 251,7798 }, { 252,7798 }, { 253,7798 }, { 254,7798 },
 { 255,7798 }, { 256,7798 }, {   0,   0 }, {   0,32877 }, {   1,7540 },
 {   2,7540 }, {   3,7540 }, {   4,7540 }, {   5,7540 }, {   6,7540 },
 {   7,7540 }, {   8,7540 }, {   9,7540 }, {  10,7798 }, {  11,7540 },
 {  12,7540 }, {  13,7540 }, {  14,7540 }, {  15,7540 }, {  16,7540 },
 {  17,7540 }, {  18,7540 }, {  19,7540 }, {  20,7540 }, {  21,7540 },
 {  22,7540 }, {  23,7540 }, {  24,7540 }, {  25,7540 }, {  26,7540 },

 {  27,7540 }, {  28,7540 }, {  29,7540 }, {  30,7540 }, {  31,7540 },
 {  32,7540 }, {  33,7540 }, {  34,7540 }, {  35,7540 }, {  36,8056 },
 {  37,7540 }, {  38,7540 }, {  39,7540 }, {  40,7540 }, {  41,7540 },
 {  42,7540 }, {  43,7540 }, {  44,7540 }, {  45,7540 }, {  46,7540 },
 {  47,7540 }, {  48,7540 }, {  49,7540 }, {  50,7540 }, {  51,7540 },
 {  52,7540 }, {  53,7540 }, {  54,7540 }, {  55,7540 }, {  56,7540 },
 {  57,7540 }, {  58,7540 }, {  59,7540 }, {  60,7540 }, {  61,7540 },
 {  62,7540 }, {  63,7540 }, {  64,7540 }, {  65,7540 }, {  66,7540 },
 {  67,7540 }, {  68,7540 }, {  69,7540 }, {  70,7540 }, {  71,7540 },
 {  72,7540 }, {  73,7540 }, {  74,7540 }, {  75,7540 }, {  76,7540 },

 {  77,7540 }, {  78,7540 }, {  79,7540 }, {  80,7540 }, {  81,7540 },
 {  82,7540 }, {  83,7540 }, {  84,7540 }, {  85,7540 }, {  86,7540 },
 {  87,7540 }, {  88,7540 }, {  89,7540 }, {  90,7540 }, {  91,7540 },
 {  92,7540 }, {  93,7540 }, {  94,7540 }, {  95,7540 }, {  96,7540 },
 {  97,7540 }, {  98,7540 }, {  99,7540 }, { 100,7540 }, { 101,7540 },
 { 102,7540 }, { 103,7540 }, { 104,7540 }, { 105,7540 }, { 106,7540 },
 { 107,7540 }, { 108,7540 }, { 109,7540 }, { 110,7540 }, { 111,7540 },
 { 112,7540 }, { 113,7540 }, { 114,7540 }, { 115,7540 }, { 116,7540 },
 { 117,7540 }, { 118,7540 }, { 119,7540 }, { 120,7540 }, { 121,7540 },
 { 122,7540 }, { 123,7540 }, { 124,7540 }, { 125,7540 }, { 126,7540 },

 { 127,7540 }, { 128,7540 }, { 129,7540 }, { 130,7540 }, { 131,7540 },
 { 132,7540 }, { 133,7540 }, { 134,7540 }, { 135,7540 }, { 136,7540 },
 { 137,7540 }, { 138,7540 }, { 139,7540 }, { 140,7540 }, { 141,7540 },
 { 142,7540 }, { 143,7540 }, { 144,7540 }, { 145,7540 }, { 146,7540 },
 { 147,7540 }, { 148,7540 }, { 149,7540 }, { 150,7540 }, { 151,7540 },
 { 152,7540 }, { 153,7540 }, { 154,7540 }, { 155,7540 }, { 156,7540 },
 { 157,7540 }, { 158,7540 }, { 159,7540 }, { 160,7540 }, { 161,7540 },
 { 162,7540 }, { 163,7540 }, { 164,7540 }, { 165,7540 }, { 166,7540 },
 { 167,7540 }, { 168,7540 }, { 169,7540 }, { 170,7540 }, { 171,7540 },
 { 172,7540 }, { 173,7540 }, { 174,7540 }, { 175,7540 }, { 176,7540 },

 { 177,7540 }, { 178,7540 }, { 179,7540 }, { 180,7540 }, { 181,7540 },
 { 182,7540 }, { 183,7540 }, { 184,7540 }, { 185,7540 }, { 186,7540 },
 { 187,7540 }, { 188,7540 }, { 189,7540 }, { 190,7540 }, { 191,7540 },
 { 192,7540 }, { 193,7540 }, { 194,7540 }, { 195,7540 }, { 196,7540 },
 { 197,7540 }, { 198,7540 }, { 199,7540 }, { 200,7540 }, { 201,7540 },
 { 202,7540 }, { 203,7540 }, { 204,7540 }, { 205,7540 }, { 206,7540 },
 { 207,7540 }, { 208,7540 }, { 209,7540 }, { 210,7540 }, { 211,7540 },
 { 212,7540 }, { 213,7540 }, { 214,7540 }, { 215,7540 }, { 216,7540 },
 { 217,7540 }, { 218,7540 }, { 219,7540 }, { 220,7540 }, { 221,7540 },
 { 222,7540 }, { 223,7540 }, { 224,7540 }, { 225,7540 }, { 226,7540 },

 { 227,7540 }, { 228,7540 }, { 229,7540 }, { 230,7540 }, { 231,7540 },
 { 232,7540 }, { 233,7540 }, { 234,7540 }, { 235,7540 }, { 236,7540 },
 { 237,7540 }, { 238,7540 }, { 239,7540 }, { 240,7540 }, { 241,7540 },
 { 242,7540 }, { 243,7540 }, { 244,7540 }, { 245,7540 }, { 246,7540 },
 { 247,7540 }, { 248,7540 }, { 249,7540 }, { 250,7540 }, { 251,7540 },
 { 252,7540 }, { 253,7540 }, { 254,7540 }, { 255,7540 }, { 256,7540 },
 {   0,   0 }, {   0,32619 }, {   1,5593 }, {   2,5593 }, {   3,5593 },
 {   4,5593 }, {   5,5593 }, {   6,5593 }, {   7,5593 }, {   8,5593 },
 {   9,5593 }, {  10,5593 }, {  11,5593 }, {  12,5593 }, {  13,5593 },
 {  14,5593 }, {  15,5593 }, {  16,5593 }, {  17,5593 }, {  18,5593 },

 {  19,5593 }, {  20,5593 }, {  21,5593 }, {  22,5593 }, {  23,5593 },
 {  24,5593 }, {  25,5593 }, {  26,5593 }, {  27,5593 }, {  28,5593 },
 {  29,5593 }, {  30,5593 }, {  31,5593 }, {  32,5593 }, {  33,5593 },
 {  34,2639 }, {  35,5593 }, {  36,5593 }, {  37,5593 }, {  38,5593 },
 {  39,5593 }, {  40,5593 }, {  41,5593 }, {  42,5593 }, {  43,5593 },
 {  44,5593 }, {  45,5593 }, {  46,5593 }, {  47,5593 }, {  48,5593 },
 {  49,5593 }, {  50,5593 }, {  51,5593 }, {  52,5593 }, {  53,5593 },
 {  54,5593 }, {  55,5593 }, {  56,5593 }, {  57,5593 }, {  58,5593 },
 {  59,5593 }, {  60,5593 }, {  61,5593 }, {  62,5593 }, {  63,5593 },
 {  64,5593 }, {  65,5593 }, {  66,5593 }, {  67,5593 }, {  68,5593 },

 {  69,5593 }, {  70,5593 }, {  71,5593 }, {  72,5593 }, {  73,5593 },
 {  74,5593 }, {  75,5593 }, {  76,5593 }, {  77,5593 }, {  78,5593 },
 {  79,5593 }, {  80,5593 }, {  81,5593 }, {  82,5593 }, {  83,5593 },
 {  84,5593 }, {  85,5593 }, {  86,5593 }, {  87,5593 }, {  88,5593 },
 {  89,5593 }, {  90,5593 }, {  91,5593 }, {  92,5593 }, {  93,5593 },
 {  94,5593 }, {  95,5593 }, {  96,5593 }, {  97,5593 }, {  98,5593 },
 {  99,5593 }, { 100,5593 }, { 101,5593 }, { 102,5593 }, { 103,5593 },
 { 104,5593 }, { 105,5593 }, { 106,5593 }, { 107,5593 }, { 108,5593 },
 { 109,5593 }, { 110,5593 }, { 111,5593 }, { 112,5593 }, { 113,5593 },
 { 114,5593 }, { 115,5593 }, { 116,5593 }, { 117,5593 }, { 118,5593 },

 { 119,5593 }, { 120,5593 }, { 121,5593 }, { 122,5593 }, { 123,5593 },
 { 124,5593 }, { 125,5593 }, { 126,5593 }, { 127,5593 }, { 128,5593 },
 { 129,5593 }, { 130,5593 }, { 131,5593 }, { 132,5593 }, { 133,5593 },
 { 134,5593 }, { 135,5593 }, { 136,5593 }, { 137,5593 }, { 138,5593 },
 { 139,5593 }, { 140,5593 }, { 141,5593 }, { 142,5593 }, { 143,5593 },
 { 144,5593 }, { 145,5593 }, { 146,5593 }, { 147,5593 }, { 148,5593 },
 { 149,5593 }, { 150,5593 }, { 151,5593 }, { 152,5593 }, { 153,5593 },
 { 154,5593 }, { 155,5593 }, { 156,5593 }, { 157,5593 }, { 158,5593 },
 { 159,5593 }, { 160,5593 }, { 161,5593 }, { 162,5593 }, { 163,5593 },
 { 164,5593 }, { 165,5593 }, { 166,5593 }, { 167,5593 }, { 168,5593 },

 { 169,5593 }, { 170,5593 }, { 171,5593 }, { 172,5593 }, { 173,5593 },
 { 174,5593 }, { 175,5593 }, { 176,5593 }, { 177,5593 }, { 178,5593 },
 { 179,5593 }, { 180,5593 }, { 181,5593 }, { 182,5593 }, { 183,5593 },
 { 184,5593 }, { 185,5593 }, { 186,5593 }, { 187,5593 }, { 188,5593 },
 { 189,5593 }, { 190,5593 }, { 191,5593 }, { 192,5593 }, { 193,5593 },
 { 194,5593 }, { 195,5593 }, { 196,5593 }, { 197,5593 }, { 198,5593 },
 { 199,5593 }, { 200,5593 }, { 201,5593 }, { 202,5593 }, { 203,5593 },
 { 204,5593 }, { 205,5593 }, { 206,5593 }, { 207,5593 }, { 208,5593 },
 { 209,5593 }, { 210,5593 }, { 211,5593 }, { 212,5593 }, { 213,5593 },
 { 214,5593 }, { 215,5593 }, { 216,5593 }, { 217,5593 }, { 218,5593 },

 { 219,5593 }, { 220,5593 }, { 221,5593 }, { 222,5593 }, { 223,5593 },
 { 224,5593 }, { 225,5593 }, { 226,5593 }, { 227,5593 }, { 228,5593 },
 { 229,5593 }, { 230,5593 }, { 231,5593 }, { 232,5593 }, { 233,5593 },
 { 234,5593 }, { 235,5593 }, { 236,5593 }, { 237,5593 }, { 238,5593 },
 { 239,5593 }, { 240,5593 }, { 241,5593 }, { 242,5593 }, { 243,5593 },
 { 244,5593 }, { 245,5593 }, { 246,5593 }, { 247,5593 }, { 248,5593 },
 { 249,5593 }, { 250,5593 }, { 251,5593 }, { 252,5593 }, { 253,5593 },
 { 254,5593 }, { 255,5593 }, { 256,5593 }, {   0,   0 }, {   0,32361 },
 {   1,5335 }, {   2,5335 }, {   3,5335 }, {   4,5335 }, {   5,5335 },
 {   6,5335 }, {   7,5335 }, {   8,5335 }, {   9,5335 }, {  10,5335 },

 {  11,5335 }, {  12,5335 }, {  13,5335 }, {  14,5335 }, {  15,5335 },
 {  16,5335 }, {  17,5335 }, {  18,5335 }, {  19,5335 }, {  20,5335 },
 {  21,5335 }, {  22,5335 }, {  23,5335 }, {  24,5335 }, {  25,5335 },
 {  26,5335 }, {  27,5335 }, {  28,5335 }, {  29,5335 }, {  30,5335 },
 {  31,5335 }, {  32,5335 }, {  33,5335 }, {  34,2381 }, {  35,5335 },
 {  36,5335 }, {  37,5335 }, {  38,5335 }, {  39,5335 }, {  40,5335 },
 {  41,5335 }, {  42,5335 }, {  43,5335 }, {  44,5335 }, {  45,5335 },
 {  46,5335 }, {  47,5335 }, {  48,5335 }, {  49,5335 }, {  50,5335 },
 {  51,5335 }, {  52,5335 }, {  53,5335 }, {  54,5335 }, {  55,5335 },
 {  56,5335 }, {  57,5335 }, {  58,5335 }, {  59,5335 }, {  60,5335 },

 {  61,5335 }, {  62,5335 }, {  63,5335 }, {  64,5335 }, {  65,5335 },
 {  66,5335 }, {  67,5335 }, {  68,5335 }, {  69,5335 }, {  70,5335 },
 {  71,5335 }, {  72,5335 }, {  73,5335 }, {  74,5335 }, {  75,5335 },
 {  76,5335 }, {  77,5335 }, {  78,5335 }, {  79,5335 }, {  80,5335 },
 {  81,5335 }, {  82,5335 }, {  83,5335 }, {  84,5335 }, {  85,5335 },
 {  86,5335 }, {  87,5335 }, {  88,5335 }, {  89,5335 }, {  90,5335 },
 {  91,5335 }, {  92,5335 }, {  93,5335 }, {  94,5335 }, {  95,5335 },
 {  96,5335 }, {  97,5335 }, {  98,5335 }, {  99,5335 }, { 100,5335 },
 { 101,5335 }, { 102,5335 }, { 103,5335 }, { 104,5335 }, { 105,5335 },
 { 106,5335 }, { 107,5335 }, { 108,5335 }, { 109,5335 }, { 110,5335 },

 { 111,5335 }, { 112,5335 }, { 113,5335 }, { 114,5335 }, { 115,5335 },
 { 116,5335 }, { 117,5335 }, { 118,5335 }, { 119,5335 }, { 120,5335 },
 { 121,5335 }, { 122,5335 }, { 123,5335 }, { 124,5335 }, { 125,5335 },
 { 126,5335 }, { 127,5335 }, { 128,5335 }, { 129,5335 }, { 130,5335 },
 { 131,5335 }, { 132,5335 }, { 133,5335 }, { 134,5335 }, { 135,5335 },
 { 136,5335 }, { 137,5335 }, { 138,5335 }, { 139,5335 }, { 140,5335 },
 { 141,5335 }, { 142,5335 }, { 143,5335 }, { 144,5335 }, { 145,5335 },
 { 146,5335 }, { 147,5335 }, { 148,5335 }, { 149,5335 }, { 150,5335 },
 { 151,5335 }, { 152,5335 }, { 153,5335 }, { 154,5335 }, { 155,5335 },
 { 156,5335 }, { 157,5335 }, { 158,5335 }, { 159,5335 }, { 160,5335 },

 { 161,5335 }, { 162,5335 }, { 163,5335 }, { 164,5335 }, { 165,5335 },
 { 166,5335 }, { 167,5335 }, { 168,5335 }, { 169,5335 }, { 170,5335 },
 { 171,5335 }, { 172,5335 }, { 173,5335 }, { 174,5335 }, { 175,5335 },
 { 176,5335 }, { 177,5335 }, { 178,5335 }, { 179,5335 }, { 180,5335 },
 { 181,5335 }, { 182,5335 }, { 183,5335 }, { 184,5335 }, { 185,5335 },
 { 186,5335 }, { 187,5335 }, { 188,5335 }, { 189,5335 }, { 190,5335 },
 { 191,5335 }, { 192,5335 }, { 193,5335 }, { 194,5335 }, { 195,5335 },
 { 196,5335 }, { 197,5335 }, { 198,5335 }, { 199,5335 }, { 200,5335 },
 { 201,5335 }, { 202,5335 }, { 203,5335 }, { 204,5335 }, { 205,5335 },
 { 206,5335 }, { 207,5335 }, { 208,5335 }, { 209,5335 }, { 210,5335 },

 { 211,5335 }, { 212,5335 }, { 213,5335 }, { 214,5335 }, { 215,5335 },
 { 216,5335 }, { 217,5335 }, { 218,5335 }, { 219,5335 }, { 220,5335 },
 { 221,5335 }, { 222,5335 }, { 223,5335 }, { 224,5335 }, { 225,5335 },
 { 226,5335 }, { 227,5335 }, { 228,5335 }, { 229,5335 }, { 230,5335 },
 { 231,5335 }, { 232,5335 }, { 233,5335 }, { 234,5335 }, { 235,5335 },
 { 236,5335 }, { 237,5335 }, { 238,5335 }, { 239,5335 }, { 240,5335 },
 { 241,5335 }, { 242,5335 }, { 243,5335 }, { 244,5335 }, { 245,5335 },
 { 246,5335 }, { 247,5335 }, { 248,5335 }, { 249,5335 }, { 250,5335 },
 { 251,5335 }, { 252,5335 }, { 253,5335 }, { 254,5335 }, { 255,5335 },
 { 256,5335 }, {   0,  55 }, {   0,32103 }, {   1,2125 }, {   2,2125 },

 {   3,2125 }, {   4,2125 }, {   5,2125 }, {   6,2125 }, {   7,2125 },
 {   8,2125 }, {   9,7284 }, {  10,7289 }, {  11,2125 }, {  12,7284 },
 {  13,7284 }, {  14,2125 }, {  15,2125 }, {  16,2125 }, {  17,2125 },
 {  18,2125 }, {  19,2125 }, {  20,2125 }, {  21,2125 }, {  22,2125 },
 {  23,2125 }, {  24,2125 }, {  25,2125 }, {  26,2125 }, {  27,2125 },
 {  28,2125 }, {  29,2125 }, {  30,2125 }, {  31,2125 }, {  32,7284 },
 {  33,2125 }, {  34,2125 }, {  35,2125 }, {  36,2125 }, {  37,2125 },
 {  38,2125 }, {  39,2125 }, {  40,2125 }, {  41,2125 }, {  42,2125 },
 {  43,2125 }, {  44,2125 }, {  45,2127 }, {  46,2125 }, {  47,2125 },
 {  48,2125 }, {  49,2125 }, {  50,2125 }, {  51,2125 }, {  52,2125 },

 {  53,2125 }, {  54,2125 }, {  55,2125 }, {  56,2125 }, {  57,2125 },
 {  58,2125 }, {  59,2125 }, {  60,2125 }, {  61,2125 }, {  62,2125 },
 {  63,2125 }, {  64,2125 }, {  65,2125 }, {  66,2125 }, {  67,2125 },
 {  68,2125 }, {  69,2125 }, {  70,2125 }, {  71,2125 }, {  72,2125 },
 {  73,2125 }, {  74,2125 }, {  75,2125 }, {  76,2125 }, {  77,2125 },
 {  78,2125 }, {  79,2125 }, {  80,2125 }, {  81,2125 }, {  82,2125 },
 {  83,2125 }, {  84,2125 }, {  85,2141 }, {  86,2125 }, {  87,2125 },
 {  88,2125 }, {  89,2125 }, {  90,2125 }, {  91,2125 }, {  92,2125 },
 {  93,2125 }, {  94,2125 }, {  95,2125 }, {  96,2125 }, {  97,2125 },
 {  98,2125 }, {  99,2125 }, { 100,2125 }, { 101,2125 }, { 102,2125 },

 { 103,2125 }, { 104,2125 }, { 105,2125 }, { 106,2125 }, { 107,2125 },
 { 108,2125 }, { 109,2125 }, { 110,2125 }, { 111,2125 }, { 112,2125 },
 { 113,2125 }, { 114,2125 }, { 115,2125 }, { 116,2125 }, { 117,2141 },
 { 118,2125 }, { 119,2125 }, { 120,2125 }, { 121,2125 }, { 122,2125 },
 { 123,2125 }, { 124,2125 }, { 125,2125 }, { 126,2125 }, { 127,2125 },
 { 128,2125 }, { 129,2125 }, { 130,2125 }, { 131,2125 }, { 132,2125 },
 { 133,2125 }, { 134,2125 }, { 135,2125 }, { 136,2125 }, { 137,2125 },
 { 138,2125 }, { 139,2125 }, { 140,2125 }, { 141,2125 }, { 142,2125 },
 { 143,2125 }, { 144,2125 }, { 145,2125 }, { 146,2125 }, { 147,2125 },
 { 148,2125 }, { 149,2125 }, { 150,2125 }, { 151,2125 }, { 152,2125 },

 { 153,2125 }, { 154,2125 }, { 155,2125 }, { 156,2125 }, { 157,2125 },
 { 158,2125 }, { 159,2125 }, { 160,2125 }, { 161,2125 }, { 162,2125 },
 { 163,2125 }, { 164,2125 }, { 165,2125 }, { 166,2125 }, { 167,2125 },
 { 168,2125 }, { 169,2125 }, { 170,2125 }, { 171,2125 }, { 172,2125 },
 { 173,2125 }, { 174,2125 }, { 175,2125 }, { 176,2125 }, { 177,2125 },
 { 178,2125 }, { 179,2125 }, { 180,2125 }, { 181,2125 }, { 182,2125 },
 { 183,2125 }, { 184,2125 }, { 185,2125 }, { 186,2125 }, { 187,2125 },
 { 188,2125 }, { 189,2125 }, { 190,2125 }, { 191,2125 }, { 192,2125 },
 { 193,2125 }, { 194,2125 }, { 195,2125 }, { 196,2125 }, { 197,2125 },
 { 198,2125 }, { 199,2125 }, { 200,2125 }, { 201,2125 }, { 202,2125 },

 { 203,2125 }, { 204,2125 }, { 205,2125 }, { 206,2125 }, { 207,2125 },
 { 208,2125 }, { 209,2125 }, { 210,2125 }, { 211,2125 }, { 212,2125 },
 { 213,2125 }, { 214,2125 }, { 215,2125 }, { 216,2125 }, { 217,2125 },
 { 218,2125 }, { 219,2125 }, { 220,2125 }, { 221,2125 }, { 222,2125 },
 { 223,2125 }, { 224,2125 }, { 225,2125 }, { 226,2125 }, { 227,2125 },
 { 228,2125 }, { 229,2125 }, { 230,2125 }, { 231,2125 }, { 232,2125 },
 { 233,2125 }, { 234,2125 }, { 235,2125 }, { 236,2125 }, { 237,2125 },
 { 238,2125 }, { 239,2125 }, { 240,2125 }, { 241,2125 }, { 242,2125 },
 { 243,2125 }, { 244,2125 }, { 245,2125 }, { 246,2125 }, { 247,2125 },
 { 248,2125 }, { 249,2125 }, { 250,2125 }, { 251,2125 }, { 252,2125 },

 { 253,2125 }, { 254,2125 }, { 255,2125 }, { 256,2125 }, {   0,  55 },
 {   0,31845 }, {   1,1867 }, {   2,1867 }, {   3,1867 }, {   4,1867 },
 {   5,1867 }, {   6,1867 }, {   7,1867 }, {   8,1867 }, {   9,7026 },
 {  10,7031 }, {  11,1867 }, {  12,7026 }, {  13,7026 }, {  14,1867 },
 {  15,1867 }, {  16,1867 }, {  17,1867 }, {  18,1867 }, {  19,1867 },
 {  20,1867 }, {  21,1867 }, {  22,1867 }, {  23,1867 }, {  24,1867 },
 {  25,1867 }, {  26,1867 }, {  27,1867 }, {  28,1867 }, {  29,1867 },
 {  30,1867 }, {  31,1867 }, {  32,7026 }, {  33,1867 }, {  34,1867 },
 {  35,1867 }, {  36,1867 }, {  37,1867 }, {  38,1867 }, {  39,1867 },
 {  40,1867 }, {  41,1867 }, {  42,1867 }, {  43,1867 }, {  44,1867 },

 {  45,1869 }, {  46,1867 }, {  47,1867 }, {  48,1867 }, {  49,1867 },
 {  50,1867 }, {  51,1867 }, {  52,1867 }, {  53,1867 }, {  54,1867 },
 {  55,1867 }, {  56,1867 }, {  57,1867 }, {  58,1867 }, {  59,1867 },
 {  60,1867 }, {  61,1867 }, {  62,1867 }, {  63,1867 }, {  64,1867 },
 {  65,1867 }, {  66,1867 }, {  67,1867 }, {  68,1867 }, {  69,1867 },
 {  70,1867 }, {  71,1867 }, {  72,1867 }, {  73,1867 }, {  74,1867 },
 {  75,1867 }, {  76,1867 }, {  77,1867 }, {  78,1867 }, {  79,1867 },
 {  80,1867 }, {  81,1867 }, {  82,1867 }, {  83,1867 }, {  84,1867 },
 {  85,1883 }, {  86,1867 }, {  87,1867 }, {  88,1867 }, {  89,1867 },
 {  90,1867 }, {  91,1867 }, {  92,1867 }, {  93,1867 }, {  94,1867 },

 {  95,1867 }, {  96,1867 }, {  97,1867 }, {  98,1867 }, {  99,1867 },
 { 100,1867 }, { 101,1867 }, { 102,1867 }, { 103,1867 }, { 104,1867 },
 { 105,1867 }, { 106,1867 }, { 107,1867 }, { 108,1867 }, { 109,1867 },
 { 110,1867 }, { 111,1867 }, { 112,1867 }, { 113,1867 }, { 114,1867 },
 { 115,1867 }, { 116,1867 }, { 117,1883 }, { 118,1867 }, { 119,1867 },
 { 120,1867 }, { 121,1867 }, { 122,1867 }, { 123,1867 }, { 124,1867 },
 { 125,1867 }, { 126,1867 }, { 127,1867 }, { 128,1867 }, { 129,1867 },
 { 130,1867 }, { 131,1867 }, { 132,1867 }, { 133,1867 }, { 134,1867 },
 { 135,1867 }, { 136,1867 }, { 137,1867 }, { 138,1867 }, { 139,1867 },
 { 140,1867 }, { 141,1867 }, { 142,1867 }, { 143,1867 }, { 144,1867 },

 { 145,1867 }, { 146,1867 }, { 147,1867 }, { 148,1867 }, { 149,1867 },
 { 150,1867 }, { 151,1867 }, { 152,1867 }, { 153,1867 }, { 154,1867 },
 { 155,1867 }, { 156,1867 }, { 157,1867 }, { 158,1867 }, { 159,1867 },
 { 160,1867 }, { 161,1867 }, { 162,1867 }, { 163,1867 }, { 164,1867 },
 { 165,1867 }, { 166,1867 }, { 167,1867 }, { 168,1867 }, { 169,1867 },
 { 170,1867 }, { 171,1867 }, { 172,1867 }, { 173,1867 }, { 174,1867 },
 { 175,1867 }, { 176,1867 }, { 177,1867 }, { 178,1867 }, { 179,1867 },
 { 180,1867 }, { 181,1867 }, { 182,1867 }, { 183,1867 }, { 184,1867 },
 { 185,1867 }, { 186,1867 }, { 187,1867 }, { 188,1867 }, { 189,1867 },
 { 190,1867 }, { 191,1867 }, { 192,1867 }, { 193,1867 }, { 194,1867 },

 { 195,1867 }, { 196,1867 }, { 197,1867 }, { 198,1867 }, { 199,1867 },
 { 200,1867 }, { 201,1867 }, { 202,1867 }, { 203,1867 }, { 204,1867 },
 { 205,1867 }, { 206,1867 }, { 207,1867 }, { 208,1867 }, { 209,1867 },
 { 210,1867 }, { 211,1867 }, { 212,1867 }, { 213,1867 }, { 214,1867 },
 { 215,1867 }, { 216,1867 }, { 217,1867 }, { 218,1867 }, { 219,1867 },
 { 220,1867 }, { 221,1867 }, { 222,1867 }, { 223,1867 }, { 224,1867 },
 { 225,1867 }, { 226,1867 }, { 227,1867 }, { 228,1867 }, { 229,1867 },
 { 230,1867 }, { 231,1867 }, { 232,1867 }, { 233,1867 }, { 234,1867 },
 { 235,1867 }, { 236,1867 }, { 237,1867 }, { 238,1867 }, { 239,1867 },
 { 240,1867 }, { 241,1867 }, { 242,1867 }, { 243,1867 }, { 244,1867 },

 { 245,1867 }, { 246,1867 }, { 247,1867 }, { 248,1867 }, { 249,1867 },
 { 250,1867 }, { 251,1867 }, { 252,1867 }, { 253,1867 }, { 254,1867 },
 { 255,1867 }, { 256,1867 }, {   0,   0 }, {   0,31587 }, {   1,5945 },
 {   2,5945 }, {   3,5945 }, {   4,5945 }, {   5,5945 }, {   6,5945 },
 {   7,5945 }, {   8,5945 }, {   9,5945 }, {  10,5945 }, {  11,5945 },
 {  12,5945 }, {  13,5945 }, {  14,5945 }, {  15,5945 }, {  16,5945 },
 {  17,5945 }, {  18,5945 }, {  19,5945 }, {  20,5945 }, {  21,5945 },
 {  22,5945 }, {  23,5945 }, {  24,5945 }, {  25,5945 }, {  26,5945 },
 {  27,5945 }, {  28,5945 }, {  29,5945 }, {  30,5945 }, {  31,5945 },
 {  32,5945 }, {  33,5945 }, {  34,5945 }, {  35,5945 }, {  36,5945 },

 {  37,5945 }, {  38,5945 }, {  39,7023 }, {  40,5945 }, {  41,5945 },
 {  42,5945 }, {  43,5945 }, {  44,5945 }, {  45,5945 }, {  46,5945 },
 {  47,5945 }, {  48,5945 }, {  49,5945 }, {  50,5945 }, {  51,5945 },
 {  52,5945 }, {  53,5945 }, {  54,5945 }, {  55,5945 }, {  56,5945 },
 {  57,5945 }, {  58,5945 }, {  59,5945 }, {  60,5945 }, {  61,5945 },
 {  62,5945 }, {  63,5945 }, {  64,5945 }, {  65,5945 }, {  66,5945 },
 {  67,5945 }, {  68,5945 }, {  69,5945 }, {  70,5945 }, {  71,5945 },
 {  72,5945 }, {  73,5945 }, {  74,5945 }, {  75,5945 }, {  76,5945 },
 {  77,5945 }, {  78,5945 }, {  79,5945 }, {  80,5945 }, {  81,5945 },
 {  82,5945 }, {  83,5945 }, {  84,5945 }, {  85,5945 }, {  86,5945 },

 {  87,5945 }, {  88,5945 }, {  89,5945 }, {  90,5945 }, {  91,5945 },
 {  92,5945 }, {  93,5945 }, {  94,5945 }, {  95,5945 }, {  96,5945 },
 {  97,5945 }, {  98,5945 }, {  99,5945 }, { 100,5945 }, { 101,5945 },
 { 102,5945 }, { 103,5945 }, { 104,5945 }, { 105,5945 }, { 106,5945 },
 { 107,5945 }, { 108,5945 }, { 109,5945 }, { 110,5945 }, { 111,5945 },
 { 112,5945 }, { 113,5945 }, { 114,5945 }, { 115,5945 }, { 116,5945 },
 { 117,5945 }, { 118,5945 }, { 119,5945 }, { 120,5945 }, { 121,5945 },
 { 122,5945 }, { 123,5945 }, { 124,5945 }, { 125,5945 }, { 126,5945 },
 { 127,5945 }, { 128,5945 }, { 129,5945 }, { 130,5945 }, { 131,5945 },
 { 132,5945 }, { 133,5945 }, { 134,5945 }, { 135,5945 }, { 136,5945 },

 { 137,5945 }, { 138,5945 }, { 139,5945 }, { 140,5945 }, { 141,5945 },
 { 142,5945 }, { 143,5945 }, { 144,5945 }, { 145,5945 }, { 146,5945 },
 { 147,5945 }, { 148,5945 }, { 149,5945 }, { 150,5945 }, { 151,5945 },
 { 152,5945 }, { 153,5945 }, { 154,5945 }, { 155,5945 }, { 156,5945 },
 { 157,5945 }, { 158,5945 }, { 159,5945 }, { 160,5945 }, { 161,5945 },
 { 162,5945 }, { 163,5945 }, { 164,5945 }, { 165,5945 }, { 166,5945 },
 { 167,5945 }, { 168,5945 }, { 169,5945 }, { 170,5945 }, { 171,5945 },
 { 172,5945 }, { 173,5945 }, { 174,5945 }, { 175,5945 }, { 176,5945 },
 { 177,5945 }, { 178,5945 }, { 179,5945 }, { 180,5945 }, { 181,5945 },
 { 182,5945 }, { 183,5945 }, { 184,5945 }, { 185,5945 }, { 186,5945 },

 { 187,5945 }, { 188,5945 }, { 189,5945 }, { 190,5945 }, { 191,5945 },
 { 192,5945 }, { 193,5945 }, { 194,5945 }, { 195,5945 }, { 196,5945 },
 { 197,5945 }, { 198,5945 }, { 199,5945 }, { 200,5945 }, { 201,5945 },
 { 202,5945 }, { 203,5945 }, { 204,5945 }, { 205,5945 }, { 206,5945 },
 { 207,5945 }, { 208,5945 }, { 209,5945 }, { 210,5945 }, { 211,5945 },
 { 212,5945 }, { 213,5945 }, { 214,5945 }, { 215,5945 }, { 216,5945 },
 { 217,5945 }, { 218,5945 }, { 219,5945 }, { 220,5945 }, { 221,5945 },
 { 222,5945 }, { 223,5945 }, { 224,5945 }, { 225,5945 }, { 226,5945 },
 { 227,5945 }, { 228,5945 }, { 229,5945 }, { 230,5945 }, { 231,5945 },
 { 232,5945 }, { 233,5945 }, { 234,5945 }, { 235,5945 }, { 236,5945 },

 { 237,5945 }, { 238,5945 }, { 239,5945 }, { 240,5945 }, { 241,5945 },
 { 242,5945 }, { 243,5945 }, { 244,5945 }, { 245,5945 }, { 246,5945 },
 { 247,5945 }, { 248,5945 }, { 249,5945 }, { 250,5945 }, { 251,5945 },
 { 252,5945 }, { 253,5945 }, { 254,5945 }, { 255,5945 }, { 256,5945 },
 {   0,   0 }, {   0,31329 }, {   1,5687 }, {   2,5687 }, {   3,5687 },
 {   4,5687 }, {   5,5687 }, {   6,5687 }, {   7,5687 }, {   8,5687 },
 {   9,5687 }, {  10,5687 }, {  11,5687 }, {  12,5687 }, {  13,5687 },
 {  14,5687 }, {  15,5687 }, {  16,5687 }, {  17,5687 }, {  18,5687 },
 {  19,5687 }, {  20,5687 }, {  21,5687 }, {  22,5687 }, {  23,5687 },
 {  24,5687 }, {  25,5687 }, {  26,5687 }, {  27,5687 }, {  28,5687 },

 {  29,5687 }, {  30,5687 }, {  31,5687 }, {  32,5687 }, {  33,5687 },
 {  34,5687 }, {  35,5687 }, {  36,5687 }, {  37,5687 }, {  38,5687 },
 {  39,6765 }, {  40,5687 }, {  41,5687 }, {  42,5687 }, {  43,5687 },
 {  44,5687 }, {  45,5687 }, {  46,5687 }, {  47,5687 }, {  48,5687 },
 {  49,5687 }, {  50,5687 }, {  51,5687 }, {  52,5687 }, {  53,5687 },
 {  54,5687 }, {  55,5687 }, {  56,5687 }, {  57,5687 }, {  58,5687 },
 {  59,5687 }, {  60,5687 }, {  61,5687 }, {  62,5687 }, {  63,5687 },
 {  64,5687 }, {  65,5687 }, {  66,5687 }, {  67,5687 }, {  68,5687 },
 {  69,5687 }, {  70,5687 }, {  71,5687 }, {  72,5687 }, {  73,5687 },
 {  74,5687 }, {  75,5687 }, {  76,5687 }, {  77,5687 }, {  78,5687 },

 {  79,5687 }, {  80,5687 }, {  81,5687 }, {  82,5687 }, {  83,5687 },
 {  84,5687 }, {  85,5687 }, {  86,5687 }, {  87,5687 }, {  88,5687 },
 {  89,5687 }, {  90,5687 }, {  91,5687 }, {  92,5687 }, {  93,5687 },
 {  94,5687 }, {  95,5687 }, {  96,5687 }, {  97,5687 }, {  98,5687 },
 {  99,5687 }, { 100,5687 }, { 101,5687 }, { 102,5687 }, { 103,5687 },
 { 104,5687 }, { 105,5687 }, { 106,5687 }, { 107,5687 }, { 108,5687 },
 { 109,5687 }, { 110,5687 }, { 111,5687 }, { 112,5687 }, { 113,5687 },
 { 114,5687 }, { 115,5687 }, { 116,5687 }, { 117,5687 }, { 118,5687 },
 { 119,5687 }, { 120,5687 }, { 121,5687 }, { 122,5687 }, { 123,5687 },
 { 124,5687 }, { 125,5687 }, { 126,5687 }, { 127,5687 }, { 128,5687 },

 { 129,5687 }, { 130,5687 }, { 131,5687 }, { 132,5687 }, { 133,5687 },
 { 134,5687 }, { 135,5687 }, { 136,5687 }, { 137,5687 }, { 138,5687 },
 { 139,5687 }, { 140,5687 }, { 141,5687 }, { 142,5687 }, { 143,5687 },
 { 144,5687 }, { 145,5687 }, { 146,5687 }, { 147,5687 }, { 148,5687 },
 { 149,5687 }, { 150,5687 }, { 151,5687 }, { 152,5687 }, { 153,5687 },
 { 154,5687 }, { 155,5687 }, { 156,5687 }, { 157,5687 }, { 158,5687 },
 { 159,5687 }, { 160,5687 }, { 161,5687 }, { 162,5687 }, { 163,5687 },
 { 164,5687 }, { 165,5687 }, { 166,5687 }, { 167,5687 }, { 168,5687 },
 { 169,5687 }, { 170,5687 }, { 171,5687 }, { 172,5687 }, { 173,5687 },
 { 174,5687 }, { 175,5687 }, { 176,5687 }, { 177,5687 }, { 178,5687 },

 { 179,5687 }, { 180,5687 }, { 181,5687 }, { 182,5687 }, { 183,5687 },
 { 184,5687 }, { 185,5687 }, { 186,5687 }, { 187,5687 }, { 188,5687 },
 { 189,5687 }, { 190,5687 }, { 191,5687 }, { 192,5687 }, { 193,5687 },
 { 194,5687 }, { 195,5687 }, { 196,5687 }, { 197,5687 }, { 198,5687 },
 { 199,5687 }, { 200,5687 }, { 201,5687 }, { 202,5687 }, { 203,5687 },
 { 204,5687 }, { 205,5687 }, { 206,5687 }, { 207,5687 }, { 208,5687 },
 { 209,5687 }, { 210,5687 }, { 211,5687 }, { 212,5687 }, { 213,5687 },
 { 214,5687 }, { 215,5687 }, { 216,5687 }, { 217,5687 }, { 218,5687 },
 { 219,5687 }, { 220,5687 }, { 221,5687 }, { 222,5687 }, { 223,5687 },
 { 224,5687 }, { 225,5687 }, { 226,5687 }, { 227,5687 }, { 228,5687 },

 { 229,5687 }, { 230,5687 }, { 231,5687 }, { 232,5687 }, { 233,5687 },
 { 234,5687 }, { 235,5687 }, { 236,5687 }, { 237,5687 }, { 238,5687 },
 { 239,5687 }, { 240,5687 }, { 241,5687 }, { 242,5687 }, { 243,5687 },
 { 244,5687 }, { 245,5687 }, { 246,5687 }, { 247,5687 }, { 248,5687 },
 { 249,5687 }, { 250,5687 }, { 251,5687 }, { 252,5687 }, { 253,5687 },
 { 254,5687 }, { 255,5687 }, { 256,5687 }, {   0,  28 }, {   0,31071 },
 {   1,1113 }, {   2,1113 }, {   3,1113 }, {   4,1113 }, {   5,1113 },
 {   6,1113 }, {   7,1113 }, {   8,1113 }, {   9,6512 }, {  10,6528 },
 {  11,1113 }, {  12,6512 }, {  13,6512 }, {  14,1113 }, {  15,1113 },
 {  16,1113 }, {  17,1113 }, {  18,1113 }, {  19,1113 }, {  20,1113 },

 {  21,1113 }, {  22,1113 }, {  23,1113 }, {  24,1113 }, {  25,1113 },
 {  26,1113 }, {  27,1113 }, {  28,1113 }, {  29,1113 }, {  30,1113 },
 {  31,1113 }, {  32,6512 }, {  33,1113 }, {  34,1113 }, {  35,1113 },
 {  36,1113 }, {  37,1113 }, {  38,1113 }, {  39,1113 }, {  40,1113 },
 {  41,1113 }, {  42,1113 }, {  43,1113 }, {  44,1113 }, {  45,1131 },
 {  46,1113 }, {  47,1113 }, {  48,1113 }, {  49,1113 }, {  50,1113 },
 {  51,1113 }, {  52,1113 }, {  53,1113 }, {  54,1113 }, {  55,1113 },
 {  56,1113 }, {  57,1113 }, {  58,1113 }, {  59,1113 }, {  60,1113 },
 {  61,1113 }, {  62,1113 }, {  63,1113 }, {  64,1113 }, {  65,1113 },
 {  66,1113 }, {  67,1113 }, {  68,1113 }, {  69,1113 }, {  70,1113 },

 {  71,1113 }, {  72,1113 }, {  73,1113 }, {  74,1113 }, {  75,1113 },
 {  76,1113 }, {  77,1113 }, {  78,1113 }, {  79,1113 }, {  80,1113 },
 {  81,1113 }, {  82,1113 }, {  83,1113 }, {  84,1113 }, {  85,1139 },
 {  86,1113 }, {  87,1113 }, {  88,1113 }, {  89,1113 }, {  90,1113 },
 {  91,1113 }, {  92,1113 }, {  93,1113 }, {  94,1113 }, {  95,1113 },
 {  96,1113 }, {  97,1113 }, {  98,1113 }, {  99,1113 }, { 100,1113 },
 { 101,1113 }, { 102,1113 }, { 103,1113 }, { 104,1113 }, { 105,1113 },
 { 106,1113 }, { 107,1113 }, { 108,1113 }, { 109,1113 }, { 110,1113 },
 { 111,1113 }, { 112,1113 }, { 113,1113 }, { 114,1113 }, { 115,1113 },
 { 116,1113 }, { 117,1139 }, { 118,1113 }, { 119,1113 }, { 120,1113 },

 { 121,1113 }, { 122,1113 }, { 123,1113 }, { 124,1113 }, { 125,1113 },
 { 126,1113 }, { 127,1113 }, { 128,1113 }, { 129,1113 }, { 130,1113 },
 { 131,1113 }, { 132,1113 }, { 133,1113 }, { 134,1113 }, { 135,1113 },
 { 136,1113 }, { 137,1113 }, { 138,1113 }, { 139,1113 }, { 140,1113 },
 { 141,1113 }, { 142,1113 }, { 143,1113 }, { 144,1113 }, { 145,1113 },
 { 146,1113 }, { 147,1113 }, { 148,1113 }, { 149,1113 }, { 150,1113 },
 { 151,1113 }, { 152,1113 }, { 153,1113 }, { 154,1113 }, { 155,1113 },
 { 156,1113 }, { 157,1113 }, { 158,1113 }, { 159,1113 }, { 160,1113 },
 { 161,1113 }, { 162,1113 }, { 163,1113 }, { 164,1113 }, { 165,1113 },
 { 166,1113 }, { 167,1113 }, { 168,1113 }, { 169,1113 }, { 170,1113 },

 { 171,1113 }, { 172,1113 }, { 173,1113 }, { 174,1113 }, { 175,1113 },
 { 176,1113 }, { 177,1113 }, { 178,1113 }, { 179,1113 }, { 180,1113 },
 { 181,1113 }, { 182,1113 }, { 183,1113 }, { 184,1113 }, { 185,1113 },
 { 186,1113 }, { 187,1113 }, { 188,1113 }, { 189,1113 }, { 190,1113 },
 { 191,1113 }, { 192,1113 }, { 193,1113 }, { 194,1113 }, { 195,1113 },
 { 196,1113 }, { 197,1113 }, { 198,1113 }, { 199,1113 }, { 200,1113 },
 { 201,1113 }, { 202,1113 }, { 203,1113 }, { 204,1113 }, { 205,1113 },
 { 206,1113 }, { 207,1113 }, { 208,1113 }, { 209,1113 }, { 210,1113 },
 { 211,1113 }, { 212,1113 }, { 213,1113 }, { 214,1113 }, { 215,1113 },
 { 216,1113 }, { 217,1113 }, { 218,1113 }, { 219,1113 }, { 220,1113 },

 { 221,1113 }, { 222,1113 }, { 223,1113 }, { 224,1113 }, { 225,1113 },
 { 226,1113 }, { 227,1113 }, { 228,1113 }, { 229,1113 }, { 230,1113 },
 { 231,1113 }, { 232,1113 }, { 233,1113 }, { 234,1113 }, { 235,1113 },
 { 236,1113 }, { 237,1113 }, { 238,1113 }, { 239,1113 }, { 240,1113 },
 { 241,1113 }, { 242,1113 }, { 243,1113 }, { 244,1113 }, { 245,1113 },
 { 246,1113 }, { 247,1113 }, { 248,1113 }, { 249,1113 }, { 250,1113 },
 { 251,1113 }, { 252,1113 }, { 253,1113 }, { 254,1113 }, { 255,1113 },
 { 256,1113 }, {   0,  28 }, {   0,30813 }, {   1, 855 }, {   2, 855 },
 {   3, 855 }, {   4, 855 }, {   5, 855 }, {   6, 855 }, {   7, 855 },
 {   8, 855 }, {   9,6254 }, {  10,6270 }, {  11, 855 }, {  12,6254 },

 {  13,6254 }, {  14, 855 }, {  15, 855 }, {  16, 855 }, {  17, 855 },
 {  18, 855 }, {  19, 855 }, {  20, 855 }, {  21, 855 }, {  22, 855 },
 {  23, 855 }, {  24, 855 }, {  25, 855 }, {  26, 855 }, {  27, 855 },
 {  28, 855 }, {  29, 855 }, {  30, 855 }, {  31, 855 }, {  32,6254 },
 {  33, 855 }, {  34, 855 }, {  35, 855 }, {  36, 855 }, {  37, 855 },
 {  38, 855 }, {  39, 855 }, {  40, 855 }, {  41, 855 }, {  42, 855 },
 {  43, 855 }, {  44, 855 }, {  45, 873 }, {  46, 855 }, {  47, 855 },
 {  48, 855 }, {  49, 855 }, {  50, 855 }, {  51, 855 }, {  52, 855 },
 {  53, 855 }, {  54, 855 }, {  55, 855 }, {  56, 855 }, {  57, 855 },
 {  58, 855 }, {  59, 855 }, {  60, 855 }, {  61, 855 }, {  62, 855 },

 {  63, 855 }, {  64, 855 }, {  65, 855 }, {  66, 855 }, {  67, 855 },
 {  68, 855 }, {  69, 855 }, {  70, 855 }, {  71, 855 }, {  72, 855 },
 {  73, 855 }, {  74, 855 }, {  75, 855 }, {  76, 855 }, {  77, 855 },
 {  78, 855 }, {  79, 855 }, {  80, 855 }, {  81, 855 }, {  82, 855 },
 {  83, 855 }, {  84, 855 }, {  85, 881 }, {  86, 855 }, {  87, 855 },
 {  88, 855 }, {  89, 855 }, {  90, 855 }, {  91, 855 }, {  92, 855 },
 {  93, 855 }, {  94, 855 }, {  95, 855 }, {  96, 855 }, {  97, 855 },
 {  98, 855 }, {  99, 855 }, { 100, 855 }, { 101, 855 }, { 102, 855 },
 { 103, 855 }, { 104, 855 }, { 105, 855 }, { 106, 855 }, { 107, 855 },
 { 108, 855 }, { 109, 855 }, { 110, 855 }, { 111, 855 }, { 112, 855 },

 { 113, 855 }, { 114, 855 }, { 115, 855 }, { 116, 855 }, { 117, 881 },
 { 118, 855 }, { 119, 855 }, { 120, 855 }, { 121, 855 }, { 122, 855 },
 { 123, 855 }, { 124, 855 }, { 125, 855 }, { 126, 855 }, { 127, 855 },
 { 128, 855 }, { 129, 855 }, { 130, 855 }, { 131, 855 }, { 132, 855 },
 { 133, 855 }, { 134, 855 }, { 135, 855 }, { 136, 855 }, { 137, 855 },
 { 138, 855 }, { 139, 855 }, { 140, 855 }, { 141, 855 }, { 142, 855 },
 { 143, 855 }, { 144, 855 }, { 145, 855 }, { 146, 855 }, { 147, 855 },
 { 148, 855 }, { 149, 855 }, { 150, 855 }, { 151, 855 }, { 152, 855 },
 { 153, 855 }, { 154, 855 }, { 155, 855 }, { 156, 855 }, { 157, 855 },
 { 158, 855 }, { 159, 855 }, { 160, 855 }, { 161, 855 }, { 162, 855 },

 { 163, 855 }, { 164, 855 }, { 165, 855 }, { 166, 855 }, { 167, 855 },
 { 168, 855 }, { 169, 855 }, { 170, 855 }, { 171, 855 }, { 172, 855 },
 { 173, 855 }, { 174, 855 }, { 175, 855 }, { 176, 855 }, { 177, 855 },
 { 178, 855 }, { 179, 855 }, { 180, 855 }, { 181, 855 }, { 182, 855 },
 { 183, 855 }, { 184, 855 }, { 185, 855 }, { 186, 855 }, { 187, 855 },
 { 188, 855 }, { 189, 855 }, { 190, 855 }, { 191, 855 }, { 192, 855 },
 { 193, 855 }, { 194, 855 }, { 195, 855 }, { 196, 855 }, { 197, 855 },
 { 198, 855 }, { 199, 855 }, { 200, 855 }, { 201, 855 }, { 202, 855 },
 { 203, 855 }, { 204, 855 }, { 205, 855 }, { 206, 855 }, { 207, 855 },
 { 208, 855 }, { 209, 855 }, { 210, 855 }, { 211, 855 }, { 212, 855 },

 { 213, 855 }, { 214, 855 }, { 215, 855 }, { 216, 855 }, { 217, 855 },
 { 218, 855 }, { 219, 855 }, { 220, 855 }, { 221, 855 }, { 222, 855 },
 { 223, 855 }, { 224, 855 }, { 225, 855 }, { 226, 855 }, { 227, 855 },
 { 228, 855 }, { 229, 855 }, { 230, 855 }, { 231, 855 }, { 232, 855 },
 { 233, 855 }, { 234, 855 }, { 235, 855 }, { 236, 855 }, { 237, 855 },
 { 238, 855 }, { 239, 855 }, { 240, 855 }, { 241, 855 }, { 242, 855 },
 { 243, 855 }, { 244, 855 }, { 245, 855 }, { 246, 855 }, { 247, 855 },
 { 248, 855 }, { 249, 855 }, { 250, 855 }, { 251, 855 }, { 252, 855 },
 { 253, 855 }, { 254, 855 }, { 255, 855 }, { 256, 855 }, {   0,   0 },
 {   0,30555 }, {   1, 633 }, {   2, 633 }, {   3, 633 }, {   4, 633 },

 {   5, 633 }, {   6, 633 }, {   7, 633 }, {   8, 633 }, {   9, 633 },
 {  10, 635 }, {  11, 633 }, {  12, 633 }, {  13, 633 }, {  14, 633 },
 {  15, 633 }, {  16, 633 }, {  17, 633 }, {  18, 633 }, {  19, 633 },
 {  20, 633 }, {  21, 633 }, {  22, 633 }, {  23, 633 }, {  24, 633 },
 {  25, 633 }, {  26, 633 }, {  27, 633 }, {  28, 633 }, {  29, 633 },
 {  30, 633 }, {  31, 633 }, {  32, 633 }, {  33, 633 }, {  34, 633 },
 {  35, 633 }, {  36, 633 }, {  37, 633 }, {  38, 633 }, {  39, 633 },
 {  40, 633 }, {  41, 633 }, {  42, 633 }, {  43, 633 }, {  44, 633 },
 {  45, 633 }, {  46, 633 }, {  47, 633 }, {  48, 633 }, {  49, 633 },
 {  50, 633 }, {  51, 633 }, {  52, 633 }, {  53, 633 }, {  54, 633 },

 {  55, 633 }, {  56, 633 }, {  57, 633 }, {  58, 633 }, {  59, 633 },
 {  60, 633 }, {  61, 633 }, {  62, 633 }, {  63, 633 }, {  64, 633 },
 {  65, 633 }, {  66, 633 }, {  67, 633 }, {  68, 633 }, {  69, 633 },
 {  70, 633 }, {  71, 633 }, {  72, 633 }, {  73, 633 }, {  74, 633 },
 {  75, 633 }, {  76, 633 }, {  77, 633 }, {  78, 633 }, {  79, 633 },
 {  80, 633 }, {  81, 633 }, {  82, 633 }, {  83, 633 }, {  84, 633 },
 {  85, 633 }, {  86, 633 }, {  87, 633 }, {  88, 633 }, {  89, 633 },
 {  90, 633 }, {  91, 633 }, {  92, 637 }, {  93, 633 }, {  94, 633 },
 {  95, 633 }, {  96, 633 }, {  97, 633 }, {  98, 633 }, {  99, 633 },
 { 100, 633 }, { 101, 633 }, { 102, 633 }, { 103, 633 }, { 104, 633 },

 { 105, 633 }, { 106, 633 }, { 107, 633 }, { 108, 633 }, { 109, 633 },
 { 110, 633 }, { 111, 633 }, { 112, 633 }, { 113, 633 }, { 114, 633 },
 { 115, 633 }, { 116, 633 }, { 117, 633 }, { 118, 633 }, { 119, 633 },
 { 120, 633 }, { 121, 633 }, { 122, 633 }, { 123, 633 }, { 124, 633 },
 { 125, 633 }, { 126, 633 }, { 127, 633 }, { 128, 633 }, { 129, 633 },
 { 130, 633 }, { 131, 633 }, { 132, 633 }, { 133, 633 }, { 134, 633 },
 { 135, 633 }, { 136, 633 }, { 137, 633 }, { 138, 633 }, { 139, 633 },
 { 140, 633 }, { 141, 633 }, { 142, 633 }, { 143, 633 }, { 144, 633 },
 { 145, 633 }, { 146, 633 }, { 147, 633 }, { 148, 633 }, { 149, 633 },
 { 150, 633 }, { 151, 633 }, { 152, 633 }, { 153, 633 }, { 154, 633 },

 { 155, 633 }, { 156, 633 }, { 157, 633 }, { 158, 633 }, { 159, 633 },
 { 160, 633 }, { 161, 633 }, { 162, 633 }, { 163, 633 }, { 164, 633 },
 { 165, 633 }, { 166, 633 }, { 167, 633 }, { 168, 633 }, { 169, 633 },
 { 170, 633 }, { 171, 633 }, { 172, 633 }, { 173, 633 }, { 174, 633 },
 { 175, 633 }, { 176, 633 }, { 177, 633 }, { 178, 633 }, { 179, 633 },
 { 180, 633 }, { 181, 633 }, { 182, 633 }, { 183, 633 }, { 184, 633 },
 { 185, 633 }, { 186, 633 }, { 187, 633 }, { 188, 633 }, { 189, 633 },
 { 190, 633 }, { 191, 633 }, { 192, 633 }, { 193, 633 }, { 194, 633 },
 { 195, 633 }, { 196, 633 }, { 197, 633 }, { 198, 633 }, { 199, 633 },
 { 200, 633 }, { 201, 633 }, { 202, 633 }, { 203, 633 }, { 204, 633 },

 { 205, 633 }, { 206, 633 }, { 207, 633 }, { 208, 633 }, { 209, 633 },
 { 210, 633 }, { 211, 633 }, { 212, 633 }, { 213, 633 }, { 214, 633 },
 { 215, 633 }, { 216, 633 }, { 217, 633 }, { 218, 633 }, { 219, 633 },
 { 220, 633 }, { 221, 633 }, { 222, 633 }, { 223, 633 }, { 224, 633 },
 { 225, 633 }, { 226, 633 }, { 227, 633 }, { 228, 633 }, { 229, 633 },
 { 230, 633 }, { 231, 633 }, { 232, 633 }, { 233, 633 }, { 234, 633 },
 { 235, 633 }, { 236, 633 }, { 237, 633 }, { 238, 633 }, { 239, 633 },
 { 240, 633 }, { 241, 633 }, { 242, 633 }, { 243, 633 }, { 244, 633 },
 { 245, 633 }, { 246, 633 }, { 247, 633 }, { 248, 633 }, { 249, 633 },
 { 250, 633 }, { 251, 633 }, { 252, 633 }, { 253, 633 }, { 254, 633 },

 { 255, 633 }, { 256, 633 }, {   0,   0 }, {   0,30297 }, {   1, 375 },
 {   2, 375 }, {   3, 375 }, {   4, 375 }, {   5, 375 }, {   6, 375 },
 {   7, 375 }, {   8, 375 }, {   9, 375 }, {  10, 377 }, {  11, 375 },
 {  12, 375 }, {  13, 375 }, {  14, 375 }, {  15, 375 }, {  16, 375 },
 {  17, 375 }, {  18, 375 }, {  19, 375 }, {  20, 375 }, {  21, 375 },
 {  22, 375 }, {  23, 375 }, {  24, 375 }, {  25, 375 }, {  26, 375 },
 {  27, 375 }, {  28, 375 }, {  29, 375 }, {  30, 375 }, {  31, 375 },
 {  32, 375 }, {  33, 375 }, {  34, 375 }, {  35, 375 }, {  36, 375 },
 {  37, 375 }, {  38, 375 }, {  39, 375 }, {  40, 375 }, {  41, 375 },
 {  42, 375 }, {  43, 375 }, {  44, 375 }, {  45, 375 }, {  46, 375 },

 {  47, 375 }, {  48, 375 }, {  49, 375 }, {  50, 375 }, {  51, 375 },
 {  52, 375 }, {  53, 375 }, {  54, 375 }, {  55, 375 }, {  56, 375 },
 {  57, 375 }, {  58, 375 }, {  59, 375 }, {  60, 375 }, {  61, 375 },
 {  62, 375 }, {  63, 375 }, {  64, 375 }, {  65, 375 }, {  66, 375 },
 {  67, 375 }, {  68, 375 }, {  69, 375 }, {  70, 375 }, {  71, 375 },
 {  72, 375 }, {  73, 375 }, {  74, 375 }, {  75, 375 }, {  76, 375 },
 {  77, 375 }, {  78, 375 }, {  79, 375 }, {  80, 375 }, {  81, 375 },
 {  82, 375 }, {  83, 375 }, {  84, 375 }, {  85, 375 }, {  86, 375 },
 {  87, 375 }, {  88, 375 }, {  89, 375 }, {  90, 375 }, {  91, 375 },
 {  92, 379 }, {  93, 375 }, {  94, 375 }, {  95, 375 }, {  96, 375 },

 {  97, 375 }, {  98, 375 }, {  99, 375 }, { 100, 375 }, { 101, 375 },
 { 102, 375 }, { 103, 375 }, { 104, 375 }, { 105, 375 }, { 106, 375 },
 { 107, 375 }, { 108, 375 }, { 109, 375 }, { 110, 375 }, { 111, 375 },
 { 112, 375 }, { 113, 375 }, { 114, 375 }, { 115, 375 }, { 116, 375 },
 { 117, 375 }, { 118, 375 }, { 119, 375 }, { 120, 375 }, { 121, 375 },
 { 122, 375 }, { 123, 375 }, { 124, 375 }, { 125, 375 }, { 126, 375 },
 { 127, 375 }, { 128, 375 }, { 129, 375 }, { 130, 375 }, { 131, 375 },
 { 132, 375 }, { 133, 375 }, { 134, 375 }, { 135, 375 }, { 136, 375 },
 { 137, 375 }, { 138, 375 }, { 139, 375 }, { 140, 375 }, { 141, 375 },
 { 142, 375 }, { 143, 375 }, { 144, 375 }, { 145, 375 }, { 146, 375 },

 { 147, 375 }, { 148, 375 }, { 149, 375 }, { 150, 375 }, { 151, 375 },
 { 152, 375 }, { 153, 375 }, { 154, 375 }, { 155, 375 }, { 156, 375 },
 { 157, 375 }, { 158, 375 }, { 159, 375 }, { 160, 375 }, { 161, 375 },
 { 162, 375 }, { 163, 375 }, { 164, 375 }, { 165, 375 }, { 166, 375 },
 { 167, 375 }, { 168, 375 }, { 169, 375 }, { 170, 375 }, { 171, 375 },
 { 172, 375 }, { 173, 375 }, { 174, 375 }, { 175, 375 }, { 176, 375 },
 { 177, 375 }, { 178, 375 }, { 179, 375 }, { 180, 375 }, { 181, 375 },
 { 182, 375 }, { 183, 375 }, { 184, 375 }, { 185, 375 }, { 186, 375 },
 { 187, 375 }, { 188, 375 }, { 189, 375 }, { 190, 375 }, { 191, 375 },
 { 192, 375 }, { 193, 375 }, { 194, 375 }, { 195, 375 }, { 196, 375 },

 { 197, 375 }, { 198, 375 }, { 199, 375 }, { 200, 375 }, { 201, 375 },
 { 202, 375 }, { 203, 375 }, { 204, 375 }, { 205, 375 }, { 206, 375 },
 { 207, 375 }, { 208, 375 }, { 209, 375 }, { 210, 375 }, { 211, 375 },
 { 212, 375 }, { 213, 375 }, { 214, 375 }, { 215, 375 }, { 216, 375 },
 { 217, 375 }, { 218, 375 }, { 219, 375 }, { 220, 375 }, { 221, 375 },
 { 222, 375 }, { 223, 375 }, { 224, 375 }, { 225, 375 }, { 226, 375 },
 { 227, 375 }, { 228, 375 }, { 229, 375 }, { 230, 375 }, { 231, 375 },
 { 232, 375 }, { 233, 375 }, { 234, 375 }, { 235, 375 }, { 236, 375 },
 { 237, 375 }, { 238, 375 }, { 239, 375 }, { 240, 375 }, { 241, 375 },
 { 242, 375 }, { 243, 375 }, { 244, 375 }, { 245, 375 }, { 246, 375 },

 { 247, 375 }, { 248, 375 }, { 249, 375 }, { 250, 375 }, { 251, 375 },
 { 252, 375 }, { 253, 375 }, { 254, 375 }, { 255, 375 }, { 256, 375 },
 {   0,  79 }, {   0,30039 }, {   0,   1 }, {   0,30037 }, {   0,  49 },
 {   0,30035 }, {   0,   0 }, {   0,   1 }, {   0,30032 }, {   0,  70 },
 {   0,30030 }, {   0,   0 }, {   9,5515 }, {  10,5515 }, {   0,   0 },
 {  12,5515 }, {  13,5515 }, {   9,5510 }, {  10,5510 }, {   0,   0 },
 {  12,5510 }, {  13,5510 }, {   0,  19 }, {   0,30017 }, {   0,  69 },
 {   0,30015 }, {   0,   0 }, {   0,  69 }, {   0,30012 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   6 }, {   0,30007 }, {   0,   0 },
 {  32,5515 }, {   0,   6 }, {   0,30003 }, {   0,   0 }, {   0,   0 },

 {  32,5510 }, {   0,  51 }, {   0,29998 }, {  33,5510 }, {   0,   0 },
 {  35,5510 }, {   0,   0 }, {  37,5510 }, {  38,5510 }, {   0,  70 },
 {   0,29990 }, {   0,   0 }, {  42,5510 }, {  43,5510 }, {   0,   0 },
 {  45,5510 }, {   0,   0 }, {  47,5510 }, {   0,   0 }, {   0,  52 },
 {   0,29980 }, {   0,  54 }, {   0,29978 }, {   0,  54 }, {   0,29976 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  60,5510 }, {  61,5550 }, {  62,5510 }, {  63,5510 }, {  64,5510 },
 {  42, 408 }, {  34, 420 }, {   0,  54 }, {   0,29962 }, {  42,7294 },
 {  47, 410 }, {   0,  27 }, {   0,29958 }, {  33,5470 }, {   0,   0 },
 {  35,5470 }, {  58, 100 }, {  37,5470 }, {  38,5470 }, {  61, 102 },

 {   0,   0 }, {   0,   0 }, {  42,5470 }, {  43,5470 }, {  34, 402 },
 {  45,5470 }, {   0,   0 }, {  47,5470 }, {   0,   0 }, {   0,  27 },
 {   0,29940 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  94,5510 },
 {   0,   0 }, {  96,5510 }, {   0,  27 }, {   0,29932 }, {  45,9179 },
 {  60,5470 }, {  61,5470 }, {  62,5470 }, {  63,5470 }, {  64,5470 },
 {   0,  79 }, {   0,29924 }, {   0,  35 }, {   0,29922 }, {   0,  36 },
 {   0,29920 }, {   0,  35 }, {   0,29918 }, {   0,  43 }, {   0,29916 },
 {   0,  62 }, {   0,29914 }, {   0,  61 }, {   0,29912 }, {   0,  63 },
 {   0,29910 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 124,5510 },
 {   0,   0 }, { 126,5510 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  94,5470 },
 {  45,9456 }, {  96,5470 }, {  69, 465 }, {   0,  78 }, {   0,29891 },
 {   0,   8 }, {   0,29889 }, {  36,   8 }, {   0,  20 }, {   0,29886 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,5461 },
 {  49,5461 }, {  50,5461 }, {  51,5461 }, {  52,5461 }, {  53,5461 },
 {  54,5461 }, {  55,5461 }, {  56,5461 }, {  57,5461 }, { 124,5470 },
 {   0,   0 }, { 126,5470 }, {  69, 447 }, {   0,   0 }, { 101, 465 },
 {   0,   0 }, {  65,5523 }, {  66,5523 }, {  67,5523 }, {  68,5523 },
 {  69,5523 }, {  70,5523 }, {  71,5523 }, {  72,5523 }, {  73,5523 },

 {  74,5523 }, {  75,5523 }, {  76,5523 }, {  77,5523 }, {  78,5523 },
 {  79,5523 }, {  80,5523 }, {  81,5523 }, {  82,5523 }, {  83,5523 },
 {  84,5523 }, {  85,5523 }, {  86,5523 }, {  87,5523 }, {  88,5523 },
 {  89,5523 }, {  90,5523 }, {  85,9692 }, {   0,   0 }, { 101, 447 },
 {   0,   0 }, {  95,5523 }, {  63,   0 }, {  97,5523 }, {  98,5523 },
 {  99,5523 }, { 100,5523 }, { 101,5523 }, { 102,5523 }, { 103,5523 },
 { 104,5523 }, { 105,5523 }, { 106,5523 }, { 107,5523 }, { 108,5523 },
 { 109,5523 }, { 110,5523 }, { 111,5523 }, { 112,5523 }, { 113,5523 },
 { 114,5523 }, { 115,5523 }, { 116,5523 }, { 117,5523 }, { 118,5523 },
 { 119,5523 }, { 120,5523 }, { 121,5523 }, { 122,5523 }, { 117,9715 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 128,5523 },
 { 129,5523 }, { 130,5523 }, { 131,5523 }, { 132,5523 }, { 133,5523 },
 { 134,5523 }, { 135,5523 }, { 136,5523 }, { 137,5523 }, { 138,5523 },
 { 139,5523 }, { 140,5523 }, { 141,5523 }, { 142,5523 }, { 143,5523 },
 { 144,5523 }, { 145,5523 }, { 146,5523 }, { 147,5523 }, { 148,5523 },
 { 149,5523 }, { 150,5523 }, { 151,5523 }, { 152,5523 }, { 153,5523 },
 { 154,5523 }, { 155,5523 }, { 156,5523 }, { 157,5523 }, { 158,5523 },
 { 159,5523 }, { 160,5523 }, { 161,5523 }, { 162,5523 }, { 163,5523 },
 { 164,5523 }, { 165,5523 }, { 166,5523 }, { 167,5523 }, { 168,5523 },
 { 169,5523 }, { 170,5523 }, { 171,5523 }, { 172,5523 }, { 173,5523 },

 { 174,5523 }, { 175,5523 }, { 176,5523 }, { 177,5523 }, { 178,5523 },
 { 179,5523 }, { 180,5523 }, { 181,5523 }, { 182,5523 }, { 183,5523 },
 { 184,5523 }, { 185,5523 }, { 186,5523 }, { 187,5523 }, { 188,5523 },
 { 189,5523 }, { 190,5523 }, { 191,5523 }, { 192,5523 }, { 193,5523 },
 { 194,5523 }, { 195,5523 }, { 196,5523 }, { 197,5523 }, { 198,5523 },
 { 199,5523 }, { 200,5523 }, { 201,5523 }, { 202,5523 }, { 203,5523 },
 { 204,5523 }, { 205,5523 }, { 206,5523 }, { 207,5523 }, { 208,5523 },
 { 209,5523 }, { 210,5523 }, { 211,5523 }, { 212,5523 }, { 213,5523 },
 { 214,5523 }, { 215,5523 }, { 216,5523 }, { 217,5523 }, { 218,5523 },
 { 219,5523 }, { 220,5523 }, { 221,5523 }, { 222,5523 }, { 223,5523 },

 { 224,5523 }, { 225,5523 }, { 226,5523 }, { 227,5523 }, { 228,5523 },
 { 229,5523 }, { 230,5523 }, { 231,5523 }, { 232,5523 }, { 233,5523 },
 { 234,5523 }, { 235,5523 }, { 236,5523 }, { 237,5523 }, { 238,5523 },
 { 239,5523 }, { 240,5523 }, { 241,5523 }, { 242,5523 }, { 243,5523 },
 { 244,5523 }, { 245,5523 }, { 246,5523 }, { 247,5523 }, { 248,5523 },
 { 249,5523 }, { 250,5523 }, { 251,5523 }, { 252,5523 }, { 253,5523 },
 { 254,5523 }, { 255,5523 }, {   0,  69 }, {   0,29667 }, {   0,  60 },
 {   0,29665 }, {   0,  18 }, {   0,29663 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  69 }, {   0,29656 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  59 }, {   0,29651 },

 {   0,  15 }, {   0,29649 }, {   0,   0 }, {   0,  10 }, {   0,29646 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,  69 }, {   0,29637 }, {   0,   0 },
 {   0,   0 }, {  33,5147 }, {   0,   0 }, {  35,5147 }, {   0,   0 },
 {  37,5147 }, {  38,5147 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  42,5147 }, {  43,5147 }, {  33,5136 }, {  45,5147 }, {  35,5136 },
 {  47,5147 }, {  37,5136 }, {  38,5136 }, {  34, 170 }, {   0,   0 },
 {   0,   0 }, {  42,5136 }, {  43,5136 }, {  39, 172 }, {  45,5512 },
 {   0,   0 }, {  47,5136 }, {   0,   0 }, {  60,5147 }, {  61,5147 },
 {  62,5147 }, {  63,5147 }, {  64,5147 }, {  63,-226 }, {  45,10420 },

 {   0,   7 }, {   0,29599 }, {   0,   4 }, {   0,29597 }, {  60,5136 },
 {  61,5136 }, {  62,5136 }, {  63,5136 }, {  64,5136 }, {  46,-277 },
 {   0,   0 }, {  48,5751 }, {  49,5751 }, {  50,5751 }, {  51,5751 },
 {  52,5751 }, {  53,5751 }, {  54,5751 }, {  55,5751 }, {  56,5751 },
 {  57,5751 }, {   0,  57 }, {   0,29578 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  94,5147 }, {   0,   0 }, {  96,5147 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  69 }, {   0,29566 },
 {   0,  72 }, {   0,29564 }, {   0,   0 }, {  94,5136 }, {   0,   0 },
 {  96,5136 }, {   0,   0 }, {   0,   0 }, {  42,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  47,   2 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  17 }, {   0,29546 },
 {   0,  30 }, {   0,29544 }, { 124,5147 }, {   0,   0 }, { 126,5147 },
 {   0,  23 }, {   0,29539 }, {   0,  38 }, {   0,29537 }, {   0,  45 },
 {   0,29535 }, {   0,   0 }, {  33,5046 }, { 124,5136 }, {  35,5046 },
 { 126,5136 }, {  37,5046 }, {  38,5046 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  42,5705 }, {  43,5046 }, {   0,   0 }, {  45,5046 },
 {   0,   0 }, {  47,5046 }, {  46,5705 }, {   0,   0 }, {  48,5769 },
 {  49,5769 }, {  50,5769 }, {  51,5769 }, {  52,5769 }, {  53,5769 },
 {  54,5769 }, {  55,5769 }, {  56,5769 }, {  57,5769 }, {  60,5046 },
 {  61,5046 }, {  62,5046 }, {  63,5046 }, {  64,5046 }, {  45,10706 },

 {   0,  69 }, {   0,29499 }, {   0,  55 }, {   0,29497 }, {   0,   0 },
 {  69,5791 }, {  45,11004 }, {   0,  25 }, {   0,29492 }, {   0,   0 },
 {   0,   0 }, {   0,  69 }, {   0,29488 }, {   0,   0 }, {   0,  28 },
 {   0,29485 }, {   0,  74 }, {   0,29483 }, {   0,  50 }, {   0,29481 },
 {   0,  21 }, {   0,29479 }, {   0,  14 }, {   0,29477 }, {   0,  10 },
 {   0,29475 }, {   0,  13 }, {   0,29473 }, {  94,5046 }, {   0,   0 },
 {  96,5046 }, {   0,  17 }, {   0,29468 }, {   0,   0 }, {  33,4979 },
 {   0,   0 }, {  35,4979 }, { 101,5791 }, {  37,4979 }, {  38,4979 },
 {   0,  41 }, {   0,29459 }, {   0,   0 }, {  42,4979 }, {  43,4979 },
 {  33,4968 }, {  45,4979 }, {  35,4968 }, {  47,4979 }, {  37,4968 },

 {  38,4968 }, {   0,   0 }, {   0,   0 }, {  45,11918 }, {  42,4968 },
 {  43,4968 }, {   0,   0 }, {  45,4968 }, { 124,5046 }, {  47,4968 },
 { 126,5046 }, {  60,4979 }, {  61,5766 }, {  62,5807 }, {  63,4979 },
 {  64,4979 }, {   0,   0 }, {   0,  23 }, {   0,29432 }, {   0,   0 },
 {  45,12544 }, {   0,   0 }, {  60,4968 }, {  61,4968 }, {  62,5863 },
 {  63,4968 }, {  64,4968 }, {  45,13569 }, {   0,  69 }, {   0,29421 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  83, 100 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  94,4979 }, {   0,   0 }, {  96,4979 }, {  83, 377 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,  55 }, {   0,29397 }, {   0,  25 },
 {   0,29395 }, {  94,4968 }, {   0,   0 }, {  96,4968 }, {   0,   0 },
 {   0,  78 }, {   0,29389 }, {  33,4901 }, {  45,14565 }, {  35,4901 },
 {   0,   0 }, {  37,4901 }, {  38,4901 }, { 115, 100 }, {   0,   0 },
 {   0,   0 }, {  42,4901 }, {  43,4901 }, {   0,   0 }, {  45,4901 },
 { 124,4979 }, {  47,4901 }, { 126,4979 }, {   0,   0 }, {   0,   0 },
 { 115, 377 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, { 124,4968 }, {   0,   0 }, { 126,4968 }, {  60,4901 },
 {  61,5807 }, {  62,4901 }, {  63,4901 }, {  64,4901 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  36,5855 }, {   0,   0 }, {   0,   0 },

 {  45,15687 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,5855 },
 {  49,5855 }, {  50,5855 }, {  51,5855 }, {  52,5855 }, {  53,5855 },
 {  54,5855 }, {  55,5855 }, {  56,5855 }, {  57,5855 }, {   0,   0 },
 {  67, 548 }, {   0,   0 }, {   0,   0 }, {  94,4901 }, {  63,-502 },
 {  96,4901 }, {  65,5855 }, {  66,5855 }, {  67,5855 }, {  68,5855 },
 {  69,5855 }, {  70,5855 }, {  71,5855 }, {  72,5855 }, {  73,5855 },
 {  74,5855 }, {  75,5855 }, {  76,5855 }, {  77,5855 }, {  78,5855 },
 {  79,5855 }, {  80,5855 }, {  81,5855 }, {  82,5855 }, {  83,5855 },
 {  84,5855 }, {  85,5855 }, {  86,5855 }, {  87,5855 }, {  88,5855 },

 {  89,5855 }, {  90,5855 }, {  99, 548 }, { 124,4901 }, {   0,   0 },
 { 126,4901 }, {  95,5855 }, {   0,   0 }, {  97,5855 }, {  98,5855 },
 {  99,5855 }, { 100,5855 }, { 101,5855 }, { 102,5855 }, { 103,5855 },
 { 104,5855 }, { 105,5855 }, { 106,5855 }, { 107,5855 }, { 108,5855 },
 { 109,5855 }, { 110,5855 }, { 111,5855 }, { 112,5855 }, { 113,5855 },
 { 114,5855 }, { 115,5855 }, { 116,5855 }, { 117,5855 }, { 118,5855 },
 { 119,5855 }, { 120,5855 }, { 121,5855 }, { 122,5855 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 128,5855 },
 { 129,5855 }, { 130,5855 }, { 131,5855 }, { 132,5855 }, { 133,5855 },
 { 134,5855 }, { 135,5855 }, { 136,5855 }, { 137,5855 }, { 138,5855 },

 { 139,5855 }, { 140,5855 }, { 141,5855 }, { 142,5855 }, { 143,5855 },
 { 144,5855 }, { 145,5855 }, { 146,5855 }, { 147,5855 }, { 148,5855 },
 { 149,5855 }, { 150,5855 }, { 151,5855 }, { 152,5855 }, { 153,5855 },
 { 154,5855 }, { 155,5855 }, { 156,5855 }, { 157,5855 }, { 158,5855 },
 { 159,5855 }, { 160,5855 }, { 161,5855 }, { 162,5855 }, { 163,5855 },
 { 164,5855 }, { 165,5855 }, { 166,5855 }, { 167,5855 }, { 168,5855 },
 { 169,5855 }, { 170,5855 }, { 171,5855 }, { 172,5855 }, { 173,5855 },
 { 174,5855 }, { 175,5855 }, { 176,5855 }, { 177,5855 }, { 178,5855 },
 { 179,5855 }, { 180,5855 }, { 181,5855 }, { 182,5855 }, { 183,5855 },
 { 184,5855 }, { 185,5855 }, { 186,5855 }, { 187,5855 }, { 188,5855 },

 { 189,5855 }, { 190,5855 }, { 191,5855 }, { 192,5855 }, { 193,5855 },
 { 194,5855 }, { 195,5855 }, { 196,5855 }, { 197,5855 }, { 198,5855 },
 { 199,5855 }, { 200,5855 }, { 201,5855 }, { 202,5855 }, { 203,5855 },
 { 204,5855 }, { 205,5855 }, { 206,5855 }, { 207,5855 }, { 208,5855 },
 { 209,5855 }, { 210,5855 }, { 211,5855 }, { 212,5855 }, { 213,5855 },
 { 214,5855 }, { 215,5855 }, { 216,5855 }, { 217,5855 }, { 218,5855 },
 { 219,5855 }, { 220,5855 }, { 221,5855 }, { 222,5855 }, { 223,5855 },
 { 224,5855 }, { 225,5855 }, { 226,5855 }, { 227,5855 }, { 228,5855 },
 { 229,5855 }, { 230,5855 }, { 231,5855 }, { 232,5855 }, { 233,5855 },
 { 234,5855 }, { 235,5855 }, { 236,5855 }, { 237,5855 }, { 238,5855 },

 { 239,5855 }, { 240,5855 }, { 241,5855 }, { 242,5855 }, { 243,5855 },
 { 244,5855 }, { 245,5855 }, { 246,5855 }, { 247,5855 }, { 248,5855 },
 { 249,5855 }, { 250,5855 }, { 251,5855 }, { 252,5855 }, { 253,5855 },
 { 254,5855 }, { 255,5855 }, {   0,  78 }, {   0,29132 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  28 }, {   0,29108 }, {   0,  39 }, {   0,29106 },
 {   0,  40 }, {   0,29104 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  36,5598 },
 {   0,   0 }, {   0,   0 }, {  39,-757 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  48,5598 }, {  49,5598 }, {  50,5598 }, {  51,5598 },
 {  52,5598 }, {  53,5598 }, {  54,5598 }, {  55,5598 }, {  56,5598 },
 {  57,5598 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  63,-759 }, {   0,   0 }, {  65,5598 }, {  66,5598 },
 {  67,5598 }, {  68,5598 }, {  69,5598 }, {  70,5598 }, {  71,5598 },
 {  72,5598 }, {  73,5598 }, {  74,5598 }, {  75,5598 }, {  76,5598 },
 {  77,5598 }, {  78,5598 }, {  79,5598 }, {  80,5598 }, {  81,5598 },

 {  82,5598 }, {  83,5598 }, {  84,5598 }, {  85,5598 }, {  86,5598 },
 {  87,5598 }, {  88,5598 }, {  89,5598 }, {  90,5598 }, {  67, 261 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  95,5598 }, {   0,   0 },
 {  97,5598 }, {  98,5598 }, {  99,5598 }, { 100,5598 }, { 101,5598 },
 { 102,5598 }, { 103,5598 }, { 104,5598 }, { 105,5598 }, { 106,5598 },
 { 107,5598 }, { 108,5598 }, { 109,5598 }, { 110,5598 }, { 111,5598 },
 { 112,5598 }, { 113,5598 }, { 114,5598 }, { 115,5598 }, { 116,5598 },
 { 117,5598 }, { 118,5598 }, { 119,5598 }, { 120,5598 }, { 121,5598 },
 { 122,5598 }, {  99, 261 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, { 128,5598 }, { 129,5598 }, { 130,5598 }, { 131,5598 },

 { 132,5598 }, { 133,5598 }, { 134,5598 }, { 135,5598 }, { 136,5598 },
 { 137,5598 }, { 138,5598 }, { 139,5598 }, { 140,5598 }, { 141,5598 },
 { 142,5598 }, { 143,5598 }, { 144,5598 }, { 145,5598 }, { 146,5598 },
 { 147,5598 }, { 148,5598 }, { 149,5598 }, { 150,5598 }, { 151,5598 },
 { 152,5598 }, { 153,5598 }, { 154,5598 }, { 155,5598 }, { 156,5598 },
 { 157,5598 }, { 158,5598 }, { 159,5598 }, { 160,5598 }, { 161,5598 },
 { 162,5598 }, { 163,5598 }, { 164,5598 }, { 165,5598 }, { 166,5598 },
 { 167,5598 }, { 168,5598 }, { 169,5598 }, { 170,5598 }, { 171,5598 },
 { 172,5598 }, { 173,5598 }, { 174,5598 }, { 175,5598 }, { 176,5598 },
 { 177,5598 }, { 178,5598 }, { 179,5598 }, { 180,5598 }, { 181,5598 },

 { 182,5598 }, { 183,5598 }, { 184,5598 }, { 185,5598 }, { 186,5598 },
 { 187,5598 }, { 188,5598 }, { 189,5598 }, { 190,5598 }, { 191,5598 },
 { 192,5598 }, { 193,5598 }, { 194,5598 }, { 195,5598 }, { 196,5598 },
 { 197,5598 }, { 198,5598 }, { 199,5598 }, { 200,5598 }, { 201,5598 },
 { 202,5598 }, { 203,5598 }, { 204,5598 }, { 205,5598 }, { 206,5598 },
 { 207,5598 }, { 208,5598 }, { 209,5598 }, { 210,5598 }, { 211,5598 },
 { 212,5598 }, { 213,5598 }, { 214,5598 }, { 215,5598 }, { 216,5598 },
 { 217,5598 }, { 218,5598 }, { 219,5598 }, { 220,5598 }, { 221,5598 },
 { 222,5598 }, { 223,5598 }, { 224,5598 }, { 225,5598 }, { 226,5598 },
 { 227,5598 }, { 228,5598 }, { 229,5598 }, { 230,5598 }, { 231,5598 },

 { 232,5598 }, { 233,5598 }, { 234,5598 }, { 235,5598 }, { 236,5598 },
 { 237,5598 }, { 238,5598 }, { 239,5598 }, { 240,5598 }, { 241,5598 },
 { 242,5598 }, { 243,5598 }, { 244,5598 }, { 245,5598 }, { 246,5598 },
 { 247,5598 }, { 248,5598 }, { 249,5598 }, { 250,5598 }, { 251,5598 },
 { 252,5598 }, { 253,5598 }, { 254,5598 }, { 255,5598 }, {   0,  78 },
 {   0,28875 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,  55 }, {   0,28849 }, {   0,  28 }, {   0,28847 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  36,5341 }, {   0,   0 }, {   0,   0 }, {  39,-1011 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,5341 }, {  49,5341 },
 {  50,5341 }, {  51,5341 }, {  52,5341 }, {  53,5341 }, {  54,5341 },
 {  55,5341 }, {  56,5341 }, {  57,5341 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  63,-790 }, {   0,   0 },
 {  65,5341 }, {  66,5341 }, {  67,5341 }, {  68,5341 }, {  69,5341 },
 {  70,5341 }, {  71,5341 }, {  72,5341 }, {  73,5341 }, {  74,5341 },

 {  75,5341 }, {  76,5341 }, {  77,5341 }, {  78,5341 }, {  79,5341 },
 {  80,5341 }, {  81,5341 }, {  82,5341 }, {  83,5341 }, {  84,5341 },
 {  85,5341 }, {  86,5341 }, {  87,5341 }, {  88,5341 }, {  89,5341 },
 {  90,5341 }, {  65, 242 }, {   0,   0 }, {  65, 242 }, {   0,   0 },
 {  95,5341 }, {   0,   0 }, {  97,5341 }, {  98,5341 }, {  99,5341 },
 { 100,5341 }, { 101,5341 }, { 102,5341 }, { 103,5341 }, { 104,5341 },
 { 105,5341 }, { 106,5341 }, { 107,5341 }, { 108,5341 }, { 109,5341 },
 { 110,5341 }, { 111,5341 }, { 112,5341 }, { 113,5341 }, { 114,5341 },
 { 115,5341 }, { 116,5341 }, { 117,5341 }, { 118,5341 }, { 119,5341 },
 { 120,5341 }, { 121,5341 }, { 122,5341 }, {  97, 242 }, {   0,   0 },

 {  97, 242 }, {   0,   0 }, {   0,   0 }, { 128,5341 }, { 129,5341 },
 { 130,5341 }, { 131,5341 }, { 132,5341 }, { 133,5341 }, { 134,5341 },
 { 135,5341 }, { 136,5341 }, { 137,5341 }, { 138,5341 }, { 139,5341 },
 { 140,5341 }, { 141,5341 }, { 142,5341 }, { 143,5341 }, { 144,5341 },
 { 145,5341 }, { 146,5341 }, { 147,5341 }, { 148,5341 }, { 149,5341 },
 { 150,5341 }, { 151,5341 }, { 152,5341 }, { 153,5341 }, { 154,5341 },
 { 155,5341 }, { 156,5341 }, { 157,5341 }, { 158,5341 }, { 159,5341 },
 { 160,5341 }, { 161,5341 }, { 162,5341 }, { 163,5341 }, { 164,5341 },
 { 165,5341 }, { 166,5341 }, { 167,5341 }, { 168,5341 }, { 169,5341 },
 { 170,5341 }, { 171,5341 }, { 172,5341 }, { 173,5341 }, { 174,5341 },

 { 175,5341 }, { 176,5341 }, { 177,5341 }, { 178,5341 }, { 179,5341 },
 { 180,5341 }, { 181,5341 }, { 182,5341 }, { 183,5341 }, { 184,5341 },
 { 185,5341 }, { 186,5341 }, { 187,5341 }, { 188,5341 }, { 189,5341 },
 { 190,5341 }, { 191,5341 }, { 192,5341 }, { 193,5341 }, { 194,5341 },
 { 195,5341 }, { 196,5341 }, { 197,5341 }, { 198,5341 }, { 199,5341 },
 { 200,5341 }, { 201,5341 }, { 202,5341 }, { 203,5341 }, { 204,5341 },
 { 205,5341 }, { 206,5341 }, { 207,5341 }, { 208,5341 }, { 209,5341 },
 { 210,5341 }, { 211,5341 }, { 212,5341 }, { 213,5341 }, { 214,5341 },
 { 215,5341 }, { 216,5341 }, { 217,5341 }, { 218,5341 }, { 219,5341 },
 { 220,5341 }, { 221,5341 }, { 222,5341 }, { 223,5341 }, { 224,5341 },

 { 225,5341 }, { 226,5341 }, { 227,5341 }, { 228,5341 }, { 229,5341 },
 { 230,5341 }, { 231,5341 }, { 232,5341 }, { 233,5341 }, { 234,5341 },
 { 235,5341 }, { 236,5341 }, { 237,5341 }, { 238,5341 }, { 239,5341 },
 { 240,5341 }, { 241,5341 }, { 242,5341 }, { 243,5341 }, { 244,5341 },
 { 245,5341 }, { 246,5341 }, { 247,5341 }, { 248,5341 }, { 249,5341 },
 { 250,5341 }, { 251,5341 }, { 252,5341 }, { 253,5341 }, { 254,5341 },
 { 255,5341 }, {   0,  78 }, {   0,28618 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,  55 }, {   0,28607 }, {   0,  28 },
 {   0,28605 }, {   0,  33 }, {   0,28603 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  55 },
 {   0,28595 }, {   0,  28 }, {   0,28593 }, {   0,  34 }, {   0,28591 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  36,5084 }, {   0,   0 },
 {   0,   0 }, {  39,-1045 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  48,5084 }, {  49,5084 }, {  50,5084 }, {  51,5084 }, {  52,5084 },
 {  53,5084 }, {  54,5084 }, {  55,5084 }, {  56,5084 }, {  57,5084 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  63,-1273 }, {   0,   0 }, {  65,5084 }, {  66,5084 }, {  67,5084 },

 {  68,5084 }, {  69,5084 }, {  70,5084 }, {  71,5084 }, {  72,5084 },
 {  73,5084 }, {  74,5084 }, {  75,5084 }, {  76,5084 }, {  77,5084 },
 {  78,5084 }, {  79,5084 }, {  80,5084 }, {  81,5084 }, {  82,5084 },
 {  83,5084 }, {  84,5084 }, {  85,5084 }, {  86,5084 }, {  87,5084 },
 {  88,5084 }, {  89,5084 }, {  90,5084 }, {  80,  12 }, {  69,21847 },
 {  80,  12 }, {  69,21869 }, {  95,5084 }, {   0,   0 }, {  97,5084 },
 {  98,5084 }, {  99,5084 }, { 100,5084 }, { 101,5084 }, { 102,5084 },
 { 103,5084 }, { 104,5084 }, { 105,5084 }, { 106,5084 }, { 107,5084 },
 { 108,5084 }, { 109,5084 }, { 110,5084 }, { 111,5084 }, { 112,5084 },
 { 113,5084 }, { 114,5084 }, { 115,5084 }, { 116,5084 }, { 117,5084 },

 { 118,5084 }, { 119,5084 }, { 120,5084 }, { 121,5084 }, { 122,5084 },
 { 112,  12 }, { 101,21847 }, { 112,  12 }, { 101,21869 }, {   0,   0 },
 { 128,5084 }, { 129,5084 }, { 130,5084 }, { 131,5084 }, { 132,5084 },
 { 133,5084 }, { 134,5084 }, { 135,5084 }, { 136,5084 }, { 137,5084 },
 { 138,5084 }, { 139,5084 }, { 140,5084 }, { 141,5084 }, { 142,5084 },
 { 143,5084 }, { 144,5084 }, { 145,5084 }, { 146,5084 }, { 147,5084 },
 { 148,5084 }, { 149,5084 }, { 150,5084 }, { 151,5084 }, { 152,5084 },
 { 153,5084 }, { 154,5084 }, { 155,5084 }, { 156,5084 }, { 157,5084 },
 { 158,5084 }, { 159,5084 }, { 160,5084 }, { 161,5084 }, { 162,5084 },
 { 163,5084 }, { 164,5084 }, { 165,5084 }, { 166,5084 }, { 167,5084 },

 { 168,5084 }, { 169,5084 }, { 170,5084 }, { 171,5084 }, { 172,5084 },
 { 173,5084 }, { 174,5084 }, { 175,5084 }, { 176,5084 }, { 177,5084 },
 { 178,5084 }, { 179,5084 }, { 180,5084 }, { 181,5084 }, { 182,5084 },
 { 183,5084 }, { 184,5084 }, { 185,5084 }, { 186,5084 }, { 187,5084 },
 { 188,5084 }, { 189,5084 }, { 190,5084 }, { 191,5084 }, { 192,5084 },
 { 193,5084 }, { 194,5084 }, { 195,5084 }, { 196,5084 }, { 197,5084 },
 { 198,5084 }, { 199,5084 }, { 200,5084 }, { 201,5084 }, { 202,5084 },
 { 203,5084 }, { 204,5084 }, { 205,5084 }, { 206,5084 }, { 207,5084 },
 { 208,5084 }, { 209,5084 }, { 210,5084 }, { 211,5084 }, { 212,5084 },
 { 213,5084 }, { 214,5084 }, { 215,5084 }, { 216,5084 }, { 217,5084 },

 { 218,5084 }, { 219,5084 }, { 220,5084 }, { 221,5084 }, { 222,5084 },
 { 223,5084 }, { 224,5084 }, { 225,5084 }, { 226,5084 }, { 227,5084 },
 { 228,5084 }, { 229,5084 }, { 230,5084 }, { 231,5084 }, { 232,5084 },
 { 233,5084 }, { 234,5084 }, { 235,5084 }, { 236,5084 }, { 237,5084 },
 { 238,5084 }, { 239,5084 }, { 240,5084 }, { 241,5084 }, { 242,5084 },
 { 243,5084 }, { 244,5084 }, { 245,5084 }, { 246,5084 }, { 247,5084 },
 { 248,5084 }, { 249,5084 }, { 250,5084 }, { 251,5084 }, { 252,5084 },
 { 253,5084 }, { 254,5084 }, { 255,5084 }, {   0,  78 }, {   0,28361 },
 {   0,  55 }, {   0,28359 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,  28 }, {   0,28348 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  55 }, {   0,28341 },
 {   0,  28 }, {   0,28339 }, {   0,  56 }, {   0,28337 }, {   0,  29 },
 {   0,28335 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  36,4827 }, {   0,   0 }, {  38,-1290 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,22485 }, {  48,4827 }, {  49,4827 }, {  50,4827 },
 {  51,4827 }, {  52,4827 }, {  53,4827 }, {  54,4827 }, {  55,4827 },
 {  56,4827 }, {  57,4827 }, {  45,22732 }, {  39,   4 }, {   0,   0 },

 {  39,   4 }, {   0,   0 }, {  63,-1530 }, {   0,   0 }, {  65,4827 },
 {  66,4827 }, {  67,4827 }, {  68,4827 }, {  69,4827 }, {  70,4827 },
 {  71,4827 }, {  72,4827 }, {  73,4827 }, {  74,4827 }, {  75,4827 },
 {  76,4827 }, {  77,4827 }, {  78,4827 }, {  79,4827 }, {  80,4827 },
 {  81,4827 }, {  82,4827 }, {  83,4827 }, {  84,4827 }, {  85,4827 },
 {  86,4827 }, {  87,4827 }, {  88,4827 }, {  89,4827 }, {  90,4827 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  95,4827 },
 {   0,   0 }, {  97,4827 }, {  98,4827 }, {  99,4827 }, { 100,4827 },
 { 101,4827 }, { 102,4827 }, { 103,4827 }, { 104,4827 }, { 105,4827 },
 { 106,4827 }, { 107,4827 }, { 108,4827 }, { 109,4827 }, { 110,4827 },

 { 111,4827 }, { 112,4827 }, { 113,4827 }, { 114,4827 }, { 115,4827 },
 { 116,4827 }, { 117,4827 }, { 118,4827 }, { 119,4827 }, { 120,4827 },
 { 121,4827 }, { 122,4827 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, { 128,4827 }, { 129,4827 }, { 130,4827 },
 { 131,4827 }, { 132,4827 }, { 133,4827 }, { 134,4827 }, { 135,4827 },
 { 136,4827 }, { 137,4827 }, { 138,4827 }, { 139,4827 }, { 140,4827 },
 { 141,4827 }, { 142,4827 }, { 143,4827 }, { 144,4827 }, { 145,4827 },
 { 146,4827 }, { 147,4827 }, { 148,4827 }, { 149,4827 }, { 150,4827 },
 { 151,4827 }, { 152,4827 }, { 153,4827 }, { 154,4827 }, { 155,4827 },
 { 156,4827 }, { 157,4827 }, { 158,4827 }, { 159,4827 }, { 160,4827 },

 { 161,4827 }, { 162,4827 }, { 163,4827 }, { 164,4827 }, { 165,4827 },
 { 166,4827 }, { 167,4827 }, { 168,4827 }, { 169,4827 }, { 170,4827 },
 { 171,4827 }, { 172,4827 }, { 173,4827 }, { 174,4827 }, { 175,4827 },
 { 176,4827 }, { 177,4827 }, { 178,4827 }, { 179,4827 }, { 180,4827 },
 { 181,4827 }, { 182,4827 }, { 183,4827 }, { 184,4827 }, { 185,4827 },
 { 186,4827 }, { 187,4827 }, { 188,4827 }, { 189,4827 }, { 190,4827 },
 { 191,4827 }, { 192,4827 }, { 193,4827 }, { 194,4827 }, { 195,4827 },
 { 196,4827 }, { 197,4827 }, { 198,4827 }, { 199,4827 }, { 200,4827 },
 { 201,4827 }, { 202,4827 }, { 203,4827 }, { 204,4827 }, { 205,4827 },
 { 206,4827 }, { 207,4827 }, { 208,4827 }, { 209,4827 }, { 210,4827 },

 { 211,4827 }, { 212,4827 }, { 213,4827 }, { 214,4827 }, { 215,4827 },
 { 216,4827 }, { 217,4827 }, { 218,4827 }, { 219,4827 }, { 220,4827 },
 { 221,4827 }, { 222,4827 }, { 223,4827 }, { 224,4827 }, { 225,4827 },
 { 226,4827 }, { 227,4827 }, { 228,4827 }, { 229,4827 }, { 230,4827 },
 { 231,4827 }, { 232,4827 }, { 233,4827 }, { 234,4827 }, { 235,4827 },
 { 236,4827 }, { 237,4827 }, { 238,4827 }, { 239,4827 }, { 240,4827 },
 { 241,4827 }, { 242,4827 }, { 243,4827 }, { 244,4827 }, { 245,4827 },
 { 246,4827 }, { 247,4827 }, { 248,4827 }, { 249,4827 }, { 250,4827 },
 { 251,4827 }, { 252,4827 }, { 253,4827 }, { 254,4827 }, { 255,4827 },
 {   0,  78 }, {   0,28104 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  36,4570 }, {   0,   0 }, {   0,   0 },
 {  39,-1545 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,4570 },
 {  49,4570 }, {  50,4570 }, {  51,4570 }, {  52,4570 }, {  53,4570 },

 {  54,4570 }, {  55,4570 }, {  56,4570 }, {  57,4570 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  63,-1787 },
 {   0,   0 }, {  65,4570 }, {  66,4570 }, {  67,4570 }, {  68,4570 },
 {  69,4570 }, {  70,4570 }, {  71,4570 }, {  72,4570 }, {  73,4570 },
 {  74,4570 }, {  75,4570 }, {  76,4570 }, {  77,4570 }, {  78,4570 },
 {  79,4570 }, {  80,4570 }, {  81,4570 }, {  82,4570 }, {  83,4570 },
 {  84,4570 }, {  85,4570 }, {  86,4570 }, {  87,4570 }, {  88,4570 },
 {  89,4570 }, {  90,4570 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  95,4570 }, {   0,   0 }, {  97,4570 }, {  98,4570 },
 {  99,4570 }, { 100,4570 }, { 101,4570 }, { 102,4570 }, { 103,4570 },

 { 104,4570 }, { 105,4570 }, { 106,4570 }, { 107,4570 }, { 108,4570 },
 { 109,4570 }, { 110,4570 }, { 111,4570 }, { 112,4570 }, { 113,4570 },
 { 114,4570 }, { 115,4570 }, { 116,4570 }, { 117,4570 }, { 118,4570 },
 { 119,4570 }, { 120,4570 }, { 121,4570 }, { 122,4570 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 128,4570 },
 { 129,4570 }, { 130,4570 }, { 131,4570 }, { 132,4570 }, { 133,4570 },
 { 134,4570 }, { 135,4570 }, { 136,4570 }, { 137,4570 }, { 138,4570 },
 { 139,4570 }, { 140,4570 }, { 141,4570 }, { 142,4570 }, { 143,4570 },
 { 144,4570 }, { 145,4570 }, { 146,4570 }, { 147,4570 }, { 148,4570 },
 { 149,4570 }, { 150,4570 }, { 151,4570 }, { 152,4570 }, { 153,4570 },

 { 154,4570 }, { 155,4570 }, { 156,4570 }, { 157,4570 }, { 158,4570 },
 { 159,4570 }, { 160,4570 }, { 161,4570 }, { 162,4570 }, { 163,4570 },
 { 164,4570 }, { 165,4570 }, { 166,4570 }, { 167,4570 }, { 168,4570 },
 { 169,4570 }, { 170,4570 }, { 171,4570 }, { 172,4570 }, { 173,4570 },
 { 174,4570 }, { 175,4570 }, { 176,4570 }, { 177,4570 }, { 178,4570 },
 { 179,4570 }, { 180,4570 }, { 181,4570 }, { 182,4570 }, { 183,4570 },
 { 184,4570 }, { 185,4570 }, { 186,4570 }, { 187,4570 }, { 188,4570 },
 { 189,4570 }, { 190,4570 }, { 191,4570 }, { 192,4570 }, { 193,4570 },
 { 194,4570 }, { 195,4570 }, { 196,4570 }, { 197,4570 }, { 198,4570 },
 { 199,4570 }, { 200,4570 }, { 201,4570 }, { 202,4570 }, { 203,4570 },

 { 204,4570 }, { 205,4570 }, { 206,4570 }, { 207,4570 }, { 208,4570 },
 { 209,4570 }, { 210,4570 }, { 211,4570 }, { 212,4570 }, { 213,4570 },
 { 214,4570 }, { 215,4570 }, { 216,4570 }, { 217,4570 }, { 218,4570 },
 { 219,4570 }, { 220,4570 }, { 221,4570 }, { 222,4570 }, { 223,4570 },
 { 224,4570 }, { 225,4570 }, { 226,4570 }, { 227,4570 }, { 228,4570 },
 { 229,4570 }, { 230,4570 }, { 231,4570 }, { 232,4570 }, { 233,4570 },
 { 234,4570 }, { 235,4570 }, { 236,4570 }, { 237,4570 }, { 238,4570 },
 { 239,4570 }, { 240,4570 }, { 241,4570 }, { 242,4570 }, { 243,4570 },
 { 244,4570 }, { 245,4570 }, { 246,4570 }, { 247,4570 }, { 248,4570 },
 { 249,4570 }, { 250,4570 }, { 251,4570 }, { 252,4570 }, { 253,4570 },

 { 254,4570 }, { 255,4570 }, {   0,  12 }, {   0,27847 }, {   1,4570 },
 {   2,4570 }, {   3,4570 }, {   4,4570 }, {   5,4570 }, {   6,4570 },
 {   7,4570 }, {   8,4570 }, {   9,4570 }, {  10,4570 }, {  11,4570 },
 {  12,4570 }, {  13,4570 }, {  14,4570 }, {  15,4570 }, {  16,4570 },
 {  17,4570 }, {  18,4570 }, {  19,4570 }, {  20,4570 }, {  21,4570 },
 {  22,4570 }, {  23,4570 }, {  24,4570 }, {  25,4570 }, {  26,4570 },
 {  27,4570 }, {  28,4570 }, {  29,4570 }, {  30,4570 }, {  31,4570 },
 {  32,4570 }, {  33,4570 }, {  34,4570 }, {  35,4570 }, {  36,4570 },
 {  37,4570 }, {  38,4570 }, {   0,   0 }, {  40,4570 }, {  41,4570 },
 {  42,4570 }, {  43,4570 }, {  44,4570 }, {  45,4570 }, {  46,4570 },

 {  47,4570 }, {  48,4570 }, {  49,4570 }, {  50,4570 }, {  51,4570 },
 {  52,4570 }, {  53,4570 }, {  54,4570 }, {  55,4570 }, {  56,4570 },
 {  57,4570 }, {  58,4570 }, {  59,4570 }, {  60,4570 }, {  61,4570 },
 {  62,4570 }, {  63,4570 }, {  64,4570 }, {  65,4570 }, {  66,4570 },
 {  67,4570 }, {  68,4570 }, {  69,4570 }, {  70,4570 }, {  71,4570 },
 {  72,4570 }, {  73,4570 }, {  74,4570 }, {  75,4570 }, {  76,4570 },
 {  77,4570 }, {  78,4570 }, {  79,4570 }, {  80,4570 }, {  81,4570 },
 {  82,4570 }, {  83,4570 }, {  84,4570 }, {  85,4570 }, {  86,4570 },
 {  87,4570 }, {  88,4570 }, {  89,4570 }, {  90,4570 }, {  91,4570 },
 {  92,4570 }, {  93,4570 }, {  94,4570 }, {  95,4570 }, {  96,4570 },

 {  97,4570 }, {  98,4570 }, {  99,4570 }, { 100,4570 }, { 101,4570 },
 { 102,4570 }, { 103,4570 }, { 104,4570 }, { 105,4570 }, { 106,4570 },
 { 107,4570 }, { 108,4570 }, { 109,4570 }, { 110,4570 }, { 111,4570 },
 { 112,4570 }, { 113,4570 }, { 114,4570 }, { 115,4570 }, { 116,4570 },
 { 117,4570 }, { 118,4570 }, { 119,4570 }, { 120,4570 }, { 121,4570 },
 { 122,4570 }, { 123,4570 }, { 124,4570 }, { 125,4570 }, { 126,4570 },
 { 127,4570 }, { 128,4570 }, { 129,4570 }, { 130,4570 }, { 131,4570 },
 { 132,4570 }, { 133,4570 }, { 134,4570 }, { 135,4570 }, { 136,4570 },
 { 137,4570 }, { 138,4570 }, { 139,4570 }, { 140,4570 }, { 141,4570 },
 { 142,4570 }, { 143,4570 }, { 144,4570 }, { 145,4570 }, { 146,4570 },

 { 147,4570 }, { 148,4570 }, { 149,4570 }, { 150,4570 }, { 151,4570 },
 { 152,4570 }, { 153,4570 }, { 154,4570 }, { 155,4570 }, { 156,4570 },
 { 157,4570 }, { 158,4570 }, { 159,4570 }, { 160,4570 }, { 161,4570 },
 { 162,4570 }, { 163,4570 }, { 164,4570 }, { 165,4570 }, { 166,4570 },
 { 167,4570 }, { 168,4570 }, { 169,4570 }, { 170,4570 }, { 171,4570 },
 { 172,4570 }, { 173,4570 }, { 174,4570 }, { 175,4570 }, { 176,4570 },
 { 177,4570 }, { 178,4570 }, { 179,4570 }, { 180,4570 }, { 181,4570 },
 { 182,4570 }, { 183,4570 }, { 184,4570 }, { 185,4570 }, { 186,4570 },
 { 187,4570 }, { 188,4570 }, { 189,4570 }, { 190,4570 }, { 191,4570 },
 { 192,4570 }, { 193,4570 }, { 194,4570 }, { 195,4570 }, { 196,4570 },

 { 197,4570 }, { 198,4570 }, { 199,4570 }, { 200,4570 }, { 201,4570 },
 { 202,4570 }, { 203,4570 }, { 204,4570 }, { 205,4570 }, { 206,4570 },
 { 207,4570 }, { 208,4570 }, { 209,4570 }, { 210,4570 }, { 211,4570 },
 { 212,4570 }, { 213,4570 }, { 214,4570 }, { 215,4570 }, { 216,4570 },
 { 217,4570 }, { 218,4570 }, { 219,4570 }, { 220,4570 }, { 221,4570 },
 { 222,4570 }, { 223,4570 }, { 224,4570 }, { 225,4570 }, { 226,4570 },
 { 227,4570 }, { 228,4570 }, { 229,4570 }, { 230,4570 }, { 231,4570 },
 { 232,4570 }, { 233,4570 }, { 234,4570 }, { 235,4570 }, { 236,4570 },
 { 237,4570 }, { 238,4570 }, { 239,4570 }, { 240,4570 }, { 241,4570 },
 { 242,4570 }, { 243,4570 }, { 244,4570 }, { 245,4570 }, { 246,4570 },

 { 247,4570 }, { 248,4570 }, { 249,4570 }, { 250,4570 }, { 251,4570 },
 { 252,4570 }, { 253,4570 }, { 254,4570 }, { 255,4570 }, { 256,4570 },
 {   0,   9 }, {   0,27589 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,4570 }, {  10,4575 }, {   0,   0 }, {  12,4570 }, {  13,4575 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,4570 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-2057 }, {   0,   5 }, {   0,27542 }, {   1,4575 },
 {   2,4575 }, {   3,4575 }, {   4,4575 }, {   5,4575 }, {   6,4575 },
 {   7,4575 }, {   8,4575 }, {   9,4575 }, {  10,4575 }, {  11,4575 },
 {  12,4575 }, {  13,4575 }, {  14,4575 }, {  15,4575 }, {  16,4575 },
 {  17,4575 }, {  18,4575 }, {  19,4575 }, {  20,4575 }, {  21,4575 },
 {  22,4575 }, {  23,4575 }, {  24,4575 }, {  25,4575 }, {  26,4575 },
 {  27,4575 }, {  28,4575 }, {  29,4575 }, {  30,4575 }, {  31,4575 },
 {  32,4575 }, {  33,4575 }, {  34,4575 }, {  35,4575 }, {  36,4575 },
 {  37,4575 }, {  38,4575 }, {  39,4575 }, {  40,4575 }, {  41,4575 },

 {   0,   0 }, {  43,4575 }, {  44,4575 }, {  45,4575 }, {  46,4575 },
 {   0,   0 }, {  48,4575 }, {  49,4575 }, {  50,4575 }, {  51,4575 },
 {  52,4575 }, {  53,4575 }, {  54,4575 }, {  55,4575 }, {  56,4575 },
 {  57,4575 }, {  58,4575 }, {  59,4575 }, {  60,4575 }, {  61,4575 },
 {  62,4575 }, {  63,4575 }, {  64,4575 }, {  65,4575 }, {  66,4575 },
 {  67,4575 }, {  68,4575 }, {  69,4575 }, {  70,4575 }, {  71,4575 },
 {  72,4575 }, {  73,4575 }, {  74,4575 }, {  75,4575 }, {  76,4575 },
 {  77,4575 }, {  78,4575 }, {  79,4575 }, {  80,4575 }, {  81,4575 },
 {  82,4575 }, {  83,4575 }, {  84,4575 }, {  85,4575 }, {  86,4575 },
 {  87,4575 }, {  88,4575 }, {  89,4575 }, {  90,4575 }, {  91,4575 },

 {  92,4575 }, {  93,4575 }, {  94,4575 }, {  95,4575 }, {  96,4575 },
 {  97,4575 }, {  98,4575 }, {  99,4575 }, { 100,4575 }, { 101,4575 },
 { 102,4575 }, { 103,4575 }, { 104,4575 }, { 105,4575 }, { 106,4575 },
 { 107,4575 }, { 108,4575 }, { 109,4575 }, { 110,4575 }, { 111,4575 },
 { 112,4575 }, { 113,4575 }, { 114,4575 }, { 115,4575 }, { 116,4575 },
 { 117,4575 }, { 118,4575 }, { 119,4575 }, { 120,4575 }, { 121,4575 },
 { 122,4575 }, { 123,4575 }, { 124,4575 }, { 125,4575 }, { 126,4575 },
 { 127,4575 }, { 128,4575 }, { 129,4575 }, { 130,4575 }, { 131,4575 },
 { 132,4575 }, { 133,4575 }, { 134,4575 }, { 135,4575 }, { 136,4575 },
 { 137,4575 }, { 138,4575 }, { 139,4575 }, { 140,4575 }, { 141,4575 },

 { 142,4575 }, { 143,4575 }, { 144,4575 }, { 145,4575 }, { 146,4575 },
 { 147,4575 }, { 148,4575 }, { 149,4575 }, { 150,4575 }, { 151,4575 },
 { 152,4575 }, { 153,4575 }, { 154,4575 }, { 155,4575 }, { 156,4575 },
 { 157,4575 }, { 158,4575 }, { 159,4575 }, { 160,4575 }, { 161,4575 },
 { 162,4575 }, { 163,4575 }, { 164,4575 }, { 165,4575 }, { 166,4575 },
 { 167,4575 }, { 168,4575 }, { 169,4575 }, { 170,4575 }, { 171,4575 },
 { 172,4575 }, { 173,4575 }, { 174,4575 }, { 175,4575 }, { 176,4575 },
 { 177,4575 }, { 178,4575 }, { 179,4575 }, { 180,4575 }, { 181,4575 },
 { 182,4575 }, { 183,4575 }, { 184,4575 }, { 185,4575 }, { 186,4575 },
 { 187,4575 }, { 188,4575 }, { 189,4575 }, { 190,4575 }, { 191,4575 },

 { 192,4575 }, { 193,4575 }, { 194,4575 }, { 195,4575 }, { 196,4575 },
 { 197,4575 }, { 198,4575 }, { 199,4575 }, { 200,4575 }, { 201,4575 },
 { 202,4575 }, { 203,4575 }, { 204,4575 }, { 205,4575 }, { 206,4575 },
 { 207,4575 }, { 208,4575 }, { 209,4575 }, { 210,4575 }, { 211,4575 },
 { 212,4575 }, { 213,4575 }, { 214,4575 }, { 215,4575 }, { 216,4575 },
 { 217,4575 }, { 218,4575 }, { 219,4575 }, { 220,4575 }, { 221,4575 },
 { 222,4575 }, { 223,4575 }, { 224,4575 }, { 225,4575 }, { 226,4575 },
 { 227,4575 }, { 228,4575 }, { 229,4575 }, { 230,4575 }, { 231,4575 },
 { 232,4575 }, { 233,4575 }, { 234,4575 }, { 235,4575 }, { 236,4575 },
 { 237,4575 }, { 238,4575 }, { 239,4575 }, { 240,4575 }, { 241,4575 },

 { 242,4575 }, { 243,4575 }, { 244,4575 }, { 245,4575 }, { 246,4575 },
 { 247,4575 }, { 248,4575 }, { 249,4575 }, { 250,4575 }, { 251,4575 },
 { 252,4575 }, { 253,4575 }, { 254,4575 }, { 255,4575 }, { 256,4575 },
 {   0,   5 }, {   0,27284 }, {   1,4317 }, {   2,4317 }, {   3,4317 },
 {   4,4317 }, {   5,4317 }, {   6,4317 }, {   7,4317 }, {   8,4317 },
 {   9,4317 }, {  10,4317 }, {  11,4317 }, {  12,4317 }, {  13,4317 },
 {  14,4317 }, {  15,4317 }, {  16,4317 }, {  17,4317 }, {  18,4317 },
 {  19,4317 }, {  20,4317 }, {  21,4317 }, {  22,4317 }, {  23,4317 },
 {  24,4317 }, {  25,4317 }, {  26,4317 }, {  27,4317 }, {  28,4317 },
 {  29,4317 }, {  30,4317 }, {  31,4317 }, {  32,4317 }, {  33,4317 },

 {  34,4317 }, {  35,4317 }, {  36,4317 }, {  37,4317 }, {  38,4317 },
 {  39,4317 }, {  40,4317 }, {  41,4317 }, {   0,   0 }, {  43,4317 },
 {  44,4317 }, {  45,4317 }, {  46,4317 }, {   0,   0 }, {  48,4317 },
 {  49,4317 }, {  50,4317 }, {  51,4317 }, {  52,4317 }, {  53,4317 },
 {  54,4317 }, {  55,4317 }, {  56,4317 }, {  57,4317 }, {  58,4317 },
 {  59,4317 }, {  60,4317 }, {  61,4317 }, {  62,4317 }, {  63,4317 },
 {  64,4317 }, {  65,4317 }, {  66,4317 }, {  67,4317 }, {  68,4317 },
 {  69,4317 }, {  70,4317 }, {  71,4317 }, {  72,4317 }, {  73,4317 },
 {  74,4317 }, {  75,4317 }, {  76,4317 }, {  77,4317 }, {  78,4317 },
 {  79,4317 }, {  80,4317 }, {  81,4317 }, {  82,4317 }, {  83,4317 },

 {  84,4317 }, {  85,4317 }, {  86,4317 }, {  87,4317 }, {  88,4317 },
 {  89,4317 }, {  90,4317 }, {  91,4317 }, {  92,4317 }, {  93,4317 },
 {  94,4317 }, {  95,4317 }, {  96,4317 }, {  97,4317 }, {  98,4317 },
 {  99,4317 }, { 100,4317 }, { 101,4317 }, { 102,4317 }, { 103,4317 },
 { 104,4317 }, { 105,4317 }, { 106,4317 }, { 107,4317 }, { 108,4317 },
 { 109,4317 }, { 110,4317 }, { 111,4317 }, { 112,4317 }, { 113,4317 },
 { 114,4317 }, { 115,4317 }, { 116,4317 }, { 117,4317 }, { 118,4317 },
 { 119,4317 }, { 120,4317 }, { 121,4317 }, { 122,4317 }, { 123,4317 },
 { 124,4317 }, { 125,4317 }, { 126,4317 }, { 127,4317 }, { 128,4317 },
 { 129,4317 }, { 130,4317 }, { 131,4317 }, { 132,4317 }, { 133,4317 },

 { 134,4317 }, { 135,4317 }, { 136,4317 }, { 137,4317 }, { 138,4317 },
 { 139,4317 }, { 140,4317 }, { 141,4317 }, { 142,4317 }, { 143,4317 },
 { 144,4317 }, { 145,4317 }, { 146,4317 }, { 147,4317 }, { 148,4317 },
 { 149,4317 }, { 150,4317 }, { 151,4317 }, { 152,4317 }, { 153,4317 },
 { 154,4317 }, { 155,4317 }, { 156,4317 }, { 157,4317 }, { 158,4317 },
 { 159,4317 }, { 160,4317 }, { 161,4317 }, { 162,4317 }, { 163,4317 },
 { 164,4317 }, { 165,4317 }, { 166,4317 }, { 167,4317 }, { 168,4317 },
 { 169,4317 }, { 170,4317 }, { 171,4317 }, { 172,4317 }, { 173,4317 },
 { 174,4317 }, { 175,4317 }, { 176,4317 }, { 177,4317 }, { 178,4317 },
 { 179,4317 }, { 180,4317 }, { 181,4317 }, { 182,4317 }, { 183,4317 },

 { 184,4317 }, { 185,4317 }, { 186,4317 }, { 187,4317 }, { 188,4317 },
 { 189,4317 }, { 190,4317 }, { 191,4317 }, { 192,4317 }, { 193,4317 },
 { 194,4317 }, { 195,4317 }, { 196,4317 }, { 197,4317 }, { 198,4317 },
 { 199,4317 }, { 200,4317 }, { 201,4317 }, { 202,4317 }, { 203,4317 },
 { 204,4317 }, { 205,4317 }, { 206,4317 }, { 207,4317 }, { 208,4317 },
 { 209,4317 }, { 210,4317 }, { 211,4317 }, { 212,4317 }, { 213,4317 },
 { 214,4317 }, { 215,4317 }, { 216,4317 }, { 217,4317 }, { 218,4317 },
 { 219,4317 }, { 220,4317 }, { 221,4317 }, { 222,4317 }, { 223,4317 },
 { 224,4317 }, { 225,4317 }, { 226,4317 }, { 227,4317 }, { 228,4317 },
 { 229,4317 }, { 230,4317 }, { 231,4317 }, { 232,4317 }, { 233,4317 },

 { 234,4317 }, { 235,4317 }, { 236,4317 }, { 237,4317 }, { 238,4317 },
 { 239,4317 }, { 240,4317 }, { 241,4317 }, { 242,4317 }, { 243,4317 },
 { 244,4317 }, { 245,4317 }, { 246,4317 }, { 247,4317 }, { 248,4317 },
 { 249,4317 }, { 250,4317 }, { 251,4317 }, { 252,4317 }, { 253,4317 },
 { 254,4317 }, { 255,4317 }, { 256,4317 }, {   0,  58 }, {   0,27026 },
 {   1,4445 }, {   2,4445 }, {   3,4445 }, {   4,4445 }, {   5,4445 },
 {   6,4445 }, {   7,4445 }, {   8,4445 }, {   9,4445 }, {  10,4445 },
 {  11,4445 }, {  12,4445 }, {  13,4445 }, {  14,4445 }, {  15,4445 },
 {  16,4445 }, {  17,4445 }, {  18,4445 }, {  19,4445 }, {  20,4445 },
 {  21,4445 }, {  22,4445 }, {  23,4445 }, {  24,4445 }, {  25,4445 },

 {  26,4445 }, {  27,4445 }, {  28,4445 }, {  29,4445 }, {  30,4445 },
 {  31,4445 }, {  32,4445 }, {  33,4445 }, {   0,   0 }, {  35,4445 },
 {  36,4445 }, {  37,4445 }, {  38,4445 }, {  39,4445 }, {  40,4445 },
 {  41,4445 }, {  42,4445 }, {  43,4445 }, {  44,4445 }, {  45,4445 },
 {  46,4445 }, {  47,4445 }, {  48,4445 }, {  49,4445 }, {  50,4445 },
 {  51,4445 }, {  52,4445 }, {  53,4445 }, {  54,4445 }, {  55,4445 },
 {  56,4445 }, {  57,4445 }, {  58,4445 }, {  59,4445 }, {  60,4445 },
 {  61,4445 }, {  62,4445 }, {  63,4445 }, {  64,4445 }, {  65,4445 },
 {  66,4445 }, {  67,4445 }, {  68,4445 }, {  69,4445 }, {  70,4445 },
 {  71,4445 }, {  72,4445 }, {  73,4445 }, {  74,4445 }, {  75,4445 },

 {  76,4445 }, {  77,4445 }, {  78,4445 }, {  79,4445 }, {  80,4445 },
 {  81,4445 }, {  82,4445 }, {  83,4445 }, {  84,4445 }, {  85,4445 },
 {  86,4445 }, {  87,4445 }, {  88,4445 }, {  89,4445 }, {  90,4445 },
 {  91,4445 }, {  92,4445 }, {  93,4445 }, {  94,4445 }, {  95,4445 },
 {  96,4445 }, {  97,4445 }, {  98,4445 }, {  99,4445 }, { 100,4445 },
 { 101,4445 }, { 102,4445 }, { 103,4445 }, { 104,4445 }, { 105,4445 },
 { 106,4445 }, { 107,4445 }, { 108,4445 }, { 109,4445 }, { 110,4445 },
 { 111,4445 }, { 112,4445 }, { 113,4445 }, { 114,4445 }, { 115,4445 },
 { 116,4445 }, { 117,4445 }, { 118,4445 }, { 119,4445 }, { 120,4445 },
 { 121,4445 }, { 122,4445 }, { 123,4445 }, { 124,4445 }, { 125,4445 },

 { 126,4445 }, { 127,4445 }, { 128,4445 }, { 129,4445 }, { 130,4445 },
 { 131,4445 }, { 132,4445 }, { 133,4445 }, { 134,4445 }, { 135,4445 },
 { 136,4445 }, { 137,4445 }, { 138,4445 }, { 139,4445 }, { 140,4445 },
 { 141,4445 }, { 142,4445 }, { 143,4445 }, { 144,4445 }, { 145,4445 },
 { 146,4445 }, { 147,4445 }, { 148,4445 }, { 149,4445 }, { 150,4445 },
 { 151,4445 }, { 152,4445 }, { 153,4445 }, { 154,4445 }, { 155,4445 },
 { 156,4445 }, { 157,4445 }, { 158,4445 }, { 159,4445 }, { 160,4445 },
 { 161,4445 }, { 162,4445 }, { 163,4445 }, { 164,4445 }, { 165,4445 },
 { 166,4445 }, { 167,4445 }, { 168,4445 }, { 169,4445 }, { 170,4445 },
 { 171,4445 }, { 172,4445 }, { 173,4445 }, { 174,4445 }, { 175,4445 },

 { 176,4445 }, { 177,4445 }, { 178,4445 }, { 179,4445 }, { 180,4445 },
 { 181,4445 }, { 182,4445 }, { 183,4445 }, { 184,4445 }, { 185,4445 },
 { 186,4445 }, { 187,4445 }, { 188,4445 }, { 189,4445 }, { 190,4445 },
 { 191,4445 }, { 192,4445 }, { 193,4445 }, { 194,4445 }, { 195,4445 },
 { 196,4445 }, { 197,4445 }, { 198,4445 }, { 199,4445 }, { 200,4445 },
 { 201,4445 }, { 202,4445 }, { 203,4445 }, { 204,4445 }, { 205,4445 },
 { 206,4445 }, { 207,4445 }, { 208,4445 }, { 209,4445 }, { 210,4445 },
 { 211,4445 }, { 212,4445 }, { 213,4445 }, { 214,4445 }, { 215,4445 },
 { 216,4445 }, { 217,4445 }, { 218,4445 }, { 219,4445 }, { 220,4445 },
 { 221,4445 }, { 222,4445 }, { 223,4445 }, { 224,4445 }, { 225,4445 },

 { 226,4445 }, { 227,4445 }, { 228,4445 }, { 229,4445 }, { 230,4445 },
 { 231,4445 }, { 232,4445 }, { 233,4445 }, { 234,4445 }, { 235,4445 },
 { 236,4445 }, { 237,4445 }, { 238,4445 }, { 239,4445 }, { 240,4445 },
 { 241,4445 }, { 242,4445 }, { 243,4445 }, { 244,4445 }, { 245,4445 },
 { 246,4445 }, { 247,4445 }, { 248,4445 }, { 249,4445 }, { 250,4445 },
 { 251,4445 }, { 252,4445 }, { 253,4445 }, { 254,4445 }, { 255,4445 },
 { 256,4445 }, {   0,  11 }, {   0,26768 }, {   1,4445 }, {   2,4445 },
 {   3,4445 }, {   4,4445 }, {   5,4445 }, {   6,4445 }, {   7,4445 },
 {   8,4445 }, {   9,4445 }, {  10,4445 }, {  11,4445 }, {  12,4445 },
 {  13,4445 }, {  14,4445 }, {  15,4445 }, {  16,4445 }, {  17,4445 },

 {  18,4445 }, {  19,4445 }, {  20,4445 }, {  21,4445 }, {  22,4445 },
 {  23,4445 }, {  24,4445 }, {  25,4445 }, {  26,4445 }, {  27,4445 },
 {  28,4445 }, {  29,4445 }, {  30,4445 }, {  31,4445 }, {  32,4445 },
 {  33,4445 }, {  34,4445 }, {  35,4445 }, {  36,4445 }, {  37,4445 },
 {  38,4445 }, {   0,   0 }, {  40,4445 }, {  41,4445 }, {  42,4445 },
 {  43,4445 }, {  44,4445 }, {  45,4445 }, {  46,4445 }, {  47,4445 },
 {  48,4445 }, {  49,4445 }, {  50,4445 }, {  51,4445 }, {  52,4445 },
 {  53,4445 }, {  54,4445 }, {  55,4445 }, {  56,4445 }, {  57,4445 },
 {  58,4445 }, {  59,4445 }, {  60,4445 }, {  61,4445 }, {  62,4445 },
 {  63,4445 }, {  64,4445 }, {  65,4445 }, {  66,4445 }, {  67,4445 },

 {  68,4445 }, {  69,4445 }, {  70,4445 }, {  71,4445 }, {  72,4445 },
 {  73,4445 }, {  74,4445 }, {  75,4445 }, {  76,4445 }, {  77,4445 },
 {  78,4445 }, {  79,4445 }, {  80,4445 }, {  81,4445 }, {  82,4445 },
 {  83,4445 }, {  84,4445 }, {  85,4445 }, {  86,4445 }, {  87,4445 },
 {  88,4445 }, {  89,4445 }, {  90,4445 }, {  91,4445 }, {  92,4445 },
 {  93,4445 }, {  94,4445 }, {  95,4445 }, {  96,4445 }, {  97,4445 },
 {  98,4445 }, {  99,4445 }, { 100,4445 }, { 101,4445 }, { 102,4445 },
 { 103,4445 }, { 104,4445 }, { 105,4445 }, { 106,4445 }, { 107,4445 },
 { 108,4445 }, { 109,4445 }, { 110,4445 }, { 111,4445 }, { 112,4445 },
 { 113,4445 }, { 114,4445 }, { 115,4445 }, { 116,4445 }, { 117,4445 },

 { 118,4445 }, { 119,4445 }, { 120,4445 }, { 121,4445 }, { 122,4445 },
 { 123,4445 }, { 124,4445 }, { 125,4445 }, { 126,4445 }, { 127,4445 },
 { 128,4445 }, { 129,4445 }, { 130,4445 }, { 131,4445 }, { 132,4445 },
 { 133,4445 }, { 134,4445 }, { 135,4445 }, { 136,4445 }, { 137,4445 },
 { 138,4445 }, { 139,4445 }, { 140,4445 }, { 141,4445 }, { 142,4445 },
 { 143,4445 }, { 144,4445 }, { 145,4445 }, { 146,4445 }, { 147,4445 },
 { 148,4445 }, { 149,4445 }, { 150,4445 }, { 151,4445 }, { 152,4445 },
 { 153,4445 }, { 154,4445 }, { 155,4445 }, { 156,4445 }, { 157,4445 },
 { 158,4445 }, { 159,4445 }, { 160,4445 }, { 161,4445 }, { 162,4445 },
 { 163,4445 }, { 164,4445 }, { 165,4445 }, { 166,4445 }, { 167,4445 },

 { 168,4445 }, { 169,4445 }, { 170,4445 }, { 171,4445 }, { 172,4445 },
 { 173,4445 }, { 174,4445 }, { 175,4445 }, { 176,4445 }, { 177,4445 },
 { 178,4445 }, { 179,4445 }, { 180,4445 }, { 181,4445 }, { 182,4445 },
 { 183,4445 }, { 184,4445 }, { 185,4445 }, { 186,4445 }, { 187,4445 },
 { 188,4445 }, { 189,4445 }, { 190,4445 }, { 191,4445 }, { 192,4445 },
 { 193,4445 }, { 194,4445 }, { 195,4445 }, { 196,4445 }, { 197,4445 },
 { 198,4445 }, { 199,4445 }, { 200,4445 }, { 201,4445 }, { 202,4445 },
 { 203,4445 }, { 204,4445 }, { 205,4445 }, { 206,4445 }, { 207,4445 },
 { 208,4445 }, { 209,4445 }, { 210,4445 }, { 211,4445 }, { 212,4445 },
 { 213,4445 }, { 214,4445 }, { 215,4445 }, { 216,4445 }, { 217,4445 },

 { 218,4445 }, { 219,4445 }, { 220,4445 }, { 221,4445 }, { 222,4445 },
 { 223,4445 }, { 224,4445 }, { 225,4445 }, { 226,4445 }, { 227,4445 },
 { 228,4445 }, { 229,4445 }, { 230,4445 }, { 231,4445 }, { 232,4445 },
 { 233,4445 }, { 234,4445 }, { 235,4445 }, { 236,4445 }, { 237,4445 },
 { 238,4445 }, { 239,4445 }, { 240,4445 }, { 241,4445 }, { 242,4445 },
 { 243,4445 }, { 244,4445 }, { 245,4445 }, { 246,4445 }, { 247,4445 },
 { 248,4445 }, { 249,4445 }, { 250,4445 }, { 251,4445 }, { 252,4445 },
 { 253,4445 }, { 254,4445 }, { 255,4445 }, { 256,4445 }, {   0,  16 },
 {   0,26510 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,4445 },

 {  10,4450 }, {   0,   0 }, {  12,4445 }, {  13,4450 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,4445 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  45,-3036 }, {   0,  32 }, {   0,26463 }, {   1,4450 }, {   2,4450 },
 {   3,4450 }, {   4,4450 }, {   5,4450 }, {   6,4450 }, {   7,4450 },
 {   8,4450 }, {   9,4450 }, {  10,4450 }, {  11,4450 }, {  12,4450 },

 {  13,4450 }, {  14,4450 }, {  15,4450 }, {  16,4450 }, {  17,4450 },
 {  18,4450 }, {  19,4450 }, {  20,4450 }, {  21,4450 }, {  22,4450 },
 {  23,4450 }, {  24,4450 }, {  25,4450 }, {  26,4450 }, {  27,4450 },
 {  28,4450 }, {  29,4450 }, {  30,4450 }, {  31,4450 }, {  32,4450 },
 {  33,4450 }, {  34,4450 }, {  35,4450 }, {  36,4450 }, {  37,4450 },
 {  38,4450 }, {   0,   0 }, {  40,4450 }, {  41,4450 }, {  42,4450 },
 {  43,4450 }, {  44,4450 }, {  45,4450 }, {  46,4450 }, {  47,4450 },
 {  48,4450 }, {  49,4450 }, {  50,4450 }, {  51,4450 }, {  52,4450 },
 {  53,4450 }, {  54,4450 }, {  55,4450 }, {  56,4450 }, {  57,4450 },
 {  58,4450 }, {  59,4450 }, {  60,4450 }, {  61,4450 }, {  62,4450 },

 {  63,4450 }, {  64,4450 }, {  65,4450 }, {  66,4450 }, {  67,4450 },
 {  68,4450 }, {  69,4450 }, {  70,4450 }, {  71,4450 }, {  72,4450 },
 {  73,4450 }, {  74,4450 }, {  75,4450 }, {  76,4450 }, {  77,4450 },
 {  78,4450 }, {  79,4450 }, {  80,4450 }, {  81,4450 }, {  82,4450 },
 {  83,4450 }, {  84,4450 }, {  85,4450 }, {  86,4450 }, {  87,4450 },
 {  88,4450 }, {  89,4450 }, {  90,4450 }, {  91,4450 }, {   0,   0 },
 {  93,4450 }, {  94,4450 }, {  95,4450 }, {  96,4450 }, {  97,4450 },
 {  98,4450 }, {  99,4450 }, { 100,4450 }, { 101,4450 }, { 102,4450 },
 { 103,4450 }, { 104,4450 }, { 105,4450 }, { 106,4450 }, { 107,4450 },
 { 108,4450 }, { 109,4450 }, { 110,4450 }, { 111,4450 }, { 112,4450 },

 { 113,4450 }, { 114,4450 }, { 115,4450 }, { 116,4450 }, { 117,4450 },
 { 118,4450 }, { 119,4450 }, { 120,4450 }, { 121,4450 }, { 122,4450 },
 { 123,4450 }, { 124,4450 }, { 125,4450 }, { 126,4450 }, { 127,4450 },
 { 128,4450 }, { 129,4450 }, { 130,4450 }, { 131,4450 }, { 132,4450 },
 { 133,4450 }, { 134,4450 }, { 135,4450 }, { 136,4450 }, { 137,4450 },
 { 138,4450 }, { 139,4450 }, { 140,4450 }, { 141,4450 }, { 142,4450 },
 { 143,4450 }, { 144,4450 }, { 145,4450 }, { 146,4450 }, { 147,4450 },
 { 148,4450 }, { 149,4450 }, { 150,4450 }, { 151,4450 }, { 152,4450 },
 { 153,4450 }, { 154,4450 }, { 155,4450 }, { 156,4450 }, { 157,4450 },
 { 158,4450 }, { 159,4450 }, { 160,4450 }, { 161,4450 }, { 162,4450 },

 { 163,4450 }, { 164,4450 }, { 165,4450 }, { 166,4450 }, { 167,4450 },
 { 168,4450 }, { 169,4450 }, { 170,4450 }, { 171,4450 }, { 172,4450 },
 { 173,4450 }, { 174,4450 }, { 175,4450 }, { 176,4450 }, { 177,4450 },
 { 178,4450 }, { 179,4450 }, { 180,4450 }, { 181,4450 }, { 182,4450 },
 { 183,4450 }, { 184,4450 }, { 185,4450 }, { 186,4450 }, { 187,4450 },
 { 188,4450 }, { 189,4450 }, { 190,4450 }, { 191,4450 }, { 192,4450 },
 { 193,4450 }, { 194,4450 }, { 195,4450 }, { 196,4450 }, { 197,4450 },
 { 198,4450 }, { 199,4450 }, { 200,4450 }, { 201,4450 }, { 202,4450 },
 { 203,4450 }, { 204,4450 }, { 205,4450 }, { 206,4450 }, { 207,4450 },
 { 208,4450 }, { 209,4450 }, { 210,4450 }, { 211,4450 }, { 212,4450 },

 { 213,4450 }, { 214,4450 }, { 215,4450 }, { 216,4450 }, { 217,4450 },
 { 218,4450 }, { 219,4450 }, { 220,4450 }, { 221,4450 }, { 222,4450 },
 { 223,4450 }, { 224,4450 }, { 225,4450 }, { 226,4450 }, { 227,4450 },
 { 228,4450 }, { 229,4450 }, { 230,4450 }, { 231,4450 }, { 232,4450 },
 { 233,4450 }, { 234,4450 }, { 235,4450 }, { 236,4450 }, { 237,4450 },
 { 238,4450 }, { 239,4450 }, { 240,4450 }, { 241,4450 }, { 242,4450 },
 { 243,4450 }, { 244,4450 }, { 245,4450 }, { 246,4450 }, { 247,4450 },
 { 248,4450 }, { 249,4450 }, { 250,4450 }, { 251,4450 }, { 252,4450 },
 { 253,4450 }, { 254,4450 }, { 255,4450 }, { 256,4450 }, {   0,  32 },
 {   0,26205 }, {   1,4192 }, {   2,4192 }, {   3,4192 }, {   4,4192 },

 {   5,4192 }, {   6,4192 }, {   7,4192 }, {   8,4192 }, {   9,4192 },
 {  10,4192 }, {  11,4192 }, {  12,4192 }, {  13,4192 }, {  14,4192 },
 {  15,4192 }, {  16,4192 }, {  17,4192 }, {  18,4192 }, {  19,4192 },
 {  20,4192 }, {  21,4192 }, {  22,4192 }, {  23,4192 }, {  24,4192 },
 {  25,4192 }, {  26,4192 }, {  27,4192 }, {  28,4192 }, {  29,4192 },
 {  30,4192 }, {  31,4192 }, {  32,4192 }, {  33,4192 }, {  34,4192 },
 {  35,4192 }, {  36,4192 }, {  37,4192 }, {  38,4192 }, {   0,   0 },
 {  40,4192 }, {  41,4192 }, {  42,4192 }, {  43,4192 }, {  44,4192 },
 {  45,4192 }, {  46,4192 }, {  47,4192 }, {  48,4192 }, {  49,4192 },
 {  50,4192 }, {  51,4192 }, {  52,4192 }, {  53,4192 }, {  54,4192 },

 {  55,4192 }, {  56,4192 }, {  57,4192 }, {  58,4192 }, {  59,4192 },
 {  60,4192 }, {  61,4192 }, {  62,4192 }, {  63,4192 }, {  64,4192 },
 {  65,4192 }, {  66,4192 }, {  67,4192 }, {  68,4192 }, {  69,4192 },
 {  70,4192 }, {  71,4192 }, {  72,4192 }, {  73,4192 }, {  74,4192 },
 {  75,4192 }, {  76,4192 }, {  77,4192 }, {  78,4192 }, {  79,4192 },
 {  80,4192 }, {  81,4192 }, {  82,4192 }, {  83,4192 }, {  84,4192 },
 {  85,4192 }, {  86,4192 }, {  87,4192 }, {  88,4192 }, {  89,4192 },
 {  90,4192 }, {  91,4192 }, {   0,   0 }, {  93,4192 }, {  94,4192 },
 {  95,4192 }, {  96,4192 }, {  97,4192 }, {  98,4192 }, {  99,4192 },
 { 100,4192 }, { 101,4192 }, { 102,4192 }, { 103,4192 }, { 104,4192 },

 { 105,4192 }, { 106,4192 }, { 107,4192 }, { 108,4192 }, { 109,4192 },
 { 110,4192 }, { 111,4192 }, { 112,4192 }, { 113,4192 }, { 114,4192 },
 { 115,4192 }, { 116,4192 }, { 117,4192 }, { 118,4192 }, { 119,4192 },
 { 120,4192 }, { 121,4192 }, { 122,4192 }, { 123,4192 }, { 124,4192 },
 { 125,4192 }, { 126,4192 }, { 127,4192 }, { 128,4192 }, { 129,4192 },
 { 130,4192 }, { 131,4192 }, { 132,4192 }, { 133,4192 }, { 134,4192 },
 { 135,4192 }, { 136,4192 }, { 137,4192 }, { 138,4192 }, { 139,4192 },
 { 140,4192 }, { 141,4192 }, { 142,4192 }, { 143,4192 }, { 144,4192 },
 { 145,4192 }, { 146,4192 }, { 147,4192 }, { 148,4192 }, { 149,4192 },
 { 150,4192 }, { 151,4192 }, { 152,4192 }, { 153,4192 }, { 154,4192 },

 { 155,4192 }, { 156,4192 }, { 157,4192 }, { 158,4192 }, { 159,4192 },
 { 160,4192 }, { 161,4192 }, { 162,4192 }, { 163,4192 }, { 164,4192 },
 { 165,4192 }, { 166,4192 }, { 167,4192 }, { 168,4192 }, { 169,4192 },
 { 170,4192 }, { 171,4192 }, { 172,4192 }, { 173,4192 }, { 174,4192 },
 { 175,4192 }, { 176,4192 }, { 177,4192 }, { 178,4192 }, { 179,4192 },
 { 180,4192 }, { 181,4192 }, { 182,4192 }, { 183,4192 }, { 184,4192 },
 { 185,4192 }, { 186,4192 }, { 187,4192 }, { 188,4192 }, { 189,4192 },
 { 190,4192 }, { 191,4192 }, { 192,4192 }, { 193,4192 }, { 194,4192 },
 { 195,4192 }, { 196,4192 }, { 197,4192 }, { 198,4192 }, { 199,4192 },
 { 200,4192 }, { 201,4192 }, { 202,4192 }, { 203,4192 }, { 204,4192 },

 { 205,4192 }, { 206,4192 }, { 207,4192 }, { 208,4192 }, { 209,4192 },
 { 210,4192 }, { 211,4192 }, { 212,4192 }, { 213,4192 }, { 214,4192 },
 { 215,4192 }, { 216,4192 }, { 217,4192 }, { 218,4192 }, { 219,4192 },
 { 220,4192 }, { 221,4192 }, { 222,4192 }, { 223,4192 }, { 224,4192 },
 { 225,4192 }, { 226,4192 }, { 227,4192 }, { 228,4192 }, { 229,4192 },
 { 230,4192 }, { 231,4192 }, { 232,4192 }, { 233,4192 }, { 234,4192 },
 { 235,4192 }, { 236,4192 }, { 237,4192 }, { 238,4192 }, { 239,4192 },
 { 240,4192 }, { 241,4192 }, { 242,4192 }, { 243,4192 }, { 244,4192 },
 { 245,4192 }, { 246,4192 }, { 247,4192 }, { 248,4192 }, { 249,4192 },
 { 250,4192 }, { 251,4192 }, { 252,4192 }, { 253,4192 }, { 254,4192 },

 { 255,4192 }, { 256,4192 }, {   0,  22 }, {   0,25947 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   9,4192 }, {  10,4197 }, {   0,   0 },
 {  12,4192 }, {  13,4197 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  32,4192 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  39,-3597 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  45,-3592 }, {   0,  42 },

 {   0,25900 }, {   1,-3637 }, {   2,-3637 }, {   3,-3637 }, {   4,-3637 },
 {   5,-3637 }, {   6,-3637 }, {   7,-3637 }, {   8,-3637 }, {   9,-3637 },
 {  10,-3637 }, {  11,-3637 }, {  12,-3637 }, {  13,-3637 }, {  14,-3637 },
 {  15,-3637 }, {  16,-3637 }, {  17,-3637 }, {  18,-3637 }, {  19,-3637 },
 {  20,-3637 }, {  21,-3637 }, {  22,-3637 }, {  23,-3637 }, {  24,-3637 },
 {  25,-3637 }, {  26,-3637 }, {  27,-3637 }, {  28,-3637 }, {  29,-3637 },
 {  30,-3637 }, {  31,-3637 }, {  32,-3637 }, {  33,-3637 }, {  34,-3637 },
 {  35,-3637 }, {  36,-3637 }, {  37,-3637 }, {  38,-3637 }, {  39,-3637 },
 {  40,-3637 }, {  41,-3637 }, {  42,-3637 }, {  43,-3637 }, {  44,-3637 },
 {  45,-3637 }, {  46,-3637 }, {  47,-3637 }, {  48,4152 }, {  49,4152 },

 {  50,4152 }, {  51,4152 }, {  52,4152 }, {  53,4152 }, {  54,4152 },
 {  55,4152 }, {  56,-3637 }, {  57,-3637 }, {  58,-3637 }, {  59,-3637 },
 {  60,-3637 }, {  61,-3637 }, {  62,-3637 }, {  63,-3637 }, {  64,-3637 },
 {  65,-3637 }, {  66,-3637 }, {  67,-3637 }, {  68,-3637 }, {  69,-3637 },
 {  70,-3637 }, {  71,-3637 }, {  72,-3637 }, {  73,-3637 }, {  74,-3637 },
 {  75,-3637 }, {  76,-3637 }, {  77,-3637 }, {  78,-3637 }, {  79,-3637 },
 {  80,-3637 }, {  81,-3637 }, {  82,-3637 }, {  83,-3637 }, {  84,-3637 },
 {  85,4165 }, {  86,-3637 }, {  87,-3637 }, {  88,-3637 }, {  89,-3637 },
 {  90,-3637 }, {  91,-3637 }, {  92,-3637 }, {  93,-3637 }, {  94,-3637 },
 {  95,-3637 }, {  96,-3637 }, {  97,-3637 }, {  98,-3637 }, {  99,-3637 },

 { 100,-3637 }, { 101,-3637 }, { 102,-3637 }, { 103,-3637 }, { 104,-3637 },
 { 105,-3637 }, { 106,-3637 }, { 107,-3637 }, { 108,-3637 }, { 109,-3637 },
 { 110,-3637 }, { 111,-3637 }, { 112,-3637 }, { 113,-3637 }, { 114,-3637 },
 { 115,-3637 }, { 116,-3637 }, { 117,4188 }, { 118,-3637 }, { 119,-3637 },
 { 120,4226 }, { 121,-3637 }, { 122,-3637 }, { 123,-3637 }, { 124,-3637 },
 { 125,-3637 }, { 126,-3637 }, { 127,-3637 }, { 128,-3637 }, { 129,-3637 },
 { 130,-3637 }, { 131,-3637 }, { 132,-3637 }, { 133,-3637 }, { 134,-3637 },
 { 135,-3637 }, { 136,-3637 }, { 137,-3637 }, { 138,-3637 }, { 139,-3637 },
 { 140,-3637 }, { 141,-3637 }, { 142,-3637 }, { 143,-3637 }, { 144,-3637 },
 { 145,-3637 }, { 146,-3637 }, { 147,-3637 }, { 148,-3637 }, { 149,-3637 },

 { 150,-3637 }, { 151,-3637 }, { 152,-3637 }, { 153,-3637 }, { 154,-3637 },
 { 155,-3637 }, { 156,-3637 }, { 157,-3637 }, { 158,-3637 }, { 159,-3637 },
 { 160,-3637 }, { 161,-3637 }, { 162,-3637 }, { 163,-3637 }, { 164,-3637 },
 { 165,-3637 }, { 166,-3637 }, { 167,-3637 }, { 168,-3637 }, { 169,-3637 },
 { 170,-3637 }, { 171,-3637 }, { 172,-3637 }, { 173,-3637 }, { 174,-3637 },
 { 175,-3637 }, { 176,-3637 }, { 177,-3637 }, { 178,-3637 }, { 179,-3637 },
 { 180,-3637 }, { 181,-3637 }, { 182,-3637 }, { 183,-3637 }, { 184,-3637 },
 { 185,-3637 }, { 186,-3637 }, { 187,-3637 }, { 188,-3637 }, { 189,-3637 },
 { 190,-3637 }, { 191,-3637 }, { 192,-3637 }, { 193,-3637 }, { 194,-3637 },
 { 195,-3637 }, { 196,-3637 }, { 197,-3637 }, { 198,-3637 }, { 199,-3637 },

 { 200,-3637 }, { 201,-3637 }, { 202,-3637 }, { 203,-3637 }, { 204,-3637 },
 { 205,-3637 }, { 206,-3637 }, { 207,-3637 }, { 208,-3637 }, { 209,-3637 },
 { 210,-3637 }, { 211,-3637 }, { 212,-3637 }, { 213,-3637 }, { 214,-3637 },
 { 215,-3637 }, { 216,-3637 }, { 217,-3637 }, { 218,-3637 }, { 219,-3637 },
 { 220,-3637 }, { 221,-3637 }, { 222,-3637 }, { 223,-3637 }, { 224,-3637 },
 { 225,-3637 }, { 226,-3637 }, { 227,-3637 }, { 228,-3637 }, { 229,-3637 },
 { 230,-3637 }, { 231,-3637 }, { 232,-3637 }, { 233,-3637 }, { 234,-3637 },
 { 235,-3637 }, { 236,-3637 }, { 237,-3637 }, { 238,-3637 }, { 239,-3637 },
 { 240,-3637 }, { 241,-3637 }, { 242,-3637 }, { 243,-3637 }, { 244,-3637 },
 { 245,-3637 }, { 246,-3637 }, { 247,-3637 }, { 248,-3637 }, { 249,-3637 },

 { 250,-3637 }, { 251,-3637 }, { 252,-3637 }, { 253,-3637 }, { 254,-3637 },
 { 255,-3637 }, { 256,-3637 }, {   0,  31 }, {   0,25642 }, {   1,4072 },
 {   2,4072 }, {   3,4072 }, {   4,4072 }, {   5,4072 }, {   6,4072 },
 {   7,4072 }, {   8,4072 }, {   9,4072 }, {  10,4072 }, {  11,4072 },
 {  12,4072 }, {  13,4072 }, {  14,4072 }, {  15,4072 }, {  16,4072 },
 {  17,4072 }, {  18,4072 }, {  19,4072 }, {  20,4072 }, {  21,4072 },
 {  22,4072 }, {  23,4072 }, {  24,4072 }, {  25,4072 }, {  26,4072 },
 {  27,4072 }, {  28,4072 }, {  29,4072 }, {  30,4072 }, {  31,4072 },
 {  32,4072 }, {  33,4072 }, {  34,4072 }, {  35,4072 }, {  36,4072 },
 {  37,4072 }, {  38,4072 }, {   0,   0 }, {  40,4072 }, {  41,4072 },

 {  42,4072 }, {  43,4072 }, {  44,4072 }, {  45,4072 }, {  46,4072 },
 {  47,4072 }, {  48,4072 }, {  49,4072 }, {  50,4072 }, {  51,4072 },
 {  52,4072 }, {  53,4072 }, {  54,4072 }, {  55,4072 }, {  56,4072 },
 {  57,4072 }, {  58,4072 }, {  59,4072 }, {  60,4072 }, {  61,4072 },
 {  62,4072 }, {  63,4072 }, {  64,4072 }, {  65,4072 }, {  66,4072 },
 {  67,4072 }, {  68,4072 }, {  69,4072 }, {  70,4072 }, {  71,4072 },
 {  72,4072 }, {  73,4072 }, {  74,4072 }, {  75,4072 }, {  76,4072 },
 {  77,4072 }, {  78,4072 }, {  79,4072 }, {  80,4072 }, {  81,4072 },
 {  82,4072 }, {  83,4072 }, {  84,4072 }, {  85,4072 }, {  86,4072 },
 {  87,4072 }, {  88,4072 }, {  89,4072 }, {  90,4072 }, {  91,4072 },

 {  92,4072 }, {  93,4072 }, {  94,4072 }, {  95,4072 }, {  96,4072 },
 {  97,4072 }, {  98,4072 }, {  99,4072 }, { 100,4072 }, { 101,4072 },
 { 102,4072 }, { 103,4072 }, { 104,4072 }, { 105,4072 }, { 106,4072 },
 { 107,4072 }, { 108,4072 }, { 109,4072 }, { 110,4072 }, { 111,4072 },
 { 112,4072 }, { 113,4072 }, { 114,4072 }, { 115,4072 }, { 116,4072 },
 { 117,4072 }, { 118,4072 }, { 119,4072 }, { 120,4072 }, { 121,4072 },
 { 122,4072 }, { 123,4072 }, { 124,4072 }, { 125,4072 }, { 126,4072 },
 { 127,4072 }, { 128,4072 }, { 129,4072 }, { 130,4072 }, { 131,4072 },
 { 132,4072 }, { 133,4072 }, { 134,4072 }, { 135,4072 }, { 136,4072 },
 { 137,4072 }, { 138,4072 }, { 139,4072 }, { 140,4072 }, { 141,4072 },

 { 142,4072 }, { 143,4072 }, { 144,4072 }, { 145,4072 }, { 146,4072 },
 { 147,4072 }, { 148,4072 }, { 149,4072 }, { 150,4072 }, { 151,4072 },
 { 152,4072 }, { 153,4072 }, { 154,4072 }, { 155,4072 }, { 156,4072 },
 { 157,4072 }, { 158,4072 }, { 159,4072 }, { 160,4072 }, { 161,4072 },
 { 162,4072 }, { 163,4072 }, { 164,4072 }, { 165,4072 }, { 166,4072 },
 { 167,4072 }, { 168,4072 }, { 169,4072 }, { 170,4072 }, { 171,4072 },
 { 172,4072 }, { 173,4072 }, { 174,4072 }, { 175,4072 }, { 176,4072 },
 { 177,4072 }, { 178,4072 }, { 179,4072 }, { 180,4072 }, { 181,4072 },
 { 182,4072 }, { 183,4072 }, { 184,4072 }, { 185,4072 }, { 186,4072 },
 { 187,4072 }, { 188,4072 }, { 189,4072 }, { 190,4072 }, { 191,4072 },

 { 192,4072 }, { 193,4072 }, { 194,4072 }, { 195,4072 }, { 196,4072 },
 { 197,4072 }, { 198,4072 }, { 199,4072 }, { 200,4072 }, { 201,4072 },
 { 202,4072 }, { 203,4072 }, { 204,4072 }, { 205,4072 }, { 206,4072 },
 { 207,4072 }, { 208,4072 }, { 209,4072 }, { 210,4072 }, { 211,4072 },
 { 212,4072 }, { 213,4072 }, { 214,4072 }, { 215,4072 }, { 216,4072 },
 { 217,4072 }, { 218,4072 }, { 219,4072 }, { 220,4072 }, { 221,4072 },
 { 222,4072 }, { 223,4072 }, { 224,4072 }, { 225,4072 }, { 226,4072 },
 { 227,4072 }, { 228,4072 }, { 229,4072 }, { 230,4072 }, { 231,4072 },
 { 232,4072 }, { 233,4072 }, { 234,4072 }, { 235,4072 }, { 236,4072 },
 { 237,4072 }, { 238,4072 }, { 239,4072 }, { 240,4072 }, { 241,4072 },

 { 242,4072 }, { 243,4072 }, { 244,4072 }, { 245,4072 }, { 246,4072 },
 { 247,4072 }, { 248,4072 }, { 249,4072 }, { 250,4072 }, { 251,4072 },
 { 252,4072 }, { 253,4072 }, { 254,4072 }, { 255,4072 }, { 256,4072 },
 {   0,  22 }, {   0,25384 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,3629 }, {  10,3634 }, {   0,   0 }, {  12,3629 }, {  13,3634 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,3629 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39,-4160 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-4155 }, {   0,  46 }, {   0,25337 }, {   1,4025 },
 {   2,4025 }, {   3,4025 }, {   4,4025 }, {   5,4025 }, {   6,4025 },
 {   7,4025 }, {   8,4025 }, {   9,4025 }, {  10,4025 }, {  11,4025 },
 {  12,4025 }, {  13,4025 }, {  14,4025 }, {  15,4025 }, {  16,4025 },
 {  17,4025 }, {  18,4025 }, {  19,4025 }, {  20,4025 }, {  21,4025 },
 {  22,4025 }, {  23,4025 }, {  24,4025 }, {  25,4025 }, {  26,4025 },
 {  27,4025 }, {  28,4025 }, {  29,4025 }, {  30,4025 }, {  31,4025 },
 {  32,4025 }, {  33,4025 }, {  34,4025 }, {  35,4025 }, {   0,   0 },

 {  37,4025 }, {  38,4025 }, {  39,4025 }, {  40,4025 }, {  41,4025 },
 {  42,4025 }, {  43,4025 }, {  44,4025 }, {  45,4025 }, {  46,4025 },
 {  47,4025 }, {  48,4025 }, {  49,4025 }, {  50,4025 }, {  51,4025 },
 {  52,4025 }, {  53,4025 }, {  54,4025 }, {  55,4025 }, {  56,4025 },
 {  57,4025 }, {  58,4025 }, {  59,4025 }, {  60,4025 }, {  61,4025 },
 {  62,4025 }, {  63,4025 }, {  64,4025 }, {  65,4025 }, {  66,4025 },
 {  67,4025 }, {  68,4025 }, {  69,4025 }, {  70,4025 }, {  71,4025 },
 {  72,4025 }, {  73,4025 }, {  74,4025 }, {  75,4025 }, {  76,4025 },
 {  77,4025 }, {  78,4025 }, {  79,4025 }, {  80,4025 }, {  81,4025 },
 {  82,4025 }, {  83,4025 }, {  84,4025 }, {  85,4025 }, {  86,4025 },

 {  87,4025 }, {  88,4025 }, {  89,4025 }, {  90,4025 }, {  91,4025 },
 {  92,4025 }, {  93,4025 }, {  94,4025 }, {  95,4025 }, {  96,4025 },
 {  97,4025 }, {  98,4025 }, {  99,4025 }, { 100,4025 }, { 101,4025 },
 { 102,4025 }, { 103,4025 }, { 104,4025 }, { 105,4025 }, { 106,4025 },
 { 107,4025 }, { 108,4025 }, { 109,4025 }, { 110,4025 }, { 111,4025 },
 { 112,4025 }, { 113,4025 }, { 114,4025 }, { 115,4025 }, { 116,4025 },
 { 117,4025 }, { 118,4025 }, { 119,4025 }, { 120,4025 }, { 121,4025 },
 { 122,4025 }, { 123,4025 }, { 124,4025 }, { 125,4025 }, { 126,4025 },
 { 127,4025 }, { 128,4025 }, { 129,4025 }, { 130,4025 }, { 131,4025 },
 { 132,4025 }, { 133,4025 }, { 134,4025 }, { 135,4025 }, { 136,4025 },

 { 137,4025 }, { 138,4025 }, { 139,4025 }, { 140,4025 }, { 141,4025 },
 { 142,4025 }, { 143,4025 }, { 144,4025 }, { 145,4025 }, { 146,4025 },
 { 147,4025 }, { 148,4025 }, { 149,4025 }, { 150,4025 }, { 151,4025 },
 { 152,4025 }, { 153,4025 }, { 154,4025 }, { 155,4025 }, { 156,4025 },
 { 157,4025 }, { 158,4025 }, { 159,4025 }, { 160,4025 }, { 161,4025 },
 { 162,4025 }, { 163,4025 }, { 164,4025 }, { 165,4025 }, { 166,4025 },
 { 167,4025 }, { 168,4025 }, { 169,4025 }, { 170,4025 }, { 171,4025 },
 { 172,4025 }, { 173,4025 }, { 174,4025 }, { 175,4025 }, { 176,4025 },
 { 177,4025 }, { 178,4025 }, { 179,4025 }, { 180,4025 }, { 181,4025 },
 { 182,4025 }, { 183,4025 }, { 184,4025 }, { 185,4025 }, { 186,4025 },

 { 187,4025 }, { 188,4025 }, { 189,4025 }, { 190,4025 }, { 191,4025 },
 { 192,4025 }, { 193,4025 }, { 194,4025 }, { 195,4025 }, { 196,4025 },
 { 197,4025 }, { 198,4025 }, { 199,4025 }, { 200,4025 }, { 201,4025 },
 { 202,4025 }, { 203,4025 }, { 204,4025 }, { 205,4025 }, { 206,4025 },
 { 207,4025 }, { 208,4025 }, { 209,4025 }, { 210,4025 }, { 211,4025 },
 { 212,4025 }, { 213,4025 }, { 214,4025 }, { 215,4025 }, { 216,4025 },
 { 217,4025 }, { 218,4025 }, { 219,4025 }, { 220,4025 }, { 221,4025 },
 { 222,4025 }, { 223,4025 }, { 224,4025 }, { 225,4025 }, { 226,4025 },
 { 227,4025 }, { 228,4025 }, { 229,4025 }, { 230,4025 }, { 231,4025 },
 { 232,4025 }, { 233,4025 }, { 234,4025 }, { 235,4025 }, { 236,4025 },

 { 237,4025 }, { 238,4025 }, { 239,4025 }, { 240,4025 }, { 241,4025 },
 { 242,4025 }, { 243,4025 }, { 244,4025 }, { 245,4025 }, { 246,4025 },
 { 247,4025 }, { 248,4025 }, { 249,4025 }, { 250,4025 }, { 251,4025 },
 { 252,4025 }, { 253,4025 }, { 254,4025 }, { 255,4025 }, { 256,4025 },
 {   0,  46 }, {   0,25079 }, {   1,3767 }, {   2,3767 }, {   3,3767 },
 {   4,3767 }, {   5,3767 }, {   6,3767 }, {   7,3767 }, {   8,3767 },
 {   9,3767 }, {  10,3767 }, {  11,3767 }, {  12,3767 }, {  13,3767 },
 {  14,3767 }, {  15,3767 }, {  16,3767 }, {  17,3767 }, {  18,3767 },
 {  19,3767 }, {  20,3767 }, {  21,3767 }, {  22,3767 }, {  23,3767 },
 {  24,3767 }, {  25,3767 }, {  26,3767 }, {  27,3767 }, {  28,3767 },

 {  29,3767 }, {  30,3767 }, {  31,3767 }, {  32,3767 }, {  33,3767 },
 {  34,3767 }, {  35,3767 }, {   0,   0 }, {  37,3767 }, {  38,3767 },
 {  39,3767 }, {  40,3767 }, {  41,3767 }, {  42,3767 }, {  43,3767 },
 {  44,3767 }, {  45,3767 }, {  46,3767 }, {  47,3767 }, {  48,3767 },
 {  49,3767 }, {  50,3767 }, {  51,3767 }, {  52,3767 }, {  53,3767 },
 {  54,3767 }, {  55,3767 }, {  56,3767 }, {  57,3767 }, {  58,3767 },
 {  59,3767 }, {  60,3767 }, {  61,3767 }, {  62,3767 }, {  63,3767 },
 {  64,3767 }, {  65,3767 }, {  66,3767 }, {  67,3767 }, {  68,3767 },
 {  69,3767 }, {  70,3767 }, {  71,3767 }, {  72,3767 }, {  73,3767 },
 {  74,3767 }, {  75,3767 }, {  76,3767 }, {  77,3767 }, {  78,3767 },

 {  79,3767 }, {  80,3767 }, {  81,3767 }, {  82,3767 }, {  83,3767 },
 {  84,3767 }, {  85,3767 }, {  86,3767 }, {  87,3767 }, {  88,3767 },
 {  89,3767 }, {  90,3767 }, {  91,3767 }, {  92,3767 }, {  93,3767 },
 {  94,3767 }, {  95,3767 }, {  96,3767 }, {  97,3767 }, {  98,3767 },
 {  99,3767 }, { 100,3767 }, { 101,3767 }, { 102,3767 }, { 103,3767 },
 { 104,3767 }, { 105,3767 }, { 106,3767 }, { 107,3767 }, { 108,3767 },
 { 109,3767 }, { 110,3767 }, { 111,3767 }, { 112,3767 }, { 113,3767 },
 { 114,3767 }, { 115,3767 }, { 116,3767 }, { 117,3767 }, { 118,3767 },
 { 119,3767 }, { 120,3767 }, { 121,3767 }, { 122,3767 }, { 123,3767 },
 { 124,3767 }, { 125,3767 }, { 126,3767 }, { 127,3767 }, { 128,3767 },

 { 129,3767 }, { 130,3767 }, { 131,3767 }, { 132,3767 }, { 133,3767 },
 { 134,3767 }, { 135,3767 }, { 136,3767 }, { 137,3767 }, { 138,3767 },
 { 139,3767 }, { 140,3767 }, { 141,3767 }, { 142,3767 }, { 143,3767 },
 { 144,3767 }, { 145,3767 }, { 146,3767 }, { 147,3767 }, { 148,3767 },
 { 149,3767 }, { 150,3767 }, { 151,3767 }, { 152,3767 }, { 153,3767 },
 { 154,3767 }, { 155,3767 }, { 156,3767 }, { 157,3767 }, { 158,3767 },
 { 159,3767 }, { 160,3767 }, { 161,3767 }, { 162,3767 }, { 163,3767 },
 { 164,3767 }, { 165,3767 }, { 166,3767 }, { 167,3767 }, { 168,3767 },
 { 169,3767 }, { 170,3767 }, { 171,3767 }, { 172,3767 }, { 173,3767 },
 { 174,3767 }, { 175,3767 }, { 176,3767 }, { 177,3767 }, { 178,3767 },

 { 179,3767 }, { 180,3767 }, { 181,3767 }, { 182,3767 }, { 183,3767 },
 { 184,3767 }, { 185,3767 }, { 186,3767 }, { 187,3767 }, { 188,3767 },
 { 189,3767 }, { 190,3767 }, { 191,3767 }, { 192,3767 }, { 193,3767 },
 { 194,3767 }, { 195,3767 }, { 196,3767 }, { 197,3767 }, { 198,3767 },
 { 199,3767 }, { 200,3767 }, { 201,3767 }, { 202,3767 }, { 203,3767 },
 { 204,3767 }, { 205,3767 }, { 206,3767 }, { 207,3767 }, { 208,3767 },
 { 209,3767 }, { 210,3767 }, { 211,3767 }, { 212,3767 }, { 213,3767 },
 { 214,3767 }, { 215,3767 }, { 216,3767 }, { 217,3767 }, { 218,3767 },
 { 219,3767 }, { 220,3767 }, { 221,3767 }, { 222,3767 }, { 223,3767 },
 { 224,3767 }, { 225,3767 }, { 226,3767 }, { 227,3767 }, { 228,3767 },

 { 229,3767 }, { 230,3767 }, { 231,3767 }, { 232,3767 }, { 233,3767 },
 { 234,3767 }, { 235,3767 }, { 236,3767 }, { 237,3767 }, { 238,3767 },
 { 239,3767 }, { 240,3767 }, { 241,3767 }, { 242,3767 }, { 243,3767 },
 { 244,3767 }, { 245,3767 }, { 246,3767 }, { 247,3767 }, { 248,3767 },
 { 249,3767 }, { 250,3767 }, { 251,3767 }, { 252,3767 }, { 253,3767 },
 { 254,3767 }, { 255,3767 }, { 256,3767 }, {   0,  48 }, {   0,24821 },
 {   0,  53 }, {   0,24819 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  53 }, {   0,24814 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,3767 }, {  10,3767 }, {   0,   0 }, {  12,3767 }, {  13,3767 },
 {   9,3762 }, {  10,3762 }, {   0,   0 }, {  12,3762 }, {  13,3762 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,3767 }, {   0,   0 },
 {  36,-4714 }, {   0,   0 }, {   0,   0 }, {  32,3762 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,3767 },
 {  66,3767 }, {  67,3767 }, {  68,3767 }, {  69,3767 }, {  70,3767 },

 {  71,3767 }, {  72,3767 }, {  73,3767 }, {  74,3767 }, {  75,3767 },
 {  76,3767 }, {  77,3767 }, {  78,3767 }, {  79,3767 }, {  80,3767 },
 {  81,3767 }, {  82,3767 }, {  83,3767 }, {  84,3767 }, {  85,3767 },
 {  86,3767 }, {  87,3767 }, {  88,3767 }, {  89,3767 }, {  90,3767 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  95,3767 },
 {   0,   0 }, {  97,3767 }, {  98,3767 }, {  99,3767 }, { 100,3767 },
 { 101,3767 }, { 102,3767 }, { 103,3767 }, { 104,3767 }, { 105,3767 },
 { 106,3767 }, { 107,3767 }, { 108,3767 }, { 109,3767 }, { 110,3767 },
 { 111,3767 }, { 112,3767 }, { 113,3767 }, { 114,3767 }, { 115,3767 },
 { 116,3767 }, { 117,3767 }, { 118,3767 }, { 119,3767 }, { 120,3767 },

 { 121,3767 }, { 122,3767 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, { 128,3767 }, { 129,3767 }, { 130,3767 },
 { 131,3767 }, { 132,3767 }, { 133,3767 }, { 134,3767 }, { 135,3767 },
 { 136,3767 }, { 137,3767 }, { 138,3767 }, { 139,3767 }, { 140,3767 },
 { 141,3767 }, { 142,3767 }, { 143,3767 }, { 144,3767 }, { 145,3767 },
 { 146,3767 }, { 147,3767 }, { 148,3767 }, { 149,3767 }, { 150,3767 },
 { 151,3767 }, { 152,3767 }, { 153,3767 }, { 154,3767 }, { 155,3767 },
 { 156,3767 }, { 157,3767 }, { 158,3767 }, { 159,3767 }, { 160,3767 },
 { 161,3767 }, { 162,3767 }, { 163,3767 }, { 164,3767 }, { 165,3767 },
 { 166,3767 }, { 167,3767 }, { 168,3767 }, { 169,3767 }, { 170,3767 },

 { 171,3767 }, { 172,3767 }, { 173,3767 }, { 174,3767 }, { 175,3767 },
 { 176,3767 }, { 177,3767 }, { 178,3767 }, { 179,3767 }, { 180,3767 },
 { 181,3767 }, { 182,3767 }, { 183,3767 }, { 184,3767 }, { 185,3767 },
 { 186,3767 }, { 187,3767 }, { 188,3767 }, { 189,3767 }, { 190,3767 },
 { 191,3767 }, { 192,3767 }, { 193,3767 }, { 194,3767 }, { 195,3767 },
 { 196,3767 }, { 197,3767 }, { 198,3767 }, { 199,3767 }, { 200,3767 },
 { 201,3767 }, { 202,3767 }, { 203,3767 }, { 204,3767 }, { 205,3767 },
 { 206,3767 }, { 207,3767 }, { 208,3767 }, { 209,3767 }, { 210,3767 },
 { 211,3767 }, { 212,3767 }, { 213,3767 }, { 214,3767 }, { 215,3767 },
 { 216,3767 }, { 217,3767 }, { 218,3767 }, { 219,3767 }, { 220,3767 },

 { 221,3767 }, { 222,3767 }, { 223,3767 }, { 224,3767 }, { 225,3767 },
 { 226,3767 }, { 227,3767 }, { 228,3767 }, { 229,3767 }, { 230,3767 },
 { 231,3767 }, { 232,3767 }, { 233,3767 }, { 234,3767 }, { 235,3767 },
 { 236,3767 }, { 237,3767 }, { 238,3767 }, { 239,3767 }, { 240,3767 },
 { 241,3767 }, { 242,3767 }, { 243,3767 }, { 244,3767 }, { 245,3767 },
 { 246,3767 }, { 247,3767 }, { 248,3767 }, { 249,3767 }, { 250,3767 },
 { 251,3767 }, { 252,3767 }, { 253,3767 }, { 254,3767 }, { 255,3767 },
 {   0,  24 }, {   0,24564 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  26 }, {   0,24559 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,4025 }, {  10,4030 }, {   0,   0 }, {  12,4025 }, {  13,4030 },

 {   9,4041 }, {  10,4041 }, {   0,   0 }, {  12,4041 }, {  13,4041 },
 {   0,   0 }, {   0,  26 }, {   0,24543 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   9,4025 }, {  10,4025 }, {  32,4025 }, {  12,4025 },
 {  13,4025 }, {   0,   0 }, {   0,   0 }, {  32,4041 }, {   0,   0 },
 {  39,-4980 }, {   0,   0 }, {   0,   1 }, {   0,24522 }, {   0,  70 },
 {   0,24520 }, {  45,-4928 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 }, {  32,4025 },
 {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  32,   0 }, {   0,   0 }, {   0,   0 }, {  33,   0 }, {   0,   0 },
 {  35,   0 }, {   0,   0 }, {  37,   0 }, {  38,   0 }, {   0,  68 },
 {   0,24480 }, {   0,   0 }, {  42,   0 }, {  43,   0 }, {   0,   0 },
 {  45,   0 }, {   0,   0 }, {  47,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  71 }, {   0,24463 }, {   0,   0 }, {   0,   0 },
 {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  33, -40 }, {   0,   0 },
 {  35, -40 }, {   0,   0 }, {  37, -40 }, {  38, -40 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  42, -40 }, {  43, -40 }, {   0,   0 },
 {  45, -40 }, {   0,   0 }, {  47, -40 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  94,   0 },
 {   0,   0 }, {  96,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  60, -40 }, {  61, -40 }, {  62, -40 }, {  63, -40 }, {  64, -40 },
 {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 },
 {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  44 }, {   0,24401 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 124,   0 },
 {   0,   0 }, { 126,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  94, -40 },
 {   0,   0 }, {  96, -40 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  36,-5515 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 124, -40 },
 {   0,   0 }, { 126, -40 }, {  48,4257 }, {  49,4257 }, {  50,4257 },

 {  51,4257 }, {  52,4257 }, {  53,4257 }, {  54,4257 }, {  55,4257 },
 {  56,4257 }, {  57,4257 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,4257 },
 {  66,4257 }, {  67,4257 }, {  68,4257 }, {  69,4257 }, {  70,4257 },
 {  71,4257 }, {  72,4257 }, {  73,4257 }, {  74,4257 }, {  75,4257 },
 {  76,4257 }, {  77,4257 }, {  78,4257 }, {  79,4257 }, {  80,4257 },
 {  81,4257 }, {  82,4257 }, {  83,4257 }, {  84,4257 }, {  85,4257 },
 {  86,4257 }, {  87,4257 }, {  88,4257 }, {  89,4257 }, {  90,4257 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  95,4257 },
 {   0,   0 }, {  97,4257 }, {  98,4257 }, {  99,4257 }, { 100,4257 },

 { 101,4257 }, { 102,4257 }, { 103,4257 }, { 104,4257 }, { 105,4257 },
 { 106,4257 }, { 107,4257 }, { 108,4257 }, { 109,4257 }, { 110,4257 },
 { 111,4257 }, { 112,4257 }, { 113,4257 }, { 114,4257 }, { 115,4257 },
 { 116,4257 }, { 117,4257 }, { 118,4257 }, { 119,4257 }, { 120,4257 },
 { 121,4257 }, { 122,4257 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, { 128,4257 }, { 129,4257 }, { 130,4257 },
 { 131,4257 }, { 132,4257 }, { 133,4257 }, { 134,4257 }, { 135,4257 },
 { 136,4257 }, { 137,4257 }, { 138,4257 }, { 139,4257 }, { 140,4257 },
 { 141,4257 }, { 142,4257 }, { 143,4257 }, { 144,4257 }, { 145,4257 },
 { 146,4257 }, { 147,4257 }, { 148,4257 }, { 149,4257 }, { 150,4257 },

 { 151,4257 }, { 152,4257 }, { 153,4257 }, { 154,4257 }, { 155,4257 },
 { 156,4257 }, { 157,4257 }, { 158,4257 }, { 159,4257 }, { 160,4257 },
 { 161,4257 }, { 162,4257 }, { 163,4257 }, { 164,4257 }, { 165,4257 },
 { 166,4257 }, { 167,4257 }, { 168,4257 }, { 169,4257 }, { 170,4257 },
 { 171,4257 }, { 172,4257 }, { 173,4257 }, { 174,4257 }, { 175,4257 },
 { 176,4257 }, { 177,4257 }, { 178,4257 }, { 179,4257 }, { 180,4257 },
 { 181,4257 }, { 182,4257 }, { 183,4257 }, { 184,4257 }, { 185,4257 },
 { 186,4257 }, { 187,4257 }, { 188,4257 }, { 189,4257 }, { 190,4257 },
 { 191,4257 }, { 192,4257 }, { 193,4257 }, { 194,4257 }, { 195,4257 },
 { 196,4257 }, { 197,4257 }, { 198,4257 }, { 199,4257 }, { 200,4257 },

 { 201,4257 }, { 202,4257 }, { 203,4257 }, { 204,4257 }, { 205,4257 },
 { 206,4257 }, { 207,4257 }, { 208,4257 }, { 209,4257 }, { 210,4257 },
 { 211,4257 }, { 212,4257 }, { 213,4257 }, { 214,4257 }, { 215,4257 },
 { 216,4257 }, { 217,4257 }, { 218,4257 }, { 219,4257 }, { 220,4257 },
 { 221,4257 }, { 222,4257 }, { 223,4257 }, { 224,4257 }, { 225,4257 },
 { 226,4257 }, { 227,4257 }, { 228,4257 }, { 229,4257 }, { 230,4257 },
 { 231,4257 }, { 232,4257 }, { 233,4257 }, { 234,4257 }, { 235,4257 },
 { 236,4257 }, { 237,4257 }, { 238,4257 }, { 239,4257 }, { 240,4257 },
 { 241,4257 }, { 242,4257 }, { 243,4257 }, { 244,4257 }, { 245,4257 },
 { 246,4257 }, { 247,4257 }, { 248,4257 }, { 249,4257 }, { 250,4257 },

 { 251,4257 }, { 252,4257 }, { 253,4257 }, { 254,4257 }, { 255,4257 },
 {   0,   1 }, {   0,24144 }, {   1,4257 }, {   2,4257 }, {   3,4257 },
 {   4,4257 }, {   5,4257 }, {   6,4257 }, {   7,4257 }, {   8,4257 },
 {   9,4257 }, {   0,   0 }, {  11,4257 }, {  12,4257 }, {   0,   0 },
 {  14,4257 }, {  15,4257 }, {  16,4257 }, {  17,4257 }, {  18,4257 },
 {  19,4257 }, {  20,4257 }, {  21,4257 }, {  22,4257 }, {  23,4257 },
 {  24,4257 }, {  25,4257 }, {  26,4257 }, {  27,4257 }, {  28,4257 },
 {  29,4257 }, {  30,4257 }, {  31,4257 }, {  32,4257 }, {  33,4515 },
 {  34,4257 }, {  35,4515 }, {  36,4257 }, {  37,4515 }, {  38,4515 },
 {  39,4257 }, {  40,4257 }, {  41,4257 }, {  42,4515 }, {  43,4515 },

 {  44,4257 }, {  45,4515 }, {  46,4257 }, {  47,4515 }, {  48,4257 },
 {  49,4257 }, {  50,4257 }, {  51,4257 }, {  52,4257 }, {  53,4257 },
 {  54,4257 }, {  55,4257 }, {  56,4257 }, {  57,4257 }, {  58,4257 },
 {  59,4257 }, {  60,4515 }, {  61,4515 }, {  62,4515 }, {  63,4515 },
 {  64,4515 }, {  65,4257 }, {  66,4257 }, {  67,4257 }, {  68,4257 },
 {  69,4257 }, {  70,4257 }, {  71,4257 }, {  72,4257 }, {  73,4257 },
 {  74,4257 }, {  75,4257 }, {  76,4257 }, {  77,4257 }, {  78,4257 },
 {  79,4257 }, {  80,4257 }, {  81,4257 }, {  82,4257 }, {  83,4257 },
 {  84,4257 }, {  85,4257 }, {  86,4257 }, {  87,4257 }, {  88,4257 },
 {  89,4257 }, {  90,4257 }, {  91,4257 }, {  92,4257 }, {  93,4257 },

 {  94,4515 }, {  95,4257 }, {  96,4515 }, {  97,4257 }, {  98,4257 },
 {  99,4257 }, { 100,4257 }, { 101,4257 }, { 102,4257 }, { 103,4257 },
 { 104,4257 }, { 105,4257 }, { 106,4257 }, { 107,4257 }, { 108,4257 },
 { 109,4257 }, { 110,4257 }, { 111,4257 }, { 112,4257 }, { 113,4257 },
 { 114,4257 }, { 115,4257 }, { 116,4257 }, { 117,4257 }, { 118,4257 },
 { 119,4257 }, { 120,4257 }, { 121,4257 }, { 122,4257 }, { 123,4257 },
 { 124,4515 }, { 125,4257 }, { 126,4515 }, { 127,4257 }, { 128,4257 },
 { 129,4257 }, { 130,4257 }, { 131,4257 }, { 132,4257 }, { 133,4257 },
 { 134,4257 }, { 135,4257 }, { 136,4257 }, { 137,4257 }, { 138,4257 },
 { 139,4257 }, { 140,4257 }, { 141,4257 }, { 142,4257 }, { 143,4257 },

 { 144,4257 }, { 145,4257 }, { 146,4257 }, { 147,4257 }, { 148,4257 },
 { 149,4257 }, { 150,4257 }, { 151,4257 }, { 152,4257 }, { 153,4257 },
 { 154,4257 }, { 155,4257 }, { 156,4257 }, { 157,4257 }, { 158,4257 },
 { 159,4257 }, { 160,4257 }, { 161,4257 }, { 162,4257 }, { 163,4257 },
 { 164,4257 }, { 165,4257 }, { 166,4257 }, { 167,4257 }, { 168,4257 },
 { 169,4257 }, { 170,4257 }, { 171,4257 }, { 172,4257 }, { 173,4257 },
 { 174,4257 }, { 175,4257 }, { 176,4257 }, { 177,4257 }, { 178,4257 },
 { 179,4257 }, { 180,4257 }, { 181,4257 }, { 182,4257 }, { 183,4257 },
 { 184,4257 }, { 185,4257 }, { 186,4257 }, { 187,4257 }, { 188,4257 },
 { 189,4257 }, { 190,4257 }, { 191,4257 }, { 192,4257 }, { 193,4257 },

 { 194,4257 }, { 195,4257 }, { 196,4257 }, { 197,4257 }, { 198,4257 },
 { 199,4257 }, { 200,4257 }, { 201,4257 }, { 202,4257 }, { 203,4257 },
 { 204,4257 }, { 205,4257 }, { 206,4257 }, { 207,4257 }, { 208,4257 },
 { 209,4257 }, { 210,4257 }, { 211,4257 }, { 212,4257 }, { 213,4257 },
 { 214,4257 }, { 215,4257 }, { 216,4257 }, { 217,4257 }, { 218,4257 },
 { 219,4257 }, { 220,4257 }, { 221,4257 }, { 222,4257 }, { 223,4257 },
 { 224,4257 }, { 225,4257 }, { 226,4257 }, { 227,4257 }, { 228,4257 },
 { 229,4257 }, { 230,4257 }, { 231,4257 }, { 232,4257 }, { 233,4257 },
 { 234,4257 }, { 235,4257 }, { 236,4257 }, { 237,4257 }, { 238,4257 },
 { 239,4257 }, { 240,4257 }, { 241,4257 }, { 242,4257 }, { 243,4257 },

 { 244,4257 }, { 245,4257 }, { 246,4257 }, { 247,4257 }, { 248,4257 },
 { 249,4257 }, { 250,4257 }, { 251,4257 }, { 252,4257 }, { 253,4257 },
 { 254,4257 }, { 255,4257 }, { 256,4257 }, {   0,  73 }, {   0,23886 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   2 }, {   0,23861 },
 {   0,  73 }, {   0,23859 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 },
 {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 },
 {  56,   0 }, {  57,   0 }, {  33,4490 }, {   0,   0 }, {  35,4490 },
 {   0,   0 }, {  37,4490 }, {  38,4490 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  42,4490 }, {  43,4490 }, {  69, 113 }, {  45,4490 },
 {   0,   0 }, {  47,4490 }, {  46,-5624 }, {   0,   0 }, {  48,4490 },
 {  49,4490 }, {  50,4490 }, {  51,4490 }, {  52,4490 }, {  53,4490 },
 {  54,4490 }, {  55,4490 }, {  56,4490 }, {  57,4490 }, {  60,4490 },

 {  61,4490 }, {  62,4490 }, {  63,4490 }, {  64,4490 }, {   0,  72 },
 {   0,23795 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  69,  86 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 { 101, 113 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  76 }, {   0,23773 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  94,4490 }, {   0,   0 },
 {  96,4490 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, { 101,  86 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {  46, -64 }, {   0,   0 }, {  48,   0 }, {  49,   0 },
 {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 },
 {  55,   0 }, {  56,   0 }, {  57,   0 }, { 124,4490 }, {   0,   0 },
 { 126,4490 }, {   0,  65 }, {   0,23733 }, {   0,   0 }, {   0,   0 },
 {  43,4426 }, {   0,   0 }, {  45,4426 }, {   0,   0 }, {  69,  22 },
 {  48,4468 }, {  49,4468 }, {  50,4468 }, {  51,4468 }, {  52,4468 },
 {  53,4468 }, {  54,4468 }, {  55,4468 }, {  56,4468 }, {  57,4468 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  33,-787 }, {   0,   0 }, {  35,-787 }, {   0,   0 }, {  37,-787 },
 {  38,-787 }, { 101,  22 }, {   0,  67 }, {   0,23692 }, {  42,-787 },
 {  43,-787 }, {   0,   0 }, {  45,-787 }, {   0,   0 }, {  47,-787 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  60,-787 }, {  61,-787 }, {  62,-787 },
 {  63,-787 }, {  64,-787 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  33,-828 }, {   0,   0 }, {  35,-828 }, {   0,   0 },
 {  37,-828 }, {  38,-828 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  42,-828 }, {  43,-828 }, {   0,   0 }, {  45,-828 }, {   0,   0 },
 {  47,-828 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  94,-787 }, {   0,   0 }, {  96,-787 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  60,-828 }, {  61,-828 },
 {  62,-828 }, {  63,-828 }, {  64,-828 }, {   0,   0 }, {   0,  64 },
 {   0,23625 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  66 }, {   0,23614 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, { 124,-787 }, {   0,   0 }, { 126,-787 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {  94,-828 }, {   0,   0 }, {  96,-828 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  33,-895 }, {   0,   0 },
 {  35,-895 }, {   0,   0 }, {  37,-895 }, {  38,-895 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  42,-895 }, {  43,-895 }, {  33,-906 },
 {  45,-895 }, {  35,-906 }, {  47,-895 }, {  37,-906 }, {  38,-906 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  42,-906 }, {  43,-906 },
 {   0,   0 }, {  45,-906 }, { 124,-828 }, {  47,-906 }, { 126,-828 },
 {  60,-895 }, {  61,-895 }, {  62,-895 }, {  63,-895 }, {  64,-895 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  60,-906 }, {  61,-906 }, {  62,-906 }, {  63,-906 },

 {  64,-906 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  78 }, {   0,23534 }, {   0,   0 }, {   0,   0 }, {  94,-895 },
 {   0,   0 }, {  96,-895 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  94,-906 }, {   0,   0 }, {  96,-906 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 124,-895 },

 {   0,   0 }, { 126,-895 }, {  36,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 { 124,-906 }, {   0,   0 }, { 126,-906 }, {   0,   0 }, {  48,   0 },
 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },
 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  63,-6357 },
 {   0,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 },
 {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 },
 {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 },
 {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 },

 {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 },
 {  89,   0 }, {  90,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  95,   0 }, {   0,   0 }, {  97,   0 }, {  98,   0 },
 {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 },
 { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 },
 { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 },
 { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 },
 { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 128,   0 },
 { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 },

 { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 },
 { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 },
 { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 },
 { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 },
 { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 },
 { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 },
 { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 },
 { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 },
 { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 },
 { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 },

 { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 },
 { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 },
 { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 },
 { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 },
 { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 },
 { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 },
 { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 },
 { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 },
 { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 },
 { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 },

 { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 },
 { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 },
 { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 },
 { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 },
 { 254,   0 }, { 255,   0 }, {   0,  12 }, {   0,23277 }, {   1,   0 },
 {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 },
 {   7,   0 }, {   8,   0 }, {   9,   0 }, {  10,   0 }, {  11,   0 },
 {  12,   0 }, {  13,   0 }, {  14,   0 }, {  15,   0 }, {  16,   0 },
 {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 },
 {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 },

 {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 },
 {  32,   0 }, {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 },
 {  37,   0 }, {  38,   0 }, {   0,   0 }, {  40,   0 }, {  41,   0 },
 {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45,   0 }, {  46,   0 },
 {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 },
 {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 },
 {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 },
 {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 },
 {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 },
 {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 },

 {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 },
 {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 },
 {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 },
 {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 },
 {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 },
 { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 },
 { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 },
 { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 },
 { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 },
 { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 },

 { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 },
 { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 },
 { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 },
 { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 },
 { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 },
 { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 },
 { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 },
 { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 },
 { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 },
 { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 },

 { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 },
 { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 },
 { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 },
 { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 },
 { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 },
 { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 },
 { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 },
 { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 },
 { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 },
 { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 },

 { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 },
 { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 },
 { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 },
 { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 },
 { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 },
 { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 },
 {   0,   9 }, {   0,23019 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   9 }, {   0,23014 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,   0 }, {  10,   5 }, {   0,   0 }, {  12,   0 }, {  13,   5 },
 {   9,3741 }, {  10,3741 }, {   0,   0 }, {  12,3741 }, {  13,3741 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,3741 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39,-6463 }, {  45,-6627 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-6461 }, {   0,   5 }, {   0,22967 }, {   1,   0 },
 {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 },
 {   7,   0 }, {   8,   0 }, {   9,   0 }, {  10,   0 }, {  11,   0 },
 {  12,   0 }, {  13,   0 }, {  14,   0 }, {  15,   0 }, {  16,   0 },

 {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 },
 {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 },
 {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 },
 {  32,   0 }, {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 },
 {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 }, {  41,   0 },
 {   0,   0 }, {  43,   0 }, {  44,   0 }, {  45,   0 }, {  46,   0 },
 {   0,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 },
 {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 },
 {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 },
 {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 },

 {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 },
 {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 },
 {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 },
 {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 },
 {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 },
 {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 },
 {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 },
 { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 },
 { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 },
 { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 },

 { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 },
 { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 },
 { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 },
 { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 },
 { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 },
 { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 },
 { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 },
 { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 },
 { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 },
 { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 },

 { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 },
 { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 },
 { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 },
 { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 },
 { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 },
 { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 },
 { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 },
 { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 },
 { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 },
 { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 },

 { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 },
 { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 },
 { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 },
 { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 },
 { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 },
 { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 },
 { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 },
 { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 },
 {   0,   3 }, {   0,22709 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  33,3741 },
 {   0,   0 }, {  35,3741 }, {   0,   0 }, {  37,3741 }, {  38,3741 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  42,3741 }, {  43,3741 },
 {   0,   0 }, {  45,3741 }, {   0,   0 }, {  47,3741 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {  60,3741 }, {  61,3741 }, {  62,3741 }, {  63,3741 },
 {  64,3741 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  94,3741 }, {   0,   0 }, {  96,3741 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 { 124,3741 }, {   0,   0 }, { 126,3741 }, {   0,  58 }, {   0,22581 },
 {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 },
 {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9,   0 }, {  10,   0 },
 {  11,   0 }, {  12,   0 }, {  13,   0 }, {  14,   0 }, {  15,   0 },
 {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 },
 {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 },
 {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 },

 {  31,   0 }, {  32,   0 }, {  33,   0 }, {   0,   0 }, {  35,   0 },
 {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 },
 {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45,   0 },
 {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 },
 {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 },
 {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 },
 {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 },
 {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 },
 {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 },
 {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 },

 {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 },
 {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 },
 {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 },
 {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 },
 { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 },
 { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 },
 { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 },
 { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 },
 { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 },
 { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 },

 { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 },
 { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 },
 { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 },
 { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 },
 { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 },
 { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 },
 { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 },
 { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 },
 { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 },
 { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 },

 { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 },
 { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 },
 { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 },
 { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 },
 { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 },
 { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 },
 { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 },
 { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 },
 { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 },
 { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 },

 { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 },
 { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 },
 { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 },
 { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 },
 { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 },
 { 256,   0 }, {   0,  11 }, {   0,22323 }, {   1,   0 }, {   2,   0 },
 {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 },
 {   8,   0 }, {   9,   0 }, {  10,   0 }, {  11,   0 }, {  12,   0 },
 {  13,   0 }, {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 },
 {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 },

 {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 },
 {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32,   0 },
 {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 },
 {  38,   0 }, {   0,   0 }, {  40,   0 }, {  41,   0 }, {  42,   0 },
 {  43,   0 }, {  44,   0 }, {  45,   0 }, {  46,   0 }, {  47,   0 },
 {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 },
 {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 },
 {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 },
 {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 },
 {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 },

 {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 },
 {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 },
 {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 },
 {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 }, {  92,   0 },
 {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 },
 {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 },
 { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 },
 { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 },
 { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 },
 { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 },

 { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 },
 { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 },
 { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 },
 { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 },
 { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 },
 { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 },
 { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 },
 { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 },
 { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 },
 { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 },

 { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 },
 { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 },
 { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 },
 { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 },
 { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 },
 { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 },
 { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 },
 { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 },
 { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 },
 { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 },

 { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 },
 { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 },
 { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 },
 { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 },
 { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 },
 { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 },
 { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,  16 },
 {   0,22065 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  16 },
 {   0,22060 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,   0 },
 {  10,   5 }, {   0,   0 }, {  12,   0 }, {  13,   5 }, {   9,3099 },

 {  10,3099 }, {   0,   0 }, {  12,3099 }, {  13,3099 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,3099 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  39,-7413 },
 {  45,-7481 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  45,-7408 }, {   0,  32 }, {   0,22013 }, {   1,   0 }, {   2,   0 },
 {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 },
 {   8,   0 }, {   9,   0 }, {  10,   0 }, {  11,   0 }, {  12,   0 },

 {  13,   0 }, {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 },
 {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 },
 {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 },
 {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32,   0 },
 {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 },
 {  38,   0 }, {   0,   0 }, {  40,   0 }, {  41,   0 }, {  42,   0 },
 {  43,   0 }, {  44,   0 }, {  45,   0 }, {  46,   0 }, {  47,   0 },
 {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 },
 {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 },
 {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 },

 {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 },
 {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 },
 {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 },
 {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 },
 {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 },
 {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 }, {   0,   0 },
 {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 },
 {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 },
 { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 },
 { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 },

 { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 },
 { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 },
 { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 },
 { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 },
 { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 },
 { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 },
 { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 },
 { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 },
 { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 },
 { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 },

 { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 },
 { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 },
 { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 },
 { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 },
 { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 },
 { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 },
 { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 },
 { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 },
 { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 },
 { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 },

 { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 },
 { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 },
 { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 },
 { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 },
 { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 },
 { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 },
 { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 },
 { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 },
 { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,  22 },
 {   0,21755 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  22 },

 {   0,21750 }, {   0,  39 }, {   0,21748 }, {   0,   0 }, {   9,   0 },
 {  10,   5 }, {   0,   0 }, {  12,   0 }, {  13,   5 }, {   9,3168 },
 {  10,3168 }, {   0,   0 }, {  12,3168 }, {  13,3168 }, {   0,  37 },
 {   0,21735 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,3168 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,  37 }, {   0,21712 }, {  39,-7709 },
 {  45,-7784 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  45,-7682 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  48,3471 }, {  49,3471 }, {  50,3471 }, {  51,3471 }, {  52,3471 },
 {  53,3471 }, {  54,3471 }, {  55,3471 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,3466 }, {  49,3466 },
 {  50,3466 }, {  51,3466 }, {  52,3466 }, {  53,3466 }, {  54,3466 },
 {  55,3466 }, {  56,3466 }, {  57,3466 }, {   0,   0 }, {   0,   0 },
 {   0,  38 }, {   0,21674 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  65,3466 }, {  66,3466 }, {  67,3466 }, {  68,3466 }, {  69,3466 },
 {  70,3466 }, {  48,3466 }, {  49,3466 }, {  50,3466 }, {  51,3466 },
 {  52,3466 }, {  53,3466 }, {  54,3466 }, {  55,3466 }, {  56,3466 },
 {  57,3466 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,3466 }, {  66,3466 },
 {  67,3466 }, {  68,3466 }, {  69,3466 }, {  70,3466 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  97,3466 }, {  98,3466 }, {  99,3466 },
 { 100,3466 }, { 101,3466 }, { 102,3466 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,3466 },
 {  49,3466 }, {  50,3466 }, {  51,3466 }, {  52,3466 }, {  53,3466 },
 {  54,3466 }, {  55,3466 }, {  56,3466 }, {  57,3466 }, {   0,   0 },
 {  97,3466 }, {  98,3466 }, {  99,3466 }, { 100,3466 }, { 101,3466 },
 { 102,3466 }, {  65,3466 }, {  66,3466 }, {  67,3466 }, {  68,3466 },
 {  69,3466 }, {  70,3466 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,3466 }, {  98,3466 },
 {  99,3466 }, { 100,3466 }, { 101,3466 }, { 102,3466 }, {   0,  31 },
 {   0,21570 }, {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 },
 {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9,   0 },
 {  10,   0 }, {  11,   0 }, {  12,   0 }, {  13,   0 }, {  14,   0 },
 {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 },

 {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 },
 {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 },
 {  30,   0 }, {  31,   0 }, {  32,   0 }, {  33,   0 }, {  34,   0 },
 {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 }, {   0,   0 },
 {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 },
 {  45,   0 }, {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 },
 {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 },
 {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 },
 {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 },
 {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 },

 {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 },
 {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 },
 {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 },
 {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 },
 {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 },
 {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 },
 { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 },
 { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 },
 { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 },
 { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 },

 { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 },
 { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 },
 { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 },
 { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 },
 { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 },
 { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 },
 { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 },
 { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 },
 { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 },
 { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 },

 { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 },
 { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 },
 { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 },
 { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 },
 { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 },
 { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 },
 { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 },
 { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 },
 { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 },
 { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 },

 { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 },
 { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 },
 { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 },
 { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 },
 { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 },
 { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 },
 { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 },
 { 255,   0 }, { 256,   0 }, {   0,  46 }, {   0,21312 }, {   1,   0 },
 {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 },
 {   7,   0 }, {   8,   0 }, {   9,   0 }, {  10,   0 }, {  11,   0 },

 {  12,   0 }, {  13,   0 }, {  14,   0 }, {  15,   0 }, {  16,   0 },
 {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 },
 {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 },
 {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 },
 {  32,   0 }, {  33,   0 }, {  34,   0 }, {  35,   0 }, {   0,   0 },
 {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 }, {  41,   0 },
 {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45,   0 }, {  46,   0 },
 {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 },
 {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 },
 {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 },

 {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 },
 {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 },
 {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 },
 {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 },
 {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 },
 {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 },
 {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 },
 {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 },
 { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 },
 { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 },

 { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 },
 { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 },
 { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 },
 { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 },
 { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 },
 { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 },
 { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 },
 { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 },
 { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 },
 { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 },

 { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 },
 { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 },
 { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 },
 { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 },
 { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 },
 { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 },
 { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 },
 { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 },
 { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 },
 { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 },

 { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 },
 { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 },
 { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 },
 { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 },
 { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 },
 { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 },
 { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 },
 { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 },
 { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 },
 {   0,  47 }, {   0,21054 }, {   0,  53 }, {   0,21052 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 }, {   0,   0 },
 {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  32,   0 }, {   0,   0 }, {  36,-8481 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,2918 },
 {  49,2918 }, {  50,2918 }, {  51,2918 }, {  52,2918 }, {  53,2918 },

 {  54,2918 }, {  55,2918 }, {  56,2918 }, {  57,2918 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  65,2918 }, {  66,2918 }, {  67,2918 }, {  68,2918 },
 {  69,2918 }, {  70,2918 }, {  71,2918 }, {  72,2918 }, {  73,2918 },
 {  74,2918 }, {  75,2918 }, {  76,2918 }, {  77,2918 }, {  78,2918 },
 {  79,2918 }, {  80,2918 }, {  81,2918 }, {  82,2918 }, {  83,2918 },
 {  84,2918 }, {  85,2918 }, {  86,2918 }, {  87,2918 }, {  88,2918 },
 {  89,2918 }, {  90,2918 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  95,2918 }, {   0,   0 }, {  97,2918 }, {  98,2918 },
 {  99,2918 }, { 100,2918 }, { 101,2918 }, { 102,2918 }, { 103,2918 },

 { 104,2918 }, { 105,2918 }, { 106,2918 }, { 107,2918 }, { 108,2918 },
 { 109,2918 }, { 110,2918 }, { 111,2918 }, { 112,2918 }, { 113,2918 },
 { 114,2918 }, { 115,2918 }, { 116,2918 }, { 117,2918 }, { 118,2918 },
 { 119,2918 }, { 120,2918 }, { 121,2918 }, { 122,2918 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 128,2918 },
 { 129,2918 }, { 130,2918 }, { 131,2918 }, { 132,2918 }, { 133,2918 },
 { 134,2918 }, { 135,2918 }, { 136,2918 }, { 137,2918 }, { 138,2918 },
 { 139,2918 }, { 140,2918 }, { 141,2918 }, { 142,2918 }, { 143,2918 },
 { 144,2918 }, { 145,2918 }, { 146,2918 }, { 147,2918 }, { 148,2918 },
 { 149,2918 }, { 150,2918 }, { 151,2918 }, { 152,2918 }, { 153,2918 },

 { 154,2918 }, { 155,2918 }, { 156,2918 }, { 157,2918 }, { 158,2918 },
 { 159,2918 }, { 160,2918 }, { 161,2918 }, { 162,2918 }, { 163,2918 },
 { 164,2918 }, { 165,2918 }, { 166,2918 }, { 167,2918 }, { 168,2918 },
 { 169,2918 }, { 170,2918 }, { 171,2918 }, { 172,2918 }, { 173,2918 },
 { 174,2918 }, { 175,2918 }, { 176,2918 }, { 177,2918 }, { 178,2918 },
 { 179,2918 }, { 180,2918 }, { 181,2918 }, { 182,2918 }, { 183,2918 },
 { 184,2918 }, { 185,2918 }, { 186,2918 }, { 187,2918 }, { 188,2918 },
 { 189,2918 }, { 190,2918 }, { 191,2918 }, { 192,2918 }, { 193,2918 },
 { 194,2918 }, { 195,2918 }, { 196,2918 }, { 197,2918 }, { 198,2918 },
 { 199,2918 }, { 200,2918 }, { 201,2918 }, { 202,2918 }, { 203,2918 },

 { 204,2918 }, { 205,2918 }, { 206,2918 }, { 207,2918 }, { 208,2918 },
 { 209,2918 }, { 210,2918 }, { 211,2918 }, { 212,2918 }, { 213,2918 },
 { 214,2918 }, { 215,2918 }, { 216,2918 }, { 217,2918 }, { 218,2918 },
 { 219,2918 }, { 220,2918 }, { 221,2918 }, { 222,2918 }, { 223,2918 },
 { 224,2918 }, { 225,2918 }, { 226,2918 }, { 227,2918 }, { 228,2918 },
 { 229,2918 }, { 230,2918 }, { 231,2918 }, { 232,2918 }, { 233,2918 },
 { 234,2918 }, { 235,2918 }, { 236,2918 }, { 237,2918 }, { 238,2918 },
 { 239,2918 }, { 240,2918 }, { 241,2918 }, { 242,2918 }, { 243,2918 },
 { 244,2918 }, { 245,2918 }, { 246,2918 }, { 247,2918 }, { 248,2918 },
 { 249,2918 }, { 250,2918 }, { 251,2918 }, { 252,2918 }, { 253,2918 },

 { 254,2918 }, { 255,2918 }, {   0,  53 }, {   0,20797 }, {   1,2918 },
 {   2,2918 }, {   3,2918 }, {   4,2918 }, {   5,2918 }, {   6,2918 },
 {   7,2918 }, {   8,2918 }, {   9,2918 }, {   0,   0 }, {  11,2918 },
 {  12,2918 }, {   0,   0 }, {  14,2918 }, {  15,2918 }, {  16,2918 },
 {  17,2918 }, {  18,2918 }, {  19,2918 }, {  20,2918 }, {  21,2918 },
 {  22,2918 }, {  23,2918 }, {  24,2918 }, {  25,2918 }, {  26,2918 },
 {  27,2918 }, {  28,2918 }, {  29,2918 }, {  30,2918 }, {  31,2918 },
 {  32,2918 }, {  33,2918 }, {  34,2918 }, {  35,2918 }, {  36,2918 },
 {  37,2918 }, {  38,2918 }, {  39,2918 }, {  40,2918 }, {  41,2918 },
 {  42,2918 }, {  43,2918 }, {  44,2918 }, {  45,2918 }, {  46,2918 },

 {  47,2918 }, {  48,2918 }, {  49,2918 }, {  50,2918 }, {  51,2918 },
 {  52,2918 }, {  53,2918 }, {  54,2918 }, {  55,2918 }, {  56,2918 },
 {  57,2918 }, {  58,2918 }, {  59,2918 }, {  60,2918 }, {  61,2918 },
 {  62,2918 }, {  63,2918 }, {  64,2918 }, {  65,2918 }, {  66,2918 },
 {  67,2918 }, {  68,2918 }, {  69,2918 }, {  70,2918 }, {  71,2918 },
 {  72,2918 }, {  73,2918 }, {  74,2918 }, {  75,2918 }, {  76,2918 },
 {  77,2918 }, {  78,2918 }, {  79,2918 }, {  80,2918 }, {  81,2918 },
 {  82,2918 }, {  83,2918 }, {  84,2918 }, {  85,2918 }, {  86,2918 },
 {  87,2918 }, {  88,2918 }, {  89,2918 }, {  90,2918 }, {  91,2918 },
 {  92,2918 }, {  93,2918 }, {  94,2918 }, {  95,2918 }, {  96,2918 },

 {  97,2918 }, {  98,2918 }, {  99,2918 }, { 100,2918 }, { 101,2918 },
 { 102,2918 }, { 103,2918 }, { 104,2918 }, { 105,2918 }, { 106,2918 },
 { 107,2918 }, { 108,2918 }, { 109,2918 }, { 110,2918 }, { 111,2918 },
 { 112,2918 }, { 113,2918 }, { 114,2918 }, { 115,2918 }, { 116,2918 },
 { 117,2918 }, { 118,2918 }, { 119,2918 }, { 120,2918 }, { 121,2918 },
 { 122,2918 }, { 123,2918 }, { 124,2918 }, { 125,2918 }, { 126,2918 },
 { 127,2918 }, { 128,2918 }, { 129,2918 }, { 130,2918 }, { 131,2918 },
 { 132,2918 }, { 133,2918 }, { 134,2918 }, { 135,2918 }, { 136,2918 },
 { 137,2918 }, { 138,2918 }, { 139,2918 }, { 140,2918 }, { 141,2918 },
 { 142,2918 }, { 143,2918 }, { 144,2918 }, { 145,2918 }, { 146,2918 },

 { 147,2918 }, { 148,2918 }, { 149,2918 }, { 150,2918 }, { 151,2918 },
 { 152,2918 }, { 153,2918 }, { 154,2918 }, { 155,2918 }, { 156,2918 },
 { 157,2918 }, { 158,2918 }, { 159,2918 }, { 160,2918 }, { 161,2918 },
 { 162,2918 }, { 163,2918 }, { 164,2918 }, { 165,2918 }, { 166,2918 },
 { 167,2918 }, { 168,2918 }, { 169,2918 }, { 170,2918 }, { 171,2918 },
 { 172,2918 }, { 173,2918 }, { 174,2918 }, { 175,2918 }, { 176,2918 },
 { 177,2918 }, { 178,2918 }, { 179,2918 }, { 180,2918 }, { 181,2918 },
 { 182,2918 }, { 183,2918 }, { 184,2918 }, { 185,2918 }, { 186,2918 },
 { 187,2918 }, { 188,2918 }, { 189,2918 }, { 190,2918 }, { 191,2918 },
 { 192,2918 }, { 193,2918 }, { 194,2918 }, { 195,2918 }, { 196,2918 },

 { 197,2918 }, { 198,2918 }, { 199,2918 }, { 200,2918 }, { 201,2918 },
 { 202,2918 }, { 203,2918 }, { 204,2918 }, { 205,2918 }, { 206,2918 },
 { 207,2918 }, { 208,2918 }, { 209,2918 }, { 210,2918 }, { 211,2918 },
 { 212,2918 }, { 213,2918 }, { 214,2918 }, { 215,2918 }, { 216,2918 },
 { 217,2918 }, { 218,2918 }, { 219,2918 }, { 220,2918 }, { 221,2918 },
 { 222,2918 }, { 223,2918 }, { 224,2918 }, { 225,2918 }, { 226,2918 },
 { 227,2918 }, { 228,2918 }, { 229,2918 }, { 230,2918 }, { 231,2918 },
 { 232,2918 }, { 233,2918 }, { 234,2918 }, { 235,2918 }, { 236,2918 },
 { 237,2918 }, { 238,2918 }, { 239,2918 }, { 240,2918 }, { 241,2918 },
 { 242,2918 }, { 243,2918 }, { 244,2918 }, { 245,2918 }, { 246,2918 },

 { 247,2918 }, { 248,2918 }, { 249,2918 }, { 250,2918 }, { 251,2918 },
 { 252,2918 }, { 253,2918 }, { 254,2918 }, { 255,2918 }, { 256,2918 },
 {   0,  24 }, {   0,20539 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  24 }, {   0,20534 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,   0 }, {  10,   5 }, {   0,   0 }, {  12,   0 }, {  13,   5 },
 {   9,2913 }, {  10,2913 }, {   0,   0 }, {  12,2913 }, {  13,2913 },
 {   0,   0 }, {   0,  26 }, {   0,20518 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   9,   0 }, {  10,   0 }, {  32,   0 }, {  12,   0 },
 {  13,   0 }, {   0,   0 }, {   0,   0 }, {  32,2913 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39,-8925 }, {  45,-8953 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-8861 }, {   0,   0 }, {   0,   0 }, {  32,   0 },
 {   0,  26 }, {   0,20484 }, {   1,3168 }, {   2,3168 }, {   3,3168 },
 {   4,3168 }, {   5,3168 }, {   6,3168 }, {   7,3168 }, {   8,3168 },
 {   9,3168 }, {   0,   0 }, {  11,3168 }, {  12,3168 }, {   0,   0 },
 {  14,3168 }, {  15,3168 }, {  16,3168 }, {  17,3168 }, {  18,3168 },
 {  19,3168 }, {  20,3168 }, {  21,3168 }, {  22,3168 }, {  23,3168 },
 {  24,3168 }, {  25,3168 }, {  26,3168 }, {  27,3168 }, {  28,3168 },
 {  29,3168 }, {  30,3168 }, {  31,3168 }, {  32,3168 }, {  33,3168 },

 {  34,3168 }, {  35,3168 }, {  36,3168 }, {  37,3168 }, {  38,3168 },
 {  39,3168 }, {  40,3168 }, {  41,3168 }, {  42,3168 }, {  43,3168 },
 {  44,3168 }, {  45,3168 }, {  46,3168 }, {  47,3168 }, {  48,3168 },
 {  49,3168 }, {  50,3168 }, {  51,3168 }, {  52,3168 }, {  53,3168 },
 {  54,3168 }, {  55,3168 }, {  56,3168 }, {  57,3168 }, {  58,3168 },
 {  59,3168 }, {  60,3168 }, {  61,3168 }, {  62,3168 }, {  63,3168 },
 {  64,3168 }, {  65,3168 }, {  66,3168 }, {  67,3168 }, {  68,3168 },
 {  69,3168 }, {  70,3168 }, {  71,3168 }, {  72,3168 }, {  73,3168 },
 {  74,3168 }, {  75,3168 }, {  76,3168 }, {  77,3168 }, {  78,3168 },
 {  79,3168 }, {  80,3168 }, {  81,3168 }, {  82,3168 }, {  83,3168 },

 {  84,3168 }, {  85,3168 }, {  86,3168 }, {  87,3168 }, {  88,3168 },
 {  89,3168 }, {  90,3168 }, {  91,3168 }, {  92,3168 }, {  93,3168 },
 {  94,3168 }, {  95,3168 }, {  96,3168 }, {  97,3168 }, {  98,3168 },
 {  99,3168 }, { 100,3168 }, { 101,3168 }, { 102,3168 }, { 103,3168 },
 { 104,3168 }, { 105,3168 }, { 106,3168 }, { 107,3168 }, { 108,3168 },
 { 109,3168 }, { 110,3168 }, { 111,3168 }, { 112,3168 }, { 113,3168 },
 { 114,3168 }, { 115,3168 }, { 116,3168 }, { 117,3168 }, { 118,3168 },
 { 119,3168 }, { 120,3168 }, { 121,3168 }, { 122,3168 }, { 123,3168 },
 { 124,3168 }, { 125,3168 }, { 126,3168 }, { 127,3168 }, { 128,3168 },
 { 129,3168 }, { 130,3168 }, { 131,3168 }, { 132,3168 }, { 133,3168 },

 { 134,3168 }, { 135,3168 }, { 136,3168 }, { 137,3168 }, { 138,3168 },
 { 139,3168 }, { 140,3168 }, { 141,3168 }, { 142,3168 }, { 143,3168 },
 { 144,3168 }, { 145,3168 }, { 146,3168 }, { 147,3168 }, { 148,3168 },
 { 149,3168 }, { 150,3168 }, { 151,3168 }, { 152,3168 }, { 153,3168 },
 { 154,3168 }, { 155,3168 }, { 156,3168 }, { 157,3168 }, { 158,3168 },
 { 159,3168 }, { 160,3168 }, { 161,3168 }, { 162,3168 }, { 163,3168 },
 { 164,3168 }, { 165,3168 }, { 166,3168 }, { 167,3168 }, { 168,3168 },
 { 169,3168 }, { 170,3168 }, { 171,3168 }, { 172,3168 }, { 173,3168 },
 { 174,3168 }, { 175,3168 }, { 176,3168 }, { 177,3168 }, { 178,3168 },
 { 179,3168 }, { 180,3168 }, { 181,3168 }, { 182,3168 }, { 183,3168 },

 { 184,3168 }, { 185,3168 }, { 186,3168 }, { 187,3168 }, { 188,3168 },
 { 189,3168 }, { 190,3168 }, { 191,3168 }, { 192,3168 }, { 193,3168 },
 { 194,3168 }, { 195,3168 }, { 196,3168 }, { 197,3168 }, { 198,3168 },
 { 199,3168 }, { 200,3168 }, { 201,3168 }, { 202,3168 }, { 203,3168 },
 { 204,3168 }, { 205,3168 }, { 206,3168 }, { 207,3168 }, { 208,3168 },
 { 209,3168 }, { 210,3168 }, { 211,3168 }, { 212,3168 }, { 213,3168 },
 { 214,3168 }, { 215,3168 }, { 216,3168 }, { 217,3168 }, { 218,3168 },
 { 219,3168 }, { 220,3168 }, { 221,3168 }, { 222,3168 }, { 223,3168 },
 { 224,3168 }, { 225,3168 }, { 226,3168 }, { 227,3168 }, { 228,3168 },
 { 229,3168 }, { 230,3168 }, { 231,3168 }, { 232,3168 }, { 233,3168 },

 { 234,3168 }, { 235,3168 }, { 236,3168 }, { 237,3168 }, { 238,3168 },
 { 239,3168 }, { 240,3168 }, { 241,3168 }, { 242,3168 }, { 243,3168 },
 { 244,3168 }, { 245,3168 }, { 246,3168 }, { 247,3168 }, { 248,3168 },
 { 249,3168 }, { 250,3168 }, { 251,3168 }, { 252,3168 }, { 253,3168 },
 { 254,3168 }, { 255,3168 }, { 256,3168 }, {   0,  37 }, {   0,20226 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  37 }, {   0,20203 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  48,3168 }, {  49,3168 }, {  50,3168 },
 {  51,3168 }, {  52,3168 }, {  53,3168 }, {  54,3168 }, {  55,3168 },
 {  56,3168 }, {  57,3168 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,3168 },
 {  66,3168 }, {  67,3168 }, {  68,3168 }, {  69,3168 }, {  70,3168 },
 {  48,3168 }, {  49,3168 }, {  50,3168 }, {  51,3168 }, {  52,3168 },

 {  53,3168 }, {  54,3168 }, {  55,3168 }, {  56,3168 }, {  57,3168 },
 {   0,  44 }, {   0,20144 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65,3168 }, {  66,3168 }, {  67,3168 },
 {  68,3168 }, {  69,3168 }, {  70,3168 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  97,3168 }, {  98,3168 }, {  99,3168 }, { 100,3168 },
 { 101,3168 }, { 102,3168 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  36,-9772 }, {   0,   0 }, {  97,3168 },
 {  98,3168 }, {  99,3168 }, { 100,3168 }, { 101,3168 }, { 102,3168 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,   0 },
 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },
 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 },
 {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 },
 {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 },
 {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 },
 {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 },
 {  89,   0 }, {  90,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {  95,   0 }, {   0,   0 }, {  97,   0 }, {  98,   0 },
 {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 },
 { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 },
 { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 },
 { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 },
 { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, { 128,   0 },
 { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 },
 { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 },
 { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 },

 { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 },
 { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 },
 { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 },
 { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 },
 { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 },
 { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 },
 { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 },
 { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 },
 { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 },
 { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 },

 { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 },
 { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 },
 { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 },
 { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 },
 { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 },
 { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 },
 { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 },
 { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 },
 { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 },
 { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 },

 { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 },
 { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 },
 { 254,   0 }, { 255,   0 }, {   0,   1 }, {   0,19887 }, {   1,   0 },
 {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 },
 {   7,   0 }, {   8,   0 }, {   9,   0 }, {   0,   0 }, {  11,   0 },
 {  12,   0 }, {   0,   0 }, {  14,   0 }, {  15,   0 }, {  16,   0 },
 {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 },
 {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 },
 {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 },
 {  32,   0 }, {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 },

 {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 }, {  41,   0 },
 {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45,   0 }, {  46,   0 },
 {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 },
 {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 },
 {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 },
 {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 },
 {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 },
 {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 },
 {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 },
 {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 },

 {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 },
 {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 },
 {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 },
 { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 },
 { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 },
 { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 },
 { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 },
 { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 },
 { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 },
 { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 },

 { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 },
 { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 },
 { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 },
 { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 },
 { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 },
 { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 },
 { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 },
 { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 },
 { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 },
 { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 },

 { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 },
 { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 },
 { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 },
 { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 },
 { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 },
 { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 },
 { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 },
 { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 },
 { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 },
 { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 },

 { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 },
 { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 },
 { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 },
 { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 },
 {   0,   1 }, {   0,19629 }, {   1,-258 }, {   2,-258 }, {   3,-258 },
 {   4,-258 }, {   5,-258 }, {   6,-258 }, {   7,-258 }, {   8,-258 },
 {   9,-258 }, {   0,   0 }, {  11,-258 }, {  12,-258 }, {   0,   0 },
 {  14,-258 }, {  15,-258 }, {  16,-258 }, {  17,-258 }, {  18,-258 },
 {  19,-258 }, {  20,-258 }, {  21,-258 }, {  22,-258 }, {  23,-258 },
 {  24,-258 }, {  25,-258 }, {  26,-258 }, {  27,-258 }, {  28,-258 },

 {  29,-258 }, {  30,-258 }, {  31,-258 }, {  32,-258 }, {  33,   0 },
 {  34,-258 }, {  35,   0 }, {  36,-258 }, {  37,   0 }, {  38,   0 },
 {  39,-258 }, {  40,-258 }, {  41,-258 }, {  42,   0 }, {  43,   0 },
 {  44,-258 }, {  45,   0 }, {  46,-258 }, {  47,   0 }, {  48,-258 },
 {  49,-258 }, {  50,-258 }, {  51,-258 }, {  52,-258 }, {  53,-258 },
 {  54,-258 }, {  55,-258 }, {  56,-258 }, {  57,-258 }, {  58,-258 },
 {  59,-258 }, {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 },
 {  64,   0 }, {  65,-258 }, {  66,-258 }, {  67,-258 }, {  68,-258 },
 {  69,-258 }, {  70,-258 }, {  71,-258 }, {  72,-258 }, {  73,-258 },
 {  74,-258 }, {  75,-258 }, {  76,-258 }, {  77,-258 }, {  78,-258 },

 {  79,-258 }, {  80,-258 }, {  81,-258 }, {  82,-258 }, {  83,-258 },
 {  84,-258 }, {  85,-258 }, {  86,-258 }, {  87,-258 }, {  88,-258 },
 {  89,-258 }, {  90,-258 }, {  91,-258 }, {  92,-258 }, {  93,-258 },
 {  94,   0 }, {  95,-258 }, {  96,   0 }, {  97,-258 }, {  98,-258 },
 {  99,-258 }, { 100,-258 }, { 101,-258 }, { 102,-258 }, { 103,-258 },
 { 104,-258 }, { 105,-258 }, { 106,-258 }, { 107,-258 }, { 108,-258 },
 { 109,-258 }, { 110,-258 }, { 111,-258 }, { 112,-258 }, { 113,-258 },
 { 114,-258 }, { 115,-258 }, { 116,-258 }, { 117,-258 }, { 118,-258 },
 { 119,-258 }, { 120,-258 }, { 121,-258 }, { 122,-258 }, { 123,-258 },
 { 124,   0 }, { 125,-258 }, { 126,   0 }, { 127,-258 }, { 128,-258 },

 { 129,-258 }, { 130,-258 }, { 131,-258 }, { 132,-258 }, { 133,-258 },
 { 134,-258 }, { 135,-258 }, { 136,-258 }, { 137,-258 }, { 138,-258 },
 { 139,-258 }, { 140,-258 }, { 141,-258 }, { 142,-258 }, { 143,-258 },
 { 144,-258 }, { 145,-258 }, { 146,-258 }, { 147,-258 }, { 148,-258 },
 { 149,-258 }, { 150,-258 }, { 151,-258 }, { 152,-258 }, { 153,-258 },
 { 154,-258 }, { 155,-258 }, { 156,-258 }, { 157,-258 }, { 158,-258 },
 { 159,-258 }, { 160,-258 }, { 161,-258 }, { 162,-258 }, { 163,-258 },
 { 164,-258 }, { 165,-258 }, { 166,-258 }, { 167,-258 }, { 168,-258 },
 { 169,-258 }, { 170,-258 }, { 171,-258 }, { 172,-258 }, { 173,-258 },
 { 174,-258 }, { 175,-258 }, { 176,-258 }, { 177,-258 }, { 178,-258 },

 { 179,-258 }, { 180,-258 }, { 181,-258 }, { 182,-258 }, { 183,-258 },
 { 184,-258 }, { 185,-258 }, { 186,-258 }, { 187,-258 }, { 188,-258 },
 { 189,-258 }, { 190,-258 }, { 191,-258 }, { 192,-258 }, { 193,-258 },
 { 194,-258 }, { 195,-258 }, { 196,-258 }, { 197,-258 }, { 198,-258 },
 { 199,-258 }, { 200,-258 }, { 201,-258 }, { 202,-258 }, { 203,-258 },
 { 204,-258 }, { 205,-258 }, { 206,-258 }, { 207,-258 }, { 208,-258 },
 { 209,-258 }, { 210,-258 }, { 211,-258 }, { 212,-258 }, { 213,-258 },
 { 214,-258 }, { 215,-258 }, { 216,-258 }, { 217,-258 }, { 218,-258 },
 { 219,-258 }, { 220,-258 }, { 221,-258 }, { 222,-258 }, { 223,-258 },
 { 224,-258 }, { 225,-258 }, { 226,-258 }, { 227,-258 }, { 228,-258 },

 { 229,-258 }, { 230,-258 }, { 231,-258 }, { 232,-258 }, { 233,-258 },
 { 234,-258 }, { 235,-258 }, { 236,-258 }, { 237,-258 }, { 238,-258 },
 { 239,-258 }, { 240,-258 }, { 241,-258 }, { 242,-258 }, { 243,-258 },
 { 244,-258 }, { 245,-258 }, { 246,-258 }, { 247,-258 }, { 248,-258 },
 { 249,-258 }, { 250,-258 }, { 251,-258 }, { 252,-258 }, { 253,-258 },
 { 254,-258 }, { 255,-258 }, { 256,-258 }, {   0,   2 }, {   0,19371 },
 {   0,  73 }, {   0,19369 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,  77 }, {   0,19347 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  33,   0 }, {   0,   0 }, {  35,   0 },
 {   0,   0 }, {  37,   0 }, {  38,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  42,   0 }, {  43,   0 }, {   0,   0 }, {  45,   0 },
 {   0,   0 }, {  47,   0 }, {   0,   0 }, {   0,   0 }, {  48,   0 },
 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },
 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {  60,   0 },
 {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 }, {   0,  75 },
 {   0,19305 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  69,-4404 }, {  48,  42 }, {  49,  42 }, {  50,  42 }, {  51,  42 },
 {  52,  42 }, {  53,  42 }, {  54,  42 }, {  55,  42 }, {  56,  42 },
 {  57,  42 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  94,   0 }, {   0,   0 },
 {  96,   0 }, {   0,   9 }, {   0,19273 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, { 101,-4404 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   9,   0 }, {  10,   0 }, {   0,   0 }, {  12,   0 },
 {  13,   0 }, {   0,   0 }, {   0,   0 }, {  48,   0 }, {  49,   0 },
 {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 },

 {  55,   0 }, {  56,   0 }, {  57,   0 }, { 124,   0 }, {   0,   0 },
 { 126,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  39,-10204 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  45,-10202 }, {   0,   9 }, {   0,19226 },
 {   1,2553 }, {   2,2553 }, {   3,2553 }, {   4,2553 }, {   5,2553 },
 {   6,2553 }, {   7,2553 }, {   8,2553 }, {   9,2811 }, {  10,-3788 },
 {  11,2553 }, {  12,2811 }, {  13,-3788 }, {  14,2553 }, {  15,2553 },
 {  16,2553 }, {  17,2553 }, {  18,2553 }, {  19,2553 }, {  20,2553 },
 {  21,2553 }, {  22,2553 }, {  23,2553 }, {  24,2553 }, {  25,2553 },

 {  26,2553 }, {  27,2553 }, {  28,2553 }, {  29,2553 }, {  30,2553 },
 {  31,2553 }, {  32,2811 }, {  33,2553 }, {  34,2553 }, {  35,2553 },
 {  36,2553 }, {  37,2553 }, {  38,2553 }, {  39,2553 }, {  40,2553 },
 {  41,2553 }, {  42,2553 }, {  43,2553 }, {  44,2553 }, {  45,3069 },
 {  46,2553 }, {  47,2553 }, {  48,2553 }, {  49,2553 }, {  50,2553 },
 {  51,2553 }, {  52,2553 }, {  53,2553 }, {  54,2553 }, {  55,2553 },
 {  56,2553 }, {  57,2553 }, {  58,2553 }, {  59,2553 }, {  60,2553 },
 {  61,2553 }, {  62,2553 }, {  63,2553 }, {  64,2553 }, {  65,2553 },
 {  66,2553 }, {  67,2553 }, {  68,2553 }, {  69,2553 }, {  70,2553 },
 {  71,2553 }, {  72,2553 }, {  73,2553 }, {  74,2553 }, {  75,2553 },

 {  76,2553 }, {  77,2553 }, {  78,2553 }, {  79,2553 }, {  80,2553 },
 {  81,2553 }, {  82,2553 }, {  83,2553 }, {  84,2553 }, {  85,2553 },
 {  86,2553 }, {  87,2553 }, {  88,2553 }, {  89,2553 }, {  90,2553 },
 {  91,2553 }, {  92,2553 }, {  93,2553 }, {  94,2553 }, {  95,2553 },
 {  96,2553 }, {  97,2553 }, {  98,2553 }, {  99,2553 }, { 100,2553 },
 { 101,2553 }, { 102,2553 }, { 103,2553 }, { 104,2553 }, { 105,2553 },
 { 106,2553 }, { 107,2553 }, { 108,2553 }, { 109,2553 }, { 110,2553 },
 { 111,2553 }, { 112,2553 }, { 113,2553 }, { 114,2553 }, { 115,2553 },
 { 116,2553 }, { 117,2553 }, { 118,2553 }, { 119,2553 }, { 120,2553 },
 { 121,2553 }, { 122,2553 }, { 123,2553 }, { 124,2553 }, { 125,2553 },

 { 126,2553 }, { 127,2553 }, { 128,2553 }, { 129,2553 }, { 130,2553 },
 { 131,2553 }, { 132,2553 }, { 133,2553 }, { 134,2553 }, { 135,2553 },
 { 136,2553 }, { 137,2553 }, { 138,2553 }, { 139,2553 }, { 140,2553 },
 { 141,2553 }, { 142,2553 }, { 143,2553 }, { 144,2553 }, { 145,2553 },
 { 146,2553 }, { 147,2553 }, { 148,2553 }, { 149,2553 }, { 150,2553 },
 { 151,2553 }, { 152,2553 }, { 153,2553 }, { 154,2553 }, { 155,2553 },
 { 156,2553 }, { 157,2553 }, { 158,2553 }, { 159,2553 }, { 160,2553 },
 { 161,2553 }, { 162,2553 }, { 163,2553 }, { 164,2553 }, { 165,2553 },
 { 166,2553 }, { 167,2553 }, { 168,2553 }, { 169,2553 }, { 170,2553 },
 { 171,2553 }, { 172,2553 }, { 173,2553 }, { 174,2553 }, { 175,2553 },

 { 176,2553 }, { 177,2553 }, { 178,2553 }, { 179,2553 }, { 180,2553 },
 { 181,2553 }, { 182,2553 }, { 183,2553 }, { 184,2553 }, { 185,2553 },
 { 186,2553 }, { 187,2553 }, { 188,2553 }, { 189,2553 }, { 190,2553 },
 { 191,2553 }, { 192,2553 }, { 193,2553 }, { 194,2553 }, { 195,2553 },
 { 196,2553 }, { 197,2553 }, { 198,2553 }, { 199,2553 }, { 200,2553 },
 { 201,2553 }, { 202,2553 }, { 203,2553 }, { 204,2553 }, { 205,2553 },
 { 206,2553 }, { 207,2553 }, { 208,2553 }, { 209,2553 }, { 210,2553 },
 { 211,2553 }, { 212,2553 }, { 213,2553 }, { 214,2553 }, { 215,2553 },
 { 216,2553 }, { 217,2553 }, { 218,2553 }, { 219,2553 }, { 220,2553 },
 { 221,2553 }, { 222,2553 }, { 223,2553 }, { 224,2553 }, { 225,2553 },

 { 226,2553 }, { 227,2553 }, { 228,2553 }, { 229,2553 }, { 230,2553 },
 { 231,2553 }, { 232,2553 }, { 233,2553 }, { 234,2553 }, { 235,2553 },
 { 236,2553 }, { 237,2553 }, { 238,2553 }, { 239,2553 }, { 240,2553 },
 { 241,2553 }, { 242,2553 }, { 243,2553 }, { 244,2553 }, { 245,2553 },
 { 246,2553 }, { 247,2553 }, { 248,2553 }, { 249,2553 }, { 250,2553 },
 { 251,2553 }, { 252,2553 }, { 253,2553 }, { 254,2553 }, { 255,2553 },
 { 256,2553 }, {   0,   3 }, {   0,18968 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  16 }, {   0,18961 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 },

 {   0,   0 }, {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  33,   0 }, {   0,   0 }, {  35,   0 }, {   0,   0 }, {  37,   0 },
 {  38,   0 }, {  32,   0 }, {   0,   0 }, {   0,   0 }, {  42,   0 },
 {  43,   0 }, {   0,   0 }, {  45,   0 }, {  39,-10512 }, {  47,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  45,-10507 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 },
 {  63,   0 }, {  64,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  94,   0 }, {   0,   0 }, {  96,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, { 124,   0 }, {   0,   0 }, { 126,   0 }, {   0,  16 },
 {   0,18840 }, {   1,3199 }, {   2,3199 }, {   3,3199 }, {   4,3199 },
 {   5,3199 }, {   6,3199 }, {   7,3199 }, {   8,3199 }, {   9,3457 },
 {  10,-3220 }, {  11,3199 }, {  12,3457 }, {  13,-3220 }, {  14,3199 },
 {  15,3199 }, {  16,3199 }, {  17,3199 }, {  18,3199 }, {  19,3199 },
 {  20,3199 }, {  21,3199 }, {  22,3199 }, {  23,3199 }, {  24,3199 },
 {  25,3199 }, {  26,3199 }, {  27,3199 }, {  28,3199 }, {  29,3199 },
 {  30,3199 }, {  31,3199 }, {  32,3457 }, {  33,3199 }, {  34,3199 },
 {  35,3199 }, {  36,3199 }, {  37,3199 }, {  38,3199 }, {  39,3199 },

 {  40,3199 }, {  41,3199 }, {  42,3199 }, {  43,3199 }, {  44,3199 },
 {  45,3715 }, {  46,3199 }, {  47,3199 }, {  48,3199 }, {  49,3199 },
 {  50,3199 }, {  51,3199 }, {  52,3199 }, {  53,3199 }, {  54,3199 },
 {  55,3199 }, {  56,3199 }, {  57,3199 }, {  58,3199 }, {  59,3199 },
 {  60,3199 }, {  61,3199 }, {  62,3199 }, {  63,3199 }, {  64,3199 },
 {  65,3199 }, {  66,3199 }, {  67,3199 }, {  68,3199 }, {  69,3199 },
 {  70,3199 }, {  71,3199 }, {  72,3199 }, {  73,3199 }, {  74,3199 },
 {  75,3199 }, {  76,3199 }, {  77,3199 }, {  78,3199 }, {  79,3199 },
 {  80,3199 }, {  81,3199 }, {  82,3199 }, {  83,3199 }, {  84,3199 },
 {  85,3199 }, {  86,3199 }, {  87,3199 }, {  88,3199 }, {  89,3199 },

 {  90,3199 }, {  91,3199 }, {  92,3199 }, {  93,3199 }, {  94,3199 },
 {  95,3199 }, {  96,3199 }, {  97,3199 }, {  98,3199 }, {  99,3199 },
 { 100,3199 }, { 101,3199 }, { 102,3199 }, { 103,3199 }, { 104,3199 },
 { 105,3199 }, { 106,3199 }, { 107,3199 }, { 108,3199 }, { 109,3199 },
 { 110,3199 }, { 111,3199 }, { 112,3199 }, { 113,3199 }, { 114,3199 },
 { 115,3199 }, { 116,3199 }, { 117,3199 }, { 118,3199 }, { 119,3199 },
 { 120,3199 }, { 121,3199 }, { 122,3199 }, { 123,3199 }, { 124,3199 },
 { 125,3199 }, { 126,3199 }, { 127,3199 }, { 128,3199 }, { 129,3199 },
 { 130,3199 }, { 131,3199 }, { 132,3199 }, { 133,3199 }, { 134,3199 },
 { 135,3199 }, { 136,3199 }, { 137,3199 }, { 138,3199 }, { 139,3199 },

 { 140,3199 }, { 141,3199 }, { 142,3199 }, { 143,3199 }, { 144,3199 },
 { 145,3199 }, { 146,3199 }, { 147,3199 }, { 148,3199 }, { 149,3199 },
 { 150,3199 }, { 151,3199 }, { 152,3199 }, { 153,3199 }, { 154,3199 },
 { 155,3199 }, { 156,3199 }, { 157,3199 }, { 158,3199 }, { 159,3199 },
 { 160,3199 }, { 161,3199 }, { 162,3199 }, { 163,3199 }, { 164,3199 },
 { 165,3199 }, { 166,3199 }, { 167,3199 }, { 168,3199 }, { 169,3199 },
 { 170,3199 }, { 171,3199 }, { 172,3199 }, { 173,3199 }, { 174,3199 },
 { 175,3199 }, { 176,3199 }, { 177,3199 }, { 178,3199 }, { 179,3199 },
 { 180,3199 }, { 181,3199 }, { 182,3199 }, { 183,3199 }, { 184,3199 },
 { 185,3199 }, { 186,3199 }, { 187,3199 }, { 188,3199 }, { 189,3199 },

 { 190,3199 }, { 191,3199 }, { 192,3199 }, { 193,3199 }, { 194,3199 },
 { 195,3199 }, { 196,3199 }, { 197,3199 }, { 198,3199 }, { 199,3199 },
 { 200,3199 }, { 201,3199 }, { 202,3199 }, { 203,3199 }, { 204,3199 },
 { 205,3199 }, { 206,3199 }, { 207,3199 }, { 208,3199 }, { 209,3199 },
 { 210,3199 }, { 211,3199 }, { 212,3199 }, { 213,3199 }, { 214,3199 },
 { 215,3199 }, { 216,3199 }, { 217,3199 }, { 218,3199 }, { 219,3199 },
 { 220,3199 }, { 221,3199 }, { 222,3199 }, { 223,3199 }, { 224,3199 },
 { 225,3199 }, { 226,3199 }, { 227,3199 }, { 228,3199 }, { 229,3199 },
 { 230,3199 }, { 231,3199 }, { 232,3199 }, { 233,3199 }, { 234,3199 },
 { 235,3199 }, { 236,3199 }, { 237,3199 }, { 238,3199 }, { 239,3199 },

 { 240,3199 }, { 241,3199 }, { 242,3199 }, { 243,3199 }, { 244,3199 },
 { 245,3199 }, { 246,3199 }, { 247,3199 }, { 248,3199 }, { 249,3199 },
 { 250,3199 }, { 251,3199 }, { 252,3199 }, { 253,3199 }, { 254,3199 },
 { 255,3199 }, { 256,3199 }, {   0,  22 }, {   0,18582 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 }, {   0,   0 },
 {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  32,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  39,-10877 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  45,-10850 }, {   0,  22 },
 {   0,18535 }, {   1,3926 }, {   2,3926 }, {   3,3926 }, {   4,3926 },
 {   5,3926 }, {   6,3926 }, {   7,3926 }, {   8,3926 }, {   9,4184 },
 {  10,-3215 }, {  11,3926 }, {  12,4184 }, {  13,-3215 }, {  14,3926 },
 {  15,3926 }, {  16,3926 }, {  17,3926 }, {  18,3926 }, {  19,3926 },
 {  20,3926 }, {  21,3926 }, {  22,3926 }, {  23,3926 }, {  24,3926 },
 {  25,3926 }, {  26,3926 }, {  27,3926 }, {  28,3926 }, {  29,3926 },
 {  30,3926 }, {  31,3926 }, {  32,4184 }, {  33,3926 }, {  34,3926 },

 {  35,3926 }, {  36,3926 }, {  37,3926 }, {  38,3926 }, {  39,3926 },
 {  40,3926 }, {  41,3926 }, {  42,3926 }, {  43,3926 }, {  44,3926 },
 {  45,4442 }, {  46,3926 }, {  47,3926 }, {  48,3926 }, {  49,3926 },
 {  50,3926 }, {  51,3926 }, {  52,3926 }, {  53,3926 }, {  54,3926 },
 {  55,3926 }, {  56,3926 }, {  57,3926 }, {  58,3926 }, {  59,3926 },
 {  60,3926 }, {  61,3926 }, {  62,3926 }, {  63,3926 }, {  64,3926 },
 {  65,3926 }, {  66,3926 }, {  67,3926 }, {  68,3926 }, {  69,3926 },
 {  70,3926 }, {  71,3926 }, {  72,3926 }, {  73,3926 }, {  74,3926 },
 {  75,3926 }, {  76,3926 }, {  77,3926 }, {  78,3926 }, {  79,3926 },
 {  80,3926 }, {  81,3926 }, {  82,3926 }, {  83,3926 }, {  84,3926 },

 {  85,3926 }, {  86,3926 }, {  87,3926 }, {  88,3926 }, {  89,3926 },
 {  90,3926 }, {  91,3926 }, {  92,3926 }, {  93,3926 }, {  94,3926 },
 {  95,3926 }, {  96,3926 }, {  97,3926 }, {  98,3926 }, {  99,3926 },
 { 100,3926 }, { 101,3926 }, { 102,3926 }, { 103,3926 }, { 104,3926 },
 { 105,3926 }, { 106,3926 }, { 107,3926 }, { 108,3926 }, { 109,3926 },
 { 110,3926 }, { 111,3926 }, { 112,3926 }, { 113,3926 }, { 114,3926 },
 { 115,3926 }, { 116,3926 }, { 117,3926 }, { 118,3926 }, { 119,3926 },
 { 120,3926 }, { 121,3926 }, { 122,3926 }, { 123,3926 }, { 124,3926 },
 { 125,3926 }, { 126,3926 }, { 127,3926 }, { 128,3926 }, { 129,3926 },
 { 130,3926 }, { 131,3926 }, { 132,3926 }, { 133,3926 }, { 134,3926 },

 { 135,3926 }, { 136,3926 }, { 137,3926 }, { 138,3926 }, { 139,3926 },
 { 140,3926 }, { 141,3926 }, { 142,3926 }, { 143,3926 }, { 144,3926 },
 { 145,3926 }, { 146,3926 }, { 147,3926 }, { 148,3926 }, { 149,3926 },
 { 150,3926 }, { 151,3926 }, { 152,3926 }, { 153,3926 }, { 154,3926 },
 { 155,3926 }, { 156,3926 }, { 157,3926 }, { 158,3926 }, { 159,3926 },
 { 160,3926 }, { 161,3926 }, { 162,3926 }, { 163,3926 }, { 164,3926 },
 { 165,3926 }, { 166,3926 }, { 167,3926 }, { 168,3926 }, { 169,3926 },
 { 170,3926 }, { 171,3926 }, { 172,3926 }, { 173,3926 }, { 174,3926 },
 { 175,3926 }, { 176,3926 }, { 177,3926 }, { 178,3926 }, { 179,3926 },
 { 180,3926 }, { 181,3926 }, { 182,3926 }, { 183,3926 }, { 184,3926 },

 { 185,3926 }, { 186,3926 }, { 187,3926 }, { 188,3926 }, { 189,3926 },
 { 190,3926 }, { 191,3926 }, { 192,3926 }, { 193,3926 }, { 194,3926 },
 { 195,3926 }, { 196,3926 }, { 197,3926 }, { 198,3926 }, { 199,3926 },
 { 200,3926 }, { 201,3926 }, { 202,3926 }, { 203,3926 }, { 204,3926 },
 { 205,3926 }, { 206,3926 }, { 207,3926 }, { 208,3926 }, { 209,3926 },
 { 210,3926 }, { 211,3926 }, { 212,3926 }, { 213,3926 }, { 214,3926 },
 { 215,3926 }, { 216,3926 }, { 217,3926 }, { 218,3926 }, { 219,3926 },
 { 220,3926 }, { 221,3926 }, { 222,3926 }, { 223,3926 }, { 224,3926 },
 { 225,3926 }, { 226,3926 }, { 227,3926 }, { 228,3926 }, { 229,3926 },
 { 230,3926 }, { 231,3926 }, { 232,3926 }, { 233,3926 }, { 234,3926 },

 { 235,3926 }, { 236,3926 }, { 237,3926 }, { 238,3926 }, { 239,3926 },
 { 240,3926 }, { 241,3926 }, { 242,3926 }, { 243,3926 }, { 244,3926 },
 { 245,3926 }, { 246,3926 }, { 247,3926 }, { 248,3926 }, { 249,3926 },
 { 250,3926 }, { 251,3926 }, { 252,3926 }, { 253,3926 }, { 254,3926 },
 { 255,3926 }, { 256,3926 }, {   0,  39 }, {   0,18277 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  37 }, {   0,18269 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  37 }, {   0,18246 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  48,-10829 }, {  49,-10829 }, {  50,-10829 }, {  51,-10829 },
 {  52,-10829 }, {  53,-10829 }, {  54,-10829 }, {  55,-10829 }, {  48,4434 },
 {  49,4434 }, {  50,4434 }, {  51,4434 }, {  52,4434 }, {  53,4434 },
 {  54,4434 }, {  55,4434 }, {  56,4434 }, {  57,4434 }, {   0,   0 },
 {   0,   0 }, {   0,  40 }, {   0,18208 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  65,4434 }, {  66,4434 }, {  67,4434 }, {  68,4434 },

 {  69,4434 }, {  70,4434 }, {  48,4434 }, {  49,4434 }, {  50,4434 },
 {  51,4434 }, {  52,4434 }, {  53,4434 }, {  54,4434 }, {  55,4434 },
 {  56,4434 }, {  57,4434 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,4434 },
 {  66,4434 }, {  67,4434 }, {  68,4434 }, {  69,4434 }, {  70,4434 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,4434 }, {  98,4434 },
 {  99,4434 }, { 100,4434 }, { 101,4434 }, { 102,4434 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  48,-10896 }, {  49,-10896 }, {  50,-10896 }, {  51,-10896 }, {  52,-10896 },
 {  53,-10896 }, {  54,-10896 }, {  55,-10896 }, {  56,-10896 }, {  57,-10896 },

 {   0,   0 }, {  97,4434 }, {  98,4434 }, {  99,4434 }, { 100,4434 },
 { 101,4434 }, { 102,4434 }, {  65,-10896 }, {  66,-10896 }, {  67,-10896 },
 {  68,-10896 }, {  69,-10896 }, {  70,-10896 }, {   0,  47 }, {   0,18136 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,-10896 },
 {  98,-10896 }, {  99,-10896 }, { 100,-10896 }, { 101,-10896 }, { 102,-10896 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  36,-11399 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 },
 {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 },
 {  56,   0 }, {  57,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,   0 },
 {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 },
 {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 },
 {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 },
 {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 },

 {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  95,   0 },
 {   0,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 },
 { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 },
 { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 },
 { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 },
 { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 },
 { 121,   0 }, { 122,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 },
 { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 },

 { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 },
 { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 },
 { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 },
 { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 },
 { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 },
 { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 },
 { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 },
 { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 },
 { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 },
 { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 },

 { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 },
 { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 },
 { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 },
 { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 },
 { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 },
 { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 },
 { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 },
 { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 },
 { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 },
 { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 },

 { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 },
 { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 },
 { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 },
 { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 },
 {   0,  53 }, {   0,17879 }, {   1,   0 }, {   2,   0 }, {   3,   0 },
 {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 },
 {   9,   0 }, {   0,   0 }, {  11,   0 }, {  12,   0 }, {   0,   0 },
 {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 },
 {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 },
 {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 },

 {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32,   0 }, {  33,   0 },
 {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 },
 {  39,   0 }, {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 },
 {  44,   0 }, {  45,   0 }, {  46,   0 }, {  47,   0 }, {  48,   0 },
 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },
 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 },
 {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 },
 {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 },
 {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 },
 {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 },

 {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 },
 {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 },
 {  89,   0 }, {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 },
 {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 },
 {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 },
 { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 },
 { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 },
 { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 },
 { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 },
 { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 },

 { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 },
 { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 },
 { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 },
 { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 },
 { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 },
 { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 },
 { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 },
 { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 },
 { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 },
 { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 },

 { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 },
 { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 },
 { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 },
 { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 },
 { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 },
 { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 },
 { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 },
 { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 },
 { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 },
 { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 },

 { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 },
 { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 },
 { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 },
 { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 },
 { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 },
 { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,  24 }, {   0,17621 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 },
 {   0,   0 }, {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  32,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  39,-11838 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  45,-11774 },
 {   0,  24 }, {   0,17574 }, {   1,4124 }, {   2,4124 }, {   3,4124 },
 {   4,4124 }, {   5,4124 }, {   6,4124 }, {   7,4124 }, {   8,4124 },
 {   9,4382 }, {  10,-2960 }, {  11,4124 }, {  12,4382 }, {  13,-2960 },
 {  14,4124 }, {  15,4124 }, {  16,4124 }, {  17,4124 }, {  18,4124 },
 {  19,4124 }, {  20,4124 }, {  21,4124 }, {  22,4124 }, {  23,4124 },

 {  24,4124 }, {  25,4124 }, {  26,4124 }, {  27,4124 }, {  28,4124 },
 {  29,4124 }, {  30,4124 }, {  31,4124 }, {  32,4382 }, {  33,4124 },
 {  34,4124 }, {  35,4124 }, {  36,4124 }, {  37,4124 }, {  38,4124 },
 {  39,4124 }, {  40,4124 }, {  41,4124 }, {  42,4124 }, {  43,4124 },
 {  44,4124 }, {  45,4640 }, {  46,4124 }, {  47,4124 }, {  48,4124 },
 {  49,4124 }, {  50,4124 }, {  51,4124 }, {  52,4124 }, {  53,4124 },
 {  54,4124 }, {  55,4124 }, {  56,4124 }, {  57,4124 }, {  58,4124 },
 {  59,4124 }, {  60,4124 }, {  61,4124 }, {  62,4124 }, {  63,4124 },
 {  64,4124 }, {  65,4124 }, {  66,4124 }, {  67,4124 }, {  68,4124 },
 {  69,4124 }, {  70,4124 }, {  71,4124 }, {  72,4124 }, {  73,4124 },

 {  74,4124 }, {  75,4124 }, {  76,4124 }, {  77,4124 }, {  78,4124 },
 {  79,4124 }, {  80,4124 }, {  81,4124 }, {  82,4124 }, {  83,4124 },
 {  84,4124 }, {  85,4124 }, {  86,4124 }, {  87,4124 }, {  88,4124 },
 {  89,4124 }, {  90,4124 }, {  91,4124 }, {  92,4124 }, {  93,4124 },
 {  94,4124 }, {  95,4124 }, {  96,4124 }, {  97,4124 }, {  98,4124 },
 {  99,4124 }, { 100,4124 }, { 101,4124 }, { 102,4124 }, { 103,4124 },
 { 104,4124 }, { 105,4124 }, { 106,4124 }, { 107,4124 }, { 108,4124 },
 { 109,4124 }, { 110,4124 }, { 111,4124 }, { 112,4124 }, { 113,4124 },
 { 114,4124 }, { 115,4124 }, { 116,4124 }, { 117,4124 }, { 118,4124 },
 { 119,4124 }, { 120,4124 }, { 121,4124 }, { 122,4124 }, { 123,4124 },

 { 124,4124 }, { 125,4124 }, { 126,4124 }, { 127,4124 }, { 128,4124 },
 { 129,4124 }, { 130,4124 }, { 131,4124 }, { 132,4124 }, { 133,4124 },
 { 134,4124 }, { 135,4124 }, { 136,4124 }, { 137,4124 }, { 138,4124 },
 { 139,4124 }, { 140,4124 }, { 141,4124 }, { 142,4124 }, { 143,4124 },
 { 144,4124 }, { 145,4124 }, { 146,4124 }, { 147,4124 }, { 148,4124 },
 { 149,4124 }, { 150,4124 }, { 151,4124 }, { 152,4124 }, { 153,4124 },
 { 154,4124 }, { 155,4124 }, { 156,4124 }, { 157,4124 }, { 158,4124 },
 { 159,4124 }, { 160,4124 }, { 161,4124 }, { 162,4124 }, { 163,4124 },
 { 164,4124 }, { 165,4124 }, { 166,4124 }, { 167,4124 }, { 168,4124 },
 { 169,4124 }, { 170,4124 }, { 171,4124 }, { 172,4124 }, { 173,4124 },

 { 174,4124 }, { 175,4124 }, { 176,4124 }, { 177,4124 }, { 178,4124 },
 { 179,4124 }, { 180,4124 }, { 181,4124 }, { 182,4124 }, { 183,4124 },
 { 184,4124 }, { 185,4124 }, { 186,4124 }, { 187,4124 }, { 188,4124 },
 { 189,4124 }, { 190,4124 }, { 191,4124 }, { 192,4124 }, { 193,4124 },
 { 194,4124 }, { 195,4124 }, { 196,4124 }, { 197,4124 }, { 198,4124 },
 { 199,4124 }, { 200,4124 }, { 201,4124 }, { 202,4124 }, { 203,4124 },
 { 204,4124 }, { 205,4124 }, { 206,4124 }, { 207,4124 }, { 208,4124 },
 { 209,4124 }, { 210,4124 }, { 211,4124 }, { 212,4124 }, { 213,4124 },
 { 214,4124 }, { 215,4124 }, { 216,4124 }, { 217,4124 }, { 218,4124 },
 { 219,4124 }, { 220,4124 }, { 221,4124 }, { 222,4124 }, { 223,4124 },

 { 224,4124 }, { 225,4124 }, { 226,4124 }, { 227,4124 }, { 228,4124 },
 { 229,4124 }, { 230,4124 }, { 231,4124 }, { 232,4124 }, { 233,4124 },
 { 234,4124 }, { 235,4124 }, { 236,4124 }, { 237,4124 }, { 238,4124 },
 { 239,4124 }, { 240,4124 }, { 241,4124 }, { 242,4124 }, { 243,4124 },
 { 244,4124 }, { 245,4124 }, { 246,4124 }, { 247,4124 }, { 248,4124 },
 { 249,4124 }, { 250,4124 }, { 251,4124 }, { 252,4124 }, { 253,4124 },
 { 254,4124 }, { 255,4124 }, { 256,4124 }, {   0,  26 }, {   0,17316 },
 {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 },
 {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9,   0 }, {   0,   0 },
 {  11,   0 }, {  12,   0 }, {   0,   0 }, {  14,   0 }, {  15,   0 },

 {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 },
 {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 },
 {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 },
 {  31,   0 }, {  32,   0 }, {  33,   0 }, {  34,   0 }, {  35,   0 },
 {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 },
 {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45,   0 },
 {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 },
 {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 },
 {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 },
 {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 },

 {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 },
 {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 },
 {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 },
 {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 },
 {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 },
 {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 },
 {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 },
 { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 },
 { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 },
 { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 },

 { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 },
 { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 },
 { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 },
 { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 },
 { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 },
 { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 },
 { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 },
 { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 },
 { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 },
 { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 },

 { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 },
 { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 },
 { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 },
 { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 },
 { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 },
 { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 },
 { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 },
 { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 },
 { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 },
 { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 },

 { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 },
 { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 },
 { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 },
 { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 },
 { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 },
 { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 },
 { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 },
 { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 },
 { 256,   0 }, {   0,  37 }, {   0,17058 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  37 },
 {   0,17035 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  48,4382 }, {  49,4382 }, {  50,4382 }, {  51,4382 }, {  52,4382 },
 {  53,4382 }, {  54,4382 }, {  55,4382 }, {  56,4382 }, {  57,4382 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65,4382 }, {  66,4382 }, {  67,4382 },
 {  68,4382 }, {  69,4382 }, {  70,4382 }, {  48,4382 }, {  49,4382 },
 {  50,4382 }, {  51,4382 }, {  52,4382 }, {  53,4382 }, {  54,4382 },
 {  55,4382 }, {  56,4382 }, {  57,4382 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  65,4382 }, {  66,4382 }, {  67,4382 }, {  68,4382 }, {  69,4382 },
 {  70,4382 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,4382 },
 {  98,4382 }, {  99,4382 }, { 100,4382 }, { 101,4382 }, { 102,4382 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  97,4382 }, {  98,4382 }, {  99,4382 },
 { 100,4382 }, { 101,4382 }, { 102,4382 }, {   0,   9 }, {   0,16931 },
 {   1,4382 }, {   2,4382 }, {   3,4382 }, {   4,4382 }, {   5,4382 },
 {   6,4382 }, {   7,4382 }, {   8,4382 }, {   9,4640 }, {  10,4898 },
 {  11,4382 }, {  12,4640 }, {  13,4898 }, {  14,4382 }, {  15,4382 },
 {  16,4382 }, {  17,4382 }, {  18,4382 }, {  19,4382 }, {  20,4382 },
 {  21,4382 }, {  22,4382 }, {  23,4382 }, {  24,4382 }, {  25,4382 },
 {  26,4382 }, {  27,4382 }, {  28,4382 }, {  29,4382 }, {  30,4382 },

 {  31,4382 }, {  32,4640 }, {  33,4382 }, {  34,4382 }, {  35,4382 },
 {  36,4382 }, {  37,4382 }, {  38,4382 }, {  39,4382 }, {  40,4382 },
 {  41,4382 }, {  42,4382 }, {  43,4382 }, {  44,4382 }, {  45,4945 },
 {  46,4382 }, {  47,4382 }, {  48,4382 }, {  49,4382 }, {  50,4382 },
 {  51,4382 }, {  52,4382 }, {  53,4382 }, {  54,4382 }, {  55,4382 },
 {  56,4382 }, {  57,4382 }, {  58,4382 }, {  59,4382 }, {  60,4382 },
 {  61,4382 }, {  62,4382 }, {  63,4382 }, {  64,4382 }, {  65,4382 },
 {  66,4382 }, {  67,4382 }, {  68,4382 }, {  69,4382 }, {  70,4382 },
 {  71,4382 }, {  72,4382 }, {  73,4382 }, {  74,4382 }, {  75,4382 },
 {  76,4382 }, {  77,4382 }, {  78,4382 }, {  79,4382 }, {  80,4382 },

 {  81,4382 }, {  82,4382 }, {  83,4382 }, {  84,4382 }, {  85,4382 },
 {  86,4382 }, {  87,4382 }, {  88,4382 }, {  89,4382 }, {  90,4382 },
 {  91,4382 }, {  92,4382 }, {  93,4382 }, {  94,4382 }, {  95,4382 },
 {  96,4382 }, {  97,4382 }, {  98,4382 }, {  99,4382 }, { 100,4382 },
 { 101,4382 }, { 102,4382 }, { 103,4382 }, { 104,4382 }, { 105,4382 },
 { 106,4382 }, { 107,4382 }, { 108,4382 }, { 109,4382 }, { 110,4382 },
 { 111,4382 }, { 112,4382 }, { 113,4382 }, { 114,4382 }, { 115,4382 },
 { 116,4382 }, { 117,4382 }, { 118,4382 }, { 119,4382 }, { 120,4382 },
 { 121,4382 }, { 122,4382 }, { 123,4382 }, { 124,4382 }, { 125,4382 },
 { 126,4382 }, { 127,4382 }, { 128,4382 }, { 129,4382 }, { 130,4382 },

 { 131,4382 }, { 132,4382 }, { 133,4382 }, { 134,4382 }, { 135,4382 },
 { 136,4382 }, { 137,4382 }, { 138,4382 }, { 139,4382 }, { 140,4382 },
 { 141,4382 }, { 142,4382 }, { 143,4382 }, { 144,4382 }, { 145,4382 },
 { 146,4382 }, { 147,4382 }, { 148,4382 }, { 149,4382 }, { 150,4382 },
 { 151,4382 }, { 152,4382 }, { 153,4382 }, { 154,4382 }, { 155,4382 },
 { 156,4382 }, { 157,4382 }, { 158,4382 }, { 159,4382 }, { 160,4382 },
 { 161,4382 }, { 162,4382 }, { 163,4382 }, { 164,4382 }, { 165,4382 },
 { 166,4382 }, { 167,4382 }, { 168,4382 }, { 169,4382 }, { 170,4382 },
 { 171,4382 }, { 172,4382 }, { 173,4382 }, { 174,4382 }, { 175,4382 },
 { 176,4382 }, { 177,4382 }, { 178,4382 }, { 179,4382 }, { 180,4382 },

 { 181,4382 }, { 182,4382 }, { 183,4382 }, { 184,4382 }, { 185,4382 },
 { 186,4382 }, { 187,4382 }, { 188,4382 }, { 189,4382 }, { 190,4382 },
 { 191,4382 }, { 192,4382 }, { 193,4382 }, { 194,4382 }, { 195,4382 },
 { 196,4382 }, { 197,4382 }, { 198,4382 }, { 199,4382 }, { 200,4382 },
 { 201,4382 }, { 202,4382 }, { 203,4382 }, { 204,4382 }, { 205,4382 },
 { 206,4382 }, { 207,4382 }, { 208,4382 }, { 209,4382 }, { 210,4382 },
 { 211,4382 }, { 212,4382 }, { 213,4382 }, { 214,4382 }, { 215,4382 },
 { 216,4382 }, { 217,4382 }, { 218,4382 }, { 219,4382 }, { 220,4382 },
 { 221,4382 }, { 222,4382 }, { 223,4382 }, { 224,4382 }, { 225,4382 },
 { 226,4382 }, { 227,4382 }, { 228,4382 }, { 229,4382 }, { 230,4382 },

 { 231,4382 }, { 232,4382 }, { 233,4382 }, { 234,4382 }, { 235,4382 },
 { 236,4382 }, { 237,4382 }, { 238,4382 }, { 239,4382 }, { 240,4382 },
 { 241,4382 }, { 242,4382 }, { 243,4382 }, { 244,4382 }, { 245,4382 },
 { 246,4382 }, { 247,4382 }, { 248,4382 }, { 249,4382 }, { 250,4382 },
 { 251,4382 }, { 252,4382 }, { 253,4382 }, { 254,4382 }, { 255,4382 },
 { 256,4382 }, {   0,   9 }, {   0,16673 }, {   1,   0 }, {   2,   0 },
 {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 },
 {   8,   0 }, {   9, 258 }, {  10,-6341 }, {  11,   0 }, {  12, 258 },
 {  13,-6341 }, {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 },
 {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 },

 {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 },
 {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32, 258 },
 {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 },
 {  38,   0 }, {  39,   0 }, {  40,   0 }, {  41,   0 }, {  42,   0 },
 {  43,   0 }, {  44,   0 }, {  45, 516 }, {  46,   0 }, {  47,   0 },
 {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 },
 {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 },
 {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 },
 {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 },
 {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 },

 {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 },
 {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 },
 {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 },
 {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 }, {  92,   0 },
 {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 },
 {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 },
 { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 },
 { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 },
 { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 },
 { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 },

 { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 },
 { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 },
 { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 },
 { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 },
 { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 },
 { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 },
 { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 },
 { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 },
 { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 },
 { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 },

 { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 },
 { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 },
 { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 },
 { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 },
 { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 },
 { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 },
 { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 },
 { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 },
 { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 },
 { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 },

 { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 },
 { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 },
 { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 },
 { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 },
 { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 },
 { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 },
 { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,   9 },
 {   0,16415 }, {   1,-258 }, {   2,-258 }, {   3,-258 }, {   4,-258 },
 {   5,-258 }, {   6,-258 }, {   7,-258 }, {   8,-258 }, {   9,   0 },
 {  10,-6599 }, {  11,-258 }, {  12,   0 }, {  13,-6599 }, {  14,-258 },

 {  15,-258 }, {  16,-258 }, {  17,-258 }, {  18,-258 }, {  19,-258 },
 {  20,-258 }, {  21,-258 }, {  22,-258 }, {  23,-258 }, {  24,-258 },
 {  25,-258 }, {  26,-258 }, {  27,-258 }, {  28,-258 }, {  29,-258 },
 {  30,-258 }, {  31,-258 }, {  32,   0 }, {  33,-258 }, {  34,-258 },
 {  35,-258 }, {  36,-258 }, {  37,-258 }, {  38,-258 }, {  39,-258 },
 {  40,-258 }, {  41,-258 }, {  42,-258 }, {  43,-258 }, {  44,-258 },
 {  45, 258 }, {  46,-258 }, {  47,-258 }, {  48,-258 }, {  49,-258 },
 {  50,-258 }, {  51,-258 }, {  52,-258 }, {  53,-258 }, {  54,-258 },
 {  55,-258 }, {  56,-258 }, {  57,-258 }, {  58,-258 }, {  59,-258 },
 {  60,-258 }, {  61,-258 }, {  62,-258 }, {  63,-258 }, {  64,-258 },

 {  65,-258 }, {  66,-258 }, {  67,-258 }, {  68,-258 }, {  69,-258 },
 {  70,-258 }, {  71,-258 }, {  72,-258 }, {  73,-258 }, {  74,-258 },
 {  75,-258 }, {  76,-258 }, {  77,-258 }, {  78,-258 }, {  79,-258 },
 {  80,-258 }, {  81,-258 }, {  82,-258 }, {  83,-258 }, {  84,-258 },
 {  85,-258 }, {  86,-258 }, {  87,-258 }, {  88,-258 }, {  89,-258 },
 {  90,-258 }, {  91,-258 }, {  92,-258 }, {  93,-258 }, {  94,-258 },
 {  95,-258 }, {  96,-258 }, {  97,-258 }, {  98,-258 }, {  99,-258 },
 { 100,-258 }, { 101,-258 }, { 102,-258 }, { 103,-258 }, { 104,-258 },
 { 105,-258 }, { 106,-258 }, { 107,-258 }, { 108,-258 }, { 109,-258 },
 { 110,-258 }, { 111,-258 }, { 112,-258 }, { 113,-258 }, { 114,-258 },

 { 115,-258 }, { 116,-258 }, { 117,-258 }, { 118,-258 }, { 119,-258 },
 { 120,-258 }, { 121,-258 }, { 122,-258 }, { 123,-258 }, { 124,-258 },
 { 125,-258 }, { 126,-258 }, { 127,-258 }, { 128,-258 }, { 129,-258 },
 { 130,-258 }, { 131,-258 }, { 132,-258 }, { 133,-258 }, { 134,-258 },
 { 135,-258 }, { 136,-258 }, { 137,-258 }, { 138,-258 }, { 139,-258 },
 { 140,-258 }, { 141,-258 }, { 142,-258 }, { 143,-258 }, { 144,-258 },
 { 145,-258 }, { 146,-258 }, { 147,-258 }, { 148,-258 }, { 149,-258 },
 { 150,-258 }, { 151,-258 }, { 152,-258 }, { 153,-258 }, { 154,-258 },
 { 155,-258 }, { 156,-258 }, { 157,-258 }, { 158,-258 }, { 159,-258 },
 { 160,-258 }, { 161,-258 }, { 162,-258 }, { 163,-258 }, { 164,-258 },

 { 165,-258 }, { 166,-258 }, { 167,-258 }, { 168,-258 }, { 169,-258 },
 { 170,-258 }, { 171,-258 }, { 172,-258 }, { 173,-258 }, { 174,-258 },
 { 175,-258 }, { 176,-258 }, { 177,-258 }, { 178,-258 }, { 179,-258 },
 { 180,-258 }, { 181,-258 }, { 182,-258 }, { 183,-258 }, { 184,-258 },
 { 185,-258 }, { 186,-258 }, { 187,-258 }, { 188,-258 }, { 189,-258 },
 { 190,-258 }, { 191,-258 }, { 192,-258 }, { 193,-258 }, { 194,-258 },
 { 195,-258 }, { 196,-258 }, { 197,-258 }, { 198,-258 }, { 199,-258 },
 { 200,-258 }, { 201,-258 }, { 202,-258 }, { 203,-258 }, { 204,-258 },
 { 205,-258 }, { 206,-258 }, { 207,-258 }, { 208,-258 }, { 209,-258 },
 { 210,-258 }, { 211,-258 }, { 212,-258 }, { 213,-258 }, { 214,-258 },

 { 215,-258 }, { 216,-258 }, { 217,-258 }, { 218,-258 }, { 219,-258 },
 { 220,-258 }, { 221,-258 }, { 222,-258 }, { 223,-258 }, { 224,-258 },
 { 225,-258 }, { 226,-258 }, { 227,-258 }, { 228,-258 }, { 229,-258 },
 { 230,-258 }, { 231,-258 }, { 232,-258 }, { 233,-258 }, { 234,-258 },
 { 235,-258 }, { 236,-258 }, { 237,-258 }, { 238,-258 }, { 239,-258 },
 { 240,-258 }, { 241,-258 }, { 242,-258 }, { 243,-258 }, { 244,-258 },
 { 245,-258 }, { 246,-258 }, { 247,-258 }, { 248,-258 }, { 249,-258 },
 { 250,-258 }, { 251,-258 }, { 252,-258 }, { 253,-258 }, { 254,-258 },
 { 255,-258 }, { 256,-258 }, {   0,   9 }, {   0,16157 }, {   1,-516 },
 {   2,-516 }, {   3,-516 }, {   4,-516 }, {   5,-516 }, {   6,-516 },

 {   7,-516 }, {   8,-516 }, {   9,-258 }, {  10,-6857 }, {  11,-516 },
 {  12,-258 }, {  13,-6857 }, {  14,-516 }, {  15,-516 }, {  16,-516 },
 {  17,-516 }, {  18,-516 }, {  19,-516 }, {  20,-516 }, {  21,-516 },
 {  22,-516 }, {  23,-516 }, {  24,-516 }, {  25,-516 }, {  26,-516 },
 {  27,-516 }, {  28,-516 }, {  29,-516 }, {  30,-516 }, {  31,-516 },
 {  32,-258 }, {  33,-516 }, {  34,-516 }, {  35,-516 }, {  36,-516 },
 {  37,-516 }, {  38,-516 }, {  39,-516 }, {  40,-516 }, {  41,-516 },
 {  42,-516 }, {  43,-516 }, {  44,-516 }, {  45,4429 }, {  46,-516 },
 {  47,-516 }, {  48,-516 }, {  49,-516 }, {  50,-516 }, {  51,-516 },
 {  52,-516 }, {  53,-516 }, {  54,-516 }, {  55,-516 }, {  56,-516 },

 {  57,-516 }, {  58,-516 }, {  59,-516 }, {  60,-516 }, {  61,-516 },
 {  62,-516 }, {  63,-516 }, {  64,-516 }, {  65,-516 }, {  66,-516 },
 {  67,-516 }, {  68,-516 }, {  69,-516 }, {  70,-516 }, {  71,-516 },
 {  72,-516 }, {  73,-516 }, {  74,-516 }, {  75,-516 }, {  76,-516 },
 {  77,-516 }, {  78,-516 }, {  79,-516 }, {  80,-516 }, {  81,-516 },
 {  82,-516 }, {  83,-516 }, {  84,-516 }, {  85,-516 }, {  86,-516 },
 {  87,-516 }, {  88,-516 }, {  89,-516 }, {  90,-516 }, {  91,-516 },
 {  92,-516 }, {  93,-516 }, {  94,-516 }, {  95,-516 }, {  96,-516 },
 {  97,-516 }, {  98,-516 }, {  99,-516 }, { 100,-516 }, { 101,-516 },
 { 102,-516 }, { 103,-516 }, { 104,-516 }, { 105,-516 }, { 106,-516 },

 { 107,-516 }, { 108,-516 }, { 109,-516 }, { 110,-516 }, { 111,-516 },
 { 112,-516 }, { 113,-516 }, { 114,-516 }, { 115,-516 }, { 116,-516 },
 { 117,-516 }, { 118,-516 }, { 119,-516 }, { 120,-516 }, { 121,-516 },
 { 122,-516 }, { 123,-516 }, { 124,-516 }, { 125,-516 }, { 126,-516 },
 { 127,-516 }, { 128,-516 }, { 129,-516 }, { 130,-516 }, { 131,-516 },
 { 132,-516 }, { 133,-516 }, { 134,-516 }, { 135,-516 }, { 136,-516 },
 { 137,-516 }, { 138,-516 }, { 139,-516 }, { 140,-516 }, { 141,-516 },
 { 142,-516 }, { 143,-516 }, { 144,-516 }, { 145,-516 }, { 146,-516 },
 { 147,-516 }, { 148,-516 }, { 149,-516 }, { 150,-516 }, { 151,-516 },
 { 152,-516 }, { 153,-516 }, { 154,-516 }, { 155,-516 }, { 156,-516 },

 { 157,-516 }, { 158,-516 }, { 159,-516 }, { 160,-516 }, { 161,-516 },
 { 162,-516 }, { 163,-516 }, { 164,-516 }, { 165,-516 }, { 166,-516 },
 { 167,-516 }, { 168,-516 }, { 169,-516 }, { 170,-516 }, { 171,-516 },
 { 172,-516 }, { 173,-516 }, { 174,-516 }, { 175,-516 }, { 176,-516 },
 { 177,-516 }, { 178,-516 }, { 179,-516 }, { 180,-516 }, { 181,-516 },
 { 182,-516 }, { 183,-516 }, { 184,-516 }, { 185,-516 }, { 186,-516 },
 { 187,-516 }, { 188,-516 }, { 189,-516 }, { 190,-516 }, { 191,-516 },
 { 192,-516 }, { 193,-516 }, { 194,-516 }, { 195,-516 }, { 196,-516 },
 { 197,-516 }, { 198,-516 }, { 199,-516 }, { 200,-516 }, { 201,-516 },
 { 202,-516 }, { 203,-516 }, { 204,-516 }, { 205,-516 }, { 206,-516 },

 { 207,-516 }, { 208,-516 }, { 209,-516 }, { 210,-516 }, { 211,-516 },
 { 212,-516 }, { 213,-516 }, { 214,-516 }, { 215,-516 }, { 216,-516 },
 { 217,-516 }, { 218,-516 }, { 219,-516 }, { 220,-516 }, { 221,-516 },
 { 222,-516 }, { 223,-516 }, { 224,-516 }, { 225,-516 }, { 226,-516 },
 { 227,-516 }, { 228,-516 }, { 229,-516 }, { 230,-516 }, { 231,-516 },
 { 232,-516 }, { 233,-516 }, { 234,-516 }, { 235,-516 }, { 236,-516 },
 { 237,-516 }, { 238,-516 }, { 239,-516 }, { 240,-516 }, { 241,-516 },
 { 242,-516 }, { 243,-516 }, { 244,-516 }, { 245,-516 }, { 246,-516 },
 { 247,-516 }, { 248,-516 }, { 249,-516 }, { 250,-516 }, { 251,-516 },
 { 252,-516 }, { 253,-516 }, { 254,-516 }, { 255,-516 }, { 256,-516 },

 {   0,  16 }, {   0,15899 }, {   1,4429 }, {   2,4429 }, {   3,4429 },
 {   4,4429 }, {   5,4429 }, {   6,4429 }, {   7,4429 }, {   8,4429 },
 {   9,4687 }, {  10,4945 }, {  11,4429 }, {  12,4687 }, {  13,4945 },
 {  14,4429 }, {  15,4429 }, {  16,4429 }, {  17,4429 }, {  18,4429 },
 {  19,4429 }, {  20,4429 }, {  21,4429 }, {  22,4429 }, {  23,4429 },
 {  24,4429 }, {  25,4429 }, {  26,4429 }, {  27,4429 }, {  28,4429 },
 {  29,4429 }, {  30,4429 }, {  31,4429 }, {  32,4687 }, {  33,4429 },
 {  34,4429 }, {  35,4429 }, {  36,4429 }, {  37,4429 }, {  38,4429 },
 {  39,4429 }, {  40,4429 }, {  41,4429 }, {  42,4429 }, {  43,4429 },
 {  44,4429 }, {  45,4992 }, {  46,4429 }, {  47,4429 }, {  48,4429 },

 {  49,4429 }, {  50,4429 }, {  51,4429 }, {  52,4429 }, {  53,4429 },
 {  54,4429 }, {  55,4429 }, {  56,4429 }, {  57,4429 }, {  58,4429 },
 {  59,4429 }, {  60,4429 }, {  61,4429 }, {  62,4429 }, {  63,4429 },
 {  64,4429 }, {  65,4429 }, {  66,4429 }, {  67,4429 }, {  68,4429 },
 {  69,4429 }, {  70,4429 }, {  71,4429 }, {  72,4429 }, {  73,4429 },
 {  74,4429 }, {  75,4429 }, {  76,4429 }, {  77,4429 }, {  78,4429 },
 {  79,4429 }, {  80,4429 }, {  81,4429 }, {  82,4429 }, {  83,4429 },
 {  84,4429 }, {  85,4429 }, {  86,4429 }, {  87,4429 }, {  88,4429 },
 {  89,4429 }, {  90,4429 }, {  91,4429 }, {  92,4429 }, {  93,4429 },
 {  94,4429 }, {  95,4429 }, {  96,4429 }, {  97,4429 }, {  98,4429 },

 {  99,4429 }, { 100,4429 }, { 101,4429 }, { 102,4429 }, { 103,4429 },
 { 104,4429 }, { 105,4429 }, { 106,4429 }, { 107,4429 }, { 108,4429 },
 { 109,4429 }, { 110,4429 }, { 111,4429 }, { 112,4429 }, { 113,4429 },
 { 114,4429 }, { 115,4429 }, { 116,4429 }, { 117,4429 }, { 118,4429 },
 { 119,4429 }, { 120,4429 }, { 121,4429 }, { 122,4429 }, { 123,4429 },
 { 124,4429 }, { 125,4429 }, { 126,4429 }, { 127,4429 }, { 128,4429 },
 { 129,4429 }, { 130,4429 }, { 131,4429 }, { 132,4429 }, { 133,4429 },
 { 134,4429 }, { 135,4429 }, { 136,4429 }, { 137,4429 }, { 138,4429 },
 { 139,4429 }, { 140,4429 }, { 141,4429 }, { 142,4429 }, { 143,4429 },
 { 144,4429 }, { 145,4429 }, { 146,4429 }, { 147,4429 }, { 148,4429 },

 { 149,4429 }, { 150,4429 }, { 151,4429 }, { 152,4429 }, { 153,4429 },
 { 154,4429 }, { 155,4429 }, { 156,4429 }, { 157,4429 }, { 158,4429 },
 { 159,4429 }, { 160,4429 }, { 161,4429 }, { 162,4429 }, { 163,4429 },
 { 164,4429 }, { 165,4429 }, { 166,4429 }, { 167,4429 }, { 168,4429 },
 { 169,4429 }, { 170,4429 }, { 171,4429 }, { 172,4429 }, { 173,4429 },
 { 174,4429 }, { 175,4429 }, { 176,4429 }, { 177,4429 }, { 178,4429 },
 { 179,4429 }, { 180,4429 }, { 181,4429 }, { 182,4429 }, { 183,4429 },
 { 184,4429 }, { 185,4429 }, { 186,4429 }, { 187,4429 }, { 188,4429 },
 { 189,4429 }, { 190,4429 }, { 191,4429 }, { 192,4429 }, { 193,4429 },
 { 194,4429 }, { 195,4429 }, { 196,4429 }, { 197,4429 }, { 198,4429 },

 { 199,4429 }, { 200,4429 }, { 201,4429 }, { 202,4429 }, { 203,4429 },
 { 204,4429 }, { 205,4429 }, { 206,4429 }, { 207,4429 }, { 208,4429 },
 { 209,4429 }, { 210,4429 }, { 211,4429 }, { 212,4429 }, { 213,4429 },
 { 214,4429 }, { 215,4429 }, { 216,4429 }, { 217,4429 }, { 218,4429 },
 { 219,4429 }, { 220,4429 }, { 221,4429 }, { 222,4429 }, { 223,4429 },
 { 224,4429 }, { 225,4429 }, { 226,4429 }, { 227,4429 }, { 228,4429 },
 { 229,4429 }, { 230,4429 }, { 231,4429 }, { 232,4429 }, { 233,4429 },
 { 234,4429 }, { 235,4429 }, { 236,4429 }, { 237,4429 }, { 238,4429 },
 { 239,4429 }, { 240,4429 }, { 241,4429 }, { 242,4429 }, { 243,4429 },
 { 244,4429 }, { 245,4429 }, { 246,4429 }, { 247,4429 }, { 248,4429 },

 { 249,4429 }, { 250,4429 }, { 251,4429 }, { 252,4429 }, { 253,4429 },
 { 254,4429 }, { 255,4429 }, { 256,4429 }, {   0,  16 }, {   0,15641 },
 {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 },
 {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9, 258 }, {  10,-6419 },
 {  11,   0 }, {  12, 258 }, {  13,-6419 }, {  14,   0 }, {  15,   0 },
 {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 },
 {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 },
 {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 },
 {  31,   0 }, {  32, 258 }, {  33,   0 }, {  34,   0 }, {  35,   0 },
 {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 },

 {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45, 516 },
 {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 },
 {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 },
 {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 },
 {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 },
 {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 },
 {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 },
 {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 },
 {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 },
 {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 },

 {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 },
 {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 },
 { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 },
 { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 },
 { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 },
 { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 },
 { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 },
 { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 },
 { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 },
 { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 },

 { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 },
 { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 },
 { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 },
 { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 },
 { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 },
 { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 },
 { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 },
 { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 },
 { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 },
 { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 },

 { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 },
 { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 },
 { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 },
 { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 },
 { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 },
 { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 },
 { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 },
 { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 },
 { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 },
 { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 },

 { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 },
 { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 },
 { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 },
 { 256,   0 }, {   0,  16 }, {   0,15383 }, {   1,-258 }, {   2,-258 },
 {   3,-258 }, {   4,-258 }, {   5,-258 }, {   6,-258 }, {   7,-258 },
 {   8,-258 }, {   9,   0 }, {  10,-6677 }, {  11,-258 }, {  12,   0 },
 {  13,-6677 }, {  14,-258 }, {  15,-258 }, {  16,-258 }, {  17,-258 },
 {  18,-258 }, {  19,-258 }, {  20,-258 }, {  21,-258 }, {  22,-258 },
 {  23,-258 }, {  24,-258 }, {  25,-258 }, {  26,-258 }, {  27,-258 },
 {  28,-258 }, {  29,-258 }, {  30,-258 }, {  31,-258 }, {  32,   0 },

 {  33,-258 }, {  34,-258 }, {  35,-258 }, {  36,-258 }, {  37,-258 },
 {  38,-258 }, {  39,-258 }, {  40,-258 }, {  41,-258 }, {  42,-258 },
 {  43,-258 }, {  44,-258 }, {  45, 258 }, {  46,-258 }, {  47,-258 },
 {  48,-258 }, {  49,-258 }, {  50,-258 }, {  51,-258 }, {  52,-258 },
 {  53,-258 }, {  54,-258 }, {  55,-258 }, {  56,-258 }, {  57,-258 },
 {  58,-258 }, {  59,-258 }, {  60,-258 }, {  61,-258 }, {  62,-258 },
 {  63,-258 }, {  64,-258 }, {  65,-258 }, {  66,-258 }, {  67,-258 },
 {  68,-258 }, {  69,-258 }, {  70,-258 }, {  71,-258 }, {  72,-258 },
 {  73,-258 }, {  74,-258 }, {  75,-258 }, {  76,-258 }, {  77,-258 },
 {  78,-258 }, {  79,-258 }, {  80,-258 }, {  81,-258 }, {  82,-258 },

 {  83,-258 }, {  84,-258 }, {  85,-258 }, {  86,-258 }, {  87,-258 },
 {  88,-258 }, {  89,-258 }, {  90,-258 }, {  91,-258 }, {  92,-258 },
 {  93,-258 }, {  94,-258 }, {  95,-258 }, {  96,-258 }, {  97,-258 },
 {  98,-258 }, {  99,-258 }, { 100,-258 }, { 101,-258 }, { 102,-258 },
 { 103,-258 }, { 104,-258 }, { 105,-258 }, { 106,-258 }, { 107,-258 },
 { 108,-258 }, { 109,-258 }, { 110,-258 }, { 111,-258 }, { 112,-258 },
 { 113,-258 }, { 114,-258 }, { 115,-258 }, { 116,-258 }, { 117,-258 },
 { 118,-258 }, { 119,-258 }, { 120,-258 }, { 121,-258 }, { 122,-258 },
 { 123,-258 }, { 124,-258 }, { 125,-258 }, { 126,-258 }, { 127,-258 },
 { 128,-258 }, { 129,-258 }, { 130,-258 }, { 131,-258 }, { 132,-258 },

 { 133,-258 }, { 134,-258 }, { 135,-258 }, { 136,-258 }, { 137,-258 },
 { 138,-258 }, { 139,-258 }, { 140,-258 }, { 141,-258 }, { 142,-258 },
 { 143,-258 }, { 144,-258 }, { 145,-258 }, { 146,-258 }, { 147,-258 },
 { 148,-258 }, { 149,-258 }, { 150,-258 }, { 151,-258 }, { 152,-258 },
 { 153,-258 }, { 154,-258 }, { 155,-258 }, { 156,-258 }, { 157,-258 },
 { 158,-258 }, { 159,-258 }, { 160,-258 }, { 161,-258 }, { 162,-258 },
 { 163,-258 }, { 164,-258 }, { 165,-258 }, { 166,-258 }, { 167,-258 },
 { 168,-258 }, { 169,-258 }, { 170,-258 }, { 171,-258 }, { 172,-258 },
 { 173,-258 }, { 174,-258 }, { 175,-258 }, { 176,-258 }, { 177,-258 },
 { 178,-258 }, { 179,-258 }, { 180,-258 }, { 181,-258 }, { 182,-258 },

 { 183,-258 }, { 184,-258 }, { 185,-258 }, { 186,-258 }, { 187,-258 },
 { 188,-258 }, { 189,-258 }, { 190,-258 }, { 191,-258 }, { 192,-258 },
 { 193,-258 }, { 194,-258 }, { 195,-258 }, { 196,-258 }, { 197,-258 },
 { 198,-258 }, { 199,-258 }, { 200,-258 }, { 201,-258 }, { 202,-258 },
 { 203,-258 }, { 204,-258 }, { 205,-258 }, { 206,-258 }, { 207,-258 },
 { 208,-258 }, { 209,-258 }, { 210,-258 }, { 211,-258 }, { 212,-258 },
 { 213,-258 }, { 214,-258 }, { 215,-258 }, { 216,-258 }, { 217,-258 },
 { 218,-258 }, { 219,-258 }, { 220,-258 }, { 221,-258 }, { 222,-258 },
 { 223,-258 }, { 224,-258 }, { 225,-258 }, { 226,-258 }, { 227,-258 },
 { 228,-258 }, { 229,-258 }, { 230,-258 }, { 231,-258 }, { 232,-258 },

 { 233,-258 }, { 234,-258 }, { 235,-258 }, { 236,-258 }, { 237,-258 },
 { 238,-258 }, { 239,-258 }, { 240,-258 }, { 241,-258 }, { 242,-258 },
 { 243,-258 }, { 244,-258 }, { 245,-258 }, { 246,-258 }, { 247,-258 },
 { 248,-258 }, { 249,-258 }, { 250,-258 }, { 251,-258 }, { 252,-258 },
 { 253,-258 }, { 254,-258 }, { 255,-258 }, { 256,-258 }, {   0,  16 },
 {   0,15125 }, {   1,-516 }, {   2,-516 }, {   3,-516 }, {   4,-516 },
 {   5,-516 }, {   6,-516 }, {   7,-516 }, {   8,-516 }, {   9,-258 },
 {  10,-6935 }, {  11,-516 }, {  12,-258 }, {  13,-6935 }, {  14,-516 },
 {  15,-516 }, {  16,-516 }, {  17,-516 }, {  18,-516 }, {  19,-516 },
 {  20,-516 }, {  21,-516 }, {  22,-516 }, {  23,-516 }, {  24,-516 },

 {  25,-516 }, {  26,-516 }, {  27,-516 }, {  28,-516 }, {  29,-516 },
 {  30,-516 }, {  31,-516 }, {  32,-258 }, {  33,-516 }, {  34,-516 },
 {  35,-516 }, {  36,-516 }, {  37,-516 }, {  38,-516 }, {  39,-516 },
 {  40,-516 }, {  41,-516 }, {  42,-516 }, {  43,-516 }, {  44,-516 },
 {  45,4476 }, {  46,-516 }, {  47,-516 }, {  48,-516 }, {  49,-516 },
 {  50,-516 }, {  51,-516 }, {  52,-516 }, {  53,-516 }, {  54,-516 },
 {  55,-516 }, {  56,-516 }, {  57,-516 }, {  58,-516 }, {  59,-516 },
 {  60,-516 }, {  61,-516 }, {  62,-516 }, {  63,-516 }, {  64,-516 },
 {  65,-516 }, {  66,-516 }, {  67,-516 }, {  68,-516 }, {  69,-516 },
 {  70,-516 }, {  71,-516 }, {  72,-516 }, {  73,-516 }, {  74,-516 },

 {  75,-516 }, {  76,-516 }, {  77,-516 }, {  78,-516 }, {  79,-516 },
 {  80,-516 }, {  81,-516 }, {  82,-516 }, {  83,-516 }, {  84,-516 },
 {  85,-516 }, {  86,-516 }, {  87,-516 }, {  88,-516 }, {  89,-516 },
 {  90,-516 }, {  91,-516 }, {  92,-516 }, {  93,-516 }, {  94,-516 },
 {  95,-516 }, {  96,-516 }, {  97,-516 }, {  98,-516 }, {  99,-516 },
 { 100,-516 }, { 101,-516 }, { 102,-516 }, { 103,-516 }, { 104,-516 },
 { 105,-516 }, { 106,-516 }, { 107,-516 }, { 108,-516 }, { 109,-516 },
 { 110,-516 }, { 111,-516 }, { 112,-516 }, { 113,-516 }, { 114,-516 },
 { 115,-516 }, { 116,-516 }, { 117,-516 }, { 118,-516 }, { 119,-516 },
 { 120,-516 }, { 121,-516 }, { 122,-516 }, { 123,-516 }, { 124,-516 },

 { 125,-516 }, { 126,-516 }, { 127,-516 }, { 128,-516 }, { 129,-516 },
 { 130,-516 }, { 131,-516 }, { 132,-516 }, { 133,-516 }, { 134,-516 },
 { 135,-516 }, { 136,-516 }, { 137,-516 }, { 138,-516 }, { 139,-516 },
 { 140,-516 }, { 141,-516 }, { 142,-516 }, { 143,-516 }, { 144,-516 },
 { 145,-516 }, { 146,-516 }, { 147,-516 }, { 148,-516 }, { 149,-516 },
 { 150,-516 }, { 151,-516 }, { 152,-516 }, { 153,-516 }, { 154,-516 },
 { 155,-516 }, { 156,-516 }, { 157,-516 }, { 158,-516 }, { 159,-516 },
 { 160,-516 }, { 161,-516 }, { 162,-516 }, { 163,-516 }, { 164,-516 },
 { 165,-516 }, { 166,-516 }, { 167,-516 }, { 168,-516 }, { 169,-516 },
 { 170,-516 }, { 171,-516 }, { 172,-516 }, { 173,-516 }, { 174,-516 },

 { 175,-516 }, { 176,-516 }, { 177,-516 }, { 178,-516 }, { 179,-516 },
 { 180,-516 }, { 181,-516 }, { 182,-516 }, { 183,-516 }, { 184,-516 },
 { 185,-516 }, { 186,-516 }, { 187,-516 }, { 188,-516 }, { 189,-516 },
 { 190,-516 }, { 191,-516 }, { 192,-516 }, { 193,-516 }, { 194,-516 },
 { 195,-516 }, { 196,-516 }, { 197,-516 }, { 198,-516 }, { 199,-516 },
 { 200,-516 }, { 201,-516 }, { 202,-516 }, { 203,-516 }, { 204,-516 },
 { 205,-516 }, { 206,-516 }, { 207,-516 }, { 208,-516 }, { 209,-516 },
 { 210,-516 }, { 211,-516 }, { 212,-516 }, { 213,-516 }, { 214,-516 },
 { 215,-516 }, { 216,-516 }, { 217,-516 }, { 218,-516 }, { 219,-516 },
 { 220,-516 }, { 221,-516 }, { 222,-516 }, { 223,-516 }, { 224,-516 },

 { 225,-516 }, { 226,-516 }, { 227,-516 }, { 228,-516 }, { 229,-516 },
 { 230,-516 }, { 231,-516 }, { 232,-516 }, { 233,-516 }, { 234,-516 },
 { 235,-516 }, { 236,-516 }, { 237,-516 }, { 238,-516 }, { 239,-516 },
 { 240,-516 }, { 241,-516 }, { 242,-516 }, { 243,-516 }, { 244,-516 },
 { 245,-516 }, { 246,-516 }, { 247,-516 }, { 248,-516 }, { 249,-516 },
 { 250,-516 }, { 251,-516 }, { 252,-516 }, { 253,-516 }, { 254,-516 },
 { 255,-516 }, { 256,-516 }, {   0,  22 }, {   0,14867 }, {   1,4476 },
 {   2,4476 }, {   3,4476 }, {   4,4476 }, {   5,4476 }, {   6,4476 },
 {   7,4476 }, {   8,4476 }, {   9,4734 }, {  10,4992 }, {  11,4476 },
 {  12,4734 }, {  13,4992 }, {  14,4476 }, {  15,4476 }, {  16,4476 },

 {  17,4476 }, {  18,4476 }, {  19,4476 }, {  20,4476 }, {  21,4476 },
 {  22,4476 }, {  23,4476 }, {  24,4476 }, {  25,4476 }, {  26,4476 },
 {  27,4476 }, {  28,4476 }, {  29,4476 }, {  30,4476 }, {  31,4476 },
 {  32,4734 }, {  33,4476 }, {  34,4476 }, {  35,4476 }, {  36,4476 },
 {  37,4476 }, {  38,4476 }, {  39,4476 }, {  40,4476 }, {  41,4476 },
 {  42,4476 }, {  43,4476 }, {  44,4476 }, {  45,5039 }, {  46,4476 },
 {  47,4476 }, {  48,4476 }, {  49,4476 }, {  50,4476 }, {  51,4476 },
 {  52,4476 }, {  53,4476 }, {  54,4476 }, {  55,4476 }, {  56,4476 },
 {  57,4476 }, {  58,4476 }, {  59,4476 }, {  60,4476 }, {  61,4476 },
 {  62,4476 }, {  63,4476 }, {  64,4476 }, {  65,4476 }, {  66,4476 },

 {  67,4476 }, {  68,4476 }, {  69,4476 }, {  70,4476 }, {  71,4476 },
 {  72,4476 }, {  73,4476 }, {  74,4476 }, {  75,4476 }, {  76,4476 },
 {  77,4476 }, {  78,4476 }, {  79,4476 }, {  80,4476 }, {  81,4476 },
 {  82,4476 }, {  83,4476 }, {  84,4476 }, {  85,4476 }, {  86,4476 },
 {  87,4476 }, {  88,4476 }, {  89,4476 }, {  90,4476 }, {  91,4476 },
 {  92,4476 }, {  93,4476 }, {  94,4476 }, {  95,4476 }, {  96,4476 },
 {  97,4476 }, {  98,4476 }, {  99,4476 }, { 100,4476 }, { 101,4476 },
 { 102,4476 }, { 103,4476 }, { 104,4476 }, { 105,4476 }, { 106,4476 },
 { 107,4476 }, { 108,4476 }, { 109,4476 }, { 110,4476 }, { 111,4476 },
 { 112,4476 }, { 113,4476 }, { 114,4476 }, { 115,4476 }, { 116,4476 },

 { 117,4476 }, { 118,4476 }, { 119,4476 }, { 120,4476 }, { 121,4476 },
 { 122,4476 }, { 123,4476 }, { 124,4476 }, { 125,4476 }, { 126,4476 },
 { 127,4476 }, { 128,4476 }, { 129,4476 }, { 130,4476 }, { 131,4476 },
 { 132,4476 }, { 133,4476 }, { 134,4476 }, { 135,4476 }, { 136,4476 },
 { 137,4476 }, { 138,4476 }, { 139,4476 }, { 140,4476 }, { 141,4476 },
 { 142,4476 }, { 143,4476 }, { 144,4476 }, { 145,4476 }, { 146,4476 },
 { 147,4476 }, { 148,4476 }, { 149,4476 }, { 150,4476 }, { 151,4476 },
 { 152,4476 }, { 153,4476 }, { 154,4476 }, { 155,4476 }, { 156,4476 },
 { 157,4476 }, { 158,4476 }, { 159,4476 }, { 160,4476 }, { 161,4476 },
 { 162,4476 }, { 163,4476 }, { 164,4476 }, { 165,4476 }, { 166,4476 },

 { 167,4476 }, { 168,4476 }, { 169,4476 }, { 170,4476 }, { 171,4476 },
 { 172,4476 }, { 173,4476 }, { 174,4476 }, { 175,4476 }, { 176,4476 },
 { 177,4476 }, { 178,4476 }, { 179,4476 }, { 180,4476 }, { 181,4476 },
 { 182,4476 }, { 183,4476 }, { 184,4476 }, { 185,4476 }, { 186,4476 },
 { 187,4476 }, { 188,4476 }, { 189,4476 }, { 190,4476 }, { 191,4476 },
 { 192,4476 }, { 193,4476 }, { 194,4476 }, { 195,4476 }, { 196,4476 },
 { 197,4476 }, { 198,4476 }, { 199,4476 }, { 200,4476 }, { 201,4476 },
 { 202,4476 }, { 203,4476 }, { 204,4476 }, { 205,4476 }, { 206,4476 },
 { 207,4476 }, { 208,4476 }, { 209,4476 }, { 210,4476 }, { 211,4476 },
 { 212,4476 }, { 213,4476 }, { 214,4476 }, { 215,4476 }, { 216,4476 },

 { 217,4476 }, { 218,4476 }, { 219,4476 }, { 220,4476 }, { 221,4476 },
 { 222,4476 }, { 223,4476 }, { 224,4476 }, { 225,4476 }, { 226,4476 },
 { 227,4476 }, { 228,4476 }, { 229,4476 }, { 230,4476 }, { 231,4476 },
 { 232,4476 }, { 233,4476 }, { 234,4476 }, { 235,4476 }, { 236,4476 },
 { 237,4476 }, { 238,4476 }, { 239,4476 }, { 240,4476 }, { 241,4476 },
 { 242,4476 }, { 243,4476 }, { 244,4476 }, { 245,4476 }, { 246,4476 },
 { 247,4476 }, { 248,4476 }, { 249,4476 }, { 250,4476 }, { 251,4476 },
 { 252,4476 }, { 253,4476 }, { 254,4476 }, { 255,4476 }, { 256,4476 },
 {   0,  22 }, {   0,14609 }, {   1,   0 }, {   2,   0 }, {   3,   0 },
 {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 },

 {   9, 258 }, {  10,-7141 }, {  11,   0 }, {  12, 258 }, {  13,-7141 },
 {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 },
 {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 },
 {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 },
 {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32, 258 }, {  33,   0 },
 {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 },
 {  39,   0 }, {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 },
 {  44,   0 }, {  45, 516 }, {  46,   0 }, {  47,   0 }, {  48,   0 },
 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },
 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 },

 {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 },
 {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 },
 {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 },
 {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 },
 {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 },
 {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 },
 {  89,   0 }, {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 },
 {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 },
 {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 },
 { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 },

 { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 },
 { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 },
 { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 },
 { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 },
 { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 },
 { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 },
 { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 },
 { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 },
 { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 },
 { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 },

 { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 },
 { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 },
 { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 },
 { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 },
 { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 },
 { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 },
 { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 },
 { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 },
 { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 },
 { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 },

 { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 },
 { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 },
 { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 },
 { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 },
 { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 },
 { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 },
 { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 },
 { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 },
 { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 },
 { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,  22 }, {   0,14351 },

 {   1,-258 }, {   2,-258 }, {   3,-258 }, {   4,-258 }, {   5,-258 },
 {   6,-258 }, {   7,-258 }, {   8,-258 }, {   9,   0 }, {  10,-7399 },
 {  11,-258 }, {  12,   0 }, {  13,-7399 }, {  14,-258 }, {  15,-258 },
 {  16,-258 }, {  17,-258 }, {  18,-258 }, {  19,-258 }, {  20,-258 },
 {  21,-258 }, {  22,-258 }, {  23,-258 }, {  24,-258 }, {  25,-258 },
 {  26,-258 }, {  27,-258 }, {  28,-258 }, {  29,-258 }, {  30,-258 },
 {  31,-258 }, {  32,   0 }, {  33,-258 }, {  34,-258 }, {  35,-258 },
 {  36,-258 }, {  37,-258 }, {  38,-258 }, {  39,-258 }, {  40,-258 },
 {  41,-258 }, {  42,-258 }, {  43,-258 }, {  44,-258 }, {  45, 258 },
 {  46,-258 }, {  47,-258 }, {  48,-258 }, {  49,-258 }, {  50,-258 },

 {  51,-258 }, {  52,-258 }, {  53,-258 }, {  54,-258 }, {  55,-258 },
 {  56,-258 }, {  57,-258 }, {  58,-258 }, {  59,-258 }, {  60,-258 },
 {  61,-258 }, {  62,-258 }, {  63,-258 }, {  64,-258 }, {  65,-258 },
 {  66,-258 }, {  67,-258 }, {  68,-258 }, {  69,-258 }, {  70,-258 },
 {  71,-258 }, {  72,-258 }, {  73,-258 }, {  74,-258 }, {  75,-258 },
 {  76,-258 }, {  77,-258 }, {  78,-258 }, {  79,-258 }, {  80,-258 },
 {  81,-258 }, {  82,-258 }, {  83,-258 }, {  84,-258 }, {  85,-258 },
 {  86,-258 }, {  87,-258 }, {  88,-258 }, {  89,-258 }, {  90,-258 },
 {  91,-258 }, {  92,-258 }, {  93,-258 }, {  94,-258 }, {  95,-258 },
 {  96,-258 }, {  97,-258 }, {  98,-258 }, {  99,-258 }, { 100,-258 },

 { 101,-258 }, { 102,-258 }, { 103,-258 }, { 104,-258 }, { 105,-258 },
 { 106,-258 }, { 107,-258 }, { 108,-258 }, { 109,-258 }, { 110,-258 },
 { 111,-258 }, { 112,-258 }, { 113,-258 }, { 114,-258 }, { 115,-258 },
 { 116,-258 }, { 117,-258 }, { 118,-258 }, { 119,-258 }, { 120,-258 },
 { 121,-258 }, { 122,-258 }, { 123,-258 }, { 124,-258 }, { 125,-258 },
 { 126,-258 }, { 127,-258 }, { 128,-258 }, { 129,-258 }, { 130,-258 },
 { 131,-258 }, { 132,-258 }, { 133,-258 }, { 134,-258 }, { 135,-258 },
 { 136,-258 }, { 137,-258 }, { 138,-258 }, { 139,-258 }, { 140,-258 },
 { 141,-258 }, { 142,-258 }, { 143,-258 }, { 144,-258 }, { 145,-258 },
 { 146,-258 }, { 147,-258 }, { 148,-258 }, { 149,-258 }, { 150,-258 },

 { 151,-258 }, { 152,-258 }, { 153,-258 }, { 154,-258 }, { 155,-258 },
 { 156,-258 }, { 157,-258 }, { 158,-258 }, { 159,-258 }, { 160,-258 },
 { 161,-258 }, { 162,-258 }, { 163,-258 }, { 164,-258 }, { 165,-258 },
 { 166,-258 }, { 167,-258 }, { 168,-258 }, { 169,-258 }, { 170,-258 },
 { 171,-258 }, { 172,-258 }, { 173,-258 }, { 174,-258 }, { 175,-258 },
 { 176,-258 }, { 177,-258 }, { 178,-258 }, { 179,-258 }, { 180,-258 },
 { 181,-258 }, { 182,-258 }, { 183,-258 }, { 184,-258 }, { 185,-258 },
 { 186,-258 }, { 187,-258 }, { 188,-258 }, { 189,-258 }, { 190,-258 },
 { 191,-258 }, { 192,-258 }, { 193,-258 }, { 194,-258 }, { 195,-258 },
 { 196,-258 }, { 197,-258 }, { 198,-258 }, { 199,-258 }, { 200,-258 },

 { 201,-258 }, { 202,-258 }, { 203,-258 }, { 204,-258 }, { 205,-258 },
 { 206,-258 }, { 207,-258 }, { 208,-258 }, { 209,-258 }, { 210,-258 },
 { 211,-258 }, { 212,-258 }, { 213,-258 }, { 214,-258 }, { 215,-258 },
 { 216,-258 }, { 217,-258 }, { 218,-258 }, { 219,-258 }, { 220,-258 },
 { 221,-258 }, { 222,-258 }, { 223,-258 }, { 224,-258 }, { 225,-258 },
 { 226,-258 }, { 227,-258 }, { 228,-258 }, { 229,-258 }, { 230,-258 },
 { 231,-258 }, { 232,-258 }, { 233,-258 }, { 234,-258 }, { 235,-258 },
 { 236,-258 }, { 237,-258 }, { 238,-258 }, { 239,-258 }, { 240,-258 },
 { 241,-258 }, { 242,-258 }, { 243,-258 }, { 244,-258 }, { 245,-258 },
 { 246,-258 }, { 247,-258 }, { 248,-258 }, { 249,-258 }, { 250,-258 },

 { 251,-258 }, { 252,-258 }, { 253,-258 }, { 254,-258 }, { 255,-258 },
 { 256,-258 }, {   0,  22 }, {   0,14093 }, {   1,-516 }, {   2,-516 },
 {   3,-516 }, {   4,-516 }, {   5,-516 }, {   6,-516 }, {   7,-516 },
 {   8,-516 }, {   9,-258 }, {  10,-7657 }, {  11,-516 }, {  12,-258 },
 {  13,-7657 }, {  14,-516 }, {  15,-516 }, {  16,-516 }, {  17,-516 },
 {  18,-516 }, {  19,-516 }, {  20,-516 }, {  21,-516 }, {  22,-516 },
 {  23,-516 }, {  24,-516 }, {  25,-516 }, {  26,-516 }, {  27,-516 },
 {  28,-516 }, {  29,-516 }, {  30,-516 }, {  31,-516 }, {  32,-258 },
 {  33,-516 }, {  34,-516 }, {  35,-516 }, {  36,-516 }, {  37,-516 },
 {  38,-516 }, {  39,-516 }, {  40,-516 }, {  41,-516 }, {  42,-516 },

 {  43,-516 }, {  44,-516 }, {  45,4523 }, {  46,-516 }, {  47,-516 },
 {  48,-516 }, {  49,-516 }, {  50,-516 }, {  51,-516 }, {  52,-516 },
 {  53,-516 }, {  54,-516 }, {  55,-516 }, {  56,-516 }, {  57,-516 },
 {  58,-516 }, {  59,-516 }, {  60,-516 }, {  61,-516 }, {  62,-516 },
 {  63,-516 }, {  64,-516 }, {  65,-516 }, {  66,-516 }, {  67,-516 },
 {  68,-516 }, {  69,-516 }, {  70,-516 }, {  71,-516 }, {  72,-516 },
 {  73,-516 }, {  74,-516 }, {  75,-516 }, {  76,-516 }, {  77,-516 },
 {  78,-516 }, {  79,-516 }, {  80,-516 }, {  81,-516 }, {  82,-516 },
 {  83,-516 }, {  84,-516 }, {  85,-516 }, {  86,-516 }, {  87,-516 },
 {  88,-516 }, {  89,-516 }, {  90,-516 }, {  91,-516 }, {  92,-516 },

 {  93,-516 }, {  94,-516 }, {  95,-516 }, {  96,-516 }, {  97,-516 },
 {  98,-516 }, {  99,-516 }, { 100,-516 }, { 101,-516 }, { 102,-516 },
 { 103,-516 }, { 104,-516 }, { 105,-516 }, { 106,-516 }, { 107,-516 },
 { 108,-516 }, { 109,-516 }, { 110,-516 }, { 111,-516 }, { 112,-516 },
 { 113,-516 }, { 114,-516 }, { 115,-516 }, { 116,-516 }, { 117,-516 },
 { 118,-516 }, { 119,-516 }, { 120,-516 }, { 121,-516 }, { 122,-516 },
 { 123,-516 }, { 124,-516 }, { 125,-516 }, { 126,-516 }, { 127,-516 },
 { 128,-516 }, { 129,-516 }, { 130,-516 }, { 131,-516 }, { 132,-516 },
 { 133,-516 }, { 134,-516 }, { 135,-516 }, { 136,-516 }, { 137,-516 },
 { 138,-516 }, { 139,-516 }, { 140,-516 }, { 141,-516 }, { 142,-516 },

 { 143,-516 }, { 144,-516 }, { 145,-516 }, { 146,-516 }, { 147,-516 },
 { 148,-516 }, { 149,-516 }, { 150,-516 }, { 151,-516 }, { 152,-516 },
 { 153,-516 }, { 154,-516 }, { 155,-516 }, { 156,-516 }, { 157,-516 },
 { 158,-516 }, { 159,-516 }, { 160,-516 }, { 161,-516 }, { 162,-516 },
 { 163,-516 }, { 164,-516 }, { 165,-516 }, { 166,-516 }, { 167,-516 },
 { 168,-516 }, { 169,-516 }, { 170,-516 }, { 171,-516 }, { 172,-516 },
 { 173,-516 }, { 174,-516 }, { 175,-516 }, { 176,-516 }, { 177,-516 },
 { 178,-516 }, { 179,-516 }, { 180,-516 }, { 181,-516 }, { 182,-516 },
 { 183,-516 }, { 184,-516 }, { 185,-516 }, { 186,-516 }, { 187,-516 },
 { 188,-516 }, { 189,-516 }, { 190,-516 }, { 191,-516 }, { 192,-516 },

 { 193,-516 }, { 194,-516 }, { 195,-516 }, { 196,-516 }, { 197,-516 },
 { 198,-516 }, { 199,-516 }, { 200,-516 }, { 201,-516 }, { 202,-516 },
 { 203,-516 }, { 204,-516 }, { 205,-516 }, { 206,-516 }, { 207,-516 },
 { 208,-516 }, { 209,-516 }, { 210,-516 }, { 211,-516 }, { 212,-516 },
 { 213,-516 }, { 214,-516 }, { 215,-516 }, { 216,-516 }, { 217,-516 },
 { 218,-516 }, { 219,-516 }, { 220,-516 }, { 221,-516 }, { 222,-516 },
 { 223,-516 }, { 224,-516 }, { 225,-516 }, { 226,-516 }, { 227,-516 },
 { 228,-516 }, { 229,-516 }, { 230,-516 }, { 231,-516 }, { 232,-516 },
 { 233,-516 }, { 234,-516 }, { 235,-516 }, { 236,-516 }, { 237,-516 },
 { 238,-516 }, { 239,-516 }, { 240,-516 }, { 241,-516 }, { 242,-516 },

 { 243,-516 }, { 244,-516 }, { 245,-516 }, { 246,-516 }, { 247,-516 },
 { 248,-516 }, { 249,-516 }, { 250,-516 }, { 251,-516 }, { 252,-516 },
 { 253,-516 }, { 254,-516 }, { 255,-516 }, { 256,-516 }, {   0,  37 },
 {   0,13835 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,  37 }, {   0,13812 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48,4523 }, {  49,4523 },
 {  50,4523 }, {  51,4523 }, {  52,4523 }, {  53,4523 }, {  54,4523 },
 {  55,4523 }, {  56,4523 }, {  57,4523 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  65,4523 }, {  66,4523 }, {  67,4523 }, {  68,4523 }, {  69,4523 },
 {  70,4523 }, {  48,4523 }, {  49,4523 }, {  50,4523 }, {  51,4523 },
 {  52,4523 }, {  53,4523 }, {  54,4523 }, {  55,4523 }, {  56,4523 },
 {  57,4523 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,4523 }, {  66,4523 },
 {  67,4523 }, {  68,4523 }, {  69,4523 }, {  70,4523 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  97,4523 }, {  98,4523 }, {  99,4523 },
 { 100,4523 }, { 101,4523 }, { 102,4523 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  97,4523 }, {  98,4523 }, {  99,4523 }, { 100,4523 }, { 101,4523 },
 { 102,4523 }, {   0,  24 }, {   0,13708 }, {   1,4523 }, {   2,4523 },
 {   3,4523 }, {   4,4523 }, {   5,4523 }, {   6,4523 }, {   7,4523 },

 {   8,4523 }, {   9,4781 }, {  10,5039 }, {  11,4523 }, {  12,4781 },
 {  13,5039 }, {  14,4523 }, {  15,4523 }, {  16,4523 }, {  17,4523 },
 {  18,4523 }, {  19,4523 }, {  20,4523 }, {  21,4523 }, {  22,4523 },
 {  23,4523 }, {  24,4523 }, {  25,4523 }, {  26,4523 }, {  27,4523 },
 {  28,4523 }, {  29,4523 }, {  30,4523 }, {  31,4523 }, {  32,4781 },
 {  33,4523 }, {  34,4523 }, {  35,4523 }, {  36,4523 }, {  37,4523 },
 {  38,4523 }, {  39,4523 }, {  40,4523 }, {  41,4523 }, {  42,4523 },
 {  43,4523 }, {  44,4523 }, {  45,5086 }, {  46,4523 }, {  47,4523 },
 {  48,4523 }, {  49,4523 }, {  50,4523 }, {  51,4523 }, {  52,4523 },
 {  53,4523 }, {  54,4523 }, {  55,4523 }, {  56,4523 }, {  57,4523 },

 {  58,4523 }, {  59,4523 }, {  60,4523 }, {  61,4523 }, {  62,4523 },
 {  63,4523 }, {  64,4523 }, {  65,4523 }, {  66,4523 }, {  67,4523 },
 {  68,4523 }, {  69,4523 }, {  70,4523 }, {  71,4523 }, {  72,4523 },
 {  73,4523 }, {  74,4523 }, {  75,4523 }, {  76,4523 }, {  77,4523 },
 {  78,4523 }, {  79,4523 }, {  80,4523 }, {  81,4523 }, {  82,4523 },
 {  83,4523 }, {  84,4523 }, {  85,4523 }, {  86,4523 }, {  87,4523 },
 {  88,4523 }, {  89,4523 }, {  90,4523 }, {  91,4523 }, {  92,4523 },
 {  93,4523 }, {  94,4523 }, {  95,4523 }, {  96,4523 }, {  97,4523 },
 {  98,4523 }, {  99,4523 }, { 100,4523 }, { 101,4523 }, { 102,4523 },
 { 103,4523 }, { 104,4523 }, { 105,4523 }, { 106,4523 }, { 107,4523 },

 { 108,4523 }, { 109,4523 }, { 110,4523 }, { 111,4523 }, { 112,4523 },
 { 113,4523 }, { 114,4523 }, { 115,4523 }, { 116,4523 }, { 117,4523 },
 { 118,4523 }, { 119,4523 }, { 120,4523 }, { 121,4523 }, { 122,4523 },
 { 123,4523 }, { 124,4523 }, { 125,4523 }, { 126,4523 }, { 127,4523 },
 { 128,4523 }, { 129,4523 }, { 130,4523 }, { 131,4523 }, { 132,4523 },
 { 133,4523 }, { 134,4523 }, { 135,4523 }, { 136,4523 }, { 137,4523 },
 { 138,4523 }, { 139,4523 }, { 140,4523 }, { 141,4523 }, { 142,4523 },
 { 143,4523 }, { 144,4523 }, { 145,4523 }, { 146,4523 }, { 147,4523 },
 { 148,4523 }, { 149,4523 }, { 150,4523 }, { 151,4523 }, { 152,4523 },
 { 153,4523 }, { 154,4523 }, { 155,4523 }, { 156,4523 }, { 157,4523 },

 { 158,4523 }, { 159,4523 }, { 160,4523 }, { 161,4523 }, { 162,4523 },
 { 163,4523 }, { 164,4523 }, { 165,4523 }, { 166,4523 }, { 167,4523 },
 { 168,4523 }, { 169,4523 }, { 170,4523 }, { 171,4523 }, { 172,4523 },
 { 173,4523 }, { 174,4523 }, { 175,4523 }, { 176,4523 }, { 177,4523 },
 { 178,4523 }, { 179,4523 }, { 180,4523 }, { 181,4523 }, { 182,4523 },
 { 183,4523 }, { 184,4523 }, { 185,4523 }, { 186,4523 }, { 187,4523 },
 { 188,4523 }, { 189,4523 }, { 190,4523 }, { 191,4523 }, { 192,4523 },
 { 193,4523 }, { 194,4523 }, { 195,4523 }, { 196,4523 }, { 197,4523 },
 { 198,4523 }, { 199,4523 }, { 200,4523 }, { 201,4523 }, { 202,4523 },
 { 203,4523 }, { 204,4523 }, { 205,4523 }, { 206,4523 }, { 207,4523 },

 { 208,4523 }, { 209,4523 }, { 210,4523 }, { 211,4523 }, { 212,4523 },
 { 213,4523 }, { 214,4523 }, { 215,4523 }, { 216,4523 }, { 217,4523 },
 { 218,4523 }, { 219,4523 }, { 220,4523 }, { 221,4523 }, { 222,4523 },
 { 223,4523 }, { 224,4523 }, { 225,4523 }, { 226,4523 }, { 227,4523 },
 { 228,4523 }, { 229,4523 }, { 230,4523 }, { 231,4523 }, { 232,4523 },
 { 233,4523 }, { 234,4523 }, { 235,4523 }, { 236,4523 }, { 237,4523 },
 { 238,4523 }, { 239,4523 }, { 240,4523 }, { 241,4523 }, { 242,4523 },
 { 243,4523 }, { 244,4523 }, { 245,4523 }, { 246,4523 }, { 247,4523 },
 { 248,4523 }, { 249,4523 }, { 250,4523 }, { 251,4523 }, { 252,4523 },
 { 253,4523 }, { 254,4523 }, { 255,4523 }, { 256,4523 }, {   0,  24 },

 {   0,13450 }, {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 },
 {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9, 258 },
 {  10,-7084 }, {  11,   0 }, {  12, 258 }, {  13,-7084 }, {  14,   0 },
 {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 },
 {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 },
 {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 },
 {  30,   0 }, {  31,   0 }, {  32, 258 }, {  33,   0 }, {  34,   0 },
 {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 },
 {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 },
 {  45, 516 }, {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 },

 {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 },
 {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 },
 {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 },
 {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 },
 {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 },
 {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 },
 {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 },
 {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 },
 {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 },
 {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 },

 { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 },
 { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 },
 { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 },
 { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 },
 { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 },
 { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 },
 { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 },
 { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 },
 { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 },
 { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 },

 { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 },
 { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 },
 { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 },
 { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 },
 { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 },
 { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 },
 { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 },
 { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 },
 { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 },
 { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 },

 { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 },
 { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 },
 { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 },
 { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 },
 { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 },
 { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 },
 { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 },
 { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 },
 { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 },
 { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 },

 { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 },
 { 255,   0 }, { 256,   0 }, {   0,  24 }, {   0,13192 }, {   1,-258 },
 {   2,-258 }, {   3,-258 }, {   4,-258 }, {   5,-258 }, {   6,-258 },
 {   7,-258 }, {   8,-258 }, {   9,   0 }, {  10,-7342 }, {  11,-258 },
 {  12,   0 }, {  13,-7342 }, {  14,-258 }, {  15,-258 }, {  16,-258 },
 {  17,-258 }, {  18,-258 }, {  19,-258 }, {  20,-258 }, {  21,-258 },
 {  22,-258 }, {  23,-258 }, {  24,-258 }, {  25,-258 }, {  26,-258 },
 {  27,-258 }, {  28,-258 }, {  29,-258 }, {  30,-258 }, {  31,-258 },
 {  32,   0 }, {  33,-258 }, {  34,-258 }, {  35,-258 }, {  36,-258 },
 {  37,-258 }, {  38,-258 }, {  39,-258 }, {  40,-258 }, {  41,-258 },

 {  42,-258 }, {  43,-258 }, {  44,-258 }, {  45, 258 }, {  46,-258 },
 {  47,-258 }, {  48,-258 }, {  49,-258 }, {  50,-258 }, {  51,-258 },
 {  52,-258 }, {  53,-258 }, {  54,-258 }, {  55,-258 }, {  56,-258 },
 {  57,-258 }, {  58,-258 }, {  59,-258 }, {  60,-258 }, {  61,-258 },
 {  62,-258 }, {  63,-258 }, {  64,-258 }, {  65,-258 }, {  66,-258 },
 {  67,-258 }, {  68,-258 }, {  69,-258 }, {  70,-258 }, {  71,-258 },
 {  72,-258 }, {  73,-258 }, {  74,-258 }, {  75,-258 }, {  76,-258 },
 {  77,-258 }, {  78,-258 }, {  79,-258 }, {  80,-258 }, {  81,-258 },
 {  82,-258 }, {  83,-258 }, {  84,-258 }, {  85,-258 }, {  86,-258 },
 {  87,-258 }, {  88,-258 }, {  89,-258 }, {  90,-258 }, {  91,-258 },

 {  92,-258 }, {  93,-258 }, {  94,-258 }, {  95,-258 }, {  96,-258 },
 {  97,-258 }, {  98,-258 }, {  99,-258 }, { 100,-258 }, { 101,-258 },
 { 102,-258 }, { 103,-258 }, { 104,-258 }, { 105,-258 }, { 106,-258 },
 { 107,-258 }, { 108,-258 }, { 109,-258 }, { 110,-258 }, { 111,-258 },
 { 112,-258 }, { 113,-258 }, { 114,-258 }, { 115,-258 }, { 116,-258 },
 { 117,-258 }, { 118,-258 }, { 119,-258 }, { 120,-258 }, { 121,-258 },
 { 122,-258 }, { 123,-258 }, { 124,-258 }, { 125,-258 }, { 126,-258 },
 { 127,-258 }, { 128,-258 }, { 129,-258 }, { 130,-258 }, { 131,-258 },
 { 132,-258 }, { 133,-258 }, { 134,-258 }, { 135,-258 }, { 136,-258 },
 { 137,-258 }, { 138,-258 }, { 139,-258 }, { 140,-258 }, { 141,-258 },

 { 142,-258 }, { 143,-258 }, { 144,-258 }, { 145,-258 }, { 146,-258 },
 { 147,-258 }, { 148,-258 }, { 149,-258 }, { 150,-258 }, { 151,-258 },
 { 152,-258 }, { 153,-258 }, { 154,-258 }, { 155,-258 }, { 156,-258 },
 { 157,-258 }, { 158,-258 }, { 159,-258 }, { 160,-258 }, { 161,-258 },
 { 162,-258 }, { 163,-258 }, { 164,-258 }, { 165,-258 }, { 166,-258 },
 { 167,-258 }, { 168,-258 }, { 169,-258 }, { 170,-258 }, { 171,-258 },
 { 172,-258 }, { 173,-258 }, { 174,-258 }, { 175,-258 }, { 176,-258 },
 { 177,-258 }, { 178,-258 }, { 179,-258 }, { 180,-258 }, { 181,-258 },
 { 182,-258 }, { 183,-258 }, { 184,-258 }, { 185,-258 }, { 186,-258 },
 { 187,-258 }, { 188,-258 }, { 189,-258 }, { 190,-258 }, { 191,-258 },

 { 192,-258 }, { 193,-258 }, { 194,-258 }, { 195,-258 }, { 196,-258 },
 { 197,-258 }, { 198,-258 }, { 199,-258 }, { 200,-258 }, { 201,-258 },
 { 202,-258 }, { 203,-258 }, { 204,-258 }, { 205,-258 }, { 206,-258 },
 { 207,-258 }, { 208,-258 }, { 209,-258 }, { 210,-258 }, { 211,-258 },
 { 212,-258 }, { 213,-258 }, { 214,-258 }, { 215,-258 }, { 216,-258 },
 { 217,-258 }, { 218,-258 }, { 219,-258 }, { 220,-258 }, { 221,-258 },
 { 222,-258 }, { 223,-258 }, { 224,-258 }, { 225,-258 }, { 226,-258 },
 { 227,-258 }, { 228,-258 }, { 229,-258 }, { 230,-258 }, { 231,-258 },
 { 232,-258 }, { 233,-258 }, { 234,-258 }, { 235,-258 }, { 236,-258 },
 { 237,-258 }, { 238,-258 }, { 239,-258 }, { 240,-258 }, { 241,-258 },

 { 242,-258 }, { 243,-258 }, { 244,-258 }, { 245,-258 }, { 246,-258 },
 { 247,-258 }, { 248,-258 }, { 249,-258 }, { 250,-258 }, { 251,-258 },
 { 252,-258 }, { 253,-258 }, { 254,-258 }, { 255,-258 }, { 256,-258 },
 {   0,  24 }, {   0,12934 }, {   1,-516 }, {   2,-516 }, {   3,-516 },
 {   4,-516 }, {   5,-516 }, {   6,-516 }, {   7,-516 }, {   8,-516 },
 {   9,-258 }, {  10,-7600 }, {  11,-516 }, {  12,-258 }, {  13,-7600 },
 {  14,-516 }, {  15,-516 }, {  16,-516 }, {  17,-516 }, {  18,-516 },
 {  19,-516 }, {  20,-516 }, {  21,-516 }, {  22,-516 }, {  23,-516 },
 {  24,-516 }, {  25,-516 }, {  26,-516 }, {  27,-516 }, {  28,-516 },
 {  29,-516 }, {  30,-516 }, {  31,-516 }, {  32,-258 }, {  33,-516 },

 {  34,-516 }, {  35,-516 }, {  36,-516 }, {  37,-516 }, {  38,-516 },
 {  39,-516 }, {  40,-516 }, {  41,-516 }, {  42,-516 }, {  43,-516 },
 {  44,-516 }, {  45,4570 }, {  46,-516 }, {  47,-516 }, {  48,-516 },
 {  49,-516 }, {  50,-516 }, {  51,-516 }, {  52,-516 }, {  53,-516 },
 {  54,-516 }, {  55,-516 }, {  56,-516 }, {  57,-516 }, {  58,-516 },
 {  59,-516 }, {  60,-516 }, {  61,-516 }, {  62,-516 }, {  63,-516 },
 {  64,-516 }, {  65,-516 }, {  66,-516 }, {  67,-516 }, {  68,-516 },
 {  69,-516 }, {  70,-516 }, {  71,-516 }, {  72,-516 }, {  73,-516 },
 {  74,-516 }, {  75,-516 }, {  76,-516 }, {  77,-516 }, {  78,-516 },
 {  79,-516 }, {  80,-516 }, {  81,-516 }, {  82,-516 }, {  83,-516 },

 {  84,-516 }, {  85,-516 }, {  86,-516 }, {  87,-516 }, {  88,-516 },
 {  89,-516 }, {  90,-516 }, {  91,-516 }, {  92,-516 }, {  93,-516 },
 {  94,-516 }, {  95,-516 }, {  96,-516 }, {  97,-516 }, {  98,-516 },
 {  99,-516 }, { 100,-516 }, { 101,-516 }, { 102,-516 }, { 103,-516 },
 { 104,-516 }, { 105,-516 }, { 106,-516 }, { 107,-516 }, { 108,-516 },
 { 109,-516 }, { 110,-516 }, { 111,-516 }, { 112,-516 }, { 113,-516 },
 { 114,-516 }, { 115,-516 }, { 116,-516 }, { 117,-516 }, { 118,-516 },
 { 119,-516 }, { 120,-516 }, { 121,-516 }, { 122,-516 }, { 123,-516 },
 { 124,-516 }, { 125,-516 }, { 126,-516 }, { 127,-516 }, { 128,-516 },
 { 129,-516 }, { 130,-516 }, { 131,-516 }, { 132,-516 }, { 133,-516 },

 { 134,-516 }, { 135,-516 }, { 136,-516 }, { 137,-516 }, { 138,-516 },
 { 139,-516 }, { 140,-516 }, { 141,-516 }, { 142,-516 }, { 143,-516 },
 { 144,-516 }, { 145,-516 }, { 146,-516 }, { 147,-516 }, { 148,-516 },
 { 149,-516 }, { 150,-516 }, { 151,-516 }, { 152,-516 }, { 153,-516 },
 { 154,-516 }, { 155,-516 }, { 156,-516 }, { 157,-516 }, { 158,-516 },
 { 159,-516 }, { 160,-516 }, { 161,-516 }, { 162,-516 }, { 163,-516 },
 { 164,-516 }, { 165,-516 }, { 166,-516 }, { 167,-516 }, { 168,-516 },
 { 169,-516 }, { 170,-516 }, { 171,-516 }, { 172,-516 }, { 173,-516 },
 { 174,-516 }, { 175,-516 }, { 176,-516 }, { 177,-516 }, { 178,-516 },
 { 179,-516 }, { 180,-516 }, { 181,-516 }, { 182,-516 }, { 183,-516 },

 { 184,-516 }, { 185,-516 }, { 186,-516 }, { 187,-516 }, { 188,-516 },
 { 189,-516 }, { 190,-516 }, { 191,-516 }, { 192,-516 }, { 193,-516 },
 { 194,-516 }, { 195,-516 }, { 196,-516 }, { 197,-516 }, { 198,-516 },
 { 199,-516 }, { 200,-516 }, { 201,-516 }, { 202,-516 }, { 203,-516 },
 { 204,-516 }, { 205,-516 }, { 206,-516 }, { 207,-516 }, { 208,-516 },
 { 209,-516 }, { 210,-516 }, { 211,-516 }, { 212,-516 }, { 213,-516 },
 { 214,-516 }, { 215,-516 }, { 216,-516 }, { 217,-516 }, { 218,-516 },
 { 219,-516 }, { 220,-516 }, { 221,-516 }, { 222,-516 }, { 223,-516 },
 { 224,-516 }, { 225,-516 }, { 226,-516 }, { 227,-516 }, { 228,-516 },
 { 229,-516 }, { 230,-516 }, { 231,-516 }, { 232,-516 }, { 233,-516 },

 { 234,-516 }, { 235,-516 }, { 236,-516 }, { 237,-516 }, { 238,-516 },
 { 239,-516 }, { 240,-516 }, { 241,-516 }, { 242,-516 }, { 243,-516 },
 { 244,-516 }, { 245,-516 }, { 246,-516 }, { 247,-516 }, { 248,-516 },
 { 249,-516 }, { 250,-516 }, { 251,-516 }, { 252,-516 }, { 253,-516 },
 { 254,-516 }, { 255,-516 }, { 256,-516 }, {   0,  37 }, {   0,12676 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  37 }, {   0,12653 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  48,4570 }, {  49,4570 }, {  50,4570 },
 {  51,4570 }, {  52,4570 }, {  53,4570 }, {  54,4570 }, {  55,4570 },
 {  56,4570 }, {  57,4570 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,4570 },
 {  66,4570 }, {  67,4570 }, {  68,4570 }, {  69,4570 }, {  70,4570 },
 {  48,4570 }, {  49,4570 }, {  50,4570 }, {  51,4570 }, {  52,4570 },

 {  53,4570 }, {  54,4570 }, {  55,4570 }, {  56,4570 }, {  57,4570 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65,4570 }, {  66,4570 }, {  67,4570 },
 {  68,4570 }, {  69,4570 }, {  70,4570 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  97,4570 }, {  98,4570 }, {  99,4570 }, { 100,4570 },
 { 101,4570 }, { 102,4570 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,4570 },
 {  98,4570 }, {  99,4570 }, { 100,4570 }, { 101,4570 }, { 102,4570 },

 {   0,   9 }, {   0,12549 }, {   1,   0 }, {   2,   0 }, {   3,   0 },
 {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 },
 {   9, 258 }, {  10, 516 }, {  11,   0 }, {  12, 258 }, {  13, 516 },
 {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 },
 {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 },
 {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 },
 {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32, 258 }, {  33,   0 },
 {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 },
 {  39,   0 }, {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 },
 {  44,   0 }, {  45, 563 }, {  46,   0 }, {  47,   0 }, {  48,   0 },

 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },
 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 },
 {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 },
 {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 },
 {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 },
 {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 },
 {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 },
 {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 },
 {  89,   0 }, {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 },
 {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 },

 {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 },
 { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 },
 { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 },
 { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 },
 { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 },
 { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 },
 { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 },
 { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 },
 { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 },
 { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 },

 { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 },
 { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 },
 { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 },
 { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 },
 { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 },
 { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 },
 { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 },
 { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 },
 { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 },
 { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 },

 { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 },
 { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 },
 { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 },
 { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 },
 { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 },
 { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 },
 { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 },
 { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 },
 { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 },
 { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 },

 { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 },
 { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,   9 }, {   0,12291 },
 {   1,-258 }, {   2,-258 }, {   3,-258 }, {   4,-258 }, {   5,-258 },
 {   6,-258 }, {   7,-258 }, {   8,-258 }, {   9,   0 }, {  10, 258 },
 {  11,-258 }, {  12,   0 }, {  13, 258 }, {  14,-258 }, {  15,-258 },
 {  16,-258 }, {  17,-258 }, {  18,-258 }, {  19,-258 }, {  20,-258 },
 {  21,-258 }, {  22,-258 }, {  23,-258 }, {  24,-258 }, {  25,-258 },
 {  26,-258 }, {  27,-258 }, {  28,-258 }, {  29,-258 }, {  30,-258 },
 {  31,-258 }, {  32,   0 }, {  33,-258 }, {  34,-258 }, {  35,-258 },
 {  36,-258 }, {  37,-258 }, {  38,-258 }, {  39,-258 }, {  40,-258 },

 {  41,-258 }, {  42,-258 }, {  43,-258 }, {  44,-258 }, {  45, 305 },
 {  46,-258 }, {  47,-258 }, {  48,-258 }, {  49,-258 }, {  50,-258 },
 {  51,-258 }, {  52,-258 }, {  53,-258 }, {  54,-258 }, {  55,-258 },
 {  56,-258 }, {  57,-258 }, {  58,-258 }, {  59,-258 }, {  60,-258 },
 {  61,-258 }, {  62,-258 }, {  63,-258 }, {  64,-258 }, {  65,-258 },
 {  66,-258 }, {  67,-258 }, {  68,-258 }, {  69,-258 }, {  70,-258 },
 {  71,-258 }, {  72,-258 }, {  73,-258 }, {  74,-258 }, {  75,-258 },
 {  76,-258 }, {  77,-258 }, {  78,-258 }, {  79,-258 }, {  80,-258 },
 {  81,-258 }, {  82,-258 }, {  83,-258 }, {  84,-258 }, {  85,-258 },
 {  86,-258 }, {  87,-258 }, {  88,-258 }, {  89,-258 }, {  90,-258 },

 {  91,-258 }, {  92,-258 }, {  93,-258 }, {  94,-258 }, {  95,-258 },
 {  96,-258 }, {  97,-258 }, {  98,-258 }, {  99,-258 }, { 100,-258 },
 { 101,-258 }, { 102,-258 }, { 103,-258 }, { 104,-258 }, { 105,-258 },
 { 106,-258 }, { 107,-258 }, { 108,-258 }, { 109,-258 }, { 110,-258 },
 { 111,-258 }, { 112,-258 }, { 113,-258 }, { 114,-258 }, { 115,-258 },
 { 116,-258 }, { 117,-258 }, { 118,-258 }, { 119,-258 }, { 120,-258 },
 { 121,-258 }, { 122,-258 }, { 123,-258 }, { 124,-258 }, { 125,-258 },
 { 126,-258 }, { 127,-258 }, { 128,-258 }, { 129,-258 }, { 130,-258 },
 { 131,-258 }, { 132,-258 }, { 133,-258 }, { 134,-258 }, { 135,-258 },
 { 136,-258 }, { 137,-258 }, { 138,-258 }, { 139,-258 }, { 140,-258 },

 { 141,-258 }, { 142,-258 }, { 143,-258 }, { 144,-258 }, { 145,-258 },
 { 146,-258 }, { 147,-258 }, { 148,-258 }, { 149,-258 }, { 150,-258 },
 { 151,-258 }, { 152,-258 }, { 153,-258 }, { 154,-258 }, { 155,-258 },
 { 156,-258 }, { 157,-258 }, { 158,-258 }, { 159,-258 }, { 160,-258 },
 { 161,-258 }, { 162,-258 }, { 163,-258 }, { 164,-258 }, { 165,-258 },
 { 166,-258 }, { 167,-258 }, { 168,-258 }, { 169,-258 }, { 170,-258 },
 { 171,-258 }, { 172,-258 }, { 173,-258 }, { 174,-258 }, { 175,-258 },
 { 176,-258 }, { 177,-258 }, { 178,-258 }, { 179,-258 }, { 180,-258 },
 { 181,-258 }, { 182,-258 }, { 183,-258 }, { 184,-258 }, { 185,-258 },
 { 186,-258 }, { 187,-258 }, { 188,-258 }, { 189,-258 }, { 190,-258 },

 { 191,-258 }, { 192,-258 }, { 193,-258 }, { 194,-258 }, { 195,-258 },
 { 196,-258 }, { 197,-258 }, { 198,-258 }, { 199,-258 }, { 200,-258 },
 { 201,-258 }, { 202,-258 }, { 203,-258 }, { 204,-258 }, { 205,-258 },
 { 206,-258 }, { 207,-258 }, { 208,-258 }, { 209,-258 }, { 210,-258 },
 { 211,-258 }, { 212,-258 }, { 213,-258 }, { 214,-258 }, { 215,-258 },
 { 216,-258 }, { 217,-258 }, { 218,-258 }, { 219,-258 }, { 220,-258 },
 { 221,-258 }, { 222,-258 }, { 223,-258 }, { 224,-258 }, { 225,-258 },
 { 226,-258 }, { 227,-258 }, { 228,-258 }, { 229,-258 }, { 230,-258 },
 { 231,-258 }, { 232,-258 }, { 233,-258 }, { 234,-258 }, { 235,-258 },
 { 236,-258 }, { 237,-258 }, { 238,-258 }, { 239,-258 }, { 240,-258 },

 { 241,-258 }, { 242,-258 }, { 243,-258 }, { 244,-258 }, { 245,-258 },
 { 246,-258 }, { 247,-258 }, { 248,-258 }, { 249,-258 }, { 250,-258 },
 { 251,-258 }, { 252,-258 }, { 253,-258 }, { 254,-258 }, { 255,-258 },
 { 256,-258 }, {   0,   9 }, {   0,12033 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   9,-7240 }, {  10,-7240 }, {   0,   0 }, {  12,-7240 },
 {  13,-7240 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,-7240 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  39,-17444 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  45,-17442 }, {   0,   9 }, {   0,11986 },
 {   1,-563 }, {   2,-563 }, {   3,-563 }, {   4,-563 }, {   5,-563 },
 {   6,-563 }, {   7,-563 }, {   8,-563 }, {   9,-305 }, {  10, -47 },
 {  11,-563 }, {  12,-305 }, {  13, -47 }, {  14,-563 }, {  15,-563 },
 {  16,-563 }, {  17,-563 }, {  18,-563 }, {  19,-563 }, {  20,-563 },
 {  21,-563 }, {  22,-563 }, {  23,-563 }, {  24,-563 }, {  25,-563 },
 {  26,-563 }, {  27,-563 }, {  28,-563 }, {  29,-563 }, {  30,-563 },
 {  31,-563 }, {  32,-305 }, {  33,-563 }, {  34,-563 }, {  35,-563 },

 {  36,-563 }, {  37,-563 }, {  38,-563 }, {  39,-563 }, {  40,-563 },
 {  41,-563 }, {  42,-563 }, {  43,-563 }, {  44,-563 }, {  45,4007 },
 {  46,-563 }, {  47,-563 }, {  48,-563 }, {  49,-563 }, {  50,-563 },
 {  51,-563 }, {  52,-563 }, {  53,-563 }, {  54,-563 }, {  55,-563 },
 {  56,-563 }, {  57,-563 }, {  58,-563 }, {  59,-563 }, {  60,-563 },
 {  61,-563 }, {  62,-563 }, {  63,-563 }, {  64,-563 }, {  65,-563 },
 {  66,-563 }, {  67,-563 }, {  68,-563 }, {  69,-563 }, {  70,-563 },
 {  71,-563 }, {  72,-563 }, {  73,-563 }, {  74,-563 }, {  75,-563 },
 {  76,-563 }, {  77,-563 }, {  78,-563 }, {  79,-563 }, {  80,-563 },
 {  81,-563 }, {  82,-563 }, {  83,-563 }, {  84,-563 }, {  85,-563 },

 {  86,-563 }, {  87,-563 }, {  88,-563 }, {  89,-563 }, {  90,-563 },
 {  91,-563 }, {  92,-563 }, {  93,-563 }, {  94,-563 }, {  95,-563 },
 {  96,-563 }, {  97,-563 }, {  98,-563 }, {  99,-563 }, { 100,-563 },
 { 101,-563 }, { 102,-563 }, { 103,-563 }, { 104,-563 }, { 105,-563 },
 { 106,-563 }, { 107,-563 }, { 108,-563 }, { 109,-563 }, { 110,-563 },
 { 111,-563 }, { 112,-563 }, { 113,-563 }, { 114,-563 }, { 115,-563 },
 { 116,-563 }, { 117,-563 }, { 118,-563 }, { 119,-563 }, { 120,-563 },
 { 121,-563 }, { 122,-563 }, { 123,-563 }, { 124,-563 }, { 125,-563 },
 { 126,-563 }, { 127,-563 }, { 128,-563 }, { 129,-563 }, { 130,-563 },
 { 131,-563 }, { 132,-563 }, { 133,-563 }, { 134,-563 }, { 135,-563 },

 { 136,-563 }, { 137,-563 }, { 138,-563 }, { 139,-563 }, { 140,-563 },
 { 141,-563 }, { 142,-563 }, { 143,-563 }, { 144,-563 }, { 145,-563 },
 { 146,-563 }, { 147,-563 }, { 148,-563 }, { 149,-563 }, { 150,-563 },
 { 151,-563 }, { 152,-563 }, { 153,-563 }, { 154,-563 }, { 155,-563 },
 { 156,-563 }, { 157,-563 }, { 158,-563 }, { 159,-563 }, { 160,-563 },
 { 161,-563 }, { 162,-563 }, { 163,-563 }, { 164,-563 }, { 165,-563 },
 { 166,-563 }, { 167,-563 }, { 168,-563 }, { 169,-563 }, { 170,-563 },
 { 171,-563 }, { 172,-563 }, { 173,-563 }, { 174,-563 }, { 175,-563 },
 { 176,-563 }, { 177,-563 }, { 178,-563 }, { 179,-563 }, { 180,-563 },
 { 181,-563 }, { 182,-563 }, { 183,-563 }, { 184,-563 }, { 185,-563 },

 { 186,-563 }, { 187,-563 }, { 188,-563 }, { 189,-563 }, { 190,-563 },
 { 191,-563 }, { 192,-563 }, { 193,-563 }, { 194,-563 }, { 195,-563 },
 { 196,-563 }, { 197,-563 }, { 198,-563 }, { 199,-563 }, { 200,-563 },
 { 201,-563 }, { 202,-563 }, { 203,-563 }, { 204,-563 }, { 205,-563 },
 { 206,-563 }, { 207,-563 }, { 208,-563 }, { 209,-563 }, { 210,-563 },
 { 211,-563 }, { 212,-563 }, { 213,-563 }, { 214,-563 }, { 215,-563 },
 { 216,-563 }, { 217,-563 }, { 218,-563 }, { 219,-563 }, { 220,-563 },
 { 221,-563 }, { 222,-563 }, { 223,-563 }, { 224,-563 }, { 225,-563 },
 { 226,-563 }, { 227,-563 }, { 228,-563 }, { 229,-563 }, { 230,-563 },
 { 231,-563 }, { 232,-563 }, { 233,-563 }, { 234,-563 }, { 235,-563 },

 { 236,-563 }, { 237,-563 }, { 238,-563 }, { 239,-563 }, { 240,-563 },
 { 241,-563 }, { 242,-563 }, { 243,-563 }, { 244,-563 }, { 245,-563 },
 { 246,-563 }, { 247,-563 }, { 248,-563 }, { 249,-563 }, { 250,-563 },
 { 251,-563 }, { 252,-563 }, { 253,-563 }, { 254,-563 }, { 255,-563 },
 { 256,-563 }, {   0,   9 }, {   0,11728 }, {   1,-4945 }, {   2,-4945 },
 {   3,-4945 }, {   4,-4945 }, {   5,-4945 }, {   6,-4945 }, {   7,-4945 },
 {   8,-4945 }, {   9,-4687 }, {  10,-11286 }, {  11,-4945 }, {  12,-4687 },
 {  13,-11286 }, {  14,-4945 }, {  15,-4945 }, {  16,-4945 }, {  17,-4945 },
 {  18,-4945 }, {  19,-4945 }, {  20,-4945 }, {  21,-4945 }, {  22,-4945 },
 {  23,-4945 }, {  24,-4945 }, {  25,-4945 }, {  26,-4945 }, {  27,-4945 },

 {  28,-4945 }, {  29,-4945 }, {  30,-4945 }, {  31,-4945 }, {  32,-4687 },
 {  33,-4945 }, {  34,-4945 }, {  35,-4945 }, {  36,-4945 }, {  37,-4945 },
 {  38,-4945 }, {  39,-4945 }, {  40,-4945 }, {  41,-4945 }, {  42,-4945 },
 {  43,-4945 }, {  44,-4945 }, {  45,   0 }, {  46,-4945 }, {  47,-4945 },
 {  48,-4945 }, {  49,-4945 }, {  50,-4945 }, {  51,-4945 }, {  52,-4945 },
 {  53,-4945 }, {  54,-4945 }, {  55,-4945 }, {  56,-4945 }, {  57,-4945 },
 {  58,-4945 }, {  59,-4945 }, {  60,-4945 }, {  61,-4945 }, {  62,-4945 },
 {  63,-4945 }, {  64,-4945 }, {  65,-4945 }, {  66,-4945 }, {  67,-4945 },
 {  68,-4945 }, {  69,-4945 }, {  70,-4945 }, {  71,-4945 }, {  72,-4945 },
 {  73,-4945 }, {  74,-4945 }, {  75,-4945 }, {  76,-4945 }, {  77,-4945 },

 {  78,-4945 }, {  79,-4945 }, {  80,-4945 }, {  81,-4945 }, {  82,-4945 },
 {  83,-4945 }, {  84,-4945 }, {  85,-4945 }, {  86,-4945 }, {  87,-4945 },
 {  88,-4945 }, {  89,-4945 }, {  90,-4945 }, {  91,-4945 }, {  92,-4945 },
 {  93,-4945 }, {  94,-4945 }, {  95,-4945 }, {  96,-4945 }, {  97,-4945 },
 {  98,-4945 }, {  99,-4945 }, { 100,-4945 }, { 101,-4945 }, { 102,-4945 },
 { 103,-4945 }, { 104,-4945 }, { 105,-4945 }, { 106,-4945 }, { 107,-4945 },
 { 108,-4945 }, { 109,-4945 }, { 110,-4945 }, { 111,-4945 }, { 112,-4945 },
 { 113,-4945 }, { 114,-4945 }, { 115,-4945 }, { 116,-4945 }, { 117,-4945 },
 { 118,-4945 }, { 119,-4945 }, { 120,-4945 }, { 121,-4945 }, { 122,-4945 },
 { 123,-4945 }, { 124,-4945 }, { 125,-4945 }, { 126,-4945 }, { 127,-4945 },

 { 128,-4945 }, { 129,-4945 }, { 130,-4945 }, { 131,-4945 }, { 132,-4945 },
 { 133,-4945 }, { 134,-4945 }, { 135,-4945 }, { 136,-4945 }, { 137,-4945 },
 { 138,-4945 }, { 139,-4945 }, { 140,-4945 }, { 141,-4945 }, { 142,-4945 },
 { 143,-4945 }, { 144,-4945 }, { 145,-4945 }, { 146,-4945 }, { 147,-4945 },
 { 148,-4945 }, { 149,-4945 }, { 150,-4945 }, { 151,-4945 }, { 152,-4945 },
 { 153,-4945 }, { 154,-4945 }, { 155,-4945 }, { 156,-4945 }, { 157,-4945 },
 { 158,-4945 }, { 159,-4945 }, { 160,-4945 }, { 161,-4945 }, { 162,-4945 },
 { 163,-4945 }, { 164,-4945 }, { 165,-4945 }, { 166,-4945 }, { 167,-4945 },
 { 168,-4945 }, { 169,-4945 }, { 170,-4945 }, { 171,-4945 }, { 172,-4945 },
 { 173,-4945 }, { 174,-4945 }, { 175,-4945 }, { 176,-4945 }, { 177,-4945 },

 { 178,-4945 }, { 179,-4945 }, { 180,-4945 }, { 181,-4945 }, { 182,-4945 },
 { 183,-4945 }, { 184,-4945 }, { 185,-4945 }, { 186,-4945 }, { 187,-4945 },
 { 188,-4945 }, { 189,-4945 }, { 190,-4945 }, { 191,-4945 }, { 192,-4945 },
 { 193,-4945 }, { 194,-4945 }, { 195,-4945 }, { 196,-4945 }, { 197,-4945 },
 { 198,-4945 }, { 199,-4945 }, { 200,-4945 }, { 201,-4945 }, { 202,-4945 },
 { 203,-4945 }, { 204,-4945 }, { 205,-4945 }, { 206,-4945 }, { 207,-4945 },
 { 208,-4945 }, { 209,-4945 }, { 210,-4945 }, { 211,-4945 }, { 212,-4945 },
 { 213,-4945 }, { 214,-4945 }, { 215,-4945 }, { 216,-4945 }, { 217,-4945 },
 { 218,-4945 }, { 219,-4945 }, { 220,-4945 }, { 221,-4945 }, { 222,-4945 },
 { 223,-4945 }, { 224,-4945 }, { 225,-4945 }, { 226,-4945 }, { 227,-4945 },

 { 228,-4945 }, { 229,-4945 }, { 230,-4945 }, { 231,-4945 }, { 232,-4945 },
 { 233,-4945 }, { 234,-4945 }, { 235,-4945 }, { 236,-4945 }, { 237,-4945 },
 { 238,-4945 }, { 239,-4945 }, { 240,-4945 }, { 241,-4945 }, { 242,-4945 },
 { 243,-4945 }, { 244,-4945 }, { 245,-4945 }, { 246,-4945 }, { 247,-4945 },
 { 248,-4945 }, { 249,-4945 }, { 250,-4945 }, { 251,-4945 }, { 252,-4945 },
 { 253,-4945 }, { 254,-4945 }, { 255,-4945 }, { 256,-4945 }, {   0,  16 },
 {   0,11470 }, {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 },
 {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9, 258 },
 {  10, 516 }, {  11,   0 }, {  12, 258 }, {  13, 516 }, {  14,   0 },
 {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 },

 {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 },
 {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 },
 {  30,   0 }, {  31,   0 }, {  32, 258 }, {  33,   0 }, {  34,   0 },
 {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 },
 {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 },
 {  45, 563 }, {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 },
 {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 },
 {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 },
 {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 },
 {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 },

 {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 },
 {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 },
 {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 },
 {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 },
 {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 },
 {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 },
 { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 },
 { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 },
 { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 },
 { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 },

 { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 },
 { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 },
 { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 },
 { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 },
 { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 },
 { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 },
 { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 },
 { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 },
 { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 },
 { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 },

 { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 },
 { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 },
 { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 },
 { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 },
 { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 },
 { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 },
 { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 },
 { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 },
 { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 },
 { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 },

 { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 },
 { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 },
 { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 },
 { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 },
 { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 },
 { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 },
 { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 },
 { 255,   0 }, { 256,   0 }, {   0,  16 }, {   0,11212 }, {   1,-258 },
 {   2,-258 }, {   3,-258 }, {   4,-258 }, {   5,-258 }, {   6,-258 },
 {   7,-258 }, {   8,-258 }, {   9,   0 }, {  10, 258 }, {  11,-258 },

 {  12,   0 }, {  13, 258 }, {  14,-258 }, {  15,-258 }, {  16,-258 },
 {  17,-258 }, {  18,-258 }, {  19,-258 }, {  20,-258 }, {  21,-258 },
 {  22,-258 }, {  23,-258 }, {  24,-258 }, {  25,-258 }, {  26,-258 },
 {  27,-258 }, {  28,-258 }, {  29,-258 }, {  30,-258 }, {  31,-258 },
 {  32,   0 }, {  33,-258 }, {  34,-258 }, {  35,-258 }, {  36,-258 },
 {  37,-258 }, {  38,-258 }, {  39,-258 }, {  40,-258 }, {  41,-258 },
 {  42,-258 }, {  43,-258 }, {  44,-258 }, {  45, 305 }, {  46,-258 },
 {  47,-258 }, {  48,-258 }, {  49,-258 }, {  50,-258 }, {  51,-258 },
 {  52,-258 }, {  53,-258 }, {  54,-258 }, {  55,-258 }, {  56,-258 },
 {  57,-258 }, {  58,-258 }, {  59,-258 }, {  60,-258 }, {  61,-258 },

 {  62,-258 }, {  63,-258 }, {  64,-258 }, {  65,-258 }, {  66,-258 },
 {  67,-258 }, {  68,-258 }, {  69,-258 }, {  70,-258 }, {  71,-258 },
 {  72,-258 }, {  73,-258 }, {  74,-258 }, {  75,-258 }, {  76,-258 },
 {  77,-258 }, {  78,-258 }, {  79,-258 }, {  80,-258 }, {  81,-258 },
 {  82,-258 }, {  83,-258 }, {  84,-258 }, {  85,-258 }, {  86,-258 },
 {  87,-258 }, {  88,-258 }, {  89,-258 }, {  90,-258 }, {  91,-258 },
 {  92,-258 }, {  93,-258 }, {  94,-258 }, {  95,-258 }, {  96,-258 },
 {  97,-258 }, {  98,-258 }, {  99,-258 }, { 100,-258 }, { 101,-258 },
 { 102,-258 }, { 103,-258 }, { 104,-258 }, { 105,-258 }, { 106,-258 },
 { 107,-258 }, { 108,-258 }, { 109,-258 }, { 110,-258 }, { 111,-258 },

 { 112,-258 }, { 113,-258 }, { 114,-258 }, { 115,-258 }, { 116,-258 },
 { 117,-258 }, { 118,-258 }, { 119,-258 }, { 120,-258 }, { 121,-258 },
 { 122,-258 }, { 123,-258 }, { 124,-258 }, { 125,-258 }, { 126,-258 },
 { 127,-258 }, { 128,-258 }, { 129,-258 }, { 130,-258 }, { 131,-258 },
 { 132,-258 }, { 133,-258 }, { 134,-258 }, { 135,-258 }, { 136,-258 },
 { 137,-258 }, { 138,-258 }, { 139,-258 }, { 140,-258 }, { 141,-258 },
 { 142,-258 }, { 143,-258 }, { 144,-258 }, { 145,-258 }, { 146,-258 },
 { 147,-258 }, { 148,-258 }, { 149,-258 }, { 150,-258 }, { 151,-258 },
 { 152,-258 }, { 153,-258 }, { 154,-258 }, { 155,-258 }, { 156,-258 },
 { 157,-258 }, { 158,-258 }, { 159,-258 }, { 160,-258 }, { 161,-258 },

 { 162,-258 }, { 163,-258 }, { 164,-258 }, { 165,-258 }, { 166,-258 },
 { 167,-258 }, { 168,-258 }, { 169,-258 }, { 170,-258 }, { 171,-258 },
 { 172,-258 }, { 173,-258 }, { 174,-258 }, { 175,-258 }, { 176,-258 },
 { 177,-258 }, { 178,-258 }, { 179,-258 }, { 180,-258 }, { 181,-258 },
 { 182,-258 }, { 183,-258 }, { 184,-258 }, { 185,-258 }, { 186,-258 },
 { 187,-258 }, { 188,-258 }, { 189,-258 }, { 190,-258 }, { 191,-258 },
 { 192,-258 }, { 193,-258 }, { 194,-258 }, { 195,-258 }, { 196,-258 },
 { 197,-258 }, { 198,-258 }, { 199,-258 }, { 200,-258 }, { 201,-258 },
 { 202,-258 }, { 203,-258 }, { 204,-258 }, { 205,-258 }, { 206,-258 },
 { 207,-258 }, { 208,-258 }, { 209,-258 }, { 210,-258 }, { 211,-258 },

 { 212,-258 }, { 213,-258 }, { 214,-258 }, { 215,-258 }, { 216,-258 },
 { 217,-258 }, { 218,-258 }, { 219,-258 }, { 220,-258 }, { 221,-258 },
 { 222,-258 }, { 223,-258 }, { 224,-258 }, { 225,-258 }, { 226,-258 },
 { 227,-258 }, { 228,-258 }, { 229,-258 }, { 230,-258 }, { 231,-258 },
 { 232,-258 }, { 233,-258 }, { 234,-258 }, { 235,-258 }, { 236,-258 },
 { 237,-258 }, { 238,-258 }, { 239,-258 }, { 240,-258 }, { 241,-258 },
 { 242,-258 }, { 243,-258 }, { 244,-258 }, { 245,-258 }, { 246,-258 },
 { 247,-258 }, { 248,-258 }, { 249,-258 }, { 250,-258 }, { 251,-258 },
 { 252,-258 }, { 253,-258 }, { 254,-258 }, { 255,-258 }, { 256,-258 },
 {   0,  16 }, {   0,10954 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,-8007 }, {  10,-8007 }, {   0,   0 }, {  12,-8007 }, {  13,-8007 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,-8007 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39,-18519 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-18514 }, {   0,  16 }, {   0,10907 }, {   1,-563 },
 {   2,-563 }, {   3,-563 }, {   4,-563 }, {   5,-563 }, {   6,-563 },

 {   7,-563 }, {   8,-563 }, {   9,-305 }, {  10, -47 }, {  11,-563 },
 {  12,-305 }, {  13, -47 }, {  14,-563 }, {  15,-563 }, {  16,-563 },
 {  17,-563 }, {  18,-563 }, {  19,-563 }, {  20,-563 }, {  21,-563 },
 {  22,-563 }, {  23,-563 }, {  24,-563 }, {  25,-563 }, {  26,-563 },
 {  27,-563 }, {  28,-563 }, {  29,-563 }, {  30,-563 }, {  31,-563 },
 {  32,-305 }, {  33,-563 }, {  34,-563 }, {  35,-563 }, {  36,-563 },
 {  37,-563 }, {  38,-563 }, {  39,-563 }, {  40,-563 }, {  41,-563 },
 {  42,-563 }, {  43,-563 }, {  44,-563 }, {  45,3186 }, {  46,-563 },
 {  47,-563 }, {  48,-563 }, {  49,-563 }, {  50,-563 }, {  51,-563 },
 {  52,-563 }, {  53,-563 }, {  54,-563 }, {  55,-563 }, {  56,-563 },

 {  57,-563 }, {  58,-563 }, {  59,-563 }, {  60,-563 }, {  61,-563 },
 {  62,-563 }, {  63,-563 }, {  64,-563 }, {  65,-563 }, {  66,-563 },
 {  67,-563 }, {  68,-563 }, {  69,-563 }, {  70,-563 }, {  71,-563 },
 {  72,-563 }, {  73,-563 }, {  74,-563 }, {  75,-563 }, {  76,-563 },
 {  77,-563 }, {  78,-563 }, {  79,-563 }, {  80,-563 }, {  81,-563 },
 {  82,-563 }, {  83,-563 }, {  84,-563 }, {  85,-563 }, {  86,-563 },
 {  87,-563 }, {  88,-563 }, {  89,-563 }, {  90,-563 }, {  91,-563 },
 {  92,-563 }, {  93,-563 }, {  94,-563 }, {  95,-563 }, {  96,-563 },
 {  97,-563 }, {  98,-563 }, {  99,-563 }, { 100,-563 }, { 101,-563 },
 { 102,-563 }, { 103,-563 }, { 104,-563 }, { 105,-563 }, { 106,-563 },

 { 107,-563 }, { 108,-563 }, { 109,-563 }, { 110,-563 }, { 111,-563 },
 { 112,-563 }, { 113,-563 }, { 114,-563 }, { 115,-563 }, { 116,-563 },
 { 117,-563 }, { 118,-563 }, { 119,-563 }, { 120,-563 }, { 121,-563 },
 { 122,-563 }, { 123,-563 }, { 124,-563 }, { 125,-563 }, { 126,-563 },
 { 127,-563 }, { 128,-563 }, { 129,-563 }, { 130,-563 }, { 131,-563 },
 { 132,-563 }, { 133,-563 }, { 134,-563 }, { 135,-563 }, { 136,-563 },
 { 137,-563 }, { 138,-563 }, { 139,-563 }, { 140,-563 }, { 141,-563 },
 { 142,-563 }, { 143,-563 }, { 144,-563 }, { 145,-563 }, { 146,-563 },
 { 147,-563 }, { 148,-563 }, { 149,-563 }, { 150,-563 }, { 151,-563 },
 { 152,-563 }, { 153,-563 }, { 154,-563 }, { 155,-563 }, { 156,-563 },

 { 157,-563 }, { 158,-563 }, { 159,-563 }, { 160,-563 }, { 161,-563 },
 { 162,-563 }, { 163,-563 }, { 164,-563 }, { 165,-563 }, { 166,-563 },
 { 167,-563 }, { 168,-563 }, { 169,-563 }, { 170,-563 }, { 171,-563 },
 { 172,-563 }, { 173,-563 }, { 174,-563 }, { 175,-563 }, { 176,-563 },
 { 177,-563 }, { 178,-563 }, { 179,-563 }, { 180,-563 }, { 181,-563 },
 { 182,-563 }, { 183,-563 }, { 184,-563 }, { 185,-563 }, { 186,-563 },
 { 187,-563 }, { 188,-563 }, { 189,-563 }, { 190,-563 }, { 191,-563 },
 { 192,-563 }, { 193,-563 }, { 194,-563 }, { 195,-563 }, { 196,-563 },
 { 197,-563 }, { 198,-563 }, { 199,-563 }, { 200,-563 }, { 201,-563 },
 { 202,-563 }, { 203,-563 }, { 204,-563 }, { 205,-563 }, { 206,-563 },

 { 207,-563 }, { 208,-563 }, { 209,-563 }, { 210,-563 }, { 211,-563 },
 { 212,-563 }, { 213,-563 }, { 214,-563 }, { 215,-563 }, { 216,-563 },
 { 217,-563 }, { 218,-563 }, { 219,-563 }, { 220,-563 }, { 221,-563 },
 { 222,-563 }, { 223,-563 }, { 224,-563 }, { 225,-563 }, { 226,-563 },
 { 227,-563 }, { 228,-563 }, { 229,-563 }, { 230,-563 }, { 231,-563 },
 { 232,-563 }, { 233,-563 }, { 234,-563 }, { 235,-563 }, { 236,-563 },
 { 237,-563 }, { 238,-563 }, { 239,-563 }, { 240,-563 }, { 241,-563 },
 { 242,-563 }, { 243,-563 }, { 244,-563 }, { 245,-563 }, { 246,-563 },
 { 247,-563 }, { 248,-563 }, { 249,-563 }, { 250,-563 }, { 251,-563 },
 { 252,-563 }, { 253,-563 }, { 254,-563 }, { 255,-563 }, { 256,-563 },

 {   0,  16 }, {   0,10649 }, {   1,-4992 }, {   2,-4992 }, {   3,-4992 },
 {   4,-4992 }, {   5,-4992 }, {   6,-4992 }, {   7,-4992 }, {   8,-4992 },
 {   9,-4734 }, {  10,-11411 }, {  11,-4992 }, {  12,-4734 }, {  13,-11411 },
 {  14,-4992 }, {  15,-4992 }, {  16,-4992 }, {  17,-4992 }, {  18,-4992 },
 {  19,-4992 }, {  20,-4992 }, {  21,-4992 }, {  22,-4992 }, {  23,-4992 },
 {  24,-4992 }, {  25,-4992 }, {  26,-4992 }, {  27,-4992 }, {  28,-4992 },
 {  29,-4992 }, {  30,-4992 }, {  31,-4992 }, {  32,-4734 }, {  33,-4992 },
 {  34,-4992 }, {  35,-4992 }, {  36,-4992 }, {  37,-4992 }, {  38,-4992 },
 {  39,-4992 }, {  40,-4992 }, {  41,-4992 }, {  42,-4992 }, {  43,-4992 },
 {  44,-4992 }, {  45,   0 }, {  46,-4992 }, {  47,-4992 }, {  48,-4992 },

 {  49,-4992 }, {  50,-4992 }, {  51,-4992 }, {  52,-4992 }, {  53,-4992 },
 {  54,-4992 }, {  55,-4992 }, {  56,-4992 }, {  57,-4992 }, {  58,-4992 },
 {  59,-4992 }, {  60,-4992 }, {  61,-4992 }, {  62,-4992 }, {  63,-4992 },
 {  64,-4992 }, {  65,-4992 }, {  66,-4992 }, {  67,-4992 }, {  68,-4992 },
 {  69,-4992 }, {  70,-4992 }, {  71,-4992 }, {  72,-4992 }, {  73,-4992 },
 {  74,-4992 }, {  75,-4992 }, {  76,-4992 }, {  77,-4992 }, {  78,-4992 },
 {  79,-4992 }, {  80,-4992 }, {  81,-4992 }, {  82,-4992 }, {  83,-4992 },
 {  84,-4992 }, {  85,-4992 }, {  86,-4992 }, {  87,-4992 }, {  88,-4992 },
 {  89,-4992 }, {  90,-4992 }, {  91,-4992 }, {  92,-4992 }, {  93,-4992 },
 {  94,-4992 }, {  95,-4992 }, {  96,-4992 }, {  97,-4992 }, {  98,-4992 },

 {  99,-4992 }, { 100,-4992 }, { 101,-4992 }, { 102,-4992 }, { 103,-4992 },
 { 104,-4992 }, { 105,-4992 }, { 106,-4992 }, { 107,-4992 }, { 108,-4992 },
 { 109,-4992 }, { 110,-4992 }, { 111,-4992 }, { 112,-4992 }, { 113,-4992 },
 { 114,-4992 }, { 115,-4992 }, { 116,-4992 }, { 117,-4992 }, { 118,-4992 },
 { 119,-4992 }, { 120,-4992 }, { 121,-4992 }, { 122,-4992 }, { 123,-4992 },
 { 124,-4992 }, { 125,-4992 }, { 126,-4992 }, { 127,-4992 }, { 128,-4992 },
 { 129,-4992 }, { 130,-4992 }, { 131,-4992 }, { 132,-4992 }, { 133,-4992 },
 { 134,-4992 }, { 135,-4992 }, { 136,-4992 }, { 137,-4992 }, { 138,-4992 },
 { 139,-4992 }, { 140,-4992 }, { 141,-4992 }, { 142,-4992 }, { 143,-4992 },
 { 144,-4992 }, { 145,-4992 }, { 146,-4992 }, { 147,-4992 }, { 148,-4992 },

 { 149,-4992 }, { 150,-4992 }, { 151,-4992 }, { 152,-4992 }, { 153,-4992 },
 { 154,-4992 }, { 155,-4992 }, { 156,-4992 }, { 157,-4992 }, { 158,-4992 },
 { 159,-4992 }, { 160,-4992 }, { 161,-4992 }, { 162,-4992 }, { 163,-4992 },
 { 164,-4992 }, { 165,-4992 }, { 166,-4992 }, { 167,-4992 }, { 168,-4992 },
 { 169,-4992 }, { 170,-4992 }, { 171,-4992 }, { 172,-4992 }, { 173,-4992 },
 { 174,-4992 }, { 175,-4992 }, { 176,-4992 }, { 177,-4992 }, { 178,-4992 },
 { 179,-4992 }, { 180,-4992 }, { 181,-4992 }, { 182,-4992 }, { 183,-4992 },
 { 184,-4992 }, { 185,-4992 }, { 186,-4992 }, { 187,-4992 }, { 188,-4992 },
 { 189,-4992 }, { 190,-4992 }, { 191,-4992 }, { 192,-4992 }, { 193,-4992 },
 { 194,-4992 }, { 195,-4992 }, { 196,-4992 }, { 197,-4992 }, { 198,-4992 },

 { 199,-4992 }, { 200,-4992 }, { 201,-4992 }, { 202,-4992 }, { 203,-4992 },
 { 204,-4992 }, { 205,-4992 }, { 206,-4992 }, { 207,-4992 }, { 208,-4992 },
 { 209,-4992 }, { 210,-4992 }, { 211,-4992 }, { 212,-4992 }, { 213,-4992 },
 { 214,-4992 }, { 215,-4992 }, { 216,-4992 }, { 217,-4992 }, { 218,-4992 },
 { 219,-4992 }, { 220,-4992 }, { 221,-4992 }, { 222,-4992 }, { 223,-4992 },
 { 224,-4992 }, { 225,-4992 }, { 226,-4992 }, { 227,-4992 }, { 228,-4992 },
 { 229,-4992 }, { 230,-4992 }, { 231,-4992 }, { 232,-4992 }, { 233,-4992 },
 { 234,-4992 }, { 235,-4992 }, { 236,-4992 }, { 237,-4992 }, { 238,-4992 },
 { 239,-4992 }, { 240,-4992 }, { 241,-4992 }, { 242,-4992 }, { 243,-4992 },
 { 244,-4992 }, { 245,-4992 }, { 246,-4992 }, { 247,-4992 }, { 248,-4992 },

 { 249,-4992 }, { 250,-4992 }, { 251,-4992 }, { 252,-4992 }, { 253,-4992 },
 { 254,-4992 }, { 255,-4992 }, { 256,-4992 }, {   0,  22 }, {   0,10391 },
 {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 },
 {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9, 258 }, {  10, 516 },
 {  11,   0 }, {  12, 258 }, {  13, 516 }, {  14,   0 }, {  15,   0 },
 {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 },
 {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 },
 {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 },
 {  31,   0 }, {  32, 258 }, {  33,   0 }, {  34,   0 }, {  35,   0 },
 {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 }, {  40,   0 },

 {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45, 563 },
 {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 },
 {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 },
 {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 },
 {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 },
 {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 },
 {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 },
 {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 },
 {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 },
 {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 },

 {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 },
 {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 },
 { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 },
 { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 },
 { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 },
 { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 },
 { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 },
 { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 },
 { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 },
 { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 },

 { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 },
 { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 },
 { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 },
 { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 },
 { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 },
 { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 },
 { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 },
 { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 },
 { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 },
 { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 },

 { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 },
 { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 },
 { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 },
 { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 },
 { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 },
 { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 },
 { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 },
 { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 },
 { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 },
 { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 },

 { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 },
 { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 },
 { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 },
 { 256,   0 }, {   0,  22 }, {   0,10133 }, {   1,-258 }, {   2,-258 },
 {   3,-258 }, {   4,-258 }, {   5,-258 }, {   6,-258 }, {   7,-258 },
 {   8,-258 }, {   9,   0 }, {  10, 258 }, {  11,-258 }, {  12,   0 },
 {  13, 258 }, {  14,-258 }, {  15,-258 }, {  16,-258 }, {  17,-258 },
 {  18,-258 }, {  19,-258 }, {  20,-258 }, {  21,-258 }, {  22,-258 },
 {  23,-258 }, {  24,-258 }, {  25,-258 }, {  26,-258 }, {  27,-258 },
 {  28,-258 }, {  29,-258 }, {  30,-258 }, {  31,-258 }, {  32,   0 },

 {  33,-258 }, {  34,-258 }, {  35,-258 }, {  36,-258 }, {  37,-258 },
 {  38,-258 }, {  39,-258 }, {  40,-258 }, {  41,-258 }, {  42,-258 },
 {  43,-258 }, {  44,-258 }, {  45, 305 }, {  46,-258 }, {  47,-258 },
 {  48,-258 }, {  49,-258 }, {  50,-258 }, {  51,-258 }, {  52,-258 },
 {  53,-258 }, {  54,-258 }, {  55,-258 }, {  56,-258 }, {  57,-258 },
 {  58,-258 }, {  59,-258 }, {  60,-258 }, {  61,-258 }, {  62,-258 },
 {  63,-258 }, {  64,-258 }, {  65,-258 }, {  66,-258 }, {  67,-258 },
 {  68,-258 }, {  69,-258 }, {  70,-258 }, {  71,-258 }, {  72,-258 },
 {  73,-258 }, {  74,-258 }, {  75,-258 }, {  76,-258 }, {  77,-258 },
 {  78,-258 }, {  79,-258 }, {  80,-258 }, {  81,-258 }, {  82,-258 },

 {  83,-258 }, {  84,-258 }, {  85,-258 }, {  86,-258 }, {  87,-258 },
 {  88,-258 }, {  89,-258 }, {  90,-258 }, {  91,-258 }, {  92,-258 },
 {  93,-258 }, {  94,-258 }, {  95,-258 }, {  96,-258 }, {  97,-258 },
 {  98,-258 }, {  99,-258 }, { 100,-258 }, { 101,-258 }, { 102,-258 },
 { 103,-258 }, { 104,-258 }, { 105,-258 }, { 106,-258 }, { 107,-258 },
 { 108,-258 }, { 109,-258 }, { 110,-258 }, { 111,-258 }, { 112,-258 },
 { 113,-258 }, { 114,-258 }, { 115,-258 }, { 116,-258 }, { 117,-258 },
 { 118,-258 }, { 119,-258 }, { 120,-258 }, { 121,-258 }, { 122,-258 },
 { 123,-258 }, { 124,-258 }, { 125,-258 }, { 126,-258 }, { 127,-258 },
 { 128,-258 }, { 129,-258 }, { 130,-258 }, { 131,-258 }, { 132,-258 },

 { 133,-258 }, { 134,-258 }, { 135,-258 }, { 136,-258 }, { 137,-258 },
 { 138,-258 }, { 139,-258 }, { 140,-258 }, { 141,-258 }, { 142,-258 },
 { 143,-258 }, { 144,-258 }, { 145,-258 }, { 146,-258 }, { 147,-258 },
 { 148,-258 }, { 149,-258 }, { 150,-258 }, { 151,-258 }, { 152,-258 },
 { 153,-258 }, { 154,-258 }, { 155,-258 }, { 156,-258 }, { 157,-258 },
 { 158,-258 }, { 159,-258 }, { 160,-258 }, { 161,-258 }, { 162,-258 },
 { 163,-258 }, { 164,-258 }, { 165,-258 }, { 166,-258 }, { 167,-258 },
 { 168,-258 }, { 169,-258 }, { 170,-258 }, { 171,-258 }, { 172,-258 },
 { 173,-258 }, { 174,-258 }, { 175,-258 }, { 176,-258 }, { 177,-258 },
 { 178,-258 }, { 179,-258 }, { 180,-258 }, { 181,-258 }, { 182,-258 },

 { 183,-258 }, { 184,-258 }, { 185,-258 }, { 186,-258 }, { 187,-258 },
 { 188,-258 }, { 189,-258 }, { 190,-258 }, { 191,-258 }, { 192,-258 },
 { 193,-258 }, { 194,-258 }, { 195,-258 }, { 196,-258 }, { 197,-258 },
 { 198,-258 }, { 199,-258 }, { 200,-258 }, { 201,-258 }, { 202,-258 },
 { 203,-258 }, { 204,-258 }, { 205,-258 }, { 206,-258 }, { 207,-258 },
 { 208,-258 }, { 209,-258 }, { 210,-258 }, { 211,-258 }, { 212,-258 },
 { 213,-258 }, { 214,-258 }, { 215,-258 }, { 216,-258 }, { 217,-258 },
 { 218,-258 }, { 219,-258 }, { 220,-258 }, { 221,-258 }, { 222,-258 },
 { 223,-258 }, { 224,-258 }, { 225,-258 }, { 226,-258 }, { 227,-258 },
 { 228,-258 }, { 229,-258 }, { 230,-258 }, { 231,-258 }, { 232,-258 },

 { 233,-258 }, { 234,-258 }, { 235,-258 }, { 236,-258 }, { 237,-258 },
 { 238,-258 }, { 239,-258 }, { 240,-258 }, { 241,-258 }, { 242,-258 },
 { 243,-258 }, { 244,-258 }, { 245,-258 }, { 246,-258 }, { 247,-258 },
 { 248,-258 }, { 249,-258 }, { 250,-258 }, { 251,-258 }, { 252,-258 },
 { 253,-258 }, { 254,-258 }, { 255,-258 }, { 256,-258 }, {   0,  22 },
 {   0,9875 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,-8707 },
 {  10,-8707 }, {   0,   0 }, {  12,-8707 }, {  13,-8707 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,-8707 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  39,-19584 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  45,-19557 }, {   0,  22 }, {   0,9828 }, {   1,-563 }, {   2,-563 },
 {   3,-563 }, {   4,-563 }, {   5,-563 }, {   6,-563 }, {   7,-563 },
 {   8,-563 }, {   9,-305 }, {  10, -47 }, {  11,-563 }, {  12,-305 },
 {  13, -47 }, {  14,-563 }, {  15,-563 }, {  16,-563 }, {  17,-563 },
 {  18,-563 }, {  19,-563 }, {  20,-563 }, {  21,-563 }, {  22,-563 },
 {  23,-563 }, {  24,-563 }, {  25,-563 }, {  26,-563 }, {  27,-563 },

 {  28,-563 }, {  29,-563 }, {  30,-563 }, {  31,-563 }, {  32,-305 },
 {  33,-563 }, {  34,-563 }, {  35,-563 }, {  36,-563 }, {  37,-563 },
 {  38,-563 }, {  39,-563 }, {  40,-563 }, {  41,-563 }, {  42,-563 },
 {  43,-563 }, {  44,-563 }, {  45,2365 }, {  46,-563 }, {  47,-563 },
 {  48,-563 }, {  49,-563 }, {  50,-563 }, {  51,-563 }, {  52,-563 },
 {  53,-563 }, {  54,-563 }, {  55,-563 }, {  56,-563 }, {  57,-563 },
 {  58,-563 }, {  59,-563 }, {  60,-563 }, {  61,-563 }, {  62,-563 },
 {  63,-563 }, {  64,-563 }, {  65,-563 }, {  66,-563 }, {  67,-563 },
 {  68,-563 }, {  69,-563 }, {  70,-563 }, {  71,-563 }, {  72,-563 },
 {  73,-563 }, {  74,-563 }, {  75,-563 }, {  76,-563 }, {  77,-563 },

 {  78,-563 }, {  79,-563 }, {  80,-563 }, {  81,-563 }, {  82,-563 },
 {  83,-563 }, {  84,-563 }, {  85,-563 }, {  86,-563 }, {  87,-563 },
 {  88,-563 }, {  89,-563 }, {  90,-563 }, {  91,-563 }, {  92,-563 },
 {  93,-563 }, {  94,-563 }, {  95,-563 }, {  96,-563 }, {  97,-563 },
 {  98,-563 }, {  99,-563 }, { 100,-563 }, { 101,-563 }, { 102,-563 },
 { 103,-563 }, { 104,-563 }, { 105,-563 }, { 106,-563 }, { 107,-563 },
 { 108,-563 }, { 109,-563 }, { 110,-563 }, { 111,-563 }, { 112,-563 },
 { 113,-563 }, { 114,-563 }, { 115,-563 }, { 116,-563 }, { 117,-563 },
 { 118,-563 }, { 119,-563 }, { 120,-563 }, { 121,-563 }, { 122,-563 },
 { 123,-563 }, { 124,-563 }, { 125,-563 }, { 126,-563 }, { 127,-563 },

 { 128,-563 }, { 129,-563 }, { 130,-563 }, { 131,-563 }, { 132,-563 },
 { 133,-563 }, { 134,-563 }, { 135,-563 }, { 136,-563 }, { 137,-563 },
 { 138,-563 }, { 139,-563 }, { 140,-563 }, { 141,-563 }, { 142,-563 },
 { 143,-563 }, { 144,-563 }, { 145,-563 }, { 146,-563 }, { 147,-563 },
 { 148,-563 }, { 149,-563 }, { 150,-563 }, { 151,-563 }, { 152,-563 },
 { 153,-563 }, { 154,-563 }, { 155,-563 }, { 156,-563 }, { 157,-563 },
 { 158,-563 }, { 159,-563 }, { 160,-563 }, { 161,-563 }, { 162,-563 },
 { 163,-563 }, { 164,-563 }, { 165,-563 }, { 166,-563 }, { 167,-563 },
 { 168,-563 }, { 169,-563 }, { 170,-563 }, { 171,-563 }, { 172,-563 },
 { 173,-563 }, { 174,-563 }, { 175,-563 }, { 176,-563 }, { 177,-563 },

 { 178,-563 }, { 179,-563 }, { 180,-563 }, { 181,-563 }, { 182,-563 },
 { 183,-563 }, { 184,-563 }, { 185,-563 }, { 186,-563 }, { 187,-563 },
 { 188,-563 }, { 189,-563 }, { 190,-563 }, { 191,-563 }, { 192,-563 },
 { 193,-563 }, { 194,-563 }, { 195,-563 }, { 196,-563 }, { 197,-563 },
 { 198,-563 }, { 199,-563 }, { 200,-563 }, { 201,-563 }, { 202,-563 },
 { 203,-563 }, { 204,-563 }, { 205,-563 }, { 206,-563 }, { 207,-563 },
 { 208,-563 }, { 209,-563 }, { 210,-563 }, { 211,-563 }, { 212,-563 },
 { 213,-563 }, { 214,-563 }, { 215,-563 }, { 216,-563 }, { 217,-563 },
 { 218,-563 }, { 219,-563 }, { 220,-563 }, { 221,-563 }, { 222,-563 },
 { 223,-563 }, { 224,-563 }, { 225,-563 }, { 226,-563 }, { 227,-563 },

 { 228,-563 }, { 229,-563 }, { 230,-563 }, { 231,-563 }, { 232,-563 },
 { 233,-563 }, { 234,-563 }, { 235,-563 }, { 236,-563 }, { 237,-563 },
 { 238,-563 }, { 239,-563 }, { 240,-563 }, { 241,-563 }, { 242,-563 },
 { 243,-563 }, { 244,-563 }, { 245,-563 }, { 246,-563 }, { 247,-563 },
 { 248,-563 }, { 249,-563 }, { 250,-563 }, { 251,-563 }, { 252,-563 },
 { 253,-563 }, { 254,-563 }, { 255,-563 }, { 256,-563 }, {   0,  22 },
 {   0,9570 }, {   1,-5039 }, {   2,-5039 }, {   3,-5039 }, {   4,-5039 },
 {   5,-5039 }, {   6,-5039 }, {   7,-5039 }, {   8,-5039 }, {   9,-4781 },
 {  10,-12180 }, {  11,-5039 }, {  12,-4781 }, {  13,-12180 }, {  14,-5039 },
 {  15,-5039 }, {  16,-5039 }, {  17,-5039 }, {  18,-5039 }, {  19,-5039 },

 {  20,-5039 }, {  21,-5039 }, {  22,-5039 }, {  23,-5039 }, {  24,-5039 },
 {  25,-5039 }, {  26,-5039 }, {  27,-5039 }, {  28,-5039 }, {  29,-5039 },
 {  30,-5039 }, {  31,-5039 }, {  32,-4781 }, {  33,-5039 }, {  34,-5039 },
 {  35,-5039 }, {  36,-5039 }, {  37,-5039 }, {  38,-5039 }, {  39,-5039 },
 {  40,-5039 }, {  41,-5039 }, {  42,-5039 }, {  43,-5039 }, {  44,-5039 },
 {  45,   0 }, {  46,-5039 }, {  47,-5039 }, {  48,-5039 }, {  49,-5039 },
 {  50,-5039 }, {  51,-5039 }, {  52,-5039 }, {  53,-5039 }, {  54,-5039 },
 {  55,-5039 }, {  56,-5039 }, {  57,-5039 }, {  58,-5039 }, {  59,-5039 },
 {  60,-5039 }, {  61,-5039 }, {  62,-5039 }, {  63,-5039 }, {  64,-5039 },
 {  65,-5039 }, {  66,-5039 }, {  67,-5039 }, {  68,-5039 }, {  69,-5039 },

 {  70,-5039 }, {  71,-5039 }, {  72,-5039 }, {  73,-5039 }, {  74,-5039 },
 {  75,-5039 }, {  76,-5039 }, {  77,-5039 }, {  78,-5039 }, {  79,-5039 },
 {  80,-5039 }, {  81,-5039 }, {  82,-5039 }, {  83,-5039 }, {  84,-5039 },
 {  85,-5039 }, {  86,-5039 }, {  87,-5039 }, {  88,-5039 }, {  89,-5039 },
 {  90,-5039 }, {  91,-5039 }, {  92,-5039 }, {  93,-5039 }, {  94,-5039 },
 {  95,-5039 }, {  96,-5039 }, {  97,-5039 }, {  98,-5039 }, {  99,-5039 },
 { 100,-5039 }, { 101,-5039 }, { 102,-5039 }, { 103,-5039 }, { 104,-5039 },
 { 105,-5039 }, { 106,-5039 }, { 107,-5039 }, { 108,-5039 }, { 109,-5039 },
 { 110,-5039 }, { 111,-5039 }, { 112,-5039 }, { 113,-5039 }, { 114,-5039 },
 { 115,-5039 }, { 116,-5039 }, { 117,-5039 }, { 118,-5039 }, { 119,-5039 },

 { 120,-5039 }, { 121,-5039 }, { 122,-5039 }, { 123,-5039 }, { 124,-5039 },
 { 125,-5039 }, { 126,-5039 }, { 127,-5039 }, { 128,-5039 }, { 129,-5039 },
 { 130,-5039 }, { 131,-5039 }, { 132,-5039 }, { 133,-5039 }, { 134,-5039 },
 { 135,-5039 }, { 136,-5039 }, { 137,-5039 }, { 138,-5039 }, { 139,-5039 },
 { 140,-5039 }, { 141,-5039 }, { 142,-5039 }, { 143,-5039 }, { 144,-5039 },
 { 145,-5039 }, { 146,-5039 }, { 147,-5039 }, { 148,-5039 }, { 149,-5039 },
 { 150,-5039 }, { 151,-5039 }, { 152,-5039 }, { 153,-5039 }, { 154,-5039 },
 { 155,-5039 }, { 156,-5039 }, { 157,-5039 }, { 158,-5039 }, { 159,-5039 },
 { 160,-5039 }, { 161,-5039 }, { 162,-5039 }, { 163,-5039 }, { 164,-5039 },
 { 165,-5039 }, { 166,-5039 }, { 167,-5039 }, { 168,-5039 }, { 169,-5039 },

 { 170,-5039 }, { 171,-5039 }, { 172,-5039 }, { 173,-5039 }, { 174,-5039 },
 { 175,-5039 }, { 176,-5039 }, { 177,-5039 }, { 178,-5039 }, { 179,-5039 },
 { 180,-5039 }, { 181,-5039 }, { 182,-5039 }, { 183,-5039 }, { 184,-5039 },
 { 185,-5039 }, { 186,-5039 }, { 187,-5039 }, { 188,-5039 }, { 189,-5039 },
 { 190,-5039 }, { 191,-5039 }, { 192,-5039 }, { 193,-5039 }, { 194,-5039 },
 { 195,-5039 }, { 196,-5039 }, { 197,-5039 }, { 198,-5039 }, { 199,-5039 },
 { 200,-5039 }, { 201,-5039 }, { 202,-5039 }, { 203,-5039 }, { 204,-5039 },
 { 205,-5039 }, { 206,-5039 }, { 207,-5039 }, { 208,-5039 }, { 209,-5039 },
 { 210,-5039 }, { 211,-5039 }, { 212,-5039 }, { 213,-5039 }, { 214,-5039 },
 { 215,-5039 }, { 216,-5039 }, { 217,-5039 }, { 218,-5039 }, { 219,-5039 },

 { 220,-5039 }, { 221,-5039 }, { 222,-5039 }, { 223,-5039 }, { 224,-5039 },
 { 225,-5039 }, { 226,-5039 }, { 227,-5039 }, { 228,-5039 }, { 229,-5039 },
 { 230,-5039 }, { 231,-5039 }, { 232,-5039 }, { 233,-5039 }, { 234,-5039 },
 { 235,-5039 }, { 236,-5039 }, { 237,-5039 }, { 238,-5039 }, { 239,-5039 },
 { 240,-5039 }, { 241,-5039 }, { 242,-5039 }, { 243,-5039 }, { 244,-5039 },
 { 245,-5039 }, { 246,-5039 }, { 247,-5039 }, { 248,-5039 }, { 249,-5039 },
 { 250,-5039 }, { 251,-5039 }, { 252,-5039 }, { 253,-5039 }, { 254,-5039 },
 { 255,-5039 }, { 256,-5039 }, {   0,  37 }, {   0,9312 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  37 }, {   0,9289 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  48,2107 }, {  49,2107 }, {  50,2107 }, {  51,2107 },
 {  52,2107 }, {  53,2107 }, {  54,2107 }, {  55,2107 }, {  56,2107 },
 {  57,2107 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,2107 }, {  66,2107 },
 {  67,2107 }, {  68,2107 }, {  69,2107 }, {  70,2107 }, {  48,-19314 },
 {  49,-19314 }, {  50,-19314 }, {  51,-19314 }, {  52,-19314 }, {  53,-19314 },
 {  54,-19314 }, {  55,-19314 }, {  56,-19314 }, {  57,-19314 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  65,-19314 }, {  66,-19314 }, {  67,-19314 }, {  68,-19314 },
 {  69,-19314 }, {  70,-19314 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  97,2107 }, {  98,2107 }, {  99,2107 }, { 100,2107 }, { 101,2107 },
 { 102,2107 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,-19314 }, {  98,-19314 },
 {  99,-19314 }, { 100,-19314 }, { 101,-19314 }, { 102,-19314 }, {   0,  24 },
 {   0,9185 }, {   1,   0 }, {   2,   0 }, {   3,   0 }, {   4,   0 },
 {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 }, {   9, 258 },
 {  10, 516 }, {  11,   0 }, {  12, 258 }, {  13, 516 }, {  14,   0 },
 {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 }, {  19,   0 },
 {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 }, {  24,   0 },
 {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 }, {  29,   0 },
 {  30,   0 }, {  31,   0 }, {  32, 258 }, {  33,   0 }, {  34,   0 },

 {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 }, {  39,   0 },
 {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 }, {  44,   0 },
 {  45, 563 }, {  46,   0 }, {  47,   0 }, {  48,   0 }, {  49,   0 },
 {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 }, {  54,   0 },
 {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 }, {  59,   0 },
 {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 }, {  64,   0 },
 {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 }, {  69,   0 },
 {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 }, {  74,   0 },
 {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 }, {  79,   0 },
 {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 }, {  84,   0 },

 {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 }, {  89,   0 },
 {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 }, {  94,   0 },
 {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 }, {  99,   0 },
 { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 }, { 104,   0 },
 { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 }, { 109,   0 },
 { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 }, { 114,   0 },
 { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 }, { 119,   0 },
 { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 }, { 124,   0 },
 { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 }, { 129,   0 },
 { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 }, { 134,   0 },

 { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 }, { 139,   0 },
 { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 }, { 144,   0 },
 { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 }, { 149,   0 },
 { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 }, { 154,   0 },
 { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 }, { 159,   0 },
 { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 }, { 164,   0 },
 { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 }, { 169,   0 },
 { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 }, { 174,   0 },
 { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 }, { 179,   0 },
 { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 }, { 184,   0 },

 { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 }, { 189,   0 },
 { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 }, { 194,   0 },
 { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 }, { 199,   0 },
 { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 }, { 204,   0 },
 { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 }, { 209,   0 },
 { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 }, { 214,   0 },
 { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 }, { 219,   0 },
 { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 }, { 224,   0 },
 { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 }, { 229,   0 },
 { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 }, { 234,   0 },

 { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 }, { 239,   0 },
 { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 }, { 244,   0 },
 { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 }, { 249,   0 },
 { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 }, { 254,   0 },
 { 255,   0 }, { 256,   0 }, {   0,  24 }, {   0,8927 }, {   1,-258 },
 {   2,-258 }, {   3,-258 }, {   4,-258 }, {   5,-258 }, {   6,-258 },
 {   7,-258 }, {   8,-258 }, {   9,   0 }, {  10, 258 }, {  11,-258 },
 {  12,   0 }, {  13, 258 }, {  14,-258 }, {  15,-258 }, {  16,-258 },
 {  17,-258 }, {  18,-258 }, {  19,-258 }, {  20,-258 }, {  21,-258 },
 {  22,-258 }, {  23,-258 }, {  24,-258 }, {  25,-258 }, {  26,-258 },

 {  27,-258 }, {  28,-258 }, {  29,-258 }, {  30,-258 }, {  31,-258 },
 {  32,   0 }, {  33,-258 }, {  34,-258 }, {  35,-258 }, {  36,-258 },
 {  37,-258 }, {  38,-258 }, {  39,-258 }, {  40,-258 }, {  41,-258 },
 {  42,-258 }, {  43,-258 }, {  44,-258 }, {  45, 305 }, {  46,-258 },
 {  47,-258 }, {  48,-258 }, {  49,-258 }, {  50,-258 }, {  51,-258 },
 {  52,-258 }, {  53,-258 }, {  54,-258 }, {  55,-258 }, {  56,-258 },
 {  57,-258 }, {  58,-258 }, {  59,-258 }, {  60,-258 }, {  61,-258 },
 {  62,-258 }, {  63,-258 }, {  64,-258 }, {  65,-258 }, {  66,-258 },
 {  67,-258 }, {  68,-258 }, {  69,-258 }, {  70,-258 }, {  71,-258 },
 {  72,-258 }, {  73,-258 }, {  74,-258 }, {  75,-258 }, {  76,-258 },

 {  77,-258 }, {  78,-258 }, {  79,-258 }, {  80,-258 }, {  81,-258 },
 {  82,-258 }, {  83,-258 }, {  84,-258 }, {  85,-258 }, {  86,-258 },
 {  87,-258 }, {  88,-258 }, {  89,-258 }, {  90,-258 }, {  91,-258 },
 {  92,-258 }, {  93,-258 }, {  94,-258 }, {  95,-258 }, {  96,-258 },
 {  97,-258 }, {  98,-258 }, {  99,-258 }, { 100,-258 }, { 101,-258 },
 { 102,-258 }, { 103,-258 }, { 104,-258 }, { 105,-258 }, { 106,-258 },
 { 107,-258 }, { 108,-258 }, { 109,-258 }, { 110,-258 }, { 111,-258 },
 { 112,-258 }, { 113,-258 }, { 114,-258 }, { 115,-258 }, { 116,-258 },
 { 117,-258 }, { 118,-258 }, { 119,-258 }, { 120,-258 }, { 121,-258 },
 { 122,-258 }, { 123,-258 }, { 124,-258 }, { 125,-258 }, { 126,-258 },

 { 127,-258 }, { 128,-258 }, { 129,-258 }, { 130,-258 }, { 131,-258 },
 { 132,-258 }, { 133,-258 }, { 134,-258 }, { 135,-258 }, { 136,-258 },
 { 137,-258 }, { 138,-258 }, { 139,-258 }, { 140,-258 }, { 141,-258 },
 { 142,-258 }, { 143,-258 }, { 144,-258 }, { 145,-258 }, { 146,-258 },
 { 147,-258 }, { 148,-258 }, { 149,-258 }, { 150,-258 }, { 151,-258 },
 { 152,-258 }, { 153,-258 }, { 154,-258 }, { 155,-258 }, { 156,-258 },
 { 157,-258 }, { 158,-258 }, { 159,-258 }, { 160,-258 }, { 161,-258 },
 { 162,-258 }, { 163,-258 }, { 164,-258 }, { 165,-258 }, { 166,-258 },
 { 167,-258 }, { 168,-258 }, { 169,-258 }, { 170,-258 }, { 171,-258 },
 { 172,-258 }, { 173,-258 }, { 174,-258 }, { 175,-258 }, { 176,-258 },

 { 177,-258 }, { 178,-258 }, { 179,-258 }, { 180,-258 }, { 181,-258 },
 { 182,-258 }, { 183,-258 }, { 184,-258 }, { 185,-258 }, { 186,-258 },
 { 187,-258 }, { 188,-258 }, { 189,-258 }, { 190,-258 }, { 191,-258 },
 { 192,-258 }, { 193,-258 }, { 194,-258 }, { 195,-258 }, { 196,-258 },
 { 197,-258 }, { 198,-258 }, { 199,-258 }, { 200,-258 }, { 201,-258 },
 { 202,-258 }, { 203,-258 }, { 204,-258 }, { 205,-258 }, { 206,-258 },
 { 207,-258 }, { 208,-258 }, { 209,-258 }, { 210,-258 }, { 211,-258 },
 { 212,-258 }, { 213,-258 }, { 214,-258 }, { 215,-258 }, { 216,-258 },
 { 217,-258 }, { 218,-258 }, { 219,-258 }, { 220,-258 }, { 221,-258 },
 { 222,-258 }, { 223,-258 }, { 224,-258 }, { 225,-258 }, { 226,-258 },

 { 227,-258 }, { 228,-258 }, { 229,-258 }, { 230,-258 }, { 231,-258 },
 { 232,-258 }, { 233,-258 }, { 234,-258 }, { 235,-258 }, { 236,-258 },
 { 237,-258 }, { 238,-258 }, { 239,-258 }, { 240,-258 }, { 241,-258 },
 { 242,-258 }, { 243,-258 }, { 244,-258 }, { 245,-258 }, { 246,-258 },
 { 247,-258 }, { 248,-258 }, { 249,-258 }, { 250,-258 }, { 251,-258 },
 { 252,-258 }, { 253,-258 }, { 254,-258 }, { 255,-258 }, { 256,-258 },
 {   0,  24 }, {   0,8669 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,-8952 }, {  10,-8952 }, {   0,   0 }, {  12,-8952 }, {  13,-8952 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,-8952 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39,-20790 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-20726 }, {   0,  24 }, {   0,8622 }, {   1,-563 },
 {   2,-563 }, {   3,-563 }, {   4,-563 }, {   5,-563 }, {   6,-563 },
 {   7,-563 }, {   8,-563 }, {   9,-305 }, {  10, -47 }, {  11,-563 },
 {  12,-305 }, {  13, -47 }, {  14,-563 }, {  15,-563 }, {  16,-563 },
 {  17,-563 }, {  18,-563 }, {  19,-563 }, {  20,-563 }, {  21,-563 },

 {  22,-563 }, {  23,-563 }, {  24,-563 }, {  25,-563 }, {  26,-563 },
 {  27,-563 }, {  28,-563 }, {  29,-563 }, {  30,-563 }, {  31,-563 },
 {  32,-305 }, {  33,-563 }, {  34,-563 }, {  35,-563 }, {  36,-563 },
 {  37,-563 }, {  38,-563 }, {  39,-563 }, {  40,-563 }, {  41,-563 },
 {  42,-563 }, {  43,-563 }, {  44,-563 }, {  45,1521 }, {  46,-563 },
 {  47,-563 }, {  48,-563 }, {  49,-563 }, {  50,-563 }, {  51,-563 },
 {  52,-563 }, {  53,-563 }, {  54,-563 }, {  55,-563 }, {  56,-563 },
 {  57,-563 }, {  58,-563 }, {  59,-563 }, {  60,-563 }, {  61,-563 },
 {  62,-563 }, {  63,-563 }, {  64,-563 }, {  65,-563 }, {  66,-563 },
 {  67,-563 }, {  68,-563 }, {  69,-563 }, {  70,-563 }, {  71,-563 },

 {  72,-563 }, {  73,-563 }, {  74,-563 }, {  75,-563 }, {  76,-563 },
 {  77,-563 }, {  78,-563 }, {  79,-563 }, {  80,-563 }, {  81,-563 },
 {  82,-563 }, {  83,-563 }, {  84,-563 }, {  85,-563 }, {  86,-563 },
 {  87,-563 }, {  88,-563 }, {  89,-563 }, {  90,-563 }, {  91,-563 },
 {  92,-563 }, {  93,-563 }, {  94,-563 }, {  95,-563 }, {  96,-563 },
 {  97,-563 }, {  98,-563 }, {  99,-563 }, { 100,-563 }, { 101,-563 },
 { 102,-563 }, { 103,-563 }, { 104,-563 }, { 105,-563 }, { 106,-563 },
 { 107,-563 }, { 108,-563 }, { 109,-563 }, { 110,-563 }, { 111,-563 },
 { 112,-563 }, { 113,-563 }, { 114,-563 }, { 115,-563 }, { 116,-563 },
 { 117,-563 }, { 118,-563 }, { 119,-563 }, { 120,-563 }, { 121,-563 },

 { 122,-563 }, { 123,-563 }, { 124,-563 }, { 125,-563 }, { 126,-563 },
 { 127,-563 }, { 128,-563 }, { 129,-563 }, { 130,-563 }, { 131,-563 },
 { 132,-563 }, { 133,-563 }, { 134,-563 }, { 135,-563 }, { 136,-563 },
 { 137,-563 }, { 138,-563 }, { 139,-563 }, { 140,-563 }, { 141,-563 },
 { 142,-563 }, { 143,-563 }, { 144,-563 }, { 145,-563 }, { 146,-563 },
 { 147,-563 }, { 148,-563 }, { 149,-563 }, { 150,-563 }, { 151,-563 },
 { 152,-563 }, { 153,-563 }, { 154,-563 }, { 155,-563 }, { 156,-563 },
 { 157,-563 }, { 158,-563 }, { 159,-563 }, { 160,-563 }, { 161,-563 },
 { 162,-563 }, { 163,-563 }, { 164,-563 }, { 165,-563 }, { 166,-563 },
 { 167,-563 }, { 168,-563 }, { 169,-563 }, { 170,-563 }, { 171,-563 },

 { 172,-563 }, { 173,-563 }, { 174,-563 }, { 175,-563 }, { 176,-563 },
 { 177,-563 }, { 178,-563 }, { 179,-563 }, { 180,-563 }, { 181,-563 },
 { 182,-563 }, { 183,-563 }, { 184,-563 }, { 185,-563 }, { 186,-563 },
 { 187,-563 }, { 188,-563 }, { 189,-563 }, { 190,-563 }, { 191,-563 },
 { 192,-563 }, { 193,-563 }, { 194,-563 }, { 195,-563 }, { 196,-563 },
 { 197,-563 }, { 198,-563 }, { 199,-563 }, { 200,-563 }, { 201,-563 },
 { 202,-563 }, { 203,-563 }, { 204,-563 }, { 205,-563 }, { 206,-563 },
 { 207,-563 }, { 208,-563 }, { 209,-563 }, { 210,-563 }, { 211,-563 },
 { 212,-563 }, { 213,-563 }, { 214,-563 }, { 215,-563 }, { 216,-563 },
 { 217,-563 }, { 218,-563 }, { 219,-563 }, { 220,-563 }, { 221,-563 },

 { 222,-563 }, { 223,-563 }, { 224,-563 }, { 225,-563 }, { 226,-563 },
 { 227,-563 }, { 228,-563 }, { 229,-563 }, { 230,-563 }, { 231,-563 },
 { 232,-563 }, { 233,-563 }, { 234,-563 }, { 235,-563 }, { 236,-563 },
 { 237,-563 }, { 238,-563 }, { 239,-563 }, { 240,-563 }, { 241,-563 },
 { 242,-563 }, { 243,-563 }, { 244,-563 }, { 245,-563 }, { 246,-563 },
 { 247,-563 }, { 248,-563 }, { 249,-563 }, { 250,-563 }, { 251,-563 },
 { 252,-563 }, { 253,-563 }, { 254,-563 }, { 255,-563 }, { 256,-563 },
 {   0,  24 }, {   0,8364 }, {   1,-5086 }, {   2,-5086 }, {   3,-5086 },
 {   4,-5086 }, {   5,-5086 }, {   6,-5086 }, {   7,-5086 }, {   8,-5086 },
 {   9,-4828 }, {  10,-12170 }, {  11,-5086 }, {  12,-4828 }, {  13,-12170 },

 {  14,-5086 }, {  15,-5086 }, {  16,-5086 }, {  17,-5086 }, {  18,-5086 },
 {  19,-5086 }, {  20,-5086 }, {  21,-5086 }, {  22,-5086 }, {  23,-5086 },
 {  24,-5086 }, {  25,-5086 }, {  26,-5086 }, {  27,-5086 }, {  28,-5086 },
 {  29,-5086 }, {  30,-5086 }, {  31,-5086 }, {  32,-4828 }, {  33,-5086 },
 {  34,-5086 }, {  35,-5086 }, {  36,-5086 }, {  37,-5086 }, {  38,-5086 },
 {  39,-5086 }, {  40,-5086 }, {  41,-5086 }, {  42,-5086 }, {  43,-5086 },
 {  44,-5086 }, {  45,   0 }, {  46,-5086 }, {  47,-5086 }, {  48,-5086 },
 {  49,-5086 }, {  50,-5086 }, {  51,-5086 }, {  52,-5086 }, {  53,-5086 },
 {  54,-5086 }, {  55,-5086 }, {  56,-5086 }, {  57,-5086 }, {  58,-5086 },
 {  59,-5086 }, {  60,-5086 }, {  61,-5086 }, {  62,-5086 }, {  63,-5086 },

 {  64,-5086 }, {  65,-5086 }, {  66,-5086 }, {  67,-5086 }, {  68,-5086 },
 {  69,-5086 }, {  70,-5086 }, {  71,-5086 }, {  72,-5086 }, {  73,-5086 },
 {  74,-5086 }, {  75,-5086 }, {  76,-5086 }, {  77,-5086 }, {  78,-5086 },
 {  79,-5086 }, {  80,-5086 }, {  81,-5086 }, {  82,-5086 }, {  83,-5086 },
 {  84,-5086 }, {  85,-5086 }, {  86,-5086 }, {  87,-5086 }, {  88,-5086 },
 {  89,-5086 }, {  90,-5086 }, {  91,-5086 }, {  92,-5086 }, {  93,-5086 },
 {  94,-5086 }, {  95,-5086 }, {  96,-5086 }, {  97,-5086 }, {  98,-5086 },
 {  99,-5086 }, { 100,-5086 }, { 101,-5086 }, { 102,-5086 }, { 103,-5086 },
 { 104,-5086 }, { 105,-5086 }, { 106,-5086 }, { 107,-5086 }, { 108,-5086 },
 { 109,-5086 }, { 110,-5086 }, { 111,-5086 }, { 112,-5086 }, { 113,-5086 },

 { 114,-5086 }, { 115,-5086 }, { 116,-5086 }, { 117,-5086 }, { 118,-5086 },
 { 119,-5086 }, { 120,-5086 }, { 121,-5086 }, { 122,-5086 }, { 123,-5086 },
 { 124,-5086 }, { 125,-5086 }, { 126,-5086 }, { 127,-5086 }, { 128,-5086 },
 { 129,-5086 }, { 130,-5086 }, { 131,-5086 }, { 132,-5086 }, { 133,-5086 },
 { 134,-5086 }, { 135,-5086 }, { 136,-5086 }, { 137,-5086 }, { 138,-5086 },
 { 139,-5086 }, { 140,-5086 }, { 141,-5086 }, { 142,-5086 }, { 143,-5086 },
 { 144,-5086 }, { 145,-5086 }, { 146,-5086 }, { 147,-5086 }, { 148,-5086 },
 { 149,-5086 }, { 150,-5086 }, { 151,-5086 }, { 152,-5086 }, { 153,-5086 },
 { 154,-5086 }, { 155,-5086 }, { 156,-5086 }, { 157,-5086 }, { 158,-5086 },
 { 159,-5086 }, { 160,-5086 }, { 161,-5086 }, { 162,-5086 }, { 163,-5086 },

 { 164,-5086 }, { 165,-5086 }, { 166,-5086 }, { 167,-5086 }, { 168,-5086 },
 { 169,-5086 }, { 170,-5086 }, { 171,-5086 }, { 172,-5086 }, { 173,-5086 },
 { 174,-5086 }, { 175,-5086 }, { 176,-5086 }, { 177,-5086 }, { 178,-5086 },
 { 179,-5086 }, { 180,-5086 }, { 181,-5086 }, { 182,-5086 }, { 183,-5086 },
 { 184,-5086 }, { 185,-5086 }, { 186,-5086 }, { 187,-5086 }, { 188,-5086 },
 { 189,-5086 }, { 190,-5086 }, { 191,-5086 }, { 192,-5086 }, { 193,-5086 },
 { 194,-5086 }, { 195,-5086 }, { 196,-5086 }, { 197,-5086 }, { 198,-5086 },
 { 199,-5086 }, { 200,-5086 }, { 201,-5086 }, { 202,-5086 }, { 203,-5086 },
 { 204,-5086 }, { 205,-5086 }, { 206,-5086 }, { 207,-5086 }, { 208,-5086 },
 { 209,-5086 }, { 210,-5086 }, { 211,-5086 }, { 212,-5086 }, { 213,-5086 },

 { 214,-5086 }, { 215,-5086 }, { 216,-5086 }, { 217,-5086 }, { 218,-5086 },
 { 219,-5086 }, { 220,-5086 }, { 221,-5086 }, { 222,-5086 }, { 223,-5086 },
 { 224,-5086 }, { 225,-5086 }, { 226,-5086 }, { 227,-5086 }, { 228,-5086 },
 { 229,-5086 }, { 230,-5086 }, { 231,-5086 }, { 232,-5086 }, { 233,-5086 },
 { 234,-5086 }, { 235,-5086 }, { 236,-5086 }, { 237,-5086 }, { 238,-5086 },
 { 239,-5086 }, { 240,-5086 }, { 241,-5086 }, { 242,-5086 }, { 243,-5086 },
 { 244,-5086 }, { 245,-5086 }, { 246,-5086 }, { 247,-5086 }, { 248,-5086 },
 { 249,-5086 }, { 250,-5086 }, { 251,-5086 }, { 252,-5086 }, { 253,-5086 },
 { 254,-5086 }, { 255,-5086 }, { 256,-5086 }, {   0,  37 }, {   0,8106 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  37 }, {   0,8083 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  48,1263 }, {  49,1263 }, {  50,1263 },
 {  51,1263 }, {  52,1263 }, {  53,1263 }, {  54,1263 }, {  55,1263 },

 {  56,1263 }, {  57,1263 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65,1263 },
 {  66,1263 }, {  67,1263 }, {  68,1263 }, {  69,1263 }, {  70,1263 },
 {  48,-20508 }, {  49,-20508 }, {  50,-20508 }, {  51,-20508 }, {  52,-20508 },
 {  53,-20508 }, {  54,-20508 }, {  55,-20508 }, {  56,-20508 }, {  57,-20508 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65,-20508 }, {  66,-20508 }, {  67,-20508 },
 {  68,-20508 }, {  69,-20508 }, {  70,-20508 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  97,1263 }, {  98,1263 }, {  99,1263 }, { 100,1263 },
 { 101,1263 }, { 102,1263 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,-20508 },
 {  98,-20508 }, {  99,-20508 }, { 100,-20508 }, { 101,-20508 }, { 102,-20508 },
 {   0,   9 }, {   0,7979 }, {   1,-4570 }, {   2,-4570 }, {   3,-4570 },
 {   4,-4570 }, {   5,-4570 }, {   6,-4570 }, {   7,-4570 }, {   8,-4570 },
 {   9,-4312 }, {  10,-4054 }, {  11,-4570 }, {  12,-4312 }, {  13,-4054 },
 {  14,-4570 }, {  15,-4570 }, {  16,-4570 }, {  17,-4570 }, {  18,-4570 },
 {  19,-4570 }, {  20,-4570 }, {  21,-4570 }, {  22,-4570 }, {  23,-4570 },
 {  24,-4570 }, {  25,-4570 }, {  26,-4570 }, {  27,-4570 }, {  28,-4570 },

 {  29,-4570 }, {  30,-4570 }, {  31,-4570 }, {  32,-4312 }, {  33,-4570 },
 {  34,-4570 }, {  35,-4570 }, {  36,-4570 }, {  37,-4570 }, {  38,-4570 },
 {  39,-4570 }, {  40,-4570 }, {  41,-4570 }, {  42,-4570 }, {  43,-4570 },
 {  44,-4570 }, {  45,   0 }, {  46,-4570 }, {  47,-4570 }, {  48,-4570 },
 {  49,-4570 }, {  50,-4570 }, {  51,-4570 }, {  52,-4570 }, {  53,-4570 },
 {  54,-4570 }, {  55,-4570 }, {  56,-4570 }, {  57,-4570 }, {  58,-4570 },
 {  59,-4570 }, {  60,-4570 }, {  61,-4570 }, {  62,-4570 }, {  63,-4570 },
 {  64,-4570 }, {  65,-4570 }, {  66,-4570 }, {  67,-4570 }, {  68,-4570 },
 {  69,-4570 }, {  70,-4570 }, {  71,-4570 }, {  72,-4570 }, {  73,-4570 },
 {  74,-4570 }, {  75,-4570 }, {  76,-4570 }, {  77,-4570 }, {  78,-4570 },

 {  79,-4570 }, {  80,-4570 }, {  81,-4570 }, {  82,-4570 }, {  83,-4570 },
 {  84,-4570 }, {  85,-4570 }, {  86,-4570 }, {  87,-4570 }, {  88,-4570 },
 {  89,-4570 }, {  90,-4570 }, {  91,-4570 }, {  92,-4570 }, {  93,-4570 },
 {  94,-4570 }, {  95,-4570 }, {  96,-4570 }, {  97,-4570 }, {  98,-4570 },
 {  99,-4570 }, { 100,-4570 }, { 101,-4570 }, { 102,-4570 }, { 103,-4570 },
 { 104,-4570 }, { 105,-4570 }, { 106,-4570 }, { 107,-4570 }, { 108,-4570 },
 { 109,-4570 }, { 110,-4570 }, { 111,-4570 }, { 112,-4570 }, { 113,-4570 },
 { 114,-4570 }, { 115,-4570 }, { 116,-4570 }, { 117,-4570 }, { 118,-4570 },
 { 119,-4570 }, { 120,-4570 }, { 121,-4570 }, { 122,-4570 }, { 123,-4570 },
 { 124,-4570 }, { 125,-4570 }, { 126,-4570 }, { 127,-4570 }, { 128,-4570 },

 { 129,-4570 }, { 130,-4570 }, { 131,-4570 }, { 132,-4570 }, { 133,-4570 },
 { 134,-4570 }, { 135,-4570 }, { 136,-4570 }, { 137,-4570 }, { 138,-4570 },
 { 139,-4570 }, { 140,-4570 }, { 141,-4570 }, { 142,-4570 }, { 143,-4570 },
 { 144,-4570 }, { 145,-4570 }, { 146,-4570 }, { 147,-4570 }, { 148,-4570 },
 { 149,-4570 }, { 150,-4570 }, { 151,-4570 }, { 152,-4570 }, { 153,-4570 },
 { 154,-4570 }, { 155,-4570 }, { 156,-4570 }, { 157,-4570 }, { 158,-4570 },
 { 159,-4570 }, { 160,-4570 }, { 161,-4570 }, { 162,-4570 }, { 163,-4570 },
 { 164,-4570 }, { 165,-4570 }, { 166,-4570 }, { 167,-4570 }, { 168,-4570 },
 { 169,-4570 }, { 170,-4570 }, { 171,-4570 }, { 172,-4570 }, { 173,-4570 },
 { 174,-4570 }, { 175,-4570 }, { 176,-4570 }, { 177,-4570 }, { 178,-4570 },

 { 179,-4570 }, { 180,-4570 }, { 181,-4570 }, { 182,-4570 }, { 183,-4570 },
 { 184,-4570 }, { 185,-4570 }, { 186,-4570 }, { 187,-4570 }, { 188,-4570 },
 { 189,-4570 }, { 190,-4570 }, { 191,-4570 }, { 192,-4570 }, { 193,-4570 },
 { 194,-4570 }, { 195,-4570 }, { 196,-4570 }, { 197,-4570 }, { 198,-4570 },
 { 199,-4570 }, { 200,-4570 }, { 201,-4570 }, { 202,-4570 }, { 203,-4570 },
 { 204,-4570 }, { 205,-4570 }, { 206,-4570 }, { 207,-4570 }, { 208,-4570 },
 { 209,-4570 }, { 210,-4570 }, { 211,-4570 }, { 212,-4570 }, { 213,-4570 },
 { 214,-4570 }, { 215,-4570 }, { 216,-4570 }, { 217,-4570 }, { 218,-4570 },
 { 219,-4570 }, { 220,-4570 }, { 221,-4570 }, { 222,-4570 }, { 223,-4570 },
 { 224,-4570 }, { 225,-4570 }, { 226,-4570 }, { 227,-4570 }, { 228,-4570 },

 { 229,-4570 }, { 230,-4570 }, { 231,-4570 }, { 232,-4570 }, { 233,-4570 },
 { 234,-4570 }, { 235,-4570 }, { 236,-4570 }, { 237,-4570 }, { 238,-4570 },
 { 239,-4570 }, { 240,-4570 }, { 241,-4570 }, { 242,-4570 }, { 243,-4570 },
 { 244,-4570 }, { 245,-4570 }, { 246,-4570 }, { 247,-4570 }, { 248,-4570 },
 { 249,-4570 }, { 250,-4570 }, { 251,-4570 }, { 252,-4570 }, { 253,-4570 },
 { 254,-4570 }, { 255,-4570 }, { 256,-4570 }, {   0,  16 }, {   0,7721 },
 {   1,-3749 }, {   2,-3749 }, {   3,-3749 }, {   4,-3749 }, {   5,-3749 },
 {   6,-3749 }, {   7,-3749 }, {   8,-3749 }, {   9,-3491 }, {  10,-3233 },
 {  11,-3749 }, {  12,-3491 }, {  13,-3233 }, {  14,-3749 }, {  15,-3749 },
 {  16,-3749 }, {  17,-3749 }, {  18,-3749 }, {  19,-3749 }, {  20,-3749 },

 {  21,-3749 }, {  22,-3749 }, {  23,-3749 }, {  24,-3749 }, {  25,-3749 },
 {  26,-3749 }, {  27,-3749 }, {  28,-3749 }, {  29,-3749 }, {  30,-3749 },
 {  31,-3749 }, {  32,-3491 }, {  33,-3749 }, {  34,-3749 }, {  35,-3749 },
 {  36,-3749 }, {  37,-3749 }, {  38,-3749 }, {  39,-3749 }, {  40,-3749 },
 {  41,-3749 }, {  42,-3749 }, {  43,-3749 }, {  44,-3749 }, {  45,   0 },
 {  46,-3749 }, {  47,-3749 }, {  48,-3749 }, {  49,-3749 }, {  50,-3749 },
 {  51,-3749 }, {  52,-3749 }, {  53,-3749 }, {  54,-3749 }, {  55,-3749 },
 {  56,-3749 }, {  57,-3749 }, {  58,-3749 }, {  59,-3749 }, {  60,-3749 },
 {  61,-3749 }, {  62,-3749 }, {  63,-3749 }, {  64,-3749 }, {  65,-3749 },
 {  66,-3749 }, {  67,-3749 }, {  68,-3749 }, {  69,-3749 }, {  70,-3749 },

 {  71,-3749 }, {  72,-3749 }, {  73,-3749 }, {  74,-3749 }, {  75,-3749 },
 {  76,-3749 }, {  77,-3749 }, {  78,-3749 }, {  79,-3749 }, {  80,-3749 },
 {  81,-3749 }, {  82,-3749 }, {  83,-3749 }, {  84,-3749 }, {  85,-3749 },
 {  86,-3749 }, {  87,-3749 }, {  88,-3749 }, {  89,-3749 }, {  90,-3749 },
 {  91,-3749 }, {  92,-3749 }, {  93,-3749 }, {  94,-3749 }, {  95,-3749 },
 {  96,-3749 }, {  97,-3749 }, {  98,-3749 }, {  99,-3749 }, { 100,-3749 },
 { 101,-3749 }, { 102,-3749 }, { 103,-3749 }, { 104,-3749 }, { 105,-3749 },
 { 106,-3749 }, { 107,-3749 }, { 108,-3749 }, { 109,-3749 }, { 110,-3749 },
 { 111,-3749 }, { 112,-3749 }, { 113,-3749 }, { 114,-3749 }, { 115,-3749 },
 { 116,-3749 }, { 117,-3749 }, { 118,-3749 }, { 119,-3749 }, { 120,-3749 },

 { 121,-3749 }, { 122,-3749 }, { 123,-3749 }, { 124,-3749 }, { 125,-3749 },
 { 126,-3749 }, { 127,-3749 }, { 128,-3749 }, { 129,-3749 }, { 130,-3749 },
 { 131,-3749 }, { 132,-3749 }, { 133,-3749 }, { 134,-3749 }, { 135,-3749 },
 { 136,-3749 }, { 137,-3749 }, { 138,-3749 }, { 139,-3749 }, { 140,-3749 },
 { 141,-3749 }, { 142,-3749 }, { 143,-3749 }, { 144,-3749 }, { 145,-3749 },
 { 146,-3749 }, { 147,-3749 }, { 148,-3749 }, { 149,-3749 }, { 150,-3749 },
 { 151,-3749 }, { 152,-3749 }, { 153,-3749 }, { 154,-3749 }, { 155,-3749 },
 { 156,-3749 }, { 157,-3749 }, { 158,-3749 }, { 159,-3749 }, { 160,-3749 },
 { 161,-3749 }, { 162,-3749 }, { 163,-3749 }, { 164,-3749 }, { 165,-3749 },
 { 166,-3749 }, { 167,-3749 }, { 168,-3749 }, { 169,-3749 }, { 170,-3749 },

 { 171,-3749 }, { 172,-3749 }, { 173,-3749 }, { 174,-3749 }, { 175,-3749 },
 { 176,-3749 }, { 177,-3749 }, { 178,-3749 }, { 179,-3749 }, { 180,-3749 },
 { 181,-3749 }, { 182,-3749 }, { 183,-3749 }, { 184,-3749 }, { 185,-3749 },
 { 186,-3749 }, { 187,-3749 }, { 188,-3749 }, { 189,-3749 }, { 190,-3749 },
 { 191,-3749 }, { 192,-3749 }, { 193,-3749 }, { 194,-3749 }, { 195,-3749 },
 { 196,-3749 }, { 197,-3749 }, { 198,-3749 }, { 199,-3749 }, { 200,-3749 },
 { 201,-3749 }, { 202,-3749 }, { 203,-3749 }, { 204,-3749 }, { 205,-3749 },
 { 206,-3749 }, { 207,-3749 }, { 208,-3749 }, { 209,-3749 }, { 210,-3749 },
 { 211,-3749 }, { 212,-3749 }, { 213,-3749 }, { 214,-3749 }, { 215,-3749 },
 { 216,-3749 }, { 217,-3749 }, { 218,-3749 }, { 219,-3749 }, { 220,-3749 },

 { 221,-3749 }, { 222,-3749 }, { 223,-3749 }, { 224,-3749 }, { 225,-3749 },
 { 226,-3749 }, { 227,-3749 }, { 228,-3749 }, { 229,-3749 }, { 230,-3749 },
 { 231,-3749 }, { 232,-3749 }, { 233,-3749 }, { 234,-3749 }, { 235,-3749 },
 { 236,-3749 }, { 237,-3749 }, { 238,-3749 }, { 239,-3749 }, { 240,-3749 },
 { 241,-3749 }, { 242,-3749 }, { 243,-3749 }, { 244,-3749 }, { 245,-3749 },
 { 246,-3749 }, { 247,-3749 }, { 248,-3749 }, { 249,-3749 }, { 250,-3749 },
 { 251,-3749 }, { 252,-3749 }, { 253,-3749 }, { 254,-3749 }, { 255,-3749 },
 { 256,-3749 }, {   0,  22 }, {   0,7463 }, {   1,-2928 }, {   2,-2928 },
 {   3,-2928 }, {   4,-2928 }, {   5,-2928 }, {   6,-2928 }, {   7,-2928 },
 {   8,-2928 }, {   9,-2670 }, {  10,-2412 }, {  11,-2928 }, {  12,-2670 },

 {  13,-2412 }, {  14,-2928 }, {  15,-2928 }, {  16,-2928 }, {  17,-2928 },
 {  18,-2928 }, {  19,-2928 }, {  20,-2928 }, {  21,-2928 }, {  22,-2928 },
 {  23,-2928 }, {  24,-2928 }, {  25,-2928 }, {  26,-2928 }, {  27,-2928 },
 {  28,-2928 }, {  29,-2928 }, {  30,-2928 }, {  31,-2928 }, {  32,-2670 },
 {  33,-2928 }, {  34,-2928 }, {  35,-2928 }, {  36,-2928 }, {  37,-2928 },
 {  38,-2928 }, {  39,-2928 }, {  40,-2928 }, {  41,-2928 }, {  42,-2928 },
 {  43,-2928 }, {  44,-2928 }, {  45,   0 }, {  46,-2928 }, {  47,-2928 },
 {  48,-2928 }, {  49,-2928 }, {  50,-2928 }, {  51,-2928 }, {  52,-2928 },
 {  53,-2928 }, {  54,-2928 }, {  55,-2928 }, {  56,-2928 }, {  57,-2928 },
 {  58,-2928 }, {  59,-2928 }, {  60,-2928 }, {  61,-2928 }, {  62,-2928 },

 {  63,-2928 }, {  64,-2928 }, {  65,-2928 }, {  66,-2928 }, {  67,-2928 },
 {  68,-2928 }, {  69,-2928 }, {  70,-2928 }, {  71,-2928 }, {  72,-2928 },
 {  73,-2928 }, {  74,-2928 }, {  75,-2928 }, {  76,-2928 }, {  77,-2928 },
 {  78,-2928 }, {  79,-2928 }, {  80,-2928 }, {  81,-2928 }, {  82,-2928 },
 {  83,-2928 }, {  84,-2928 }, {  85,-2928 }, {  86,-2928 }, {  87,-2928 },
 {  88,-2928 }, {  89,-2928 }, {  90,-2928 }, {  91,-2928 }, {  92,-2928 },
 {  93,-2928 }, {  94,-2928 }, {  95,-2928 }, {  96,-2928 }, {  97,-2928 },
 {  98,-2928 }, {  99,-2928 }, { 100,-2928 }, { 101,-2928 }, { 102,-2928 },
 { 103,-2928 }, { 104,-2928 }, { 105,-2928 }, { 106,-2928 }, { 107,-2928 },
 { 108,-2928 }, { 109,-2928 }, { 110,-2928 }, { 111,-2928 }, { 112,-2928 },

 { 113,-2928 }, { 114,-2928 }, { 115,-2928 }, { 116,-2928 }, { 117,-2928 },
 { 118,-2928 }, { 119,-2928 }, { 120,-2928 }, { 121,-2928 }, { 122,-2928 },
 { 123,-2928 }, { 124,-2928 }, { 125,-2928 }, { 126,-2928 }, { 127,-2928 },
 { 128,-2928 }, { 129,-2928 }, { 130,-2928 }, { 131,-2928 }, { 132,-2928 },
 { 133,-2928 }, { 134,-2928 }, { 135,-2928 }, { 136,-2928 }, { 137,-2928 },
 { 138,-2928 }, { 139,-2928 }, { 140,-2928 }, { 141,-2928 }, { 142,-2928 },
 { 143,-2928 }, { 144,-2928 }, { 145,-2928 }, { 146,-2928 }, { 147,-2928 },
 { 148,-2928 }, { 149,-2928 }, { 150,-2928 }, { 151,-2928 }, { 152,-2928 },
 { 153,-2928 }, { 154,-2928 }, { 155,-2928 }, { 156,-2928 }, { 157,-2928 },
 { 158,-2928 }, { 159,-2928 }, { 160,-2928 }, { 161,-2928 }, { 162,-2928 },

 { 163,-2928 }, { 164,-2928 }, { 165,-2928 }, { 166,-2928 }, { 167,-2928 },
 { 168,-2928 }, { 169,-2928 }, { 170,-2928 }, { 171,-2928 }, { 172,-2928 },
 { 173,-2928 }, { 174,-2928 }, { 175,-2928 }, { 176,-2928 }, { 177,-2928 },
 { 178,-2928 }, { 179,-2928 }, { 180,-2928 }, { 181,-2928 }, { 182,-2928 },
 { 183,-2928 }, { 184,-2928 }, { 185,-2928 }, { 186,-2928 }, { 187,-2928 },
 { 188,-2928 }, { 189,-2928 }, { 190,-2928 }, { 191,-2928 }, { 192,-2928 },
 { 193,-2928 }, { 194,-2928 }, { 195,-2928 }, { 196,-2928 }, { 197,-2928 },
 { 198,-2928 }, { 199,-2928 }, { 200,-2928 }, { 201,-2928 }, { 202,-2928 },
 { 203,-2928 }, { 204,-2928 }, { 205,-2928 }, { 206,-2928 }, { 207,-2928 },
 { 208,-2928 }, { 209,-2928 }, { 210,-2928 }, { 211,-2928 }, { 212,-2928 },

 { 213,-2928 }, { 214,-2928 }, { 215,-2928 }, { 216,-2928 }, { 217,-2928 },
 { 218,-2928 }, { 219,-2928 }, { 220,-2928 }, { 221,-2928 }, { 222,-2928 },
 { 223,-2928 }, { 224,-2928 }, { 225,-2928 }, { 226,-2928 }, { 227,-2928 },
 { 228,-2928 }, { 229,-2928 }, { 230,-2928 }, { 231,-2928 }, { 232,-2928 },
 { 233,-2928 }, { 234,-2928 }, { 235,-2928 }, { 236,-2928 }, { 237,-2928 },
 { 238,-2928 }, { 239,-2928 }, { 240,-2928 }, { 241,-2928 }, { 242,-2928 },
 { 243,-2928 }, { 244,-2928 }, { 245,-2928 }, { 246,-2928 }, { 247,-2928 },
 { 248,-2928 }, { 249,-2928 }, { 250,-2928 }, { 251,-2928 }, { 252,-2928 },
 { 253,-2928 }, { 254,-2928 }, { 255,-2928 }, { 256,-2928 }, {   0,  37 },
 {   0,7205 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  48, 385 }, {  49, 385 },
 {  50, 385 }, {  51, 385 }, {  52, 385 }, {  53, 385 }, {  54, 385 },

 {  55, 385 }, {  56, 385 }, {  57, 385 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  65, 385 }, {  66, 385 }, {  67, 385 }, {  68, 385 }, {  69, 385 },
 {  70, 385 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  97, 385 }, {  98, 385 }, {  99, 385 },
 { 100, 385 }, { 101, 385 }, { 102, 385 }, {   0,  24 }, {   0,7101 },

 {   1,-2084 }, {   2,-2084 }, {   3,-2084 }, {   4,-2084 }, {   5,-2084 },
 {   6,-2084 }, {   7,-2084 }, {   8,-2084 }, {   9,-1826 }, {  10,-1568 },
 {  11,-2084 }, {  12,-1826 }, {  13,-1568 }, {  14,-2084 }, {  15,-2084 },
 {  16,-2084 }, {  17,-2084 }, {  18,-2084 }, {  19,-2084 }, {  20,-2084 },
 {  21,-2084 }, {  22,-2084 }, {  23,-2084 }, {  24,-2084 }, {  25,-2084 },
 {  26,-2084 }, {  27,-2084 }, {  28,-2084 }, {  29,-2084 }, {  30,-2084 },
 {  31,-2084 }, {  32,-1826 }, {  33,-2084 }, {  34,-2084 }, {  35,-2084 },
 {  36,-2084 }, {  37,-2084 }, {  38,-2084 }, {  39,-2084 }, {  40,-2084 },
 {  41,-2084 }, {  42,-2084 }, {  43,-2084 }, {  44,-2084 }, {  45,   0 },
 {  46,-2084 }, {  47,-2084 }, {  48,-2084 }, {  49,-2084 }, {  50,-2084 },

 {  51,-2084 }, {  52,-2084 }, {  53,-2084 }, {  54,-2084 }, {  55,-2084 },
 {  56,-2084 }, {  57,-2084 }, {  58,-2084 }, {  59,-2084 }, {  60,-2084 },
 {  61,-2084 }, {  62,-2084 }, {  63,-2084 }, {  64,-2084 }, {  65,-2084 },
 {  66,-2084 }, {  67,-2084 }, {  68,-2084 }, {  69,-2084 }, {  70,-2084 },
 {  71,-2084 }, {  72,-2084 }, {  73,-2084 }, {  74,-2084 }, {  75,-2084 },
 {  76,-2084 }, {  77,-2084 }, {  78,-2084 }, {  79,-2084 }, {  80,-2084 },
 {  81,-2084 }, {  82,-2084 }, {  83,-2084 }, {  84,-2084 }, {  85,-2084 },
 {  86,-2084 }, {  87,-2084 }, {  88,-2084 }, {  89,-2084 }, {  90,-2084 },
 {  91,-2084 }, {  92,-2084 }, {  93,-2084 }, {  94,-2084 }, {  95,-2084 },
 {  96,-2084 }, {  97,-2084 }, {  98,-2084 }, {  99,-2084 }, { 100,-2084 },

 { 101,-2084 }, { 102,-2084 }, { 103,-2084 }, { 104,-2084 }, { 105,-2084 },
 { 106,-2084 }, { 107,-2084 }, { 108,-2084 }, { 109,-2084 }, { 110,-2084 },
 { 111,-2084 }, { 112,-2084 }, { 113,-2084 }, { 114,-2084 }, { 115,-2084 },
 { 116,-2084 }, { 117,-2084 }, { 118,-2084 }, { 119,-2084 }, { 120,-2084 },
 { 121,-2084 }, { 122,-2084 }, { 123,-2084 }, { 124,-2084 }, { 125,-2084 },
 { 126,-2084 }, { 127,-2084 }, { 128,-2084 }, { 129,-2084 }, { 130,-2084 },
 { 131,-2084 }, { 132,-2084 }, { 133,-2084 }, { 134,-2084 }, { 135,-2084 },
 { 136,-2084 }, { 137,-2084 }, { 138,-2084 }, { 139,-2084 }, { 140,-2084 },
 { 141,-2084 }, { 142,-2084 }, { 143,-2084 }, { 144,-2084 }, { 145,-2084 },
 { 146,-2084 }, { 147,-2084 }, { 148,-2084 }, { 149,-2084 }, { 150,-2084 },

 { 151,-2084 }, { 152,-2084 }, { 153,-2084 }, { 154,-2084 }, { 155,-2084 },
 { 156,-2084 }, { 157,-2084 }, { 158,-2084 }, { 159,-2084 }, { 160,-2084 },
 { 161,-2084 }, { 162,-2084 }, { 163,-2084 }, { 164,-2084 }, { 165,-2084 },
 { 166,-2084 }, { 167,-2084 }, { 168,-2084 }, { 169,-2084 }, { 170,-2084 },
 { 171,-2084 }, { 172,-2084 }, { 173,-2084 }, { 174,-2084 }, { 175,-2084 },
 { 176,-2084 }, { 177,-2084 }, { 178,-2084 }, { 179,-2084 }, { 180,-2084 },
 { 181,-2084 }, { 182,-2084 }, { 183,-2084 }, { 184,-2084 }, { 185,-2084 },
 { 186,-2084 }, { 187,-2084 }, { 188,-2084 }, { 189,-2084 }, { 190,-2084 },
 { 191,-2084 }, { 192,-2084 }, { 193,-2084 }, { 194,-2084 }, { 195,-2084 },
 { 196,-2084 }, { 197,-2084 }, { 198,-2084 }, { 199,-2084 }, { 200,-2084 },

 { 201,-2084 }, { 202,-2084 }, { 203,-2084 }, { 204,-2084 }, { 205,-2084 },
 { 206,-2084 }, { 207,-2084 }, { 208,-2084 }, { 209,-2084 }, { 210,-2084 },
 { 211,-2084 }, { 212,-2084 }, { 213,-2084 }, { 214,-2084 }, { 215,-2084 },
 { 216,-2084 }, { 217,-2084 }, { 218,-2084 }, { 219,-2084 }, { 220,-2084 },
 { 221,-2084 }, { 222,-2084 }, { 223,-2084 }, { 224,-2084 }, { 225,-2084 },
 { 226,-2084 }, { 227,-2084 }, { 228,-2084 }, { 229,-2084 }, { 230,-2084 },
 { 231,-2084 }, { 232,-2084 }, { 233,-2084 }, { 234,-2084 }, { 235,-2084 },
 { 236,-2084 }, { 237,-2084 }, { 238,-2084 }, { 239,-2084 }, { 240,-2084 },
 { 241,-2084 }, { 242,-2084 }, { 243,-2084 }, { 244,-2084 }, { 245,-2084 },
 { 246,-2084 }, { 247,-2084 }, { 248,-2084 }, { 249,-2084 }, { 250,-2084 },

 { 251,-2084 }, { 252,-2084 }, { 253,-2084 }, { 254,-2084 }, { 255,-2084 },
 { 256,-2084 }, {   0,  37 }, {   0,6843 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,  37 },
 {   0,6820 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  48, 136 }, {  49, 136 }, {  50, 136 }, {  51, 136 }, {  52, 136 },
 {  53, 136 }, {  54, 136 }, {  55, 136 }, {  56, 136 }, {  57, 136 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65, 136 }, {  66, 136 }, {  67, 136 },
 {  68, 136 }, {  69, 136 }, {  70, 136 }, {  48, 137 }, {  49, 137 },
 {  50, 137 }, {  51, 137 }, {  52, 137 }, {  53, 137 }, {  54, 137 },
 {  55, 137 }, {  56, 137 }, {  57, 137 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  65, 137 }, {  66, 137 }, {  67, 137 }, {  68, 137 }, {  69, 137 },

 {  70, 137 }, {   0,  55 }, {   0,6748 }, {   0,   0 }, {  97, 136 },
 {  98, 136 }, {  99, 136 }, { 100, 136 }, { 101, 136 }, { 102, 136 },
 {   0,   0 }, {   9, 137 }, {  10, 137 }, {   0,   0 }, {  12, 137 },
 {  13, 137 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,  28 }, {   0,6724 }, {  97, 137 }, {  98, 137 }, {  99, 137 },
 { 100, 137 }, { 101, 137 }, { 102, 137 }, {   0,   0 }, {  32, 137 },
 {   9, 418 }, {  10, 418 }, {   0,   0 }, {  12, 418 }, {  13, 418 },
 {   0,   0 }, {  39, 184 }, {   0,  37 }, {   0,6707 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  45,-21611 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32, 418 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39, 465 }, {   0,  37 }, {   0,6683 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-21624 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  48, 706 }, {  49, 706 }, {  50, 706 }, {  51, 706 },
 {  52, 706 }, {  53, 706 }, {  54, 706 }, {  55, 706 }, {  56, 706 },

 {  57, 706 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65, 706 }, {  66, 706 },
 {  67, 706 }, {  68, 706 }, {  69, 706 }, {  70, 706 }, {   0,   0 },
 {  48, 705 }, {  49, 705 }, {  50, 705 }, {  51, 705 }, {  52, 705 },
 {  53, 705 }, {  54, 705 }, {  55, 705 }, {  56, 705 }, {  57, 705 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65, 705 }, {  66, 705 }, {  67, 705 },
 {  68, 705 }, {  69, 705 }, {  70, 705 }, {   0,  55 }, {   0,6611 },
 {  97, 706 }, {  98, 706 }, {  99, 706 }, { 100, 706 }, { 101, 706 },
 { 102, 706 }, {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 },

 {   0,   0 }, {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97, 705 },
 {  98, 705 }, {  99, 705 }, { 100, 705 }, { 101, 705 }, { 102, 705 },
 {   0,   0 }, {  32,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  39,  47 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  45,-21748 },
 {   0,  55 }, {   0,6564 }, {   1,-21777 }, {   2,-21777 }, {   3,-21777 },
 {   4,-21777 }, {   5,-21777 }, {   6,-21777 }, {   7,-21777 }, {   8,-21777 },
 {   9,-21777 }, {  10,-21777 }, {  11,-21777 }, {  12,-21777 }, {  13,-21777 },

 {  14,-21777 }, {  15,-21777 }, {  16,-21777 }, {  17,-21777 }, {  18,-21777 },
 {  19,-21777 }, {  20,-21777 }, {  21,-21777 }, {  22,-21777 }, {  23,-21777 },
 {  24,-21777 }, {  25,-21777 }, {  26,-21777 }, {  27,-21777 }, {  28,-21777 },
 {  29,-21777 }, {  30,-21777 }, {  31,-21777 }, {  32,-21777 }, {  33,-21777 },
 {  34,-21777 }, {  35,-21777 }, {  36,-21777 }, {  37,-21777 }, {  38,-21777 },
 {   0,   0 }, {  40,-21777 }, {  41,-21777 }, {  42,-21777 }, {  43,-21777 },
 {  44,-21777 }, {  45,-21777 }, {  46,-21777 }, {  47,-21777 }, {  48,-21777 },
 {  49,-21777 }, {  50,-21777 }, {  51,-21777 }, {  52,-21777 }, {  53,-21777 },
 {  54,-21777 }, {  55,-21777 }, {  56,-21777 }, {  57,-21777 }, {  58,-21777 },
 {  59,-21777 }, {  60,-21777 }, {  61,-21777 }, {  62,-21777 }, {  63,-21777 },

 {  64,-21777 }, {  65,-21777 }, {  66,-21777 }, {  67,-21777 }, {  68,-21777 },
 {  69,-21777 }, {  70,-21777 }, {  71,-21777 }, {  72,-21777 }, {  73,-21777 },
 {  74,-21777 }, {  75,-21777 }, {  76,-21777 }, {  77,-21777 }, {  78,-21777 },
 {  79,-21777 }, {  80,-21777 }, {  81,-21777 }, {  82,-21777 }, {  83,-21777 },
 {  84,-21777 }, {  85,-21777 }, {  86,-21777 }, {  87,-21777 }, {  88,-21777 },
 {  89,-21777 }, {  90,-21777 }, {  91,-21777 }, {  92,-21777 }, {  93,-21777 },
 {  94,-21777 }, {  95,-21777 }, {  96,-21777 }, {  97,-21777 }, {  98,-21777 },
 {  99,-21777 }, { 100,-21777 }, { 101,-21777 }, { 102,-21777 }, { 103,-21777 },
 { 104,-21777 }, { 105,-21777 }, { 106,-21777 }, { 107,-21777 }, { 108,-21777 },
 { 109,-21777 }, { 110,-21777 }, { 111,-21777 }, { 112,-21777 }, { 113,-21777 },

 { 114,-21777 }, { 115,-21777 }, { 116,-21777 }, { 117,-21777 }, { 118,-21777 },
 { 119,-21777 }, { 120,-21777 }, { 121,-21777 }, { 122,-21777 }, { 123,-21777 },
 { 124,-21777 }, { 125,-21777 }, { 126,-21777 }, { 127,-21777 }, { 128,-21777 },
 { 129,-21777 }, { 130,-21777 }, { 131,-21777 }, { 132,-21777 }, { 133,-21777 },
 { 134,-21777 }, { 135,-21777 }, { 136,-21777 }, { 137,-21777 }, { 138,-21777 },
 { 139,-21777 }, { 140,-21777 }, { 141,-21777 }, { 142,-21777 }, { 143,-21777 },
 { 144,-21777 }, { 145,-21777 }, { 146,-21777 }, { 147,-21777 }, { 148,-21777 },
 { 149,-21777 }, { 150,-21777 }, { 151,-21777 }, { 152,-21777 }, { 153,-21777 },
 { 154,-21777 }, { 155,-21777 }, { 156,-21777 }, { 157,-21777 }, { 158,-21777 },
 { 159,-21777 }, { 160,-21777 }, { 161,-21777 }, { 162,-21777 }, { 163,-21777 },

 { 164,-21777 }, { 165,-21777 }, { 166,-21777 }, { 167,-21777 }, { 168,-21777 },
 { 169,-21777 }, { 170,-21777 }, { 171,-21777 }, { 172,-21777 }, { 173,-21777 },
 { 174,-21777 }, { 175,-21777 }, { 176,-21777 }, { 177,-21777 }, { 178,-21777 },
 { 179,-21777 }, { 180,-21777 }, { 181,-21777 }, { 182,-21777 }, { 183,-21777 },
 { 184,-21777 }, { 185,-21777 }, { 186,-21777 }, { 187,-21777 }, { 188,-21777 },
 { 189,-21777 }, { 190,-21777 }, { 191,-21777 }, { 192,-21777 }, { 193,-21777 },
 { 194,-21777 }, { 195,-21777 }, { 196,-21777 }, { 197,-21777 }, { 198,-21777 },
 { 199,-21777 }, { 200,-21777 }, { 201,-21777 }, { 202,-21777 }, { 203,-21777 },
 { 204,-21777 }, { 205,-21777 }, { 206,-21777 }, { 207,-21777 }, { 208,-21777 },
 { 209,-21777 }, { 210,-21777 }, { 211,-21777 }, { 212,-21777 }, { 213,-21777 },

 { 214,-21777 }, { 215,-21777 }, { 216,-21777 }, { 217,-21777 }, { 218,-21777 },
 { 219,-21777 }, { 220,-21777 }, { 221,-21777 }, { 222,-21777 }, { 223,-21777 },
 { 224,-21777 }, { 225,-21777 }, { 226,-21777 }, { 227,-21777 }, { 228,-21777 },
 { 229,-21777 }, { 230,-21777 }, { 231,-21777 }, { 232,-21777 }, { 233,-21777 },
 { 234,-21777 }, { 235,-21777 }, { 236,-21777 }, { 237,-21777 }, { 238,-21777 },
 { 239,-21777 }, { 240,-21777 }, { 241,-21777 }, { 242,-21777 }, { 243,-21777 },
 { 244,-21777 }, { 245,-21777 }, { 246,-21777 }, { 247,-21777 }, { 248,-21777 },
 { 249,-21777 }, { 250,-21777 }, { 251,-21777 }, { 252,-21777 }, { 253,-21777 },
 { 254,-21777 }, { 255,-21777 }, { 256,-21777 }, {   0,  28 }, {   0,6306 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,   0 }, {  10,   0 },
 {   0,   0 }, {  12,   0 }, {  13,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  32,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  39,  47 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  45,-22042 },
 {   0,  28 }, {   0,6259 }, {   1,-22080 }, {   2,-22080 }, {   3,-22080 },
 {   4,-22080 }, {   5,-22080 }, {   6,-22080 }, {   7,-22080 }, {   8,-22080 },

 {   9,-22080 }, {  10,-22080 }, {  11,-22080 }, {  12,-22080 }, {  13,-22080 },
 {  14,-22080 }, {  15,-22080 }, {  16,-22080 }, {  17,-22080 }, {  18,-22080 },
 {  19,-22080 }, {  20,-22080 }, {  21,-22080 }, {  22,-22080 }, {  23,-22080 },
 {  24,-22080 }, {  25,-22080 }, {  26,-22080 }, {  27,-22080 }, {  28,-22080 },
 {  29,-22080 }, {  30,-22080 }, {  31,-22080 }, {  32,-22080 }, {  33,-22080 },
 {  34,-22080 }, {  35,-22080 }, {  36,-22080 }, {  37,-22080 }, {  38,-22080 },
 {   0,   0 }, {  40,-22080 }, {  41,-22080 }, {  42,-22080 }, {  43,-22080 },
 {  44,-22080 }, {  45,-22080 }, {  46,-22080 }, {  47,-22080 }, {  48,-22080 },
 {  49,-22080 }, {  50,-22080 }, {  51,-22080 }, {  52,-22080 }, {  53,-22080 },
 {  54,-22080 }, {  55,-22080 }, {  56,-22080 }, {  57,-22080 }, {  58,-22080 },

 {  59,-22080 }, {  60,-22080 }, {  61,-22080 }, {  62,-22080 }, {  63,-22080 },
 {  64,-22080 }, {  65,-22080 }, {  66,-22080 }, {  67,-22080 }, {  68,-22080 },
 {  69,-22080 }, {  70,-22080 }, {  71,-22080 }, {  72,-22080 }, {  73,-22080 },
 {  74,-22080 }, {  75,-22080 }, {  76,-22080 }, {  77,-22080 }, {  78,-22080 },
 {  79,-22080 }, {  80,-22080 }, {  81,-22080 }, {  82,-22080 }, {  83,-22080 },
 {  84,-22080 }, {  85,-22080 }, {  86,-22080 }, {  87,-22080 }, {  88,-22080 },
 {  89,-22080 }, {  90,-22080 }, {  91,-22080 }, {  92,-22080 }, {  93,-22080 },
 {  94,-22080 }, {  95,-22080 }, {  96,-22080 }, {  97,-22080 }, {  98,-22080 },
 {  99,-22080 }, { 100,-22080 }, { 101,-22080 }, { 102,-22080 }, { 103,-22080 },
 { 104,-22080 }, { 105,-22080 }, { 106,-22080 }, { 107,-22080 }, { 108,-22080 },

 { 109,-22080 }, { 110,-22080 }, { 111,-22080 }, { 112,-22080 }, { 113,-22080 },
 { 114,-22080 }, { 115,-22080 }, { 116,-22080 }, { 117,-22080 }, { 118,-22080 },
 { 119,-22080 }, { 120,-22080 }, { 121,-22080 }, { 122,-22080 }, { 123,-22080 },
 { 124,-22080 }, { 125,-22080 }, { 126,-22080 }, { 127,-22080 }, { 128,-22080 },
 { 129,-22080 }, { 130,-22080 }, { 131,-22080 }, { 132,-22080 }, { 133,-22080 },
 { 134,-22080 }, { 135,-22080 }, { 136,-22080 }, { 137,-22080 }, { 138,-22080 },
 { 139,-22080 }, { 140,-22080 }, { 141,-22080 }, { 142,-22080 }, { 143,-22080 },
 { 144,-22080 }, { 145,-22080 }, { 146,-22080 }, { 147,-22080 }, { 148,-22080 },
 { 149,-22080 }, { 150,-22080 }, { 151,-22080 }, { 152,-22080 }, { 153,-22080 },
 { 154,-22080 }, { 155,-22080 }, { 156,-22080 }, { 157,-22080 }, { 158,-22080 },

 { 159,-22080 }, { 160,-22080 }, { 161,-22080 }, { 162,-22080 }, { 163,-22080 },
 { 164,-22080 }, { 165,-22080 }, { 166,-22080 }, { 167,-22080 }, { 168,-22080 },
 { 169,-22080 }, { 170,-22080 }, { 171,-22080 }, { 172,-22080 }, { 173,-22080 },
 { 174,-22080 }, { 175,-22080 }, { 176,-22080 }, { 177,-22080 }, { 178,-22080 },
 { 179,-22080 }, { 180,-22080 }, { 181,-22080 }, { 182,-22080 }, { 183,-22080 },
 { 184,-22080 }, { 185,-22080 }, { 186,-22080 }, { 187,-22080 }, { 188,-22080 },
 { 189,-22080 }, { 190,-22080 }, { 191,-22080 }, { 192,-22080 }, { 193,-22080 },
 { 194,-22080 }, { 195,-22080 }, { 196,-22080 }, { 197,-22080 }, { 198,-22080 },
 { 199,-22080 }, { 200,-22080 }, { 201,-22080 }, { 202,-22080 }, { 203,-22080 },
 { 204,-22080 }, { 205,-22080 }, { 206,-22080 }, { 207,-22080 }, { 208,-22080 },

 { 209,-22080 }, { 210,-22080 }, { 211,-22080 }, { 212,-22080 }, { 213,-22080 },
 { 214,-22080 }, { 215,-22080 }, { 216,-22080 }, { 217,-22080 }, { 218,-22080 },
 { 219,-22080 }, { 220,-22080 }, { 221,-22080 }, { 222,-22080 }, { 223,-22080 },
 { 224,-22080 }, { 225,-22080 }, { 226,-22080 }, { 227,-22080 }, { 228,-22080 },
 { 229,-22080 }, { 230,-22080 }, { 231,-22080 }, { 232,-22080 }, { 233,-22080 },
 { 234,-22080 }, { 235,-22080 }, { 236,-22080 }, { 237,-22080 }, { 238,-22080 },
 { 239,-22080 }, { 240,-22080 }, { 241,-22080 }, { 242,-22080 }, { 243,-22080 },
 { 244,-22080 }, { 245,-22080 }, { 246,-22080 }, { 247,-22080 }, { 248,-22080 },
 { 249,-22080 }, { 250,-22080 }, { 251,-22080 }, { 252,-22080 }, { 253,-22080 },
 { 254,-22080 }, { 255,-22080 }, { 256,-22080 }, {   0,  37 }, {   0,6001 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,  37 }, {   0,5978 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  48, 643 }, {  49, 643 }, {  50, 643 },

 {  51, 643 }, {  52, 643 }, {  53, 643 }, {  54, 643 }, {  55, 643 },
 {  56, 643 }, {  57, 643 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  65, 643 },
 {  66, 643 }, {  67, 643 }, {  68, 643 }, {  69, 643 }, {  70, 643 },
 {  48,-22625 }, {  49,-22625 }, {  50,-22625 }, {  51,-22625 }, {  52,-22625 },
 {  53,-22625 }, {  54,-22625 }, {  55,-22625 }, {  56,-22625 }, {  57,-22625 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65,-22625 }, {  66,-22625 }, {  67,-22625 },
 {  68,-22625 }, {  69,-22625 }, {  70,-22625 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  97, 643 }, {  98, 643 }, {  99, 643 }, { 100, 643 },

 { 101, 643 }, { 102, 643 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,-22625 },
 {  98,-22625 }, {  99,-22625 }, { 100,-22625 }, { 101,-22625 }, { 102,-22625 },
 {   0,  55 }, {   0,5874 }, {   1, 620 }, {   2, 620 }, {   3, 620 },
 {   4, 620 }, {   5, 620 }, {   6, 620 }, {   7, 620 }, {   8, 620 },
 {   9, 878 }, {  10,-737 }, {  11, 620 }, {  12, 878 }, {  13,-737 },
 {  14, 620 }, {  15, 620 }, {  16, 620 }, {  17, 620 }, {  18, 620 },
 {  19, 620 }, {  20, 620 }, {  21, 620 }, {  22, 620 }, {  23, 620 },

 {  24, 620 }, {  25, 620 }, {  26, 620 }, {  27, 620 }, {  28, 620 },
 {  29, 620 }, {  30, 620 }, {  31, 620 }, {  32, 878 }, {  33, 620 },
 {  34, 620 }, {  35, 620 }, {  36, 620 }, {  37, 620 }, {  38, 620 },
 {  39,1136 }, {  40, 620 }, {  41, 620 }, {  42, 620 }, {  43, 620 },
 {  44, 620 }, {  45,1394 }, {  46, 620 }, {  47, 620 }, {  48, 620 },
 {  49, 620 }, {  50, 620 }, {  51, 620 }, {  52, 620 }, {  53, 620 },
 {  54, 620 }, {  55, 620 }, {  56, 620 }, {  57, 620 }, {  58, 620 },
 {  59, 620 }, {  60, 620 }, {  61, 620 }, {  62, 620 }, {  63, 620 },
 {  64, 620 }, {  65, 620 }, {  66, 620 }, {  67, 620 }, {  68, 620 },
 {  69, 620 }, {  70, 620 }, {  71, 620 }, {  72, 620 }, {  73, 620 },

 {  74, 620 }, {  75, 620 }, {  76, 620 }, {  77, 620 }, {  78, 620 },
 {  79, 620 }, {  80, 620 }, {  81, 620 }, {  82, 620 }, {  83, 620 },
 {  84, 620 }, {  85, 620 }, {  86, 620 }, {  87, 620 }, {  88, 620 },
 {  89, 620 }, {  90, 620 }, {  91, 620 }, {  92, 620 }, {  93, 620 },
 {  94, 620 }, {  95, 620 }, {  96, 620 }, {  97, 620 }, {  98, 620 },
 {  99, 620 }, { 100, 620 }, { 101, 620 }, { 102, 620 }, { 103, 620 },
 { 104, 620 }, { 105, 620 }, { 106, 620 }, { 107, 620 }, { 108, 620 },
 { 109, 620 }, { 110, 620 }, { 111, 620 }, { 112, 620 }, { 113, 620 },
 { 114, 620 }, { 115, 620 }, { 116, 620 }, { 117, 620 }, { 118, 620 },
 { 119, 620 }, { 120, 620 }, { 121, 620 }, { 122, 620 }, { 123, 620 },

 { 124, 620 }, { 125, 620 }, { 126, 620 }, { 127, 620 }, { 128, 620 },
 { 129, 620 }, { 130, 620 }, { 131, 620 }, { 132, 620 }, { 133, 620 },
 { 134, 620 }, { 135, 620 }, { 136, 620 }, { 137, 620 }, { 138, 620 },
 { 139, 620 }, { 140, 620 }, { 141, 620 }, { 142, 620 }, { 143, 620 },
 { 144, 620 }, { 145, 620 }, { 146, 620 }, { 147, 620 }, { 148, 620 },
 { 149, 620 }, { 150, 620 }, { 151, 620 }, { 152, 620 }, { 153, 620 },
 { 154, 620 }, { 155, 620 }, { 156, 620 }, { 157, 620 }, { 158, 620 },
 { 159, 620 }, { 160, 620 }, { 161, 620 }, { 162, 620 }, { 163, 620 },
 { 164, 620 }, { 165, 620 }, { 166, 620 }, { 167, 620 }, { 168, 620 },
 { 169, 620 }, { 170, 620 }, { 171, 620 }, { 172, 620 }, { 173, 620 },

 { 174, 620 }, { 175, 620 }, { 176, 620 }, { 177, 620 }, { 178, 620 },
 { 179, 620 }, { 180, 620 }, { 181, 620 }, { 182, 620 }, { 183, 620 },
 { 184, 620 }, { 185, 620 }, { 186, 620 }, { 187, 620 }, { 188, 620 },
 { 189, 620 }, { 190, 620 }, { 191, 620 }, { 192, 620 }, { 193, 620 },
 { 194, 620 }, { 195, 620 }, { 196, 620 }, { 197, 620 }, { 198, 620 },
 { 199, 620 }, { 200, 620 }, { 201, 620 }, { 202, 620 }, { 203, 620 },
 { 204, 620 }, { 205, 620 }, { 206, 620 }, { 207, 620 }, { 208, 620 },
 { 209, 620 }, { 210, 620 }, { 211, 620 }, { 212, 620 }, { 213, 620 },
 { 214, 620 }, { 215, 620 }, { 216, 620 }, { 217, 620 }, { 218, 620 },
 { 219, 620 }, { 220, 620 }, { 221, 620 }, { 222, 620 }, { 223, 620 },

 { 224, 620 }, { 225, 620 }, { 226, 620 }, { 227, 620 }, { 228, 620 },
 { 229, 620 }, { 230, 620 }, { 231, 620 }, { 232, 620 }, { 233, 620 },
 { 234, 620 }, { 235, 620 }, { 236, 620 }, { 237, 620 }, { 238, 620 },
 { 239, 620 }, { 240, 620 }, { 241, 620 }, { 242, 620 }, { 243, 620 },
 { 244, 620 }, { 245, 620 }, { 246, 620 }, { 247, 620 }, { 248, 620 },
 { 249, 620 }, { 250, 620 }, { 251, 620 }, { 252, 620 }, { 253, 620 },
 { 254, 620 }, { 255, 620 }, { 256, 620 }, {   0,  28 }, {   0,5616 },
 {   1,1394 }, {   2,1394 }, {   3,1394 }, {   4,1394 }, {   5,1394 },
 {   6,1394 }, {   7,1394 }, {   8,1394 }, {   9,1652 }, {  10,-690 },
 {  11,1394 }, {  12,1652 }, {  13,-690 }, {  14,1394 }, {  15,1394 },

 {  16,1394 }, {  17,1394 }, {  18,1394 }, {  19,1394 }, {  20,1394 },
 {  21,1394 }, {  22,1394 }, {  23,1394 }, {  24,1394 }, {  25,1394 },
 {  26,1394 }, {  27,1394 }, {  28,1394 }, {  29,1394 }, {  30,1394 },
 {  31,1394 }, {  32,1652 }, {  33,1394 }, {  34,1394 }, {  35,1394 },
 {  36,1394 }, {  37,1394 }, {  38,1394 }, {  39,1910 }, {  40,1394 },
 {  41,1394 }, {  42,1394 }, {  43,1394 }, {  44,1394 }, {  45,2168 },
 {  46,1394 }, {  47,1394 }, {  48,1394 }, {  49,1394 }, {  50,1394 },
 {  51,1394 }, {  52,1394 }, {  53,1394 }, {  54,1394 }, {  55,1394 },
 {  56,1394 }, {  57,1394 }, {  58,1394 }, {  59,1394 }, {  60,1394 },
 {  61,1394 }, {  62,1394 }, {  63,1394 }, {  64,1394 }, {  65,1394 },

 {  66,1394 }, {  67,1394 }, {  68,1394 }, {  69,1394 }, {  70,1394 },
 {  71,1394 }, {  72,1394 }, {  73,1394 }, {  74,1394 }, {  75,1394 },
 {  76,1394 }, {  77,1394 }, {  78,1394 }, {  79,1394 }, {  80,1394 },
 {  81,1394 }, {  82,1394 }, {  83,1394 }, {  84,1394 }, {  85,1394 },
 {  86,1394 }, {  87,1394 }, {  88,1394 }, {  89,1394 }, {  90,1394 },
 {  91,1394 }, {  92,1394 }, {  93,1394 }, {  94,1394 }, {  95,1394 },
 {  96,1394 }, {  97,1394 }, {  98,1394 }, {  99,1394 }, { 100,1394 },
 { 101,1394 }, { 102,1394 }, { 103,1394 }, { 104,1394 }, { 105,1394 },
 { 106,1394 }, { 107,1394 }, { 108,1394 }, { 109,1394 }, { 110,1394 },
 { 111,1394 }, { 112,1394 }, { 113,1394 }, { 114,1394 }, { 115,1394 },

 { 116,1394 }, { 117,1394 }, { 118,1394 }, { 119,1394 }, { 120,1394 },
 { 121,1394 }, { 122,1394 }, { 123,1394 }, { 124,1394 }, { 125,1394 },
 { 126,1394 }, { 127,1394 }, { 128,1394 }, { 129,1394 }, { 130,1394 },
 { 131,1394 }, { 132,1394 }, { 133,1394 }, { 134,1394 }, { 135,1394 },
 { 136,1394 }, { 137,1394 }, { 138,1394 }, { 139,1394 }, { 140,1394 },
 { 141,1394 }, { 142,1394 }, { 143,1394 }, { 144,1394 }, { 145,1394 },
 { 146,1394 }, { 147,1394 }, { 148,1394 }, { 149,1394 }, { 150,1394 },
 { 151,1394 }, { 152,1394 }, { 153,1394 }, { 154,1394 }, { 155,1394 },
 { 156,1394 }, { 157,1394 }, { 158,1394 }, { 159,1394 }, { 160,1394 },
 { 161,1394 }, { 162,1394 }, { 163,1394 }, { 164,1394 }, { 165,1394 },

 { 166,1394 }, { 167,1394 }, { 168,1394 }, { 169,1394 }, { 170,1394 },
 { 171,1394 }, { 172,1394 }, { 173,1394 }, { 174,1394 }, { 175,1394 },
 { 176,1394 }, { 177,1394 }, { 178,1394 }, { 179,1394 }, { 180,1394 },
 { 181,1394 }, { 182,1394 }, { 183,1394 }, { 184,1394 }, { 185,1394 },
 { 186,1394 }, { 187,1394 }, { 188,1394 }, { 189,1394 }, { 190,1394 },
 { 191,1394 }, { 192,1394 }, { 193,1394 }, { 194,1394 }, { 195,1394 },
 { 196,1394 }, { 197,1394 }, { 198,1394 }, { 199,1394 }, { 200,1394 },
 { 201,1394 }, { 202,1394 }, { 203,1394 }, { 204,1394 }, { 205,1394 },
 { 206,1394 }, { 207,1394 }, { 208,1394 }, { 209,1394 }, { 210,1394 },
 { 211,1394 }, { 212,1394 }, { 213,1394 }, { 214,1394 }, { 215,1394 },

 { 216,1394 }, { 217,1394 }, { 218,1394 }, { 219,1394 }, { 220,1394 },
 { 221,1394 }, { 222,1394 }, { 223,1394 }, { 224,1394 }, { 225,1394 },
 { 226,1394 }, { 227,1394 }, { 228,1394 }, { 229,1394 }, { 230,1394 },
 { 231,1394 }, { 232,1394 }, { 233,1394 }, { 234,1394 }, { 235,1394 },
 { 236,1394 }, { 237,1394 }, { 238,1394 }, { 239,1394 }, { 240,1394 },
 { 241,1394 }, { 242,1394 }, { 243,1394 }, { 244,1394 }, { 245,1394 },
 { 246,1394 }, { 247,1394 }, { 248,1394 }, { 249,1394 }, { 250,1394 },
 { 251,1394 }, { 252,1394 }, { 253,1394 }, { 254,1394 }, { 255,1394 },
 { 256,1394 }, {   0,  37 }, {   0,5358 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  48,-23233 }, {  49,-23233 }, {  50,-23233 }, {  51,-23233 }, {  52,-23233 },
 {  53,-23233 }, {  54,-23233 }, {  55,-23233 }, {  56,-23233 }, {  57,-23233 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  65,-23233 }, {  66,-23233 }, {  67,-23233 },
 {  68,-23233 }, {  69,-23233 }, {  70,-23233 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  97,-23233 },
 {  98,-23233 }, {  99,-23233 }, { 100,-23233 }, { 101,-23233 }, { 102,-23233 },
 {   0,  55 }, {   0,5254 }, {   1,   0 }, {   2,   0 }, {   3,   0 },

 {   4,   0 }, {   5,   0 }, {   6,   0 }, {   7,   0 }, {   8,   0 },
 {   9, 258 }, {  10,-1357 }, {  11,   0 }, {  12, 258 }, {  13,-1357 },
 {  14,   0 }, {  15,   0 }, {  16,   0 }, {  17,   0 }, {  18,   0 },
 {  19,   0 }, {  20,   0 }, {  21,   0 }, {  22,   0 }, {  23,   0 },
 {  24,   0 }, {  25,   0 }, {  26,   0 }, {  27,   0 }, {  28,   0 },
 {  29,   0 }, {  30,   0 }, {  31,   0 }, {  32, 258 }, {  33,   0 },
 {  34,   0 }, {  35,   0 }, {  36,   0 }, {  37,   0 }, {  38,   0 },
 {  39, 516 }, {  40,   0 }, {  41,   0 }, {  42,   0 }, {  43,   0 },
 {  44,   0 }, {  45, 774 }, {  46,   0 }, {  47,   0 }, {  48,   0 },
 {  49,   0 }, {  50,   0 }, {  51,   0 }, {  52,   0 }, {  53,   0 },

 {  54,   0 }, {  55,   0 }, {  56,   0 }, {  57,   0 }, {  58,   0 },
 {  59,   0 }, {  60,   0 }, {  61,   0 }, {  62,   0 }, {  63,   0 },
 {  64,   0 }, {  65,   0 }, {  66,   0 }, {  67,   0 }, {  68,   0 },
 {  69,   0 }, {  70,   0 }, {  71,   0 }, {  72,   0 }, {  73,   0 },
 {  74,   0 }, {  75,   0 }, {  76,   0 }, {  77,   0 }, {  78,   0 },
 {  79,   0 }, {  80,   0 }, {  81,   0 }, {  82,   0 }, {  83,   0 },
 {  84,   0 }, {  85,   0 }, {  86,   0 }, {  87,   0 }, {  88,   0 },
 {  89,   0 }, {  90,   0 }, {  91,   0 }, {  92,   0 }, {  93,   0 },
 {  94,   0 }, {  95,   0 }, {  96,   0 }, {  97,   0 }, {  98,   0 },
 {  99,   0 }, { 100,   0 }, { 101,   0 }, { 102,   0 }, { 103,   0 },

 { 104,   0 }, { 105,   0 }, { 106,   0 }, { 107,   0 }, { 108,   0 },
 { 109,   0 }, { 110,   0 }, { 111,   0 }, { 112,   0 }, { 113,   0 },
 { 114,   0 }, { 115,   0 }, { 116,   0 }, { 117,   0 }, { 118,   0 },
 { 119,   0 }, { 120,   0 }, { 121,   0 }, { 122,   0 }, { 123,   0 },
 { 124,   0 }, { 125,   0 }, { 126,   0 }, { 127,   0 }, { 128,   0 },
 { 129,   0 }, { 130,   0 }, { 131,   0 }, { 132,   0 }, { 133,   0 },
 { 134,   0 }, { 135,   0 }, { 136,   0 }, { 137,   0 }, { 138,   0 },
 { 139,   0 }, { 140,   0 }, { 141,   0 }, { 142,   0 }, { 143,   0 },
 { 144,   0 }, { 145,   0 }, { 146,   0 }, { 147,   0 }, { 148,   0 },
 { 149,   0 }, { 150,   0 }, { 151,   0 }, { 152,   0 }, { 153,   0 },

 { 154,   0 }, { 155,   0 }, { 156,   0 }, { 157,   0 }, { 158,   0 },
 { 159,   0 }, { 160,   0 }, { 161,   0 }, { 162,   0 }, { 163,   0 },
 { 164,   0 }, { 165,   0 }, { 166,   0 }, { 167,   0 }, { 168,   0 },
 { 169,   0 }, { 170,   0 }, { 171,   0 }, { 172,   0 }, { 173,   0 },
 { 174,   0 }, { 175,   0 }, { 176,   0 }, { 177,   0 }, { 178,   0 },
 { 179,   0 }, { 180,   0 }, { 181,   0 }, { 182,   0 }, { 183,   0 },
 { 184,   0 }, { 185,   0 }, { 186,   0 }, { 187,   0 }, { 188,   0 },
 { 189,   0 }, { 190,   0 }, { 191,   0 }, { 192,   0 }, { 193,   0 },
 { 194,   0 }, { 195,   0 }, { 196,   0 }, { 197,   0 }, { 198,   0 },
 { 199,   0 }, { 200,   0 }, { 201,   0 }, { 202,   0 }, { 203,   0 },

 { 204,   0 }, { 205,   0 }, { 206,   0 }, { 207,   0 }, { 208,   0 },
 { 209,   0 }, { 210,   0 }, { 211,   0 }, { 212,   0 }, { 213,   0 },
 { 214,   0 }, { 215,   0 }, { 216,   0 }, { 217,   0 }, { 218,   0 },
 { 219,   0 }, { 220,   0 }, { 221,   0 }, { 222,   0 }, { 223,   0 },
 { 224,   0 }, { 225,   0 }, { 226,   0 }, { 227,   0 }, { 228,   0 },
 { 229,   0 }, { 230,   0 }, { 231,   0 }, { 232,   0 }, { 233,   0 },
 { 234,   0 }, { 235,   0 }, { 236,   0 }, { 237,   0 }, { 238,   0 },
 { 239,   0 }, { 240,   0 }, { 241,   0 }, { 242,   0 }, { 243,   0 },
 { 244,   0 }, { 245,   0 }, { 246,   0 }, { 247,   0 }, { 248,   0 },
 { 249,   0 }, { 250,   0 }, { 251,   0 }, { 252,   0 }, { 253,   0 },

 { 254,   0 }, { 255,   0 }, { 256,   0 }, {   0,  55 }, {   0,4996 },
 {   1,-258 }, {   2,-258 }, {   3,-258 }, {   4,-258 }, {   5,-258 },
 {   6,-258 }, {   7,-258 }, {   8,-258 }, {   9,   0 }, {  10,-1615 },
 {  11,-258 }, {  12,   0 }, {  13,-1615 }, {  14,-258 }, {  15,-258 },
 {  16,-258 }, {  17,-258 }, {  18,-258 }, {  19,-258 }, {  20,-258 },
 {  21,-258 }, {  22,-258 }, {  23,-258 }, {  24,-258 }, {  25,-258 },
 {  26,-258 }, {  27,-258 }, {  28,-258 }, {  29,-258 }, {  30,-258 },
 {  31,-258 }, {  32,   0 }, {  33,-258 }, {  34,-258 }, {  35,-258 },
 {  36,-258 }, {  37,-258 }, {  38,-258 }, {  39, 258 }, {  40,-258 },
 {  41,-258 }, {  42,-258 }, {  43,-258 }, {  44,-258 }, {  45, 516 },

 {  46,-258 }, {  47,-258 }, {  48,-258 }, {  49,-258 }, {  50,-258 },
 {  51,-258 }, {  52,-258 }, {  53,-258 }, {  54,-258 }, {  55,-258 },
 {  56,-258 }, {  57,-258 }, {  58,-258 }, {  59,-258 }, {  60,-258 },
 {  61,-258 }, {  62,-258 }, {  63,-258 }, {  64,-258 }, {  65,-258 },
 {  66,-258 }, {  67,-258 }, {  68,-258 }, {  69,-258 }, {  70,-258 },
 {  71,-258 }, {  72,-258 }, {  73,-258 }, {  74,-258 }, {  75,-258 },
 {  76,-258 }, {  77,-258 }, {  78,-258 }, {  79,-258 }, {  80,-258 },
 {  81,-258 }, {  82,-258 }, {  83,-258 }, {  84,-258 }, {  85,-258 },
 {  86,-258 }, {  87,-258 }, {  88,-258 }, {  89,-258 }, {  90,-258 },
 {  91,-258 }, {  92,-258 }, {  93,-258 }, {  94,-258 }, {  95,-258 },

 {  96,-258 }, {  97,-258 }, {  98,-258 }, {  99,-258 }, { 100,-258 },
 { 101,-258 }, { 102,-258 }, { 103,-258 }, { 104,-258 }, { 105,-258 },
 { 106,-258 }, { 107,-258 }, { 108,-258 }, { 109,-258 }, { 110,-258 },
 { 111,-258 }, { 112,-258 }, { 113,-258 }, { 114,-258 }, { 115,-258 },
 { 116,-258 }, { 117,-258 }, { 118,-258 }, { 119,-258 }, { 120,-258 },
 { 121,-258 }, { 122,-258 }, { 123,-258 }, { 124,-258 }, { 125,-258 },
 { 126,-258 }, { 127,-258 }, { 128,-258 }, { 129,-258 }, { 130,-258 },
 { 131,-258 }, { 132,-258 }, { 133,-258 }, { 134,-258 }, { 135,-258 },
 { 136,-258 }, { 137,-258 }, { 138,-258 }, { 139,-258 }, { 140,-258 },
 { 141,-258 }, { 142,-258 }, { 143,-258 }, { 144,-258 }, { 145,-258 },

 { 146,-258 }, { 147,-258 }, { 148,-258 }, { 149,-258 }, { 150,-258 },
 { 151,-258 }, { 152,-258 }, { 153,-258 }, { 154,-258 }, { 155,-258 },
 { 156,-258 }, { 157,-258 }, { 158,-258 }, { 159,-258 }, { 160,-258 },
 { 161,-258 }, { 162,-258 }, { 163,-258 }, { 164,-258 }, { 165,-258 },
 { 166,-258 }, { 167,-258 }, { 168,-258 }, { 169,-258 }, { 170,-258 },
 { 171,-258 }, { 172,-258 }, { 173,-258 }, { 174,-258 }, { 175,-258 },
 { 176,-258 }, { 177,-258 }, { 178,-258 }, { 179,-258 }, { 180,-258 },
 { 181,-258 }, { 182,-258 }, { 183,-258 }, { 184,-258 }, { 185,-258 },
 { 186,-258 }, { 187,-258 }, { 188,-258 }, { 189,-258 }, { 190,-258 },
 { 191,-258 }, { 192,-258 }, { 193,-258 }, { 194,-258 }, { 195,-258 },

 { 196,-258 }, { 197,-258 }, { 198,-258 }, { 199,-258 }, { 200,-258 },
 { 201,-258 }, { 202,-258 }, { 203,-258 }, { 204,-258 }, { 205,-258 },
 { 206,-258 }, { 207,-258 }, { 208,-258 }, { 209,-258 }, { 210,-258 },
 { 211,-258 }, { 212,-258 }, { 213,-258 }, { 214,-258 }, { 215,-258 },
 { 216,-258 }, { 217,-258 }, { 218,-258 }, { 219,-258 }, { 220,-258 },
 { 221,-258 }, { 222,-258 }, { 223,-258 }, { 224,-258 }, { 225,-258 },
 { 226,-258 }, { 227,-258 }, { 228,-258 }, { 229,-258 }, { 230,-258 },
 { 231,-258 }, { 232,-258 }, { 233,-258 }, { 234,-258 }, { 235,-258 },
 { 236,-258 }, { 237,-258 }, { 238,-258 }, { 239,-258 }, { 240,-258 },
 { 241,-258 }, { 242,-258 }, { 243,-258 }, { 244,-258 }, { 245,-258 },

 { 246,-258 }, { 247,-258 }, { 248,-258 }, { 249,-258 }, { 250,-258 },
 { 251,-258 }, { 252,-258 }, { 253,-258 }, { 254,-258 }, { 255,-258 },
 { 256,-258 }, {   0,  55 }, {   0,4738 }, {   1,1548 }, {   2,1548 },
 {   3,1548 }, {   4,1548 }, {   5,1548 }, {   6,1548 }, {   7,1548 },
 {   8,1548 }, {   9,1806 }, {  10,2064 }, {  11,1548 }, {  12,1806 },
 {  13,2064 }, {  14,1548 }, {  15,1548 }, {  16,1548 }, {  17,1548 },
 {  18,1548 }, {  19,1548 }, {  20,1548 }, {  21,1548 }, {  22,1548 },
 {  23,1548 }, {  24,1548 }, {  25,1548 }, {  26,1548 }, {  27,1548 },
 {  28,1548 }, {  29,1548 }, {  30,1548 }, {  31,1548 }, {  32,1806 },
 {  33,1548 }, {  34,1548 }, {  35,1548 }, {  36,1548 }, {  37,1548 },

 {  38,1548 }, {  39,   0 }, {  40,1548 }, {  41,1548 }, {  42,1548 },
 {  43,1548 }, {  44,1548 }, {  45,2111 }, {  46,1548 }, {  47,1548 },
 {  48,1548 }, {  49,1548 }, {  50,1548 }, {  51,1548 }, {  52,1548 },
 {  53,1548 }, {  54,1548 }, {  55,1548 }, {  56,1548 }, {  57,1548 },
 {  58,1548 }, {  59,1548 }, {  60,1548 }, {  61,1548 }, {  62,1548 },
 {  63,1548 }, {  64,1548 }, {  65,1548 }, {  66,1548 }, {  67,1548 },
 {  68,1548 }, {  69,1548 }, {  70,1548 }, {  71,1548 }, {  72,1548 },
 {  73,1548 }, {  74,1548 }, {  75,1548 }, {  76,1548 }, {  77,1548 },
 {  78,1548 }, {  79,1548 }, {  80,1548 }, {  81,1548 }, {  82,1548 },
 {  83,1548 }, {  84,1548 }, {  85,1548 }, {  86,1548 }, {  87,1548 },

 {  88,1548 }, {  89,1548 }, {  90,1548 }, {  91,1548 }, {  92,1548 },
 {  93,1548 }, {  94,1548 }, {  95,1548 }, {  96,1548 }, {  97,1548 },
 {  98,1548 }, {  99,1548 }, { 100,1548 }, { 101,1548 }, { 102,1548 },
 { 103,1548 }, { 104,1548 }, { 105,1548 }, { 106,1548 }, { 107,1548 },
 { 108,1548 }, { 109,1548 }, { 110,1548 }, { 111,1548 }, { 112,1548 },
 { 113,1548 }, { 114,1548 }, { 115,1548 }, { 116,1548 }, { 117,1548 },
 { 118,1548 }, { 119,1548 }, { 120,1548 }, { 121,1548 }, { 122,1548 },
 { 123,1548 }, { 124,1548 }, { 125,1548 }, { 126,1548 }, { 127,1548 },
 { 128,1548 }, { 129,1548 }, { 130,1548 }, { 131,1548 }, { 132,1548 },
 { 133,1548 }, { 134,1548 }, { 135,1548 }, { 136,1548 }, { 137,1548 },

 { 138,1548 }, { 139,1548 }, { 140,1548 }, { 141,1548 }, { 142,1548 },
 { 143,1548 }, { 144,1548 }, { 145,1548 }, { 146,1548 }, { 147,1548 },
 { 148,1548 }, { 149,1548 }, { 150,1548 }, { 151,1548 }, { 152,1548 },
 { 153,1548 }, { 154,1548 }, { 155,1548 }, { 156,1548 }, { 157,1548 },
 { 158,1548 }, { 159,1548 }, { 160,1548 }, { 161,1548 }, { 162,1548 },
 { 163,1548 }, { 164,1548 }, { 165,1548 }, { 166,1548 }, { 167,1548 },
 { 168,1548 }, { 169,1548 }, { 170,1548 }, { 171,1548 }, { 172,1548 },
 { 173,1548 }, { 174,1548 }, { 175,1548 }, { 176,1548 }, { 177,1548 },
 { 178,1548 }, { 179,1548 }, { 180,1548 }, { 181,1548 }, { 182,1548 },
 { 183,1548 }, { 184,1548 }, { 185,1548 }, { 186,1548 }, { 187,1548 },

 { 188,1548 }, { 189,1548 }, { 190,1548 }, { 191,1548 }, { 192,1548 },
 { 193,1548 }, { 194,1548 }, { 195,1548 }, { 196,1548 }, { 197,1548 },
 { 198,1548 }, { 199,1548 }, { 200,1548 }, { 201,1548 }, { 202,1548 },
 { 203,1548 }, { 204,1548 }, { 205,1548 }, { 206,1548 }, { 207,1548 },
 { 208,1548 }, { 209,1548 }, { 210,1548 }, { 211,1548 }, { 212,1548 },
 { 213,1548 }, { 214,1548 }, { 215,1548 }, { 216,1548 }, { 217,1548 },
 { 218,1548 }, { 219,1548 }, { 220,1548 }, { 221,1548 }, { 222,1548 },
 { 223,1548 }, { 224,1548 }, { 225,1548 }, { 226,1548 }, { 227,1548 },
 { 228,1548 }, { 229,1548 }, { 230,1548 }, { 231,1548 }, { 232,1548 },
 { 233,1548 }, { 234,1548 }, { 235,1548 }, { 236,1548 }, { 237,1548 },

 { 238,1548 }, { 239,1548 }, { 240,1548 }, { 241,1548 }, { 242,1548 },
 { 243,1548 }, { 244,1548 }, { 245,1548 }, { 246,1548 }, { 247,1548 },
 { 248,1548 }, { 249,1548 }, { 250,1548 }, { 251,1548 }, { 252,1548 },
 { 253,1548 }, { 254,1548 }, { 255,1548 }, { 256,1548 }, {   0,  55 },
 {   0,4480 }, {   1,-774 }, {   2,-774 }, {   3,-774 }, {   4,-774 },
 {   5,-774 }, {   6,-774 }, {   7,-774 }, {   8,-774 }, {   9,-516 },
 {  10,-2131 }, {  11,-774 }, {  12,-516 }, {  13,-2131 }, {  14,-774 },
 {  15,-774 }, {  16,-774 }, {  17,-774 }, {  18,-774 }, {  19,-774 },
 {  20,-774 }, {  21,-774 }, {  22,-774 }, {  23,-774 }, {  24,-774 },
 {  25,-774 }, {  26,-774 }, {  27,-774 }, {  28,-774 }, {  29,-774 },

 {  30,-774 }, {  31,-774 }, {  32,-516 }, {  33,-774 }, {  34,-774 },
 {  35,-774 }, {  36,-774 }, {  37,-774 }, {  38,-774 }, {  39,-258 },
 {  40,-774 }, {  41,-774 }, {  42,-774 }, {  43,-774 }, {  44,-774 },
 {  45,2111 }, {  46,-774 }, {  47,-774 }, {  48,-774 }, {  49,-774 },
 {  50,-774 }, {  51,-774 }, {  52,-774 }, {  53,-774 }, {  54,-774 },
 {  55,-774 }, {  56,-774 }, {  57,-774 }, {  58,-774 }, {  59,-774 },
 {  60,-774 }, {  61,-774 }, {  62,-774 }, {  63,-774 }, {  64,-774 },
 {  65,-774 }, {  66,-774 }, {  67,-774 }, {  68,-774 }, {  69,-774 },
 {  70,-774 }, {  71,-774 }, {  72,-774 }, {  73,-774 }, {  74,-774 },
 {  75,-774 }, {  76,-774 }, {  77,-774 }, {  78,-774 }, {  79,-774 },

 {  80,-774 }, {  81,-774 }, {  82,-774 }, {  83,-774 }, {  84,-774 },
 {  85,-774 }, {  86,-774 }, {  87,-774 }, {  88,-774 }, {  89,-774 },
 {  90,-774 }, {  91,-774 }, {  92,-774 }, {  93,-774 }, {  94,-774 },
 {  95,-774 }, {  96,-774 }, {  97,-774 }, {  98,-774 }, {  99,-774 },
 { 100,-774 }, { 101,-774 }, { 102,-774 }, { 103,-774 }, { 104,-774 },
 { 105,-774 }, { 106,-774 }, { 107,-774 }, { 108,-774 }, { 109,-774 },
 { 110,-774 }, { 111,-774 }, { 112,-774 }, { 113,-774 }, { 114,-774 },
 { 115,-774 }, { 116,-774 }, { 117,-774 }, { 118,-774 }, { 119,-774 },
 { 120,-774 }, { 121,-774 }, { 122,-774 }, { 123,-774 }, { 124,-774 },
 { 125,-774 }, { 126,-774 }, { 127,-774 }, { 128,-774 }, { 129,-774 },

 { 130,-774 }, { 131,-774 }, { 132,-774 }, { 133,-774 }, { 134,-774 },
 { 135,-774 }, { 136,-774 }, { 137,-774 }, { 138,-774 }, { 139,-774 },
 { 140,-774 }, { 141,-774 }, { 142,-774 }, { 143,-774 }, { 144,-774 },
 { 145,-774 }, { 146,-774 }, { 147,-774 }, { 148,-774 }, { 149,-774 },
 { 150,-774 }, { 151,-774 }, { 152,-774 }, { 153,-774 }, { 154,-774 },
 { 155,-774 }, { 156,-774 }, { 157,-774 }, { 158,-774 }, { 159,-774 },
 { 160,-774 }, { 161,-774 }, { 162,-774 }, { 163,-774 }, { 164,-774 },
 { 165,-774 }, { 166,-774 }, { 167,-774 }, { 168,-774 }, { 169,-774 },
 { 170,-774 }, { 171,-774 }, { 172,-774 }, { 173,-774 }, { 174,-774 },
 { 175,-774 }, { 176,-774 }, { 177,-774 }, { 178,-774 }, { 179,-774 },

 { 180,-774 }, { 181,-774 }, { 182,-774 }, { 183,-774 }, { 184,-774 },
 { 185,-774 }, { 186,-774 }, { 187,-774 }, { 188,-774 }, { 189,-774 },
 { 190,-774 }, { 191,-774 }, { 192,-774 }, { 193,-774 }, { 194,-774 },
 { 195,-774 }, { 196,-774 }, { 197,-774 }, { 198,-774 }, { 199,-774 },
 { 200,-774 }, { 201,-774 }, { 202,-774 }, { 203,-774 }, { 204,-774 },
 { 205,-774 }, { 206,-774 }, { 207,-774 }, { 208,-774 }, { 209,-774 },
 { 210,-774 }, { 211,-774 }, { 212,-774 }, { 213,-774 }, { 214,-774 },
 { 215,-774 }, { 216,-774 }, { 217,-774 }, { 218,-774 }, { 219,-774 },
 { 220,-774 }, { 221,-774 }, { 222,-774 }, { 223,-774 }, { 224,-774 },
 { 225,-774 }, { 226,-774 }, { 227,-774 }, { 228,-774 }, { 229,-774 },

 { 230,-774 }, { 231,-774 }, { 232,-774 }, { 233,-774 }, { 234,-774 },
 { 235,-774 }, { 236,-774 }, { 237,-774 }, { 238,-774 }, { 239,-774 },
 { 240,-774 }, { 241,-774 }, { 242,-774 }, { 243,-774 }, { 244,-774 },
 { 245,-774 }, { 246,-774 }, { 247,-774 }, { 248,-774 }, { 249,-774 },
 { 250,-774 }, { 251,-774 }, { 252,-774 }, { 253,-774 }, { 254,-774 },
 { 255,-774 }, { 256,-774 }, {   0,  28 }, {   0,4222 }, {   1,   0 },
 {   2,   0 }, {   3,   0 }, {   4,   0 }, {   5,   0 }, {   6,   0 },
 {   7,   0 }, {   8,   0 }, {   9, 258 }, {  10,-2084 }, {  11,   0 },
 {  12, 258 }, {  13,-2084 }, {  14,   0 }, {  15,   0 }, {  16,   0 },
 {  17,   0 }, {  18,   0 }, {  19,   0 }, {  20,   0 }, {  21,   0 },

 {  22,   0 }, {  23,   0 }, {  24,   0 }, {  25,   0 }, {  26,   0 },
 {  27,   0 }, {  28,   0 }, {  29,   0 }, {  30,   0 }, {  31,   0 },
 {  32, 258 }, {  33,   0 }, {  34,   0 }, {  35,   0 }, {  36,   0 },
 {  37,   0 }, {  38,   0 }, {  39, 516 }, {  40,   0 }, {  41,   0 },
 {  42,   0 }, {  43,   0 }, {  44,   0 }, {  45, 774 }, {  46,   0 },
 {  47,   0 }, {  48,   0 }, {  49,   0 }, {  50,   0 }, {  51,   0 },
 {  52,   0 }, {  53,   0 }, {  54,   0 }, {  55,   0 }, {  56,   0 },
 {  57,   0 }, {  58,   0 }, {  59,   0 }, {  60,   0 }, {  61,   0 },
 {  62,   0 }, {  63,   0 }, {  64,   0 }, {  65,   0 }, {  66,   0 },
 {  67,   0 }, {  68,   0 }, {  69,   0 }, {  70,   0 }, {  71,   0 },

 {  72,   0 }, {  73,   0 }, {  74,   0 }, {  75,   0 }, {  76,   0 },
 {  77,   0 }, {  78,   0 }, {  79,   0 }, {  80,   0 }, {  81,   0 },
 {  82,   0 }, {  83,   0 }, {  84,   0 }, {  85,   0 }, {  86,   0 },
 {  87,   0 }, {  88,   0 }, {  89,   0 }, {  90,   0 }, {  91,   0 },
 {  92,   0 }, {  93,   0 }, {  94,   0 }, {  95,   0 }, {  96,   0 },
 {  97,   0 }, {  98,   0 }, {  99,   0 }, { 100,   0 }, { 101,   0 },
 { 102,   0 }, { 103,   0 }, { 104,   0 }, { 105,   0 }, { 106,   0 },
 { 107,   0 }, { 108,   0 }, { 109,   0 }, { 110,   0 }, { 111,   0 },
 { 112,   0 }, { 113,   0 }, { 114,   0 }, { 115,   0 }, { 116,   0 },
 { 117,   0 }, { 118,   0 }, { 119,   0 }, { 120,   0 }, { 121,   0 },

 { 122,   0 }, { 123,   0 }, { 124,   0 }, { 125,   0 }, { 126,   0 },
 { 127,   0 }, { 128,   0 }, { 129,   0 }, { 130,   0 }, { 131,   0 },
 { 132,   0 }, { 133,   0 }, { 134,   0 }, { 135,   0 }, { 136,   0 },
 { 137,   0 }, { 138,   0 }, { 139,   0 }, { 140,   0 }, { 141,   0 },
 { 142,   0 }, { 143,   0 }, { 144,   0 }, { 145,   0 }, { 146,   0 },
 { 147,   0 }, { 148,   0 }, { 149,   0 }, { 150,   0 }, { 151,   0 },
 { 152,   0 }, { 153,   0 }, { 154,   0 }, { 155,   0 }, { 156,   0 },
 { 157,   0 }, { 158,   0 }, { 159,   0 }, { 160,   0 }, { 161,   0 },
 { 162,   0 }, { 163,   0 }, { 164,   0 }, { 165,   0 }, { 166,   0 },
 { 167,   0 }, { 168,   0 }, { 169,   0 }, { 170,   0 }, { 171,   0 },

 { 172,   0 }, { 173,   0 }, { 174,   0 }, { 175,   0 }, { 176,   0 },
 { 177,   0 }, { 178,   0 }, { 179,   0 }, { 180,   0 }, { 181,   0 },
 { 182,   0 }, { 183,   0 }, { 184,   0 }, { 185,   0 }, { 186,   0 },
 { 187,   0 }, { 188,   0 }, { 189,   0 }, { 190,   0 }, { 191,   0 },
 { 192,   0 }, { 193,   0 }, { 194,   0 }, { 195,   0 }, { 196,   0 },
 { 197,   0 }, { 198,   0 }, { 199,   0 }, { 200,   0 }, { 201,   0 },
 { 202,   0 }, { 203,   0 }, { 204,   0 }, { 205,   0 }, { 206,   0 },
 { 207,   0 }, { 208,   0 }, { 209,   0 }, { 210,   0 }, { 211,   0 },
 { 212,   0 }, { 213,   0 }, { 214,   0 }, { 215,   0 }, { 216,   0 },
 { 217,   0 }, { 218,   0 }, { 219,   0 }, { 220,   0 }, { 221,   0 },

 { 222,   0 }, { 223,   0 }, { 224,   0 }, { 225,   0 }, { 226,   0 },
 { 227,   0 }, { 228,   0 }, { 229,   0 }, { 230,   0 }, { 231,   0 },
 { 232,   0 }, { 233,   0 }, { 234,   0 }, { 235,   0 }, { 236,   0 },
 { 237,   0 }, { 238,   0 }, { 239,   0 }, { 240,   0 }, { 241,   0 },
 { 242,   0 }, { 243,   0 }, { 244,   0 }, { 245,   0 }, { 246,   0 },
 { 247,   0 }, { 248,   0 }, { 249,   0 }, { 250,   0 }, { 251,   0 },
 { 252,   0 }, { 253,   0 }, { 254,   0 }, { 255,   0 }, { 256,   0 },
 {   0,  28 }, {   0,3964 }, {   1,-258 }, {   2,-258 }, {   3,-258 },
 {   4,-258 }, {   5,-258 }, {   6,-258 }, {   7,-258 }, {   8,-258 },
 {   9,   0 }, {  10,-2342 }, {  11,-258 }, {  12,   0 }, {  13,-2342 },

 {  14,-258 }, {  15,-258 }, {  16,-258 }, {  17,-258 }, {  18,-258 },
 {  19,-258 }, {  20,-258 }, {  21,-258 }, {  22,-258 }, {  23,-258 },
 {  24,-258 }, {  25,-258 }, {  26,-258 }, {  27,-258 }, {  28,-258 },
 {  29,-258 }, {  30,-258 }, {  31,-258 }, {  32,   0 }, {  33,-258 },
 {  34,-258 }, {  35,-258 }, {  36,-258 }, {  37,-258 }, {  38,-258 },
 {  39, 258 }, {  40,-258 }, {  41,-258 }, {  42,-258 }, {  43,-258 },
 {  44,-258 }, {  45, 516 }, {  46,-258 }, {  47,-258 }, {  48,-258 },
 {  49,-258 }, {  50,-258 }, {  51,-258 }, {  52,-258 }, {  53,-258 },
 {  54,-258 }, {  55,-258 }, {  56,-258 }, {  57,-258 }, {  58,-258 },
 {  59,-258 }, {  60,-258 }, {  61,-258 }, {  62,-258 }, {  63,-258 },

 {  64,-258 }, {  65,-258 }, {  66,-258 }, {  67,-258 }, {  68,-258 },
 {  69,-258 }, {  70,-258 }, {  71,-258 }, {  72,-258 }, {  73,-258 },
 {  74,-258 }, {  75,-258 }, {  76,-258 }, {  77,-258 }, {  78,-258 },
 {  79,-258 }, {  80,-258 }, {  81,-258 }, {  82,-258 }, {  83,-258 },
 {  84,-258 }, {  85,-258 }, {  86,-258 }, {  87,-258 }, {  88,-258 },
 {  89,-258 }, {  90,-258 }, {  91,-258 }, {  92,-258 }, {  93,-258 },
 {  94,-258 }, {  95,-258 }, {  96,-258 }, {  97,-258 }, {  98,-258 },
 {  99,-258 }, { 100,-258 }, { 101,-258 }, { 102,-258 }, { 103,-258 },
 { 104,-258 }, { 105,-258 }, { 106,-258 }, { 107,-258 }, { 108,-258 },
 { 109,-258 }, { 110,-258 }, { 111,-258 }, { 112,-258 }, { 113,-258 },

 { 114,-258 }, { 115,-258 }, { 116,-258 }, { 117,-258 }, { 118,-258 },
 { 119,-258 }, { 120,-258 }, { 121,-258 }, { 122,-258 }, { 123,-258 },
 { 124,-258 }, { 125,-258 }, { 126,-258 }, { 127,-258 }, { 128,-258 },
 { 129,-258 }, { 130,-258 }, { 131,-258 }, { 132,-258 }, { 133,-258 },
 { 134,-258 }, { 135,-258 }, { 136,-258 }, { 137,-258 }, { 138,-258 },
 { 139,-258 }, { 140,-258 }, { 141,-258 }, { 142,-258 }, { 143,-258 },
 { 144,-258 }, { 145,-258 }, { 146,-258 }, { 147,-258 }, { 148,-258 },
 { 149,-258 }, { 150,-258 }, { 151,-258 }, { 152,-258 }, { 153,-258 },
 { 154,-258 }, { 155,-258 }, { 156,-258 }, { 157,-258 }, { 158,-258 },
 { 159,-258 }, { 160,-258 }, { 161,-258 }, { 162,-258 }, { 163,-258 },

 { 164,-258 }, { 165,-258 }, { 166,-258 }, { 167,-258 }, { 168,-258 },
 { 169,-258 }, { 170,-258 }, { 171,-258 }, { 172,-258 }, { 173,-258 },
 { 174,-258 }, { 175,-258 }, { 176,-258 }, { 177,-258 }, { 178,-258 },
 { 179,-258 }, { 180,-258 }, { 181,-258 }, { 182,-258 }, { 183,-258 },
 { 184,-258 }, { 185,-258 }, { 186,-258 }, { 187,-258 }, { 188,-258 },
 { 189,-258 }, { 190,-258 }, { 191,-258 }, { 192,-258 }, { 193,-258 },
 { 194,-258 }, { 195,-258 }, { 196,-258 }, { 197,-258 }, { 198,-258 },
 { 199,-258 }, { 200,-258 }, { 201,-258 }, { 202,-258 }, { 203,-258 },
 { 204,-258 }, { 205,-258 }, { 206,-258 }, { 207,-258 }, { 208,-258 },
 { 209,-258 }, { 210,-258 }, { 211,-258 }, { 212,-258 }, { 213,-258 },

 { 214,-258 }, { 215,-258 }, { 216,-258 }, { 217,-258 }, { 218,-258 },
 { 219,-258 }, { 220,-258 }, { 221,-258 }, { 222,-258 }, { 223,-258 },
 { 224,-258 }, { 225,-258 }, { 226,-258 }, { 227,-258 }, { 228,-258 },
 { 229,-258 }, { 230,-258 }, { 231,-258 }, { 232,-258 }, { 233,-258 },
 { 234,-258 }, { 235,-258 }, { 236,-258 }, { 237,-258 }, { 238,-258 },
 { 239,-258 }, { 240,-258 }, { 241,-258 }, { 242,-258 }, { 243,-258 },
 { 244,-258 }, { 245,-258 }, { 246,-258 }, { 247,-258 }, { 248,-258 },
 { 249,-258 }, { 250,-258 }, { 251,-258 }, { 252,-258 }, { 253,-258 },
 { 254,-258 }, { 255,-258 }, { 256,-258 }, {   0,  28 }, {   0,3706 },
 {   1,1595 }, {   2,1595 }, {   3,1595 }, {   4,1595 }, {   5,1595 },

 {   6,1595 }, {   7,1595 }, {   8,1595 }, {   9,1853 }, {  10,2111 },
 {  11,1595 }, {  12,1853 }, {  13,2111 }, {  14,1595 }, {  15,1595 },
 {  16,1595 }, {  17,1595 }, {  18,1595 }, {  19,1595 }, {  20,1595 },
 {  21,1595 }, {  22,1595 }, {  23,1595 }, {  24,1595 }, {  25,1595 },
 {  26,1595 }, {  27,1595 }, {  28,1595 }, {  29,1595 }, {  30,1595 },
 {  31,1595 }, {  32,1853 }, {  33,1595 }, {  34,1595 }, {  35,1595 },
 {  36,1595 }, {  37,1595 }, {  38,1595 }, {  39,   0 }, {  40,1595 },
 {  41,1595 }, {  42,1595 }, {  43,1595 }, {  44,1595 }, {  45,2158 },
 {  46,1595 }, {  47,1595 }, {  48,1595 }, {  49,1595 }, {  50,1595 },
 {  51,1595 }, {  52,1595 }, {  53,1595 }, {  54,1595 }, {  55,1595 },

 {  56,1595 }, {  57,1595 }, {  58,1595 }, {  59,1595 }, {  60,1595 },
 {  61,1595 }, {  62,1595 }, {  63,1595 }, {  64,1595 }, {  65,1595 },
 {  66,1595 }, {  67,1595 }, {  68,1595 }, {  69,1595 }, {  70,1595 },
 {  71,1595 }, {  72,1595 }, {  73,1595 }, {  74,1595 }, {  75,1595 },
 {  76,1595 }, {  77,1595 }, {  78,1595 }, {  79,1595 }, {  80,1595 },
 {  81,1595 }, {  82,1595 }, {  83,1595 }, {  84,1595 }, {  85,1595 },
 {  86,1595 }, {  87,1595 }, {  88,1595 }, {  89,1595 }, {  90,1595 },
 {  91,1595 }, {  92,1595 }, {  93,1595 }, {  94,1595 }, {  95,1595 },
 {  96,1595 }, {  97,1595 }, {  98,1595 }, {  99,1595 }, { 100,1595 },
 { 101,1595 }, { 102,1595 }, { 103,1595 }, { 104,1595 }, { 105,1595 },

 { 106,1595 }, { 107,1595 }, { 108,1595 }, { 109,1595 }, { 110,1595 },
 { 111,1595 }, { 112,1595 }, { 113,1595 }, { 114,1595 }, { 115,1595 },
 { 116,1595 }, { 117,1595 }, { 118,1595 }, { 119,1595 }, { 120,1595 },
 { 121,1595 }, { 122,1595 }, { 123,1595 }, { 124,1595 }, { 125,1595 },
 { 126,1595 }, { 127,1595 }, { 128,1595 }, { 129,1595 }, { 130,1595 },
 { 131,1595 }, { 132,1595 }, { 133,1595 }, { 134,1595 }, { 135,1595 },
 { 136,1595 }, { 137,1595 }, { 138,1595 }, { 139,1595 }, { 140,1595 },
 { 141,1595 }, { 142,1595 }, { 143,1595 }, { 144,1595 }, { 145,1595 },
 { 146,1595 }, { 147,1595 }, { 148,1595 }, { 149,1595 }, { 150,1595 },
 { 151,1595 }, { 152,1595 }, { 153,1595 }, { 154,1595 }, { 155,1595 },

 { 156,1595 }, { 157,1595 }, { 158,1595 }, { 159,1595 }, { 160,1595 },
 { 161,1595 }, { 162,1595 }, { 163,1595 }, { 164,1595 }, { 165,1595 },
 { 166,1595 }, { 167,1595 }, { 168,1595 }, { 169,1595 }, { 170,1595 },
 { 171,1595 }, { 172,1595 }, { 173,1595 }, { 174,1595 }, { 175,1595 },
 { 176,1595 }, { 177,1595 }, { 178,1595 }, { 179,1595 }, { 180,1595 },
 { 181,1595 }, { 182,1595 }, { 183,1595 }, { 184,1595 }, { 185,1595 },
 { 186,1595 }, { 187,1595 }, { 188,1595 }, { 189,1595 }, { 190,1595 },
 { 191,1595 }, { 192,1595 }, { 193,1595 }, { 194,1595 }, { 195,1595 },
 { 196,1595 }, { 197,1595 }, { 198,1595 }, { 199,1595 }, { 200,1595 },
 { 201,1595 }, { 202,1595 }, { 203,1595 }, { 204,1595 }, { 205,1595 },

 { 206,1595 }, { 207,1595 }, { 208,1595 }, { 209,1595 }, { 210,1595 },
 { 211,1595 }, { 212,1595 }, { 213,1595 }, { 214,1595 }, { 215,1595 },
 { 216,1595 }, { 217,1595 }, { 218,1595 }, { 219,1595 }, { 220,1595 },
 { 221,1595 }, { 222,1595 }, { 223,1595 }, { 224,1595 }, { 225,1595 },
 { 226,1595 }, { 227,1595 }, { 228,1595 }, { 229,1595 }, { 230,1595 },
 { 231,1595 }, { 232,1595 }, { 233,1595 }, { 234,1595 }, { 235,1595 },
 { 236,1595 }, { 237,1595 }, { 238,1595 }, { 239,1595 }, { 240,1595 },
 { 241,1595 }, { 242,1595 }, { 243,1595 }, { 244,1595 }, { 245,1595 },
 { 246,1595 }, { 247,1595 }, { 248,1595 }, { 249,1595 }, { 250,1595 },
 { 251,1595 }, { 252,1595 }, { 253,1595 }, { 254,1595 }, { 255,1595 },

 { 256,1595 }, {   0,  28 }, {   0,3448 }, {   1,-774 }, {   2,-774 },
 {   3,-774 }, {   4,-774 }, {   5,-774 }, {   6,-774 }, {   7,-774 },
 {   8,-774 }, {   9,-516 }, {  10,-2858 }, {  11,-774 }, {  12,-516 },
 {  13,-2858 }, {  14,-774 }, {  15,-774 }, {  16,-774 }, {  17,-774 },
 {  18,-774 }, {  19,-774 }, {  20,-774 }, {  21,-774 }, {  22,-774 },
 {  23,-774 }, {  24,-774 }, {  25,-774 }, {  26,-774 }, {  27,-774 },
 {  28,-774 }, {  29,-774 }, {  30,-774 }, {  31,-774 }, {  32,-516 },
 {  33,-774 }, {  34,-774 }, {  35,-774 }, {  36,-774 }, {  37,-774 },
 {  38,-774 }, {  39,-258 }, {  40,-774 }, {  41,-774 }, {  42,-774 },
 {  43,-774 }, {  44,-774 }, {  45,2158 }, {  46,-774 }, {  47,-774 },

 {  48,-774 }, {  49,-774 }, {  50,-774 }, {  51,-774 }, {  52,-774 },
 {  53,-774 }, {  54,-774 }, {  55,-774 }, {  56,-774 }, {  57,-774 },
 {  58,-774 }, {  59,-774 }, {  60,-774 }, {  61,-774 }, {  62,-774 },
 {  63,-774 }, {  64,-774 }, {  65,-774 }, {  66,-774 }, {  67,-774 },
 {  68,-774 }, {  69,-774 }, {  70,-774 }, {  71,-774 }, {  72,-774 },
 {  73,-774 }, {  74,-774 }, {  75,-774 }, {  76,-774 }, {  77,-774 },
 {  78,-774 }, {  79,-774 }, {  80,-774 }, {  81,-774 }, {  82,-774 },
 {  83,-774 }, {  84,-774 }, {  85,-774 }, {  86,-774 }, {  87,-774 },
 {  88,-774 }, {  89,-774 }, {  90,-774 }, {  91,-774 }, {  92,-774 },
 {  93,-774 }, {  94,-774 }, {  95,-774 }, {  96,-774 }, {  97,-774 },

 {  98,-774 }, {  99,-774 }, { 100,-774 }, { 101,-774 }, { 102,-774 },
 { 103,-774 }, { 104,-774 }, { 105,-774 }, { 106,-774 }, { 107,-774 },
 { 108,-774 }, { 109,-774 }, { 110,-774 }, { 111,-774 }, { 112,-774 },
 { 113,-774 }, { 114,-774 }, { 115,-774 }, { 116,-774 }, { 117,-774 },
 { 118,-774 }, { 119,-774 }, { 120,-774 }, { 121,-774 }, { 122,-774 },
 { 123,-774 }, { 124,-774 }, { 125,-774 }, { 126,-774 }, { 127,-774 },
 { 128,-774 }, { 129,-774 }, { 130,-774 }, { 131,-774 }, { 132,-774 },
 { 133,-774 }, { 134,-774 }, { 135,-774 }, { 136,-774 }, { 137,-774 },
 { 138,-774 }, { 139,-774 }, { 140,-774 }, { 141,-774 }, { 142,-774 },
 { 143,-774 }, { 144,-774 }, { 145,-774 }, { 146,-774 }, { 147,-774 },

 { 148,-774 }, { 149,-774 }, { 150,-774 }, { 151,-774 }, { 152,-774 },
 { 153,-774 }, { 154,-774 }, { 155,-774 }, { 156,-774 }, { 157,-774 },
 { 158,-774 }, { 159,-774 }, { 160,-774 }, { 161,-774 }, { 162,-774 },
 { 163,-774 }, { 164,-774 }, { 165,-774 }, { 166,-774 }, { 167,-774 },
 { 168,-774 }, { 169,-774 }, { 170,-774 }, { 171,-774 }, { 172,-774 },
 { 173,-774 }, { 174,-774 }, { 175,-774 }, { 176,-774 }, { 177,-774 },
 { 178,-774 }, { 179,-774 }, { 180,-774 }, { 181,-774 }, { 182,-774 },
 { 183,-774 }, { 184,-774 }, { 185,-774 }, { 186,-774 }, { 187,-774 },
 { 188,-774 }, { 189,-774 }, { 190,-774 }, { 191,-774 }, { 192,-774 },
 { 193,-774 }, { 194,-774 }, { 195,-774 }, { 196,-774 }, { 197,-774 },

 { 198,-774 }, { 199,-774 }, { 200,-774 }, { 201,-774 }, { 202,-774 },
 { 203,-774 }, { 204,-774 }, { 205,-774 }, { 206,-774 }, { 207,-774 },
 { 208,-774 }, { 209,-774 }, { 210,-774 }, { 211,-774 }, { 212,-774 },
 { 213,-774 }, { 214,-774 }, { 215,-774 }, { 216,-774 }, { 217,-774 },
 { 218,-774 }, { 219,-774 }, { 220,-774 }, { 221,-774 }, { 222,-774 },
 { 223,-774 }, { 224,-774 }, { 225,-774 }, { 226,-774 }, { 227,-774 },
 { 228,-774 }, { 229,-774 }, { 230,-774 }, { 231,-774 }, { 232,-774 },
 { 233,-774 }, { 234,-774 }, { 235,-774 }, { 236,-774 }, { 237,-774 },
 { 238,-774 }, { 239,-774 }, { 240,-774 }, { 241,-774 }, { 242,-774 },
 { 243,-774 }, { 244,-774 }, { 245,-774 }, { 246,-774 }, { 247,-774 },

 { 248,-774 }, { 249,-774 }, { 250,-774 }, { 251,-774 }, { 252,-774 },
 { 253,-774 }, { 254,-774 }, { 255,-774 }, { 256,-774 }, {   0,  55 },
 {   0,3190 }, {   1,-2064 }, {   2,-2064 }, {   3,-2064 }, {   4,-2064 },
 {   5,-2064 }, {   6,-2064 }, {   7,-2064 }, {   8,-2064 }, {   9,-1806 },
 {  10,-3421 }, {  11,-2064 }, {  12,-1806 }, {  13,-3421 }, {  14,-2064 },
 {  15,-2064 }, {  16,-2064 }, {  17,-2064 }, {  18,-2064 }, {  19,-2064 },
 {  20,-2064 }, {  21,-2064 }, {  22,-2064 }, {  23,-2064 }, {  24,-2064 },
 {  25,-2064 }, {  26,-2064 }, {  27,-2064 }, {  28,-2064 }, {  29,-2064 },
 {  30,-2064 }, {  31,-2064 }, {  32,-1806 }, {  33,-2064 }, {  34,-2064 },
 {  35,-2064 }, {  36,-2064 }, {  37,-2064 }, {  38,-2064 }, {  39,2158 },

 {  40,-2064 }, {  41,-2064 }, {  42,-2064 }, {  43,-2064 }, {  44,-2064 },
 {  45,-1290 }, {  46,-2064 }, {  47,-2064 }, {  48,-2064 }, {  49,-2064 },
 {  50,-2064 }, {  51,-2064 }, {  52,-2064 }, {  53,-2064 }, {  54,-2064 },
 {  55,-2064 }, {  56,-2064 }, {  57,-2064 }, {  58,-2064 }, {  59,-2064 },
 {  60,-2064 }, {  61,-2064 }, {  62,-2064 }, {  63,-2064 }, {  64,-2064 },
 {  65,-2064 }, {  66,-2064 }, {  67,-2064 }, {  68,-2064 }, {  69,-2064 },
 {  70,-2064 }, {  71,-2064 }, {  72,-2064 }, {  73,-2064 }, {  74,-2064 },
 {  75,-2064 }, {  76,-2064 }, {  77,-2064 }, {  78,-2064 }, {  79,-2064 },
 {  80,-2064 }, {  81,-2064 }, {  82,-2064 }, {  83,-2064 }, {  84,-2064 },
 {  85,-2064 }, {  86,-2064 }, {  87,-2064 }, {  88,-2064 }, {  89,-2064 },

 {  90,-2064 }, {  91,-2064 }, {  92,-2064 }, {  93,-2064 }, {  94,-2064 },
 {  95,-2064 }, {  96,-2064 }, {  97,-2064 }, {  98,-2064 }, {  99,-2064 },
 { 100,-2064 }, { 101,-2064 }, { 102,-2064 }, { 103,-2064 }, { 104,-2064 },
 { 105,-2064 }, { 106,-2064 }, { 107,-2064 }, { 108,-2064 }, { 109,-2064 },
 { 110,-2064 }, { 111,-2064 }, { 112,-2064 }, { 113,-2064 }, { 114,-2064 },
 { 115,-2064 }, { 116,-2064 }, { 117,-2064 }, { 118,-2064 }, { 119,-2064 },
 { 120,-2064 }, { 121,-2064 }, { 122,-2064 }, { 123,-2064 }, { 124,-2064 },
 { 125,-2064 }, { 126,-2064 }, { 127,-2064 }, { 128,-2064 }, { 129,-2064 },
 { 130,-2064 }, { 131,-2064 }, { 132,-2064 }, { 133,-2064 }, { 134,-2064 },
 { 135,-2064 }, { 136,-2064 }, { 137,-2064 }, { 138,-2064 }, { 139,-2064 },

 { 140,-2064 }, { 141,-2064 }, { 142,-2064 }, { 143,-2064 }, { 144,-2064 },
 { 145,-2064 }, { 146,-2064 }, { 147,-2064 }, { 148,-2064 }, { 149,-2064 },
 { 150,-2064 }, { 151,-2064 }, { 152,-2064 }, { 153,-2064 }, { 154,-2064 },
 { 155,-2064 }, { 156,-2064 }, { 157,-2064 }, { 158,-2064 }, { 159,-2064 },
 { 160,-2064 }, { 161,-2064 }, { 162,-2064 }, { 163,-2064 }, { 164,-2064 },
 { 165,-2064 }, { 166,-2064 }, { 167,-2064 }, { 168,-2064 }, { 169,-2064 },
 { 170,-2064 }, { 171,-2064 }, { 172,-2064 }, { 173,-2064 }, { 174,-2064 },
 { 175,-2064 }, { 176,-2064 }, { 177,-2064 }, { 178,-2064 }, { 179,-2064 },
 { 180,-2064 }, { 181,-2064 }, { 182,-2064 }, { 183,-2064 }, { 184,-2064 },
 { 185,-2064 }, { 186,-2064 }, { 187,-2064 }, { 188,-2064 }, { 189,-2064 },

 { 190,-2064 }, { 191,-2064 }, { 192,-2064 }, { 193,-2064 }, { 194,-2064 },
 { 195,-2064 }, { 196,-2064 }, { 197,-2064 }, { 198,-2064 }, { 199,-2064 },
 { 200,-2064 }, { 201,-2064 }, { 202,-2064 }, { 203,-2064 }, { 204,-2064 },
 { 205,-2064 }, { 206,-2064 }, { 207,-2064 }, { 208,-2064 }, { 209,-2064 },
 { 210,-2064 }, { 211,-2064 }, { 212,-2064 }, { 213,-2064 }, { 214,-2064 },
 { 215,-2064 }, { 216,-2064 }, { 217,-2064 }, { 218,-2064 }, { 219,-2064 },
 { 220,-2064 }, { 221,-2064 }, { 222,-2064 }, { 223,-2064 }, { 224,-2064 },
 { 225,-2064 }, { 226,-2064 }, { 227,-2064 }, { 228,-2064 }, { 229,-2064 },
 { 230,-2064 }, { 231,-2064 }, { 232,-2064 }, { 233,-2064 }, { 234,-2064 },
 { 235,-2064 }, { 236,-2064 }, { 237,-2064 }, { 238,-2064 }, { 239,-2064 },

 { 240,-2064 }, { 241,-2064 }, { 242,-2064 }, { 243,-2064 }, { 244,-2064 },
 { 245,-2064 }, { 246,-2064 }, { 247,-2064 }, { 248,-2064 }, { 249,-2064 },
 { 250,-2064 }, { 251,-2064 }, { 252,-2064 }, { 253,-2064 }, { 254,-2064 },
 { 255,-2064 }, { 256,-2064 }, {   0,  55 }, {   0,2932 }, {   1,-2322 },
 {   2,-2322 }, {   3,-2322 }, {   4,-2322 }, {   5,-2322 }, {   6,-2322 },
 {   7,-2322 }, {   8,-2322 }, {   9,-2064 }, {  10,-3679 }, {  11,-2322 },
 {  12,-2064 }, {  13,-3679 }, {  14,-2322 }, {  15,-2322 }, {  16,-2322 },
 {  17,-2322 }, {  18,-2322 }, {  19,-2322 }, {  20,-2322 }, {  21,-2322 },
 {  22,-2322 }, {  23,-2322 }, {  24,-2322 }, {  25,-2322 }, {  26,-2322 },
 {  27,-2322 }, {  28,-2322 }, {  29,-2322 }, {  30,-2322 }, {  31,-2322 },

 {  32,-2064 }, {  33,-2322 }, {  34,-2322 }, {  35,-2322 }, {  36,-2322 },
 {  37,-2322 }, {  38,-2322 }, {  39,1900 }, {  40,-2322 }, {  41,-2322 },
 {  42,-2322 }, {  43,-2322 }, {  44,-2322 }, {  45,-1548 }, {  46,-2322 },
 {  47,-2322 }, {  48,-2322 }, {  49,-2322 }, {  50,-2322 }, {  51,-2322 },
 {  52,-2322 }, {  53,-2322 }, {  54,-2322 }, {  55,-2322 }, {  56,-2322 },
 {  57,-2322 }, {  58,-2322 }, {  59,-2322 }, {  60,-2322 }, {  61,-2322 },
 {  62,-2322 }, {  63,-2322 }, {  64,-2322 }, {  65,-2322 }, {  66,-2322 },
 {  67,-2322 }, {  68,-2322 }, {  69,-2322 }, {  70,-2322 }, {  71,-2322 },
 {  72,-2322 }, {  73,-2322 }, {  74,-2322 }, {  75,-2322 }, {  76,-2322 },
 {  77,-2322 }, {  78,-2322 }, {  79,-2322 }, {  80,-2322 }, {  81,-2322 },

 {  82,-2322 }, {  83,-2322 }, {  84,-2322 }, {  85,-2322 }, {  86,-2322 },
 {  87,-2322 }, {  88,-2322 }, {  89,-2322 }, {  90,-2322 }, {  91,-2322 },
 {  92,-2322 }, {  93,-2322 }, {  94,-2322 }, {  95,-2322 }, {  96,-2322 },
 {  97,-2322 }, {  98,-2322 }, {  99,-2322 }, { 100,-2322 }, { 101,-2322 },
 { 102,-2322 }, { 103,-2322 }, { 104,-2322 }, { 105,-2322 }, { 106,-2322 },
 { 107,-2322 }, { 108,-2322 }, { 109,-2322 }, { 110,-2322 }, { 111,-2322 },
 { 112,-2322 }, { 113,-2322 }, { 114,-2322 }, { 115,-2322 }, { 116,-2322 },
 { 117,-2322 }, { 118,-2322 }, { 119,-2322 }, { 120,-2322 }, { 121,-2322 },
 { 122,-2322 }, { 123,-2322 }, { 124,-2322 }, { 125,-2322 }, { 126,-2322 },
 { 127,-2322 }, { 128,-2322 }, { 129,-2322 }, { 130,-2322 }, { 131,-2322 },

 { 132,-2322 }, { 133,-2322 }, { 134,-2322 }, { 135,-2322 }, { 136,-2322 },
 { 137,-2322 }, { 138,-2322 }, { 139,-2322 }, { 140,-2322 }, { 141,-2322 },
 { 142,-2322 }, { 143,-2322 }, { 144,-2322 }, { 145,-2322 }, { 146,-2322 },
 { 147,-2322 }, { 148,-2322 }, { 149,-2322 }, { 150,-2322 }, { 151,-2322 },
 { 152,-2322 }, { 153,-2322 }, { 154,-2322 }, { 155,-2322 }, { 156,-2322 },
 { 157,-2322 }, { 158,-2322 }, { 159,-2322 }, { 160,-2322 }, { 161,-2322 },
 { 162,-2322 }, { 163,-2322 }, { 164,-2322 }, { 165,-2322 }, { 166,-2322 },
 { 167,-2322 }, { 168,-2322 }, { 169,-2322 }, { 170,-2322 }, { 171,-2322 },
 { 172,-2322 }, { 173,-2322 }, { 174,-2322 }, { 175,-2322 }, { 176,-2322 },
 { 177,-2322 }, { 178,-2322 }, { 179,-2322 }, { 180,-2322 }, { 181,-2322 },

 { 182,-2322 }, { 183,-2322 }, { 184,-2322 }, { 185,-2322 }, { 186,-2322 },
 { 187,-2322 }, { 188,-2322 }, { 189,-2322 }, { 190,-2322 }, { 191,-2322 },
 { 192,-2322 }, { 193,-2322 }, { 194,-2322 }, { 195,-2322 }, { 196,-2322 },
 { 197,-2322 }, { 198,-2322 }, { 199,-2322 }, { 200,-2322 }, { 201,-2322 },
 { 202,-2322 }, { 203,-2322 }, { 204,-2322 }, { 205,-2322 }, { 206,-2322 },
 { 207,-2322 }, { 208,-2322 }, { 209,-2322 }, { 210,-2322 }, { 211,-2322 },
 { 212,-2322 }, { 213,-2322 }, { 214,-2322 }, { 215,-2322 }, { 216,-2322 },
 { 217,-2322 }, { 218,-2322 }, { 219,-2322 }, { 220,-2322 }, { 221,-2322 },
 { 222,-2322 }, { 223,-2322 }, { 224,-2322 }, { 225,-2322 }, { 226,-2322 },
 { 227,-2322 }, { 228,-2322 }, { 229,-2322 }, { 230,-2322 }, { 231,-2322 },

 { 232,-2322 }, { 233,-2322 }, { 234,-2322 }, { 235,-2322 }, { 236,-2322 },
 { 237,-2322 }, { 238,-2322 }, { 239,-2322 }, { 240,-2322 }, { 241,-2322 },
 { 242,-2322 }, { 243,-2322 }, { 244,-2322 }, { 245,-2322 }, { 246,-2322 },
 { 247,-2322 }, { 248,-2322 }, { 249,-2322 }, { 250,-2322 }, { 251,-2322 },
 { 252,-2322 }, { 253,-2322 }, { 254,-2322 }, { 255,-2322 }, { 256,-2322 },
 {   0,  55 }, {   0,2674 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   9,-3937 }, {  10,-3937 }, {   0,   0 }, {  12,-3937 }, {  13,-3937 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {  32,-3937 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {  39,1900 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {  45,-25685 }, {   0,  55 }, {   0,2627 }, {   1,-2627 },
 {   2,-2627 }, {   3,-2627 }, {   4,-2627 }, {   5,-2627 }, {   6,-2627 },
 {   7,-2627 }, {   8,-2627 }, {   9,-2369 }, {  10,-3984 }, {  11,-2627 },
 {  12,-2369 }, {  13,-3984 }, {  14,-2627 }, {  15,-2627 }, {  16,-2627 },
 {  17,-2627 }, {  18,-2627 }, {  19,-2627 }, {  20,-2627 }, {  21,-2627 },
 {  22,-2627 }, {  23,-2627 }, {  24,-2627 }, {  25,-2627 }, {  26,-2627 },

 {  27,-2627 }, {  28,-2627 }, {  29,-2627 }, {  30,-2627 }, {  31,-2627 },
 {  32,-2369 }, {  33,-2627 }, {  34,-2627 }, {  35,-2627 }, {  36,-2627 },
 {  37,-2627 }, {  38,-2627 }, {  39,1595 }, {  40,-2627 }, {  41,-2627 },
 {  42,-2627 }, {  43,-2627 }, {  44,-2627 }, {  45, 258 }, {  46,-2627 },
 {  47,-2627 }, {  48,-2627 }, {  49,-2627 }, {  50,-2627 }, {  51,-2627 },
 {  52,-2627 }, {  53,-2627 }, {  54,-2627 }, {  55,-2627 }, {  56,-2627 },
 {  57,-2627 }, {  58,-2627 }, {  59,-2627 }, {  60,-2627 }, {  61,-2627 },
 {  62,-2627 }, {  63,-2627 }, {  64,-2627 }, {  65,-2627 }, {  66,-2627 },
 {  67,-2627 }, {  68,-2627 }, {  69,-2627 }, {  70,-2627 }, {  71,-2627 },
 {  72,-2627 }, {  73,-2627 }, {  74,-2627 }, {  75,-2627 }, {  76,-2627 },

 {  77,-2627 }, {  78,-2627 }, {  79,-2627 }, {  80,-2627 }, {  81,-2627 },
 {  82,-2627 }, {  83,-2627 }, {  84,-2627 }, {  85,-2627 }, {  86,-2627 },
 {  87,-2627 }, {  88,-2627 }, {  89,-2627 }, {  90,-2627 }, {  91,-2627 },
 {  92,-2627 }, {  93,-2627 }, {  94,-2627 }, {  95,-2627 }, {  96,-2627 },
 {  97,-2627 }, {  98,-2627 }, {  99,-2627 }, { 100,-2627 }, { 101,-2627 },
 { 102,-2627 }, { 103,-2627 }, { 104,-2627 }, { 105,-2627 }, { 106,-2627 },
 { 107,-2627 }, { 108,-2627 }, { 109,-2627 }, { 110,-2627 }, { 111,-2627 },
 { 112,-2627 }, { 113,-2627 }, { 114,-2627 }, { 115,-2627 }, { 116,-2627 },
 { 117,-2627 }, { 118,-2627 }, { 119,-2627 }, { 120,-2627 }, { 121,-2627 },
 { 122,-2627 }, { 123,-2627 }, { 124,-2627 }, { 125,-2627 }, { 126,-2627 },

 { 127,-2627 }, { 128,-2627 }, { 129,-2627 }, { 130,-2627 }, { 131,-2627 },
 { 132,-2627 }, { 133,-2627 }, { 134,-2627 }, { 135,-2627 }, { 136,-2627 },
 { 137,-2627 }, { 138,-2627 }, { 139,-2627 }, { 140,-2627 }, { 141,-2627 },
 { 142,-2627 }, { 143,-2627 }, { 144,-2627 }, { 145,-2627 }, { 146,-2627 },
 { 147,-2627 }, { 148,-2627 }, { 149,-2627 }, { 150,-2627 }, { 151,-2627 },
 { 152,-2627 }, { 153,-2627 }, { 154,-2627 }, { 155,-2627 }, { 156,-2627 },
 { 157,-2627 }, { 158,-2627 }, { 159,-2627 }, { 160,-2627 }, { 161,-2627 },
 { 162,-2627 }, { 163,-2627 }, { 164,-2627 }, { 165,-2627 }, { 166,-2627 },
 { 167,-2627 }, { 168,-2627 }, { 169,-2627 }, { 170,-2627 }, { 171,-2627 },
 { 172,-2627 }, { 173,-2627 }, { 174,-2627 }, { 175,-2627 }, { 176,-2627 },

 { 177,-2627 }, { 178,-2627 }, { 179,-2627 }, { 180,-2627 }, { 181,-2627 },
 { 182,-2627 }, { 183,-2627 }, { 184,-2627 }, { 185,-2627 }, { 186,-2627 },
 { 187,-2627 }, { 188,-2627 }, { 189,-2627 }, { 190,-2627 }, { 191,-2627 },
 { 192,-2627 }, { 193,-2627 }, { 194,-2627 }, { 195,-2627 }, { 196,-2627 },
 { 197,-2627 }, { 198,-2627 }, { 199,-2627 }, { 200,-2627 }, { 201,-2627 },
 { 202,-2627 }, { 203,-2627 }, { 204,-2627 }, { 205,-2627 }, { 206,-2627 },
 { 207,-2627 }, { 208,-2627 }, { 209,-2627 }, { 210,-2627 }, { 211,-2627 },
 { 212,-2627 }, { 213,-2627 }, { 214,-2627 }, { 215,-2627 }, { 216,-2627 },
 { 217,-2627 }, { 218,-2627 }, { 219,-2627 }, { 220,-2627 }, { 221,-2627 },
 { 222,-2627 }, { 223,-2627 }, { 224,-2627 }, { 225,-2627 }, { 226,-2627 },

 { 227,-2627 }, { 228,-2627 }, { 229,-2627 }, { 230,-2627 }, { 231,-2627 },
 { 232,-2627 }, { 233,-2627 }, { 234,-2627 }, { 235,-2627 }, { 236,-2627 },
 { 237,-2627 }, { 238,-2627 }, { 239,-2627 }, { 240,-2627 }, { 241,-2627 },
 { 242,-2627 }, { 243,-2627 }, { 244,-2627 }, { 245,-2627 }, { 246,-2627 },
 { 247,-2627 }, { 248,-2627 }, { 249,-2627 }, { 250,-2627 }, { 251,-2627 },
 { 252,-2627 }, { 253,-2627 }, { 254,-2627 }, { 255,-2627 }, { 256,-2627 },
 {   0,  55 }, {   0,2369 }, {   1,-2885 }, {   2,-2885 }, {   3,-2885 },
 {   4,-2885 }, {   5,-2885 }, {   6,-2885 }, {   7,-2885 }, {   8,-2885 },
 {   9,-2627 }, {  10,-4242 }, {  11,-2885 }, {  12,-2627 }, {  13,-4242 },
 {  14,-2885 }, {  15,-2885 }, {  16,-2885 }, {  17,-2885 }, {  18,-2885 },

 {  19,-2885 }, {  20,-2885 }, {  21,-2885 }, {  22,-2885 }, {  23,-2885 },
 {  24,-2885 }, {  25,-2885 }, {  26,-2885 }, {  27,-2885 }, {  28,-2885 },
 {  29,-2885 }, {  30,-2885 }, {  31,-2885 }, {  32,-2627 }, {  33,-2885 },
 {  34,-2885 }, {  35,-2885 }, {  36,-2885 }, {  37,-2885 }, {  38,-2885 },
 {  39,-2369 }, {  40,-2885 }, {  41,-2885 }, {  42,-2885 }, {  43,-2885 },
 {  44,-2885 }, {  45,   0 }, {  46,-2885 }, {  47,-2885 }, {  48,-2885 },
 {  49,-2885 }, {  50,-2885 }, {  51,-2885 }, {  52,-2885 }, {  53,-2885 },
 {  54,-2885 }, {  55,-2885 }, {  56,-2885 }, {  57,-2885 }, {  58,-2885 },
 {  59,-2885 }, {  60,-2885 }, {  61,-2885 }, {  62,-2885 }, {  63,-2885 },
 {  64,-2885 }, {  65,-2885 }, {  66,-2885 }, {  67,-2885 }, {  68,-2885 },

 {  69,-2885 }, {  70,-2885 }, {  71,-2885 }, {  72,-2885 }, {  73,-2885 },
 {  74,-2885 }, {  75,-2885 }, {  76,-2885 }, {  77,-2885 }, {  78,-2885 },
 {  79,-2885 }, {  80,-2885 }, {  81,-2885 }, {  82,-2885 }, {  83,-2885 },
 {  84,-2885 }, {  85,-2885 }, {  86,-2885 }, {  87,-2885 }, {  88,-2885 },
 {  89,-2885 }, {  90,-2885 }, {  91,-2885 }, {  92,-2885 }, {  93,-2885 },
 {  94,-2885 }, {  95,-2885 }, {  96,-2885 }, {  97,-2885 }, {  98,-2885 },
 {  99,-2885 }, { 100,-2885 }, { 101,-2885 }, { 102,-2885 }, { 103,-2885 },
 { 104,-2885 }, { 105,-2885 }, { 106,-2885 }, { 107,-2885 }, { 108,-2885 },
 { 109,-2885 }, { 110,-2885 }, { 111,-2885 }, { 112,-2885 }, { 113,-2885 },
 { 114,-2885 }, { 115,-2885 }, { 116,-2885 }, { 117,-2885 }, { 118,-2885 },

 { 119,-2885 }, { 120,-2885 }, { 121,-2885 }, { 122,-2885 }, { 123,-2885 },
 { 124,-2885 }, { 125,-2885 }, { 126,-2885 }, { 127,-2885 }, { 128,-2885 },
 { 129,-2885 }, { 130,-2885 }, { 131,-2885 }, { 132,-2885 }, { 133,-2885 },
 { 134,-2885 }, { 135,-2885 }, { 136,-2885 }, { 137,-2885 }, { 138,-2885 },
 { 139,-2885 }, { 140,-2885 }, { 141,-2885 }, { 142,-2885 }, { 143,-2885 },
 { 144,-2885 }, { 145,-2885 }, { 146,-2885 }, { 147,-2885 }, { 148,-2885 },
 { 149,-2885 }, { 150,-2885 }, { 151,-2885 }, { 152,-2885 }, { 153,-2885 },
 { 154,-2885 }, { 155,-2885 }, { 156,-2885 }, { 157,-2885 }, { 158,-2885 },
 { 159,-2885 }, { 160,-2885 }, { 161,-2885 }, { 162,-2885 }, { 163,-2885 },
 { 164,-2885 }, { 165,-2885 }, { 166,-2885 }, { 167,-2885 }, { 168,-2885 },

 { 169,-2885 }, { 170,-2885 }, { 171,-2885 }, { 172,-2885 }, { 173,-2885 },
 { 174,-2885 }, { 175,-2885 }, { 176,-2885 }, { 177,-2885 }, { 178,-2885 },
 { 179,-2885 }, { 180,-2885 }, { 181,-2885 }, { 182,-2885 }, { 183,-2885 },
 { 184,-2885 }, { 185,-2885 }, { 186,-2885 }, { 187,-2885 }, { 188,-2885 },
 { 189,-2885 }, { 190,-2885 }, { 191,-2885 }, { 192,-2885 }, { 193,-2885 },
 { 194,-2885 }, { 195,-2885 }, { 196,-2885 }, { 197,-2885 }, { 198,-2885 },
 { 199,-2885 }, { 200,-2885 }, { 201,-2885 }, { 202,-2885 }, { 203,-2885 },
 { 204,-2885 }, { 205,-2885 }, { 206,-2885 }, { 207,-2885 }, { 208,-2885 },
 { 209,-2885 }, { 210,-2885 }, { 211,-2885 }, { 212,-2885 }, { 213,-2885 },
 { 214,-2885 }, { 215,-2885 }, { 216,-2885 }, { 217,-2885 }, { 218,-2885 },

 { 219,-2885 }, { 220,-2885 }, { 221,-2885 }, { 222,-2885 }, { 223,-2885 },
 { 224,-2885 }, { 225,-2885 }, { 226,-2885 }, { 227,-2885 }, { 228,-2885 },
 { 229,-2885 }, { 230,-2885 }, { 231,-2885 }, { 232,-2885 }, { 233,-2885 },
 { 234,-2885 }, { 235,-2885 }, { 236,-2885 }, { 237,-2885 }, { 238,-2885 },
 { 239,-2885 }, { 240,-2885 }, { 241,-2885 }, { 242,-2885 }, { 243,-2885 },
 { 244,-2885 }, { 245,-2885 }, { 246,-2885 }, { 247,-2885 }, { 248,-2885 },
 { 249,-2885 }, { 250,-2885 }, { 251,-2885 }, { 252,-2885 }, { 253,-2885 },
 { 254,-2885 }, { 255,-2885 }, { 256,-2885 }, {   0,  28 }, {   0,2111 },
 {   1,-2111 }, {   2,-2111 }, {   3,-2111 }, {   4,-2111 }, {   5,-2111 },
 {   6,-2111 }, {   7,-2111 }, {   8,-2111 }, {   9,-1853 }, {  10,-4195 },

 {  11,-2111 }, {  12,-1853 }, {  13,-4195 }, {  14,-2111 }, {  15,-2111 },
 {  16,-2111 }, {  17,-2111 }, {  18,-2111 }, {  19,-2111 }, {  20,-2111 },
 {  21,-2111 }, {  22,-2111 }, {  23,-2111 }, {  24,-2111 }, {  25,-2111 },
 {  26,-2111 }, {  27,-2111 }, {  28,-2111 }, {  29,-2111 }, {  30,-2111 },
 {  31,-2111 }, {  32,-1853 }, {  33,-2111 }, {  34,-2111 }, {  35,-2111 },
 {  36,-2111 }, {  37,-2111 }, {  38,-2111 }, {  39,1595 }, {  40,-2111 },
 {  41,-2111 }, {  42,-2111 }, {  43,-2111 }, {  44,-2111 }, {  45,-1337 },
 {  46,-2111 }, {  47,-2111 }, {  48,-2111 }, {  49,-2111 }, {  50,-2111 },
 {  51,-2111 }, {  52,-2111 }, {  53,-2111 }, {  54,-2111 }, {  55,-2111 },
 {  56,-2111 }, {  57,-2111 }, {  58,-2111 }, {  59,-2111 }, {  60,-2111 },

 {  61,-2111 }, {  62,-2111 }, {  63,-2111 }, {  64,-2111 }, {  65,-2111 },
 {  66,-2111 }, {  67,-2111 }, {  68,-2111 }, {  69,-2111 }, {  70,-2111 },
 {  71,-2111 }, {  72,-2111 }, {  73,-2111 }, {  74,-2111 }, {  75,-2111 },
 {  76,-2111 }, {  77,-2111 }, {  78,-2111 }, {  79,-2111 }, {  80,-2111 },
 {  81,-2111 }, {  82,-2111 }, {  83,-2111 }, {  84,-2111 }, {  85,-2111 },
 {  86,-2111 }, {  87,-2111 }, {  88,-2111 }, {  89,-2111 }, {  90,-2111 },
 {  91,-2111 }, {  92,-2111 }, {  93,-2111 }, {  94,-2111 }, {  95,-2111 },
 {  96,-2111 }, {  97,-2111 }, {  98,-2111 }, {  99,-2111 }, { 100,-2111 },
 { 101,-2111 }, { 102,-2111 }, { 103,-2111 }, { 104,-2111 }, { 105,-2111 },
 { 106,-2111 }, { 107,-2111 }, { 108,-2111 }, { 109,-2111 }, { 110,-2111 },

 { 111,-2111 }, { 112,-2111 }, { 113,-2111 }, { 114,-2111 }, { 115,-2111 },
 { 116,-2111 }, { 117,-2111 }, { 118,-2111 }, { 119,-2111 }, { 120,-2111 },
 { 121,-2111 }, { 122,-2111 }, { 123,-2111 }, { 124,-2111 }, { 125,-2111 },
 { 126,-2111 }, { 127,-2111 }, { 128,-2111 }, { 129,-2111 }, { 130,-2111 },
 { 131,-2111 }, { 132,-2111 }, { 133,-2111 }, { 134,-2111 }, { 135,-2111 },
 { 136,-2111 }, { 137,-2111 }, { 138,-2111 }, { 139,-2111 }, { 140,-2111 },
 { 141,-2111 }, { 142,-2111 }, { 143,-2111 }, { 144,-2111 }, { 145,-2111 },
 { 146,-2111 }, { 147,-2111 }, { 148,-2111 }, { 149,-2111 }, { 150,-2111 },
 { 151,-2111 }, { 152,-2111 }, { 153,-2111 }, { 154,-2111 }, { 155,-2111 },
 { 156,-2111 }, { 157,-2111 }, { 158,-2111 }, { 159,-2111 }, { 160,-2111 },

 { 161,-2111 }, { 162,-2111 }, { 163,-2111 }, { 164,-2111 }, { 165,-2111 },
 { 166,-2111 }, { 167,-2111 }, { 168,-2111 }, { 169,-2111 }, { 170,-2111 },
 { 171,-2111 }, { 172,-2111 }, { 173,-2111 }, { 174,-2111 }, { 175,-2111 },
 { 176,-2111 }, { 177,-2111 }, { 178,-2111 }, { 179,-2111 }, { 180,-2111 },
 { 181,-2111 }, { 182,-2111 }, { 183,-2111 }, { 184,-2111 }, { 185,-2111 },
 { 186,-2111 }, { 187,-2111 }, { 188,-2111 }, { 189,-2111 }, { 190,-2111 },
 { 191,-2111 }, { 192,-2111 }, { 193,-2111 }, { 194,-2111 }, { 195,-2111 },
 { 196,-2111 }, { 197,-2111 }, { 198,-2111 }, { 199,-2111 }, { 200,-2111 },
 { 201,-2111 }, { 202,-2111 }, { 203,-2111 }, { 204,-2111 }, { 205,-2111 },
 { 206,-2111 }, { 207,-2111 }, { 208,-2111 }, { 209,-2111 }, { 210,-2111 },

 { 211,-2111 }, { 212,-2111 }, { 213,-2111 }, { 214,-2111 }, { 215,-2111 },
 { 216,-2111 }, { 217,-2111 }, { 218,-2111 }, { 219,-2111 }, { 220,-2111 },
 { 221,-2111 }, { 222,-2111 }, { 223,-2111 }, { 224,-2111 }, { 225,-2111 },
 { 226,-2111 }, { 227,-2111 }, { 228,-2111 }, { 229,-2111 }, { 230,-2111 },
 { 231,-2111 }, { 232,-2111 }, { 233,-2111 }, { 234,-2111 }, { 235,-2111 },
 { 236,-2111 }, { 237,-2111 }, { 238,-2111 }, { 239,-2111 }, { 240,-2111 },
 { 241,-2111 }, { 242,-2111 }, { 243,-2111 }, { 244,-2111 }, { 245,-2111 },
 { 246,-2111 }, { 247,-2111 }, { 248,-2111 }, { 249,-2111 }, { 250,-2111 },
 { 251,-2111 }, { 252,-2111 }, { 253,-2111 }, { 254,-2111 }, { 255,-2111 },
 { 256,-2111 }, {   0,  28 }, {   0,1853 }, {   1,-2369 }, {   2,-2369 },

 {   3,-2369 }, {   4,-2369 }, {   5,-2369 }, {   6,-2369 }, {   7,-2369 },
 {   8,-2369 }, {   9,-2111 }, {  10,-4453 }, {  11,-2369 }, {  12,-2111 },
 {  13,-4453 }, {  14,-2369 }, {  15,-2369 }, {  16,-2369 }, {  17,-2369 },
 {  18,-2369 }, {  19,-2369 }, {  20,-2369 }, {  21,-2369 }, {  22,-2369 },
 {  23,-2369 }, {  24,-2369 }, {  25,-2369 }, {  26,-2369 }, {  27,-2369 },
 {  28,-2369 }, {  29,-2369 }, {  30,-2369 }, {  31,-2369 }, {  32,-2111 },
 {  33,-2369 }, {  34,-2369 }, {  35,-2369 }, {  36,-2369 }, {  37,-2369 },
 {  38,-2369 }, {  39,1337 }, {  40,-2369 }, {  41,-2369 }, {  42,-2369 },
 {  43,-2369 }, {  44,-2369 }, {  45,-1595 }, {  46,-2369 }, {  47,-2369 },
 {  48,-2369 }, {  49,-2369 }, {  50,-2369 }, {  51,-2369 }, {  52,-2369 },

 {  53,-2369 }, {  54,-2369 }, {  55,-2369 }, {  56,-2369 }, {  57,-2369 },
 {  58,-2369 }, {  59,-2369 }, {  60,-2369 }, {  61,-2369 }, {  62,-2369 },
 {  63,-2369 }, {  64,-2369 }, {  65,-2369 }, {  66,-2369 }, {  67,-2369 },
 {  68,-2369 }, {  69,-2369 }, {  70,-2369 }, {  71,-2369 }, {  72,-2369 },
 {  73,-2369 }, {  74,-2369 }, {  75,-2369 }, {  76,-2369 }, {  77,-2369 },
 {  78,-2369 }, {  79,-2369 }, {  80,-2369 }, {  81,-2369 }, {  82,-2369 },
 {  83,-2369 }, {  84,-2369 }, {  85,-2369 }, {  86,-2369 }, {  87,-2369 },
 {  88,-2369 }, {  89,-2369 }, {  90,-2369 }, {  91,-2369 }, {  92,-2369 },
 {  93,-2369 }, {  94,-2369 }, {  95,-2369 }, {  96,-2369 }, {  97,-2369 },
 {  98,-2369 }, {  99,-2369 }, { 100,-2369 }, { 101,-2369 }, { 102,-2369 },

 { 103,-2369 }, { 104,-2369 }, { 105,-2369 }, { 106,-2369 }, { 107,-2369 },
 { 108,-2369 }, { 109,-2369 }, { 110,-2369 }, { 111,-2369 }, { 112,-2369 },
 { 113,-2369 }, { 114,-2369 }, { 115,-2369 }, { 116,-2369 }, { 117,-2369 },
 { 118,-2369 }, { 119,-2369 }, { 120,-2369 }, { 121,-2369 }, { 122,-2369 },
 { 123,-2369 }, { 124,-2369 }, { 125,-2369 }, { 126,-2369 }, { 127,-2369 },
 { 128,-2369 }, { 129,-2369 }, { 130,-2369 }, { 131,-2369 }, { 132,-2369 },
 { 133,-2369 }, { 134,-2369 }, { 135,-2369 }, { 136,-2369 }, { 137,-2369 },
 { 138,-2369 }, { 139,-2369 }, { 140,-2369 }, { 141,-2369 }, { 142,-2369 },
 { 143,-2369 }, { 144,-2369 }, { 145,-2369 }, { 146,-2369 }, { 147,-2369 },
 { 148,-2369 }, { 149,-2369 }, { 150,-2369 }, { 151,-2369 }, { 152,-2369 },

 { 153,-2369 }, { 154,-2369 }, { 155,-2369 }, { 156,-2369 }, { 157,-2369 },
 { 158,-2369 }, { 159,-2369 }, { 160,-2369 }, { 161,-2369 }, { 162,-2369 },
 { 163,-2369 }, { 164,-2369 }, { 165,-2369 }, { 166,-2369 }, { 167,-2369 },
 { 168,-2369 }, { 169,-2369 }, { 170,-2369 }, { 171,-2369 }, { 172,-2369 },
 { 173,-2369 }, { 174,-2369 }, { 175,-2369 }, { 176,-2369 }, { 177,-2369 },
 { 178,-2369 }, { 179,-2369 }, { 180,-2369 }, { 181,-2369 }, { 182,-2369 },
 { 183,-2369 }, { 184,-2369 }, { 185,-2369 }, { 186,-2369 }, { 187,-2369 },
 { 188,-2369 }, { 189,-2369 }, { 190,-2369 }, { 191,-2369 }, { 192,-2369 },
 { 193,-2369 }, { 194,-2369 }, { 195,-2369 }, { 196,-2369 }, { 197,-2369 },
 { 198,-2369 }, { 199,-2369 }, { 200,-2369 }, { 201,-2369 }, { 202,-2369 },

 { 203,-2369 }, { 204,-2369 }, { 205,-2369 }, { 206,-2369 }, { 207,-2369 },
 { 208,-2369 }, { 209,-2369 }, { 210,-2369 }, { 211,-2369 }, { 212,-2369 },
 { 213,-2369 }, { 214,-2369 }, { 215,-2369 }, { 216,-2369 }, { 217,-2369 },
 { 218,-2369 }, { 219,-2369 }, { 220,-2369 }, { 221,-2369 }, { 222,-2369 },
 { 223,-2369 }, { 224,-2369 }, { 225,-2369 }, { 226,-2369 }, { 227,-2369 },
 { 228,-2369 }, { 229,-2369 }, { 230,-2369 }, { 231,-2369 }, { 232,-2369 },
 { 233,-2369 }, { 234,-2369 }, { 235,-2369 }, { 236,-2369 }, { 237,-2369 },
 { 238,-2369 }, { 239,-2369 }, { 240,-2369 }, { 241,-2369 }, { 242,-2369 },
 { 243,-2369 }, { 244,-2369 }, { 245,-2369 }, { 246,-2369 }, { 247,-2369 },
 { 248,-2369 }, { 249,-2369 }, { 250,-2369 }, { 251,-2369 }, { 252,-2369 },

 { 253,-2369 }, { 254,-2369 }, { 255,-2369 }, { 256,-2369 }, {   0,  28 },
 {   0,1595 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   9,-4711 },
 {  10,-4711 }, {   0,   0 }, {  12,-4711 }, {  13,-4711 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {  32,-4711 }, {   0,   0 }, {   0,   0 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {  39,1337 },
 {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },

 {  45,-26753 }, {   0,  28 }, {   0,1548 }, {   1,-2674 }, {   2,-2674 },
 {   3,-2674 }, {   4,-2674 }, {   5,-2674 }, {   6,-2674 }, {   7,-2674 },
 {   8,-2674 }, {   9,-2416 }, {  10,-4758 }, {  11,-2674 }, {  12,-2416 },
 {  13,-4758 }, {  14,-2674 }, {  15,-2674 }, {  16,-2674 }, {  17,-2674 },
 {  18,-2674 }, {  19,-2674 }, {  20,-2674 }, {  21,-2674 }, {  22,-2674 },
 {  23,-2674 }, {  24,-2674 }, {  25,-2674 }, {  26,-2674 }, {  27,-2674 },
 {  28,-2674 }, {  29,-2674 }, {  30,-2674 }, {  31,-2674 }, {  32,-2416 },
 {  33,-2674 }, {  34,-2674 }, {  35,-2674 }, {  36,-2674 }, {  37,-2674 },
 {  38,-2674 }, {  39,1032 }, {  40,-2674 }, {  41,-2674 }, {  42,-2674 },
 {  43,-2674 }, {  44,-2674 }, {  45, 258 }, {  46,-2674 }, {  47,-2674 },

 {  48,-2674 }, {  49,-2674 }, {  50,-2674 }, {  51,-2674 }, {  52,-2674 },
 {  53,-2674 }, {  54,-2674 }, {  55,-2674 }, {  56,-2674 }, {  57,-2674 },
 {  58,-2674 }, {  59,-2674 }, {  60,-2674 }, {  61,-2674 }, {  62,-2674 },
 {  63,-2674 }, {  64,-2674 }, {  65,-2674 }, {  66,-2674 }, {  67,-2674 },
 {  68,-2674 }, {  69,-2674 }, {  70,-2674 }, {  71,-2674 }, {  72,-2674 },
 {  73,-2674 }, {  74,-2674 }, {  75,-2674 }, {  76,-2674 }, {  77,-2674 },
 {  78,-2674 }, {  79,-2674 }, {  80,-2674 }, {  81,-2674 }, {  82,-2674 },
 {  83,-2674 }, {  84,-2674 }, {  85,-2674 }, {  86,-2674 }, {  87,-2674 },
 {  88,-2674 }, {  89,-2674 }, {  90,-2674 }, {  91,-2674 }, {  92,-2674 },
 {  93,-2674 }, {  94,-2674 }, {  95,-2674 }, {  96,-2674 }, {  97,-2674 },

 {  98,-2674 }, {  99,-2674 }, { 100,-2674 }, { 101,-2674 }, { 102,-2674 },
 { 103,-2674 }, { 104,-2674 }, { 105,-2674 }, { 106,-2674 }, { 107,-2674 },
 { 108,-2674 }, { 109,-2674 }, { 110,-2674 }, { 111,-2674 }, { 112,-2674 },
 { 113,-2674 }, { 114,-2674 }, { 115,-2674 }, { 116,-2674 }, { 117,-2674 },
 { 118,-2674 }, { 119,-2674 }, { 120,-2674 }, { 121,-2674 }, { 122,-2674 },
 { 123,-2674 }, { 124,-2674 }, { 125,-2674 }, { 126,-2674 }, { 127,-2674 },
 { 128,-2674 }, { 129,-2674 }, { 130,-2674 }, { 131,-2674 }, { 132,-2674 },
 { 133,-2674 }, { 134,-2674 }, { 135,-2674 }, { 136,-2674 }, { 137,-2674 },
 { 138,-2674 }, { 139,-2674 }, { 140,-2674 }, { 141,-2674 }, { 142,-2674 },
 { 143,-2674 }, { 144,-2674 }, { 145,-2674 }, { 146,-2674 }, { 147,-2674 },

 { 148,-2674 }, { 149,-2674 }, { 150,-2674 }, { 151,-2674 }, { 152,-2674 },
 { 153,-2674 }, { 154,-2674 }, { 155,-2674 }, { 156,-2674 }, { 157,-2674 },
 { 158,-2674 }, { 159,-2674 }, { 160,-2674 }, { 161,-2674 }, { 162,-2674 },
 { 163,-2674 }, { 164,-2674 }, { 165,-2674 }, { 166,-2674 }, { 167,-2674 },
 { 168,-2674 }, { 169,-2674 }, { 170,-2674 }, { 171,-2674 }, { 172,-2674 },
 { 173,-2674 }, { 174,-2674 }, { 175,-2674 }, { 176,-2674 }, { 177,-2674 },
 { 178,-2674 }, { 179,-2674 }, { 180,-2674 }, { 181,-2674 }, { 182,-2674 },
 { 183,-2674 }, { 184,-2674 }, { 185,-2674 }, { 186,-2674 }, { 187,-2674 },
 { 188,-2674 }, { 189,-2674 }, { 190,-2674 }, { 191,-2674 }, { 192,-2674 },
 { 193,-2674 }, { 194,-2674 }, { 195,-2674 }, { 196,-2674 }, { 197,-2674 },

 { 198,-2674 }, { 199,-2674 }, { 200,-2674 }, { 201,-2674 }, { 202,-2674 },
 { 203,-2674 }, { 204,-2674 }, { 205,-2674 }, { 206,-2674 }, { 207,-2674 },
 { 208,-2674 }, { 209,-2674 }, { 210,-2674 }, { 211,-2674 }, { 212,-2674 },
 { 213,-2674 }, { 214,-2674 }, { 215,-2674 }, { 216,-2674 }, { 217,-2674 },
 { 218,-2674 }, { 219,-2674 }, { 220,-2674 }, { 221,-2674 }, { 222,-2674 },
 { 223,-2674 }, { 224,-2674 }, { 225,-2674 }, { 226,-2674 }, { 227,-2674 },
 { 228,-2674 }, { 229,-2674 }, { 230,-2674 }, { 231,-2674 }, { 232,-2674 },
 { 233,-2674 }, { 234,-2674 }, { 235,-2674 }, { 236,-2674 }, { 237,-2674 },
 { 238,-2674 }, { 239,-2674 }, { 240,-2674 }, { 241,-2674 }, { 242,-2674 },
 { 243,-2674 }, { 244,-2674 }, { 245,-2674 }, { 246,-2674 }, { 247,-2674 },

 { 248,-2674 }, { 249,-2674 }, { 250,-2674 }, { 251,-2674 }, { 252,-2674 },
 { 253,-2674 }, { 254,-2674 }, { 255,-2674 }, { 256,-2674 }, {   0,  28 },
 {   0,1290 }, {   1,-2932 }, {   2,-2932 }, {   3,-2932 }, {   4,-2932 },
 {   5,-2932 }, {   6,-2932 }, {   7,-2932 }, {   8,-2932 }, {   9,-2674 },
 {  10,-5016 }, {  11,-2932 }, {  12,-2674 }, {  13,-5016 }, {  14,-2932 },
 {  15,-2932 }, {  16,-2932 }, {  17,-2932 }, {  18,-2932 }, {  19,-2932 },
 {  20,-2932 }, {  21,-2932 }, {  22,-2932 }, {  23,-2932 }, {  24,-2932 },
 {  25,-2932 }, {  26,-2932 }, {  27,-2932 }, {  28,-2932 }, {  29,-2932 },
 {  30,-2932 }, {  31,-2932 }, {  32,-2674 }, {  33,-2932 }, {  34,-2932 },
 {  35,-2932 }, {  36,-2932 }, {  37,-2932 }, {  38,-2932 }, {  39,-2416 },

 {  40,-2932 }, {  41,-2932 }, {  42,-2932 }, {  43,-2932 }, {  44,-2932 },
 {  45,   0 }, {  46,-2932 }, {  47,-2932 }, {  48,-2932 }, {  49,-2932 },
 {  50,-2932 }, {  51,-2932 }, {  52,-2932 }, {  53,-2932 }, {  54,-2932 },
 {  55,-2932 }, {  56,-2932 }, {  57,-2932 }, {  58,-2932 }, {  59,-2932 },
 {  60,-2932 }, {  61,-2932 }, {  62,-2932 }, {  63,-2932 }, {  64,-2932 },
 {  65,-2932 }, {  66,-2932 }, {  67,-2932 }, {  68,-2932 }, {  69,-2932 },
 {  70,-2932 }, {  71,-2932 }, {  72,-2932 }, {  73,-2932 }, {  74,-2932 },
 {  75,-2932 }, {  76,-2932 }, {  77,-2932 }, {  78,-2932 }, {  79,-2932 },
 {  80,-2932 }, {  81,-2932 }, {  82,-2932 }, {  83,-2932 }, {  84,-2932 },
 {  85,-2932 }, {  86,-2932 }, {  87,-2932 }, {  88,-2932 }, {  89,-2932 },

 {  90,-2932 }, {  91,-2932 }, {  92,-2932 }, {  93,-2932 }, {  94,-2932 },
 {  95,-2932 }, {  96,-2932 }, {  97,-2932 }, {  98,-2932 }, {  99,-2932 },
 { 100,-2932 }, { 101,-2932 }, { 102,-2932 }, { 103,-2932 }, { 104,-2932 },
 { 105,-2932 }, { 106,-2932 }, { 107,-2932 }, { 108,-2932 }, { 109,-2932 },
 { 110,-2932 }, { 111,-2932 }, { 112,-2932 }, { 113,-2932 }, { 114,-2932 },
 { 115,-2932 }, { 116,-2932 }, { 117,-2932 }, { 118,-2932 }, { 119,-2932 },
 { 120,-2932 }, { 121,-2932 }, { 122,-2932 }, { 123,-2932 }, { 124,-2932 },
 { 125,-2932 }, { 126,-2932 }, { 127,-2932 }, { 128,-2932 }, { 129,-2932 },
 { 130,-2932 }, { 131,-2932 }, { 132,-2932 }, { 133,-2932 }, { 134,-2932 },
 { 135,-2932 }, { 136,-2932 }, { 137,-2932 }, { 138,-2932 }, { 139,-2932 },

 { 140,-2932 }, { 141,-2932 }, { 142,-2932 }, { 143,-2932 }, { 144,-2932 },
 { 145,-2932 }, { 146,-2932 }, { 147,-2932 }, { 148,-2932 }, { 149,-2932 },
 { 150,-2932 }, { 151,-2932 }, { 152,-2932 }, { 153,-2932 }, { 154,-2932 },
 { 155,-2932 }, { 156,-2932 }, { 157,-2932 }, { 158,-2932 }, { 159,-2932 },
 { 160,-2932 }, { 161,-2932 }, { 162,-2932 }, { 163,-2932 }, { 164,-2932 },
 { 165,-2932 }, { 166,-2932 }, { 167,-2932 }, { 168,-2932 }, { 169,-2932 },
 { 170,-2932 }, { 171,-2932 }, { 172,-2932 }, { 173,-2932 }, { 174,-2932 },
 { 175,-2932 }, { 176,-2932 }, { 177,-2932 }, { 178,-2932 }, { 179,-2932 },
 { 180,-2932 }, { 181,-2932 }, { 182,-2932 }, { 183,-2932 }, { 184,-2932 },
 { 185,-2932 }, { 186,-2932 }, { 187,-2932 }, { 188,-2932 }, { 189,-2932 },

 { 190,-2932 }, { 191,-2932 }, { 192,-2932 }, { 193,-2932 }, { 194,-2932 },
 { 195,-2932 }, { 196,-2932 }, { 197,-2932 }, { 198,-2932 }, { 199,-2932 },
 { 200,-2932 }, { 201,-2932 }, { 202,-2932 }, { 203,-2932 }, { 204,-2932 },
 { 205,-2932 }, { 206,-2932 }, { 207,-2932 }, { 208,-2932 }, { 209,-2932 },
 { 210,-2932 }, { 211,-2932 }, { 212,-2932 }, { 213,-2932 }, { 214,-2932 },
 { 215,-2932 }, { 216,-2932 }, { 217,-2932 }, { 218,-2932 }, { 219,-2932 },
 { 220,-2932 }, { 221,-2932 }, { 222,-2932 }, { 223,-2932 }, { 224,-2932 },
 { 225,-2932 }, { 226,-2932 }, { 227,-2932 }, { 228,-2932 }, { 229,-2932 },
 { 230,-2932 }, { 231,-2932 }, { 232,-2932 }, { 233,-2932 }, { 234,-2932 },
 { 235,-2932 }, { 236,-2932 }, { 237,-2932 }, { 238,-2932 }, { 239,-2932 },

 { 240,-2932 }, { 241,-2932 }, { 242,-2932 }, { 243,-2932 }, { 244,-2932 },
 { 245,-2932 }, { 246,-2932 }, { 247,-2932 }, { 248,-2932 }, { 249,-2932 },
 { 250,-2932 }, { 251,-2932 }, { 252,-2932 }, { 253,-2932 }, { 254,-2932 },
 { 255,-2932 }, { 256,-2932 }, {   0,  55 }, {   0,1032 }, {   1,-2158 },
 {   2,-2158 }, {   3,-2158 }, {   4,-2158 }, {   5,-2158 }, {   6,-2158 },
 {   7,-2158 }, {   8,-2158 }, {   9,-1900 }, {  10,-1642 }, {  11,-2158 },
 {  12,-1900 }, {  13,-1642 }, {  14,-2158 }, {  15,-2158 }, {  16,-2158 },
 {  17,-2158 }, {  18,-2158 }, {  19,-2158 }, {  20,-2158 }, {  21,-2158 },
 {  22,-2158 }, {  23,-2158 }, {  24,-2158 }, {  25,-2158 }, {  26,-2158 },
 {  27,-2158 }, {  28,-2158 }, {  29,-2158 }, {  30,-2158 }, {  31,-2158 },

 {  32,-1900 }, {  33,-2158 }, {  34,-2158 }, {  35,-2158 }, {  36,-2158 },
 {  37,-2158 }, {  38,-2158 }, {  39,-3706 }, {  40,-2158 }, {  41,-2158 },
 {  42,-2158 }, {  43,-2158 }, {  44,-2158 }, {  45,-1595 }, {  46,-2158 },
 {  47,-2158 }, {  48,-2158 }, {  49,-2158 }, {  50,-2158 }, {  51,-2158 },
 {  52,-2158 }, {  53,-2158 }, {  54,-2158 }, {  55,-2158 }, {  56,-2158 },
 {  57,-2158 }, {  58,-2158 }, {  59,-2158 }, {  60,-2158 }, {  61,-2158 },
 {  62,-2158 }, {  63,-2158 }, {  64,-2158 }, {  65,-2158 }, {  66,-2158 },
 {  67,-2158 }, {  68,-2158 }, {  69,-2158 }, {  70,-2158 }, {  71,-2158 },
 {  72,-2158 }, {  73,-2158 }, {  74,-2158 }, {  75,-2158 }, {  76,-2158 },
 {  77,-2158 }, {  78,-2158 }, {  79,-2158 }, {  80,-2158 }, {  81,-2158 },

 {  82,-2158 }, {  83,-2158 }, {  84,-2158 }, {  85,-2158 }, {  86,-2158 },
 {  87,-2158 }, {  88,-2158 }, {  89,-2158 }, {  90,-2158 }, {  91,-2158 },
 {  92,-2158 }, {  93,-2158 }, {  94,-2158 }, {  95,-2158 }, {  96,-2158 },
 {  97,-2158 }, {  98,-2158 }, {  99,-2158 }, { 100,-2158 }, { 101,-2158 },
 { 102,-2158 }, { 103,-2158 }, { 104,-2158 }, { 105,-2158 }, { 106,-2158 },
 { 107,-2158 }, { 108,-2158 }, { 109,-2158 }, { 110,-2158 }, { 111,-2158 },
 { 112,-2158 }, { 113,-2158 }, { 114,-2158 }, { 115,-2158 }, { 116,-2158 },
 { 117,-2158 }, { 118,-2158 }, { 119,-2158 }, { 120,-2158 }, { 121,-2158 },
 { 122,-2158 }, { 123,-2158 }, { 124,-2158 }, { 125,-2158 }, { 126,-2158 },
 { 127,-2158 }, { 128,-2158 }, { 129,-2158 }, { 130,-2158 }, { 131,-2158 },

 { 132,-2158 }, { 133,-2158 }, { 134,-2158 }, { 135,-2158 }, { 136,-2158 },
 { 137,-2158 }, { 138,-2158 }, { 139,-2158 }, { 140,-2158 }, { 141,-2158 },
 { 142,-2158 }, { 143,-2158 }, { 144,-2158 }, { 145,-2158 }, { 146,-2158 },
 { 147,-2158 }, { 148,-2158 }, { 149,-2158 }, { 150,-2158 }, { 151,-2158 },
 { 152,-2158 }, { 153,-2158 }, { 154,-2158 }, { 155,-2158 }, { 156,-2158 },
 { 157,-2158 }, { 158,-2158 }, { 159,-2158 }, { 160,-2158 }, { 161,-2158 },
 { 162,-2158 }, { 163,-2158 }, { 164,-2158 }, { 165,-2158 }, { 166,-2158 },
 { 167,-2158 }, { 168,-2158 }, { 169,-2158 }, { 170,-2158 }, { 171,-2158 },
 { 172,-2158 }, { 173,-2158 }, { 174,-2158 }, { 175,-2158 }, { 176,-2158 },
 { 177,-2158 }, { 178,-2158 }, { 179,-2158 }, { 180,-2158 }, { 181,-2158 },

 { 182,-2158 }, { 183,-2158 }, { 184,-2158 }, { 185,-2158 }, { 186,-2158 },
 { 187,-2158 }, { 188,-2158 }, { 189,-2158 }, { 190,-2158 }, { 191,-2158 },
 { 192,-2158 }, { 193,-2158 }, { 194,-2158 }, { 195,-2158 }, { 196,-2158 },
 { 197,-2158 }, { 198,-2158 }, { 199,-2158 }, { 200,-2158 }, { 201,-2158 },
 { 202,-2158 }, { 203,-2158 }, { 204,-2158 }, { 205,-2158 }, { 206,-2158 },
 { 207,-2158 }, { 208,-2158 }, { 209,-2158 }, { 210,-2158 }, { 211,-2158 },
 { 212,-2158 }, { 213,-2158 }, { 214,-2158 }, { 215,-2158 }, { 216,-2158 },
 { 217,-2158 }, { 218,-2158 }, { 219,-2158 }, { 220,-2158 }, { 221,-2158 },
 { 222,-2158 }, { 223,-2158 }, { 224,-2158 }, { 225,-2158 }, { 226,-2158 },
 { 227,-2158 }, { 228,-2158 }, { 229,-2158 }, { 230,-2158 }, { 231,-2158 },

 { 232,-2158 }, { 233,-2158 }, { 234,-2158 }, { 235,-2158 }, { 236,-2158 },
 { 237,-2158 }, { 238,-2158 }, { 239,-2158 }, { 240,-2158 }, { 241,-2158 },
 { 242,-2158 }, { 243,-2158 }, { 244,-2158 }, { 245,-2158 }, { 246,-2158 },
 { 247,-2158 }, { 248,-2158 }, { 249,-2158 }, { 250,-2158 }, { 251,-2158 },
 { 252,-2158 }, { 253,-2158 }, { 254,-2158 }, { 255,-2158 }, { 256,-2158 },
 {   0,  55 }, {   0, 774 }, {   1,-27567 }, {   2,-27567 }, {   3,-27567 },
 {   4,-27567 }, {   5,-27567 }, {   6,-27567 }, {   7,-27567 }, {   8,-27567 },
 {   9,-27567 }, {  10,-27567 }, {  11,-27567 }, {  12,-27567 }, {  13,-27567 },
 {  14,-27567 }, {  15,-27567 }, {  16,-27567 }, {  17,-27567 }, {  18,-27567 },
 {  19,-27567 }, {  20,-27567 }, {  21,-27567 }, {  22,-27567 }, {  23,-27567 },

 {  24,-27567 }, {  25,-27567 }, {  26,-27567 }, {  27,-27567 }, {  28,-27567 },
 {  29,-27567 }, {  30,-27567 }, {  31,-27567 }, {  32,-27567 }, {  33,-27567 },
 {  34,-27567 }, {  35,-27567 }, {  36,-27567 }, {  37,-27567 }, {  38,-27567 },
 {   0,   0 }, {  40,-27567 }, {  41,-27567 }, {  42,-27567 }, {  43,-27567 },
 {  44,-27567 }, {  45,-27567 }, {  46,-27567 }, {  47,-27567 }, {  48,-27567 },
 {  49,-27567 }, {  50,-27567 }, {  51,-27567 }, {  52,-27567 }, {  53,-27567 },
 {  54,-27567 }, {  55,-27567 }, {  56,-27567 }, {  57,-27567 }, {  58,-27567 },
 {  59,-27567 }, {  60,-27567 }, {  61,-27567 }, {  62,-27567 }, {  63,-27567 },
 {  64,-27567 }, {  65,-27567 }, {  66,-27567 }, {  67,-27567 }, {  68,-27567 },
 {  69,-27567 }, {  70,-27567 }, {  71,-27567 }, {  72,-27567 }, {  73,-27567 },

 {  74,-27567 }, {  75,-27567 }, {  76,-27567 }, {  77,-27567 }, {  78,-27567 },
 {  79,-27567 }, {  80,-27567 }, {  81,-27567 }, {  82,-27567 }, {  83,-27567 },
 {  84,-27567 }, {  85,-27567 }, {  86,-27567 }, {  87,-27567 }, {  88,-27567 },
 {  89,-27567 }, {  90,-27567 }, {  91,-27567 }, {  92,-27567 }, {  93,-27567 },
 {  94,-27567 }, {  95,-27567 }, {  96,-27567 }, {  97,-27567 }, {  98,-27567 },
 {  99,-27567 }, { 100,-27567 }, { 101,-27567 }, { 102,-27567 }, { 103,-27567 },
 { 104,-27567 }, { 105,-27567 }, { 106,-27567 }, { 107,-27567 }, { 108,-27567 },
 { 109,-27567 }, { 110,-27567 }, { 111,-27567 }, { 112,-27567 }, { 113,-27567 },
 { 114,-27567 }, { 115,-27567 }, { 116,-27567 }, { 117,-27567 }, { 118,-27567 },
 { 119,-27567 }, { 120,-27567 }, { 121,-27567 }, { 122,-27567 }, { 123,-27567 },

 { 124,-27567 }, { 125,-27567 }, { 126,-27567 }, { 127,-27567 }, { 128,-27567 },
 { 129,-27567 }, { 130,-27567 }, { 131,-27567 }, { 132,-27567 }, { 133,-27567 },
 { 134,-27567 }, { 135,-27567 }, { 136,-27567 }, { 137,-27567 }, { 138,-27567 },
 { 139,-27567 }, { 140,-27567 }, { 141,-27567 }, { 142,-27567 }, { 143,-27567 },
 { 144,-27567 }, { 145,-27567 }, { 146,-27567 }, { 147,-27567 }, { 148,-27567 },
 { 149,-27567 }, { 150,-27567 }, { 151,-27567 }, { 152,-27567 }, { 153,-27567 },
 { 154,-27567 }, { 155,-27567 }, { 156,-27567 }, { 157,-27567 }, { 158,-27567 },
 { 159,-27567 }, { 160,-27567 }, { 161,-27567 }, { 162,-27567 }, { 163,-27567 },
 { 164,-27567 }, { 165,-27567 }, { 166,-27567 }, { 167,-27567 }, { 168,-27567 },
 { 169,-27567 }, { 170,-27567 }, { 171,-27567 }, { 172,-27567 }, { 173,-27567 },

 { 174,-27567 }, { 175,-27567 }, { 176,-27567 }, { 177,-27567 }, { 178,-27567 },
 { 179,-27567 }, { 180,-27567 }, { 181,-27567 }, { 182,-27567 }, { 183,-27567 },
 { 184,-27567 }, { 185,-27567 }, { 186,-27567 }, { 187,-27567 }, { 188,-27567 },
 { 189,-27567 }, { 190,-27567 }, { 191,-27567 }, { 192,-27567 }, { 193,-27567 },
 { 194,-27567 }, { 195,-27567 }, { 196,-27567 }, { 197,-27567 }, { 198,-27567 },
 { 199,-27567 }, { 200,-27567 }, { 201,-27567 }, { 202,-27567 }, { 203,-27567 },
 { 204,-27567 }, { 205,-27567 }, { 206,-27567 }, { 207,-27567 }, { 208,-27567 },
 { 209,-27567 }, { 210,-27567 }, { 211,-27567 }, { 212,-27567 }, { 213,-27567 },
 { 214,-27567 }, { 215,-27567 }, { 216,-27567 }, { 217,-27567 }, { 218,-27567 },
 { 219,-27567 }, { 220,-27567 }, { 221,-27567 }, { 222,-27567 }, { 223,-27567 },

 { 224,-27567 }, { 225,-27567 }, { 226,-27567 }, { 227,-27567 }, { 228,-27567 },
 { 229,-27567 }, { 230,-27567 }, { 231,-27567 }, { 232,-27567 }, { 233,-27567 },
 { 234,-27567 }, { 235,-27567 }, { 236,-27567 }, { 237,-27567 }, { 238,-27567 },
 { 239,-27567 }, { 240,-27567 }, { 241,-27567 }, { 242,-27567 }, { 243,-27567 },
 { 244,-27567 }, { 245,-27567 }, { 246,-27567 }, { 247,-27567 }, { 248,-27567 },
 { 249,-27567 }, { 250,-27567 }, { 251,-27567 }, { 252,-27567 }, { 253,-27567 },
 { 254,-27567 }, { 255,-27567 }, { 256,-27567 }, {   0,  28 }, {   0, 516 },
 {   1,-1595 }, {   2,-1595 }, {   3,-1595 }, {   4,-1595 }, {   5,-1595 },
 {   6,-1595 }, {   7,-1595 }, {   8,-1595 }, {   9,-1337 }, {  10,-1079 },
 {  11,-1595 }, {  12,-1337 }, {  13,-1079 }, {  14,-1595 }, {  15,-1595 },

 {  16,-1595 }, {  17,-1595 }, {  18,-1595 }, {  19,-1595 }, {  20,-1595 },
 {  21,-1595 }, {  22,-1595 }, {  23,-1595 }, {  24,-1595 }, {  25,-1595 },
 {  26,-1595 }, {  27,-1595 }, {  28,-1595 }, {  29,-1595 }, {  30,-1595 },
 {  31,-1595 }, {  32,-1337 }, {  33,-1595 }, {  34,-1595 }, {  35,-1595 },
 {  36,-1595 }, {  37,-1595 }, {  38,-1595 }, {  39,-3190 }, {  40,-1595 },
 {  41,-1595 }, {  42,-1595 }, {  43,-1595 }, {  44,-1595 }, {  45,-1032 },
 {  46,-1595 }, {  47,-1595 }, {  48,-1595 }, {  49,-1595 }, {  50,-1595 },
 {  51,-1595 }, {  52,-1595 }, {  53,-1595 }, {  54,-1595 }, {  55,-1595 },
 {  56,-1595 }, {  57,-1595 }, {  58,-1595 }, {  59,-1595 }, {  60,-1595 },
 {  61,-1595 }, {  62,-1595 }, {  63,-1595 }, {  64,-1595 }, {  65,-1595 },

 {  66,-1595 }, {  67,-1595 }, {  68,-1595 }, {  69,-1595 }, {  70,-1595 },
 {  71,-1595 }, {  72,-1595 }, {  73,-1595 }, {  74,-1595 }, {  75,-1595 },
 {  76,-1595 }, {  77,-1595 }, {  78,-1595 }, {  79,-1595 }, {  80,-1595 },
 {  81,-1595 }, {  82,-1595 }, {  83,-1595 }, {  84,-1595 }, {  85,-1595 },
 {  86,-1595 }, {  87,-1595 }, {  88,-1595 }, {  89,-1595 }, {  90,-1595 },
 {  91,-1595 }, {  92,-1595 }, {  93,-1595 }, {  94,-1595 }, {  95,-1595 },
 {  96,-1595 }, {  97,-1595 }, {  98,-1595 }, {  99,-1595 }, { 100,-1595 },
 { 101,-1595 }, { 102,-1595 }, { 103,-1595 }, { 104,-1595 }, { 105,-1595 },
 { 106,-1595 }, { 107,-1595 }, { 108,-1595 }, { 109,-1595 }, { 110,-1595 },
 { 111,-1595 }, { 112,-1595 }, { 113,-1595 }, { 114,-1595 }, { 115,-1595 },

 { 116,-1595 }, { 117,-1595 }, { 118,-1595 }, { 119,-1595 }, { 120,-1595 },
 { 121,-1595 }, { 122,-1595 }, { 123,-1595 }, { 124,-1595 }, { 125,-1595 },
 { 126,-1595 }, { 127,-1595 }, { 128,-1595 }, { 129,-1595 }, { 130,-1595 },
 { 131,-1595 }, { 132,-1595 }, { 133,-1595 }, { 134,-1595 }, { 135,-1595 },
 { 136,-1595 }, { 137,-1595 }, { 138,-1595 }, { 139,-1595 }, { 140,-1595 },
 { 141,-1595 }, { 142,-1595 }, { 143,-1595 }, { 144,-1595 }, { 145,-1595 },
 { 146,-1595 }, { 147,-1595 }, { 148,-1595 }, { 149,-1595 }, { 150,-1595 },
 { 151,-1595 }, { 152,-1595 }, { 153,-1595 }, { 154,-1595 }, { 155,-1595 },
 { 156,-1595 }, { 157,-1595 }, { 158,-1595 }, { 159,-1595 }, { 160,-1595 },
 { 161,-1595 }, { 162,-1595 }, { 163,-1595 }, { 164,-1595 }, { 165,-1595 },

 { 166,-1595 }, { 167,-1595 }, { 168,-1595 }, { 169,-1595 }, { 170,-1595 },
 { 171,-1595 }, { 172,-1595 }, { 173,-1595 }, { 174,-1595 }, { 175,-1595 },
 { 176,-1595 }, { 177,-1595 }, { 178,-1595 }, { 179,-1595 }, { 180,-1595 },
 { 181,-1595 }, { 182,-1595 }, { 183,-1595 }, { 184,-1595 }, { 185,-1595 },
 { 186,-1595 }, { 187,-1595 }, { 188,-1595 }, { 189,-1595 }, { 190,-1595 },
 { 191,-1595 }, { 192,-1595 }, { 193,-1595 }, { 194,-1595 }, { 195,-1595 },
 { 196,-1595 }, { 197,-1595 }, { 198,-1595 }, { 199,-1595 }, { 200,-1595 },
 { 201,-1595 }, { 202,-1595 }, { 203,-1595 }, { 204,-1595 }, { 205,-1595 },
 { 206,-1595 }, { 207,-1595 }, { 208,-1595 }, { 209,-1595 }, { 210,-1595 },
 { 211,-1595 }, { 212,-1595 }, { 213,-1595 }, { 214,-1595 }, { 215,-1595 },

 { 216,-1595 }, { 217,-1595 }, { 218,-1595 }, { 219,-1595 }, { 220,-1595 },
 { 221,-1595 }, { 222,-1595 }, { 223,-1595 }, { 224,-1595 }, { 225,-1595 },
 { 226,-1595 }, { 227,-1595 }, { 228,-1595 }, { 229,-1595 }, { 230,-1595 },
 { 231,-1595 }, { 232,-1595 }, { 233,-1595 }, { 234,-1595 }, { 235,-1595 },
 { 236,-1595 }, { 237,-1595 }, { 238,-1595 }, { 239,-1595 }, { 240,-1595 },
 { 241,-1595 }, { 242,-1595 }, { 243,-1595 }, { 244,-1595 }, { 245,-1595 },
 { 246,-1595 }, { 247,-1595 }, { 248,-1595 }, { 249,-1595 }, { 250,-1595 },
 { 251,-1595 }, { 252,-1595 }, { 253,-1595 }, { 254,-1595 }, { 255,-1595 },
 { 256,-1595 }, {   0,  28 }, {   0, 258 }, {   1,-28081 }, {   2,-28081 },
 {   3,-28081 }, {   4,-28081 }, {   5,-28081 }, {   6,-28081 }, {   7,-28081 },

 {   8,-28081 }, {   9,-28081 }, {  10,-28081 }, {  11,-28081 }, {  12,-28081 },
 {  13,-28081 }, {  14,-28081 }, {  15,-28081 }, {  16,-28081 }, {  17,-28081 },
 {  18,-28081 }, {  19,-28081 }, {  20,-28081 }, {  21,-28081 }, {  22,-28081 },
 {  23,-28081 }, {  24,-28081 }, {  25,-28081 }, {  26,-28081 }, {  27,-28081 },
 {  28,-28081 }, {  29,-28081 }, {  30,-28081 }, {  31,-28081 }, {  32,-28081 },
 {  33,-28081 }, {  34,-28081 }, {  35,-28081 }, {  36,-28081 }, {  37,-28081 },
 {  38,-28081 }, {   0,   0 }, {  40,-28081 }, {  41,-28081 }, {  42,-28081 },
 {  43,-28081 }, {  44,-28081 }, {  45,-28081 }, {  46,-28081 }, {  47,-28081 },
 {  48,-28081 }, {  49,-28081 }, {  50,-28081 }, {  51,-28081 }, {  52,-28081 },
 {  53,-28081 }, {  54,-28081 }, {  55,-28081 }, {  56,-28081 }, {  57,-28081 },

 {  58,-28081 }, {  59,-28081 }, {  60,-28081 }, {  61,-28081 }, {  62,-28081 },
 {  63,-28081 }, {  64,-28081 }, {  65,-28081 }, {  66,-28081 }, {  67,-28081 },
 {  68,-28081 }, {  69,-28081 }, {  70,-28081 }, {  71,-28081 }, {  72,-28081 },
 {  73,-28081 }, {  74,-28081 }, {  75,-28081 }, {  76,-28081 }, {  77,-28081 },
 {  78,-28081 }, {  79,-28081 }, {  80,-28081 }, {  81,-28081 }, {  82,-28081 },
 {  83,-28081 }, {  84,-28081 }, {  85,-28081 }, {  86,-28081 }, {  87,-28081 },
 {  88,-28081 }, {  89,-28081 }, {  90,-28081 }, {  91,-28081 }, {  92,-28081 },
 {  93,-28081 }, {  94,-28081 }, {  95,-28081 }, {  96,-28081 }, {  97,-28081 },
 {  98,-28081 }, {  99,-28081 }, { 100,-28081 }, { 101,-28081 }, { 102,-28081 },
 { 103,-28081 }, { 104,-28081 }, { 105,-28081 }, { 106,-28081 }, { 107,-28081 },

 { 108,-28081 }, { 109,-28081 }, { 110,-28081 }, { 111,-28081 }, { 112,-28081 },
 { 113,-28081 }, { 114,-28081 }, { 115,-28081 }, { 116,-28081 }, { 117,-28081 },
 { 118,-28081 }, { 119,-28081 }, { 120,-28081 }, { 121,-28081 }, { 122,-28081 },
 { 123,-28081 }, { 124,-28081 }, { 125,-28081 }, { 126,-28081 }, { 127,-28081 },
 { 128,-28081 }, { 129,-28081 }, { 130,-28081 }, { 131,-28081 }, { 132,-28081 },
 { 133,-28081 }, { 134,-28081 }, { 135,-28081 }, { 136,-28081 }, { 137,-28081 },
 { 138,-28081 }, { 139,-28081 }, { 140,-28081 }, { 141,-28081 }, { 142,-28081 },
 { 143,-28081 }, { 144,-28081 }, { 145,-28081 }, { 146,-28081 }, { 147,-28081 },
 { 148,-28081 }, { 149,-28081 }, { 150,-28081 }, { 151,-28081 }, { 152,-28081 },
 { 153,-28081 }, { 154,-28081 }, { 155,-28081 }, { 156,-28081 }, { 157,-28081 },

 { 158,-28081 }, { 159,-28081 }, { 160,-28081 }, { 161,-28081 }, { 162,-28081 },
 { 163,-28081 }, { 164,-28081 }, { 165,-28081 }, { 166,-28081 }, { 167,-28081 },
 { 168,-28081 }, { 169,-28081 }, { 170,-28081 }, { 171,-28081 }, { 172,-28081 },
 { 173,-28081 }, { 174,-28081 }, { 175,-28081 }, { 176,-28081 }, { 177,-28081 },
 { 178,-28081 }, { 179,-28081 }, { 180,-28081 }, { 181,-28081 }, { 182,-28081 },
 { 183,-28081 }, { 184,-28081 }, { 185,-28081 }, { 186,-28081 }, { 187,-28081 },
 { 188,-28081 }, { 189,-28081 }, { 190,-28081 }, { 191,-28081 }, { 192,-28081 },
 { 193,-28081 }, { 194,-28081 }, { 195,-28081 }, { 196,-28081 }, { 197,-28081 },
 { 198,-28081 }, { 199,-28081 }, { 200,-28081 }, { 201,-28081 }, { 202,-28081 },
 { 203,-28081 }, { 204,-28081 }, { 205,-28081 }, { 206,-28081 }, { 207,-28081 },

 { 208,-28081 }, { 209,-28081 }, { 210,-28081 }, { 211,-28081 }, { 212,-28081 },
 { 213,-28081 }, { 214,-28081 }, { 215,-28081 }, { 216,-28081 }, { 217,-28081 },
 { 218,-28081 }, { 219,-28081 }, { 220,-28081 }, { 221,-28081 }, { 222,-28081 },
 { 223,-28081 }, { 224,-28081 }, { 225,-28081 }, { 226,-28081 }, { 227,-28081 },
 { 228,-28081 }, { 229,-28081 }, { 230,-28081 }, { 231,-28081 }, { 232,-28081 },
 { 233,-28081 }, { 234,-28081 }, { 235,-28081 }, { 236,-28081 }, { 237,-28081 },
 { 238,-28081 }, { 239,-28081 }, { 240,-28081 }, { 241,-28081 }, { 242,-28081 },
 { 243,-28081 }, { 244,-28081 }, { 245,-28081 }, { 246,-28081 }, { 247,-28081 },
 { 248,-28081 }, { 249,-28081 }, { 250,-28081 }, { 251,-28081 }, { 252,-28081 },
 { 253,-28081 }, { 254,-28081 }, { 255,-28081 }, { 256,-28081 }, { 257,  81 },

 {   1,   0 },    };

static __thread yyconst struct yy_trans_info *yy_start_state_list[27] =
    {
    &yy_transition[1],
    &yy_transition[3],
    &yy_transition[261],
    &yy_transition[519],
    &yy_transition[777],
    &yy_transition[1035],
    &yy_transition[1293],
    &yy_transition[1551],
    &yy_transition[1809],
    &yy_transition[2067],
    &yy_transition[2325],
    &yy_transition[2583],
    &yy_transition[2841],
    &yy_transition[3099],
    &yy_transition[3357],
    &yy_transition[3615],
    &yy_transition[3873],
    &yy_transition[4131],
    &yy_transition[4389],
    &yy_transition[4647],
    &yy_transition[4905],
    &yy_transition[5163],
    &yy_transition[5421],
    &yy_transition[5679],
    &yy_transition[5937],
    &yy_transition[6195],
    &yy_transition[6453],

    }
;

/* The intent behind this definition is that it'll catch
 * any uses of REJECT which flex missed.
 */
#define REJECT reject_used_but_not_detected
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET



/*
 * GUC variables.  This is a DIRECT violation of the warning given at the
 * head of gram.y, ie flex/bison code must not depend on any GUC variables;
 * as such, changing their values can induce very unintuitive behavior.
 * But we shall have to live with it until we can remove these variables.
 */
__thread int			backslash_quote = PG_BACKSLASH_QUOTE_SAFE_ENCODING;

__thread bool		escape_string_warning = true;

__thread bool		standard_conforming_strings = true;


// /*
//  * Set the type of YYSTYPE.
//  */
// #define YYSTYPE core_YYSTYPE

/*
 * Set the type of yyextra.  All state variables used by the scanner should
 * be in yyextra, *not* statically allocated.
 */
#define YY_EXTRA_TYPE core_yy_extra_type *

/*
 * Each call to core_yylex must set yylloc to the location of the found token
 * (expressed as a byte offset from the start of the input text).
 * When we parse a token that requires multiple lexer rules to process,
 * this should be done in the first such rule, else yylloc will point
 * into the middle of the token.
 */
#define SET_YYLLOC()  (*(yylloc) = yytext - yyextra->scanbuf)

/*
 * Advance yylloc by the given number of bytes.
 */
#define ADVANCE_YYLLOC(delta)  ( *(yylloc) += (delta) )

#define startlit()	( yyextra->literallen = 0 )
static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner);
static char *litbufdup(core_yyscan_t yyscanner);
static char *litbuf_udeescape(unsigned char escape, core_yyscan_t yyscanner);
static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner);
static int	process_integer_literal(const char *token, YYSTYPE *lval);
static bool is_utf16_surrogate_first(pg_wchar c);
static bool is_utf16_surrogate_second(pg_wchar c);
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second);
static void addunicode(pg_wchar c, yyscan_t yyscanner);
static bool check_uescapechar(unsigned char escape);

#define scan_error(msg)  scanner_yyerror(msg, yyscanner)

#define lexer_errposition()  scanner_errposition(*(yylloc), yyscanner)

static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner);
static void check_escape_warning(core_yyscan_t yyscanner);

/*
 * Work around a bug in flex 2.5.35: it emits a couple of functions that
 * it forgets to emit declarations for.  Since we use -Wmissing-prototypes,
 * this would cause warnings.  Providing our own declarations should be
 * harmless even when the bug gets fixed.
 */
extern int	core_yyget_column(yyscan_t yyscanner);
extern void core_yyset_column(int column_no, yyscan_t yyscanner);

#define YY_NO_INPUT 1
/*
 * OK, here is a short description of lex/flex rules behavior.
 * The longest pattern which matches an input string is always chosen.
 * For equal-length patterns, the first occurring in the rules list is chosen.
 * LEX_INITIAL_STATE is the starting state, to which all non-conditional rules apply.
 * Exclusive states change parsing rules while the state is active.  When in
 * an exclusive state, only those rules defined for that state apply.
 *
 * We use exclusive states for quoted strings, extended comments,
 * and to eliminate parsing troubles for numeric strings.
 * Exclusive states:
 *  <LEX_BITSTRING_LITERAL> bit string literal
 *  <LEX_EXTENDED_C_COMMENTS> extended C-style comments
 *  <LEX_DELIMITED_IDENTIFIER> delimited identifiers (double-quoted identifiers)
 *  <LEX_HEXADECIMAL_NUMERIC_STRING> hexadecimal numeric string
 *  <LEX_STANDARD_QUOTED_STRING> standard quoted strings
 *  <LEX_EXTENDED_QUOTED_STRING> extended quoted strings (support backslash escape sequences)
 *  <LEX_DOLLAR_QUOTED_STRING> $foo$ quoted strings
 *  <LEX_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE> quoted identifier with Unicode escapes
 *  <LEX_END_OF_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE> end of a quoted identifier with Unicode escapes, UESCAPE can follow
 *  <LEX_QUOTED_STRING_WITH_UNICODE_ESCAPE> quoted string with Unicode escapes
 *  <LEX_END_OF_QUOTED_STRING_WITH_UNICODE_ESCAPE> end of a quoted string with Unicode escapes, UESCAPE can follow
 *  <LEX_UNICODE_SURROGATE_IN_EXTENDED_QUOTED_STRING> Unicode surrogate pair in extended quoted string
 *
 * Remember to add an <<EOF>> case whenever you add a new exclusive state!
 * The default one is probably not the right thing.
 */












/*
 * In order to make the world safe for Windows and Mac clients as well as
 * Unix ones, we accept either \n or \r as a newline.  A DOS-style \r\n
 * sequence will be seen as two successive newlines, but that doesn't cause
 * any problems.  Comments that start with -- and extend to the next
 * newline are treated as equivalent to a single whitespace character.
 *
 * NOTE a fine point: if there is no newline following --, we will absorb
 * everything to the end of the input as a comment.  This is correct.  Older
 * versions of Postgres failed to recognize -- as a comment if the input
 * did not end with a newline.
 *
 * XXX perhaps \f (formfeed) should be treated as a newline as well?
 *
 * XXX if you change the set of whitespace characters, fix scanner_isspace()
 * to agree, and see also the plpgsql lexer.
 */
/*
 * SQL requires at least one newline in the whitespace separating
 * string literals that are to be concatenated.  Silly, but who are we
 * to argue?  Note that {whitespace_with_newline} should not have * after
 * it, whereas {whitespace} should generally have a * after it...
 */
/*
 * To ensure that {quotecontinue} can be scanned without having to back up
 * if the full pattern isn't matched, we include trailing whitespace in
 * {quotestop}.  This matches all cases where {quotecontinue} fails to match,
 * except for {quote} followed by whitespace and just one "-" (not two,
 * which would start a {comment}).  To cover that we have {quotefail}.
 * The actions for {quotestop} and {quotefail} must throw back characters
 * beyond the quote proper.
 */
/* Bit string
 * It is tempting to scan the string for only those characters
 * which are allowed. However, this leads to silently swallowed
 * characters if illegal characters are included in the string.
 * For example, if xbinside is [01] then B'ABCD' is interpreted
 * as a zero-length string, and the ABCD' is lost!
 * Better to pass the string forward and let the input routines
 * validate the contents.
 */
/* Hexadecimal number */
/* National character */
/* Quoted string that allows backslash escapes */
/* Normalized escaped string */
/* Extended quote
 * xqdouble implements embedded quote, ''''
 */
/* $foo$ style quotes ("dollar quoting")
 * The quoted string starts with $foo$ where "foo" is an optional string
 * in the form of an identifier, except that it may not contain "$",
 * and extends to the first occurrence of an identical string.
 * There is *no* processing of the quoted text.
 *
 * {dolqfailed} is an error rule to avoid scanner backup when {dolqdelim}
 * fails to match its trailing "$".
 */
/* Double quote
 * Allows embedded spaces and other special characters into identifiers.
 */
/* Unicode escapes */
/* error rule to avoid backup */
/* Quoted identifier with Unicode escapes */
/* Quoted string with Unicode escapes */
/* Optional UESCAPE after a quoted string or identifier with Unicode escapes. */
/* error rule to avoid backup */
/* C-style comments
 *
 * The "extended comment" syntax closely resembles allowable operator syntax.
 * The tricky part here is to get lex to recognize a string starting with
 * slash-star as a comment, when interpreting it as an operator would produce
 * a longer match --- remember lex will prefer a longer match!  Also, if we
 * have something like plus-slash-star, lex will think this is a 3-character
 * operator whereas we want to see it as a + operator and a comment start.
 * The solution is two-fold:
 * 1. append {op_chars}* to xcstart so that it matches as much text as
 *    {operator} would. Then the tie-breaker (first matching rule of same
 *    length) ensures xcstart wins.  We put back the extra stuff with yyless()
 *    in case it contains a star-slash that should terminate the comment.
 * 2. In the operator rule, check for slash-star within the operator, and
 *    if found throw it back with yyless().  This handles the plus-slash-star
 *    problem.
 * Dash-dash comments have similar interactions with the operator rule.
 */
/* Assorted special-case operators and operator-like tokens */
/*
 * "self" is the set of chars that should be returned as single-character
 * tokens.  "op_chars" is the set of chars that can make up "Op" tokens,
 * which can be one or more characters long (but if a single-char token
 * appears in the "self" set, it is not to be returned as an Op).  Note
 * that the sets overlap, but each has some chars that are not in the other.
 *
 * If you change either set, adjust the character lists appearing in the
 * rule for "operator"!
 */
/* we no longer allow unary minus in numbers.
 * instead we pass it separately to parser. there it gets
 * coerced via doNegate() -- Leon aug 20 1999
 *
 * {decimalfail} is used because we would like "1..10" to lex as 1, dot_dot, 10.
 *
 * {realfail1} and {realfail2} are added to prevent the need for scanner
 * backup when the {real} rule fails to match completely.
 */
/*
 * Dollar quoted strings are totally opaque, and no escaping is done on them.
 * Other quoted strings must allow some special characters such as single-quote
 *  and newline.
 * Embedded single-quotes are implemented both in the SQL standard
 *  style of two adjacent single quotes "''" and in the Postgres/Java style
 *  of escaped-quote "\'".
 * Other embedded escaped characters are matched explicitly and the leading
 *  backslash is dropped from the string.
 * Note that xcstart must appear before operator, as explained above!
 *  Also whitespace (comment) must appear before operator.
 */


#define LEX_INITIAL_STATE 0
#define LEX_BITSTRING_LITERAL 1
#define LEX_EXTENDED_C_COMMENTS 2
#define LEX_DELIMITED_IDENTIFIER 3
#define LEX_HEXADECIMAL_NUMERIC_STRING 4
#define LEX_EXTENDED_QUOTED_STRING 5
#define LEX_STANDARD_QUOTED_STRING 6
#define LEX_DOLLAR_QUOTED_STRING 7
#define LEX_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE 8
#define LEX_END_OF_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE 9
#define LEX_QUOTED_STRING_WITH_UNICODE_ESCAPE 10
#define LEX_END_OF_QUOTED_STRING_WITH_UNICODE_ESCAPE 11
#define LEX_UNICODE_SURROGATE_IN_EXTENDED_QUOTED_STRING 12

#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.hpp", since it is non-ANSI. We include it way
 * down here because we want the user's section 1 to have been scanned first.
 * The user has a chance to override it with an option.
 */
//#include <unistd.h>
#endif

#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
#endif

/* Holds the entire state of the reentrant scanner. */
struct yyguts_t
    {

    /* User-defined. Not touched by flex. */
    YY_EXTRA_TYPE yyextra_r;

    /* The rest are the same as the globals declared in the non-reentrant scanner. */
    FILE *yyin_r, *yyout_r;
    size_t yy_buffer_stack_top; /**< index of top of stack. */
    size_t yy_buffer_stack_max; /**< capacity of stack. */
    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
    char yy_hold_char;
    yy_size_t yy_n_chars;
    yy_size_t yyleng_r;
    char *yy_c_buf_p;
    int yy_init;
    int yy_start;
    int yy_did_buffer_switch_on_eof;
    int yy_start_stack_ptr;
    int yy_start_stack_depth;
    int *yy_start_stack;
    yy_state_type yy_last_accepting_state;
    char* yy_last_accepting_cpos;

    int yylineno_r;
    int yy_flex_debug_r;

    char *yytext_r;
    int yy_more_flag;
    int yy_more_len;

    YYSTYPE * yylval_r;

    YYLTYPE * yylloc_r;

    }; /* end struct yyguts_t */

static int yy_init_globals (yyscan_t yyscanner );

#ifdef yylval
#undef yylval
#endif

#ifdef yylloc
#undef yylloc
#endif

/* This must go here because YYSTYPE and YYLTYPE are included
	* from bison output in section 1.*/
#define yylval yyg->yylval_r

#define yylloc yyg->yylloc_r

int core_yylex_init (yyscan_t* scanner);

int core_yylex_init_extra (YY_EXTRA_TYPE user_defined, yyscan_t* scanner);

/* Accessor methods to globals.
   These are made visible to non-reentrant scanners for convenience. */

int core_yylex_destroy (yyscan_t yyscanner );

int core_yyget_debug (yyscan_t yyscanner );

void core_yyset_debug (int debug_flag ,yyscan_t yyscanner );

YY_EXTRA_TYPE core_yyget_extra (yyscan_t yyscanner );

void core_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );

FILE *core_yyget_in (yyscan_t yyscanner );

void core_yyset_in  (FILE * in_str ,yyscan_t yyscanner );

FILE *core_yyget_out (yyscan_t yyscanner );

void core_yyset_out  (FILE * out_str ,yyscan_t yyscanner );

yy_size_t core_yyget_leng (yyscan_t yyscanner );

char *core_yyget_text (yyscan_t yyscanner );

int core_yyget_lineno (yyscan_t yyscanner );

void core_yyset_lineno (int line_number ,yyscan_t yyscanner );

YYSTYPE * core_yyget_lval (yyscan_t yyscanner );

void core_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );

       YYLTYPE *core_yyget_lloc (yyscan_t yyscanner );

        void core_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );

/* Macros after this point can all be overridden by user definitions in
 * section 1.
 */

#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int core_yywrap (yyscan_t yyscanner );
#else
extern int core_yywrap (yyscan_t yyscanner );
#endif
#endif

#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
#endif

#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
#endif

#ifndef YY_NO_INPUT

#ifdef __cplusplus
static int yyinput (yyscan_t yyscanner );
#else
static int input (yyscan_t yyscanner );
#endif

#endif

/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 8192
#endif

/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
 * is returned in "result".
 */
#ifndef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
		{ \
		int c = '*'; \
		yy_size_t n; \
		for ( n = 0; n < max_size && \
			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
			buf[n] = (char) c; \
		if ( c == '\n' ) \
			buf[n++] = (char) c; \
		if ( c == EOF && ferror( yyin ) ) \
			YY_FATAL_ERROR( "input in flex scanner failed" ); \
		result = n; \
		} \
	else \
		{ \
		errno=0; \
		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
			{ \
			if( errno != EINTR) \
				{ \
				YY_FATAL_ERROR( "input in flex scanner failed" ); \
				break; \
				} \
			errno=0; \
			clearerr(yyin); \
			} \
		}\
\

#endif

/* No semi-colon after return; correct usage is to write "yyterminate();" -
 * we don't want an extra ';' after the "return" because that will cause
 * some compilers to complain about unreachable statements.
 */
#ifndef yyterminate
#define yyterminate() return YY_NULL
#endif

/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif

/* Report a fatal error. */
#ifndef YY_FATAL_ERROR
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
#endif

/* end tables serialization structures and prototypes */

/* Default declaration of generated scanner - a define so the user can
 * easily add parameters.
 */
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1

extern int core_yylex \
               (core_YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);

#define YY_DECL int core_yylex \
               (core_YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
#endif /* !YY_DECL */

/* Code executed at the beginning of each rule, after yytext and yyleng
 * have been set up.
 */
#ifndef YY_USER_ACTION
#define YY_USER_ACTION
#endif

/* Code executed at the end of each rule. */
#ifndef YY_BREAK
#define YY_BREAK break;
#endif

#define YY_RULE_SETUP \
	YY_USER_ACTION

/** The main scanner function which does all the work.
 */
YY_DECL
{
	yy_state_type yy_current_state;
	char *yy_cp, *yy_bp;
	int yy_act;
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;






    yylval = (YYSTYPE*) yylval_param;

    yylloc = yylloc_param;

	if ( !yyg->yy_init )
		{
		yyg->yy_init = 1;

#ifdef YY_USER_INIT
		YY_USER_INIT;
#endif

		if ( ! yyg->yy_start )
			yyg->yy_start = 1;	/* first start state */

		if ( ! yyin )
			yyin = stdin;

		if ( ! yyout )
			yyout = stdout;

		if ( ! YY_CURRENT_BUFFER ) {
			core_yyensure_buffer_stack (yyscanner);
			YY_CURRENT_BUFFER_LVALUE =
				core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
		}

		core_yy_load_buffer_state(yyscanner );
		}

	while ( 1 )		/* loops until end-of-file is reached */
		{
		yy_cp = yyg->yy_c_buf_p;

		/* Support of yytext. */
		*yy_cp = yyg->yy_hold_char;

		/* yy_bp points to the position in yy_ch_buf of the start of
		 * the current run.
		 */
		yy_bp = yy_cp;

		yy_current_state = yy_start_state_list[yyg->yy_start];
yy_match:
		{
		yyconst struct yy_trans_info *yy_trans_info;

		YY_CHAR yy_c;

		for ( yy_c = YY_SC_TO_UI(*yy_cp);
		      (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->
		yy_verify == yy_c;
		      yy_c = YY_SC_TO_UI(*++yy_cp) )
			yy_current_state += yy_trans_info->yy_nxt;
		}

yy_find_action:
		yy_act = yy_current_state[-1].yy_nxt;

		YY_DO_BEFORE_ACTION;

do_action:	/* This label is used only to access EOF actions. */

		switch ( yy_act )
	{ /* beginning of action switch */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP

{
					/* ignore */
				}
	YY_BREAK
case 2:
YY_RULE_SETUP

{
					/* Set location in case of syntax error in comment */
					SET_YYLLOC();
					yyextra->xcdepth = 0;
					BEGIN(LEX_EXTENDED_C_COMMENTS);
					/* Put back any characters past slash-star; see above */
					yyless(2);
				}
	YY_BREAK
case 3:
YY_RULE_SETUP

{
					(yyextra->xcdepth)++;
					/* Put back any characters past slash-star; see above */
					yyless(2);
				}
	YY_BREAK
case 4:
YY_RULE_SETUP

{
					if (yyextra->xcdepth <= 0)
						BEGIN(LEX_INITIAL_STATE);
					else
						(yyextra->xcdepth)--;
				}
	YY_BREAK
case 5:
/* rule 5 can match eol */
YY_RULE_SETUP

{
					/* ignore */
				}
	YY_BREAK
case 6:
YY_RULE_SETUP

{
					/* ignore */
				}
	YY_BREAK
case 7:
YY_RULE_SETUP

{
					/* ignore */
				}
	YY_BREAK
case YY_STATE_EOF(LEX_EXTENDED_C_COMMENTS):

{ scan_error("unterminated /* comment"); }
	YY_BREAK
case 8:
YY_RULE_SETUP

{
					/* Binary bit type.
					 * At some point we should simply pass the string
					 * forward to the parser and label it there.
					 * In the meantime, place a leading "b" on the string
					 * to mark it for the input routine as a binary string.
					 */
					SET_YYLLOC();
					BEGIN(LEX_BITSTRING_LITERAL);
					startlit();
					addlitchar('b', yyscanner);
				}
	YY_BREAK
case 9:
/* rule 9 can match eol */

case 10:
/* rule 10 can match eol */
YY_RULE_SETUP

{
					yyless(1);
					BEGIN(LEX_INITIAL_STATE);
					yylval->str = litbufdup(yyscanner);
					return BCONST;
				}
	YY_BREAK
case 11:
/* rule 11 can match eol */

case 12:
/* rule 12 can match eol */
YY_RULE_SETUP

{
					addlit(yytext, yyleng, yyscanner);
				}
	YY_BREAK
case 13:
/* rule 13 can match eol */

case 14:
/* rule 14 can match eol */
YY_RULE_SETUP

{
					/* ignore */
				}
	YY_BREAK
case YY_STATE_EOF(LEX_BITSTRING_LITERAL):

{ scan_error("unterminated bit string literal"); }
	YY_BREAK
case 15:
YY_RULE_SETUP

{
					/* Hexadecimal bit type.
					 * At some point we should simply pass the string
					 * forward to the parser and label it there.
					 * In the meantime, place a leading "x" on the string
					 * to mark it for the input routine as a hex string.
					 */
					SET_YYLLOC();
					BEGIN(LEX_HEXADECIMAL_NUMERIC_STRING);
					startlit();
					addlitchar('x', yyscanner);
				}
	YY_BREAK
case 16:
/* rule 16 can match eol */

case 17:
/* rule 17 can match eol */
YY_RULE_SETUP

{
					yyless(1);
					BEGIN(LEX_INITIAL_STATE);
					yylval->str = litbufdup(yyscanner);
					return XCONST;
				}
	YY_BREAK
case YY_STATE_EOF(LEX_HEXADECIMAL_NUMERIC_STRING):

{ scan_error("unterminated hexadecimal string literal"); }
	YY_BREAK
case 18:
YY_RULE_SETUP

{
					/* National character.
					 * We will pass this along as a normal character string,
					 * but preceded with an internally-generated "NCHAR".
					 */
					const PGScanKeyword *keyword;

					SET_YYLLOC();
					yyless(1);	/* eat only 'n' this time */

					keyword = ScanKeywordLookup("nchar",
												yyextra->keywords,
												yyextra->num_keywords);
					if (keyword != NULL)
					{
						yylval->keyword = keyword->name;
						return keyword->value;
					}
					else
					{
						/* If NCHAR isn't a keyword, just return "n" */
						yylval->str = pstrdup("n");
						return IDENT;
					}
				}
	YY_BREAK
case 19:
YY_RULE_SETUP

{
					yyextra->warn_on_first_escape = true;
					yyextra->saw_non_ascii = false;
					SET_YYLLOC();
					if (yyextra->standard_conforming_strings)
						BEGIN(LEX_STANDARD_QUOTED_STRING);
					else
						BEGIN(LEX_EXTENDED_QUOTED_STRING);
					startlit();
				}
	YY_BREAK
case 20:
YY_RULE_SETUP

{
					yyextra->warn_on_first_escape = false;
					yyextra->saw_non_ascii = false;
					SET_YYLLOC();
					BEGIN(LEX_EXTENDED_QUOTED_STRING);
					startlit();
				}
	YY_BREAK
case 21:
YY_RULE_SETUP

{
					SET_YYLLOC();
					if (!yyextra->standard_conforming_strings)
						ereport(ERROR,
								(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("unsafe use of string constant with Unicode escapes"),
								 errdetail("String constants with Unicode escapes cannot be used when standard_conforming_strings is off."),
								 lexer_errposition()));
					BEGIN(LEX_QUOTED_STRING_WITH_UNICODE_ESCAPE);
					startlit();
				}
	YY_BREAK
case 22:
/* rule 22 can match eol */

case 23:
/* rule 23 can match eol */
YY_RULE_SETUP

{
					yyless(1);
					BEGIN(LEX_INITIAL_STATE);
					/*
					 * check that the data remains valid if it might have been
					 * made invalid by unescaping any chars.
					 */
					if (yyextra->saw_non_ascii)
						pg_verifymbstr(yyextra->literalbuf,
									   yyextra->literallen,
									   false);
					yylval->str = litbufdup(yyscanner);
					return SCONST;
				}
	YY_BREAK
case 24:
/* rule 24 can match eol */

case 25:
/* rule 25 can match eol */
YY_RULE_SETUP

{
					/* throw back all but the quote */
					yyless(1);
					/* LEX_END_OF_QUOTED_STRING_WITH_UNICODE_ESCAPE state looks for possible UESCAPE */
					BEGIN(LEX_END_OF_QUOTED_STRING_WITH_UNICODE_ESCAPE);
				}
	YY_BREAK
case 26:
/* rule 26 can match eol */
YY_RULE_SETUP

{
					/* stay in LEX_END_OF_QUOTED_STRING_WITH_UNICODE_ESCAPE state over whitespace */
				}
	YY_BREAK
case YY_STATE_EOF(LEX_END_OF_QUOTED_STRING_WITH_UNICODE_ESCAPE):

case 27:
/* rule 27 can match eol */

case 28:
/* rule 28 can match eol */
YY_RULE_SETUP

{
					/* no UESCAPE after the quote, throw back everything */
					yyless(0);
					BEGIN(LEX_INITIAL_STATE);
					yylval->str = litbuf_udeescape('\\', yyscanner);
					return SCONST;
				}
	YY_BREAK
case 29:
/* rule 29 can match eol */
YY_RULE_SETUP

{
					/* found UESCAPE after the end quote */
					BEGIN(LEX_INITIAL_STATE);
					if (!check_uescapechar(yytext[yyleng - 2]))
					{
						SET_YYLLOC();
						ADVANCE_YYLLOC(yyleng - 2);
						scan_error("invalid Unicode escape character");
					}
					yylval->str = litbuf_udeescape(yytext[yyleng - 2],
												   yyscanner);
					return SCONST;
				}
	YY_BREAK
case 30:
YY_RULE_SETUP

{
					addlitchar('\'', yyscanner);
				}
	YY_BREAK
case 31:
/* rule 31 can match eol */
YY_RULE_SETUP

{
					addlit(yytext, yyleng, yyscanner);
				}
	YY_BREAK
case 32:
/* rule 32 can match eol */
YY_RULE_SETUP

{
					addlit(yytext, yyleng, yyscanner);
				}
	YY_BREAK
case 33:
YY_RULE_SETUP

{
					pg_wchar	c = strtoul(yytext + 2, NULL, 16);

					check_escape_warning(yyscanner);

					if (is_utf16_surrogate_first(c))
					{
						yyextra->utf16_first_part = c;
						BEGIN(LEX_UNICODE_SURROGATE_IN_EXTENDED_QUOTED_STRING);
					}
					else if (is_utf16_surrogate_second(c))
						scan_error("invalid Unicode surrogate pair");
					else
						addunicode(c, yyscanner);
				}
	YY_BREAK
case 34:
YY_RULE_SETUP

{
					pg_wchar	c = strtoul(yytext + 2, NULL, 16);

					if (!is_utf16_surrogate_second(c))
						scan_error("invalid Unicode surrogate pair");

					c = surrogate_pair_to_codepoint(yyextra->utf16_first_part, c);

					addunicode(c, yyscanner);

					BEGIN(LEX_EXTENDED_QUOTED_STRING);
				}
	YY_BREAK
case 35:
YY_RULE_SETUP

{ scan_error("invalid Unicode surrogate pair"); }
	YY_BREAK
case 36:
/* rule 36 can match eol */
YY_RULE_SETUP

{ scan_error("invalid Unicode surrogate pair"); }
	YY_BREAK
case YY_STATE_EOF(LEX_UNICODE_SURROGATE_IN_EXTENDED_QUOTED_STRING):

{ scan_error("invalid Unicode surrogate pair"); }
	YY_BREAK
case 37:
YY_RULE_SETUP

{
					ereport(ERROR,
							(errcode(PG_ERRCODE_INVALID_ESCAPE_SEQUENCE),
							 errmsg("invalid Unicode escape"),
							 errhint("Unicode escapes must be \\uXXXX or \\UXXXXXXXX."),
							 lexer_errposition()));
				}
	YY_BREAK
case 38:
/* rule 38 can match eol */
YY_RULE_SETUP

{
					// if (yytext[1] == '\'')
					// {
					// 	if (yyextra->backslash_quote == PG_BACKSLASH_QUOTE_OFF ||
					// 		(yyextra->backslash_quote == PG_BACKSLASH_QUOTE_SAFE_ENCODING &&
					// 		 PG_ENCODING_IS_CLIENT_ONLY(pg_get_client_encoding())))
					// 		ereport(ERROR,
					// 				(errcode(PG_ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
					// 				 errmsg("unsafe use of \\' in a string literal"),
					// 				 errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),
					// 				 lexer_errposition()));
					// }
					check_string_escape_warning(yytext[1], yyscanner);
					addlitchar(unescape_single_char(yytext[1], yyscanner),
							   yyscanner);
				}
	YY_BREAK
case 39:
YY_RULE_SETUP

{
					unsigned char c = strtoul(yytext + 1, NULL, 8);

					check_escape_warning(yyscanner);
					addlitchar(c, yyscanner);
					if (c == '\0' || IS_HIGHBIT_SET(c))
						yyextra->saw_non_ascii = true;
				}
	YY_BREAK
case 40:
YY_RULE_SETUP

{
					unsigned char c = strtoul(yytext + 2, NULL, 16);

					check_escape_warning(yyscanner);
					addlitchar(c, yyscanner);
					if (c == '\0' || IS_HIGHBIT_SET(c))
						yyextra->saw_non_ascii = true;
				}
	YY_BREAK
case 41:
/* rule 41 can match eol */
YY_RULE_SETUP

{
					/* ignore */
				}
	YY_BREAK
case 42:
YY_RULE_SETUP

{
					/* This is only needed for \ just before EOF */
					addlitchar(yytext[0], yyscanner);
				}
	YY_BREAK
case YY_STATE_EOF(LEX_STANDARD_QUOTED_STRING):
case YY_STATE_EOF(LEX_EXTENDED_QUOTED_STRING):
case YY_STATE_EOF(LEX_QUOTED_STRING_WITH_UNICODE_ESCAPE):

{ scan_error("unterminated quoted string"); }
	YY_BREAK
case 43:
YY_RULE_SETUP

{
					SET_YYLLOC();
					yyextra->dolqstart = pstrdup(yytext);
					BEGIN(LEX_DOLLAR_QUOTED_STRING);
					startlit();
				}
	YY_BREAK
case 44:
YY_RULE_SETUP

{
					SET_YYLLOC();
					/* throw back all but the initial "$" */
					yyless(1);
					/* and treat it as {other} */
					return yytext[0];
				}
	YY_BREAK
case 45:
YY_RULE_SETUP

{
					if (strcmp(yytext, yyextra->dolqstart) == 0)
					{
						pfree(yyextra->dolqstart);
						yyextra->dolqstart = NULL;
						BEGIN(LEX_INITIAL_STATE);
						yylval->str = litbufdup(yyscanner);
						return SCONST;
					}
					else
					{
						/*
						 * When we fail to match $...$ to dolqstart, transfer
						 * the $... part to the output, but put back the final
						 * $ for rescanning.  Consider $delim$...$junk$delim$
						 */
						addlit(yytext, yyleng - 1, yyscanner);
						yyless(yyleng - 1);
					}
				}
	YY_BREAK
case 46:
/* rule 46 can match eol */
YY_RULE_SETUP

{
					addlit(yytext, yyleng, yyscanner);
				}
	YY_BREAK
case 47:
YY_RULE_SETUP

{
					addlit(yytext, yyleng, yyscanner);
				}
	YY_BREAK
case 48:
YY_RULE_SETUP

{
					/* This is only needed for $ inside the quoted text */
					addlitchar(yytext[0], yyscanner);
				}
	YY_BREAK
case YY_STATE_EOF(LEX_DOLLAR_QUOTED_STRING):

{ scan_error("unterminated dollar-quoted string"); }
	YY_BREAK
case 49:
YY_RULE_SETUP

{
					SET_YYLLOC();
					BEGIN(LEX_DELIMITED_IDENTIFIER);
					startlit();
				}
	YY_BREAK
case 50:
YY_RULE_SETUP

{
					SET_YYLLOC();
					BEGIN(LEX_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE);
					startlit();
				}
	YY_BREAK
case 51:
YY_RULE_SETUP

{
					char	   *ident;

					BEGIN(LEX_INITIAL_STATE);
					if (yyextra->literallen == 0)
						scan_error("zero-length delimited identifier");
					ident = litbufdup(yyscanner);
					if (yyextra->literallen >= NAMEDATALEN)
						truncate_identifier(ident, yyextra->literallen, true);
					yylval->str = ident;
					return IDENT;
				}
	YY_BREAK
case 52:
YY_RULE_SETUP

{
					yyless(1);
					/* LEX_END_OF_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE state looks for possible UESCAPE */
					BEGIN(LEX_END_OF_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE);
				}
	YY_BREAK
case 53:
/* rule 53 can match eol */
YY_RULE_SETUP

{
					/* stay in LEX_END_OF_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE state over whitespace */
				}
	YY_BREAK
case YY_STATE_EOF(LEX_END_OF_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE):

case 54:
/* rule 54 can match eol */

case 55:
/* rule 55 can match eol */
YY_RULE_SETUP

{
					/* no UESCAPE after the quote, throw back everything */
					char	   *ident;
					int			identlen;

					yyless(0);

					BEGIN(LEX_INITIAL_STATE);
					if (yyextra->literallen == 0)
						scan_error("zero-length delimited identifier");
					ident = litbuf_udeescape('\\', yyscanner);
					identlen = strlen(ident);
					if (identlen >= NAMEDATALEN)
						truncate_identifier(ident, identlen, true);
					yylval->str = ident;
					return IDENT;
				}
	YY_BREAK
case 56:
/* rule 56 can match eol */
YY_RULE_SETUP

{
					/* found UESCAPE after the end quote */
					char	   *ident;
					int			identlen;

					BEGIN(LEX_INITIAL_STATE);
					if (yyextra->literallen == 0)
						scan_error("zero-length delimited identifier");
					if (!check_uescapechar(yytext[yyleng - 2]))
					{
						SET_YYLLOC();
						ADVANCE_YYLLOC(yyleng - 2);
						scan_error("invalid Unicode escape character");
					}
					ident = litbuf_udeescape(yytext[yyleng - 2], yyscanner);
					identlen = strlen(ident);
					if (identlen >= NAMEDATALEN)
						truncate_identifier(ident, identlen, true);
					yylval->str = ident;
					return IDENT;
				}
	YY_BREAK
case 57:
YY_RULE_SETUP

{
					addlitchar('"', yyscanner);
				}
	YY_BREAK
case 58:
/* rule 58 can match eol */
YY_RULE_SETUP

{
					addlit(yytext, yyleng, yyscanner);
				}
	YY_BREAK
case YY_STATE_EOF(LEX_DELIMITED_IDENTIFIER):
case YY_STATE_EOF(LEX_QUOTED_IDENTIFIER_WITH_UNICODE_ESCAPE):

{ scan_error("unterminated quoted identifier"); }
	YY_BREAK
case 59:
YY_RULE_SETUP

{
					char	   *ident;

					SET_YYLLOC();
					/* throw back all but the initial u/U */
					yyless(1);
					/* and treat it as {identifier} */
					ident = downcase_truncate_identifier(yytext, yyleng, true);
					yylval->str = ident;
					return IDENT;
				}
	YY_BREAK
case 60:
YY_RULE_SETUP

{
          /* ignore E */
          return yytext[1];
        }
	YY_BREAK
case 61:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return TYPECAST;
				}
	YY_BREAK
case 62:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return DOT_DOT;
				}
	YY_BREAK
case 63:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return COLON_EQUALS;
				}
	YY_BREAK
case 64:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return EQUALS_GREATER;
				}
	YY_BREAK
case 65:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return LESS_EQUALS;
				}
	YY_BREAK
case 66:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return GREATER_EQUALS;
				}
	YY_BREAK
case 67:
YY_RULE_SETUP

{
					/* We accept both "<>" and "!=" as meaning NOT_EQUALS */
					SET_YYLLOC();
					return NOT_EQUALS;
				}
	YY_BREAK
case 68:
YY_RULE_SETUP

{
					/* We accept both "<>" and "!=" as meaning NOT_EQUALS */
					SET_YYLLOC();
					return NOT_EQUALS;
				}
	YY_BREAK
case 69:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return yytext[0];
				}
	YY_BREAK
case 70:
YY_RULE_SETUP

{
					/*
					 * Check for embedded slash-star or dash-dash; those
					 * are comment starts, so operator must stop there.
					 * Note that slash-star or dash-dash at the first
					 * character will match a prior rule, not this one.
					 */
					int			nchars = yyleng;
					char	   *slashstar = strstr(yytext, "/*");
					char	   *dashdash = strstr(yytext, "--");

					if (slashstar && dashdash)
					{
						/* if both appear, take the first one */
						if (slashstar > dashdash)
							slashstar = dashdash;
					}
					else if (!slashstar)
						slashstar = dashdash;
					if (slashstar)
						nchars = slashstar - yytext;

					/*
					 * For SQL compatibility, '+' and '-' cannot be the
					 * last char of a multi-char operator unless the operator
					 * contains chars that are not in SQL operators.
					 * The idea is to lex '=-' as two operators, but not
					 * to forbid operator names like '?-' that could not be
					 * sequences of SQL operators.
					 */
					while (nchars > 1 &&
						   (yytext[nchars - 1] == '+' ||
							yytext[nchars - 1] == '-'))
					{
						int			ic;

						for (ic = nchars - 2; ic >= 0; ic--)
						{
							if (strchr("~!@#^&|`?%", yytext[ic]))
								break;
						}
						if (ic >= 0)
							break; /* found a char that makes it OK */
						nchars--; /* else remove the +/-, and check again */
					}

          /* We don't accept leading ? in any multi-character operators
           * except for those in use by hstore, JSON and geometric operators.
           *
           * We don't accept contained or trailing ? in any
           * multi-character operators.
           *
           * This is necessary in order to support normalized queries without
           * spacing between ? as a substition character and a simple operator (e.g. "?=?")
           */
          if (yytext[0] == '?' &&
              strcmp(yytext, "?|") != 0 && strcmp(yytext, "?&") != 0 &&
              strcmp(yytext, "?#") != 0 && strcmp(yytext, "?-") != 0 &&
              strcmp(yytext, "?-|") != 0 && strcmp(yytext, "?||") != 0)
            nchars = 1;

          if (yytext[0] != '?' && strchr(yytext, '?'))
            /* Lex up to just before the ? character */
            nchars = strchr(yytext, '?') - yytext;

					SET_YYLLOC();

					if ((yy_size_t) nchars < yyleng)
					{
						/* Strip the unwanted chars from the token */
						yyless(nchars);
						/*
						 * If what we have left is only one char, and it's
						 * one of the characters matching "self", then
						 * return it as a character token the same way
						 * that the "self" rule would have.
						 */
						if (nchars == 1 &&
							strchr(",()[].;:+-*/%^<>=?", yytext[0]))
							return yytext[0];
					}

					/*
					 * Complain if operator is too long.  Unlike the case
					 * for identifiers, we make this an error not a notice-
					 * and-truncate, because the odds are we are looking at
					 * a syntactic mistake anyway.
					 */
					if (nchars >= NAMEDATALEN)
						scan_error("operator too long");

					yylval->str = pstrdup(yytext);
					return Op;
				}
	YY_BREAK
case 71:
YY_RULE_SETUP

{
					SET_YYLLOC();
					yylval->ival = atol(yytext + 1);
					return PARAM;
				}
	YY_BREAK
case 72:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return process_integer_literal(yytext, yylval);
				}
	YY_BREAK
case 73:
YY_RULE_SETUP

{
					SET_YYLLOC();
					yylval->str = pstrdup(yytext);
					return FCONST;
				}
	YY_BREAK
case 74:
YY_RULE_SETUP

{
					/* throw back the .., and treat as integer */
					yyless(yyleng - 2);
					SET_YYLLOC();
					return process_integer_literal(yytext, yylval);
				}
	YY_BREAK
case 75:
YY_RULE_SETUP

{
					SET_YYLLOC();
					yylval->str = pstrdup(yytext);
					return FCONST;
				}
	YY_BREAK
case 76:
YY_RULE_SETUP

{
					/*
					 * throw back the [Ee], and treat as {decimal}.  Note
					 * that it is possible the input is actually {integer},
					 * but since this case will almost certainly lead to a
					 * syntax error anyway, we don't bother to distinguish.
					 */
					yyless(yyleng - 1);
					SET_YYLLOC();
					yylval->str = pstrdup(yytext);
					return FCONST;
				}
	YY_BREAK
case 77:
YY_RULE_SETUP

{
					/* throw back the [Ee][+-], and proceed as above */
					yyless(yyleng - 2);
					SET_YYLLOC();
					yylval->str = pstrdup(yytext);
					return FCONST;
				}
	YY_BREAK
case 78:
YY_RULE_SETUP

{
					const PGScanKeyword *keyword;
					char	   *ident;
          char       *keyword_text = pstrdup(yytext);

					SET_YYLLOC();

					/* Is it a keyword? */
          if (yytext[yyleng - 1] == '?')
            keyword_text[yyleng - 1] = '\0';

					keyword = ScanKeywordLookup(keyword_text,
												yyextra->keywords,
												yyextra->num_keywords);
					if (keyword != NULL)
					{
            if (keyword_text[yyleng - 1] == '\0')
              yyless(yyleng - 1);
						yylval->keyword = keyword->name;
						return keyword->value;
					}

					/*
					 * No.  Convert the identifier to lower case, and truncate
					 * if necessary.
					 */
					ident = downcase_truncate_identifier(yytext, yyleng, true);
					yylval->str = ident;
					return IDENT;
				}
	YY_BREAK
case 79:
YY_RULE_SETUP

{
					SET_YYLLOC();
					return yytext[0];
				}
	YY_BREAK
case YY_STATE_EOF(LEX_INITIAL_STATE):

{
					SET_YYLLOC();
					yyterminate();
				}
	YY_BREAK
case 80:
YY_RULE_SETUP

YY_FATAL_ERROR( "flex scanner jammed" );
	YY_BREAK


	case YY_END_OF_BUFFER:
		{
		/* Amount of text matched not including the EOB char. */
		int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;

		/* Undo the effects of YY_DO_BEFORE_ACTION. */
		*yy_cp = yyg->yy_hold_char;
		YY_RESTORE_YY_MORE_OFFSET

		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
			{
			/* We're scanning a new file or input source.  It's
			 * possible that this happened because the user
			 * just pointed yyin at a new source and called
			 * core_yylex().  If so, then we have to assure
			 * consistency between YY_CURRENT_BUFFER and our
			 * globals.  Here is the right place to do so, because
			 * this is the first action (other than possibly a
			 * back-up) that will match for the new input source.
			 */
			yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
			}

		/* Note that here we test for yy_c_buf_p "<=" to the position
		 * of the first EOB in the buffer, since yy_c_buf_p will
		 * already have been incremented past the NUL character
		 * (since all states make transitions on EOB to the
		 * end-of-buffer state).  Contrast this with the test
		 * in input().
		 */
		if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
			{ /* This was really a NUL. */
			yy_state_type yy_next_state;

			yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;

			yy_current_state = yy_get_previous_state( yyscanner );

			/* Okay, we're now positioned to make the NUL
			 * transition.  We couldn't have
			 * yy_get_previous_state() go ahead and do it
			 * for us because it doesn't know how to deal
			 * with the possibility of jamming (and we don't
			 * want to build jamming into it because then it
			 * will run more slowly).
			 */

			yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);

			yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;

			if ( yy_next_state )
				{
				/* Consume the NUL. */
				yy_cp = ++yyg->yy_c_buf_p;
				yy_current_state = yy_next_state;
				goto yy_match;
				}

			else
				{
				yy_cp = yyg->yy_c_buf_p;
				goto yy_find_action;
				}
			}

		else switch ( yy_get_next_buffer( yyscanner ) )
			{
			case EOB_ACT_END_OF_FILE:
				{
				yyg->yy_did_buffer_switch_on_eof = 0;

				if ( core_yywrap(yyscanner ) )
					{
					/* Note: because we've taken care in
					 * yy_get_next_buffer() to have set up
					 * yytext, we can now set up
					 * yy_c_buf_p so that if some total
					 * hoser (like flex itself) wants to
					 * call the scanner after we return the
					 * YY_NULL, it'll still work - another
					 * YY_NULL will get returned.
					 */
					yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;

					yy_act = YY_STATE_EOF(YY_START);
					goto do_action;
					}

				else
					{
					if ( ! yyg->yy_did_buffer_switch_on_eof )
						YY_NEW_FILE;
					}
				break;
				}

			case EOB_ACT_CONTINUE_SCAN:
				yyg->yy_c_buf_p =
					yyg->yytext_ptr + yy_amount_of_matched_text;

				yy_current_state = yy_get_previous_state( yyscanner );

				yy_cp = yyg->yy_c_buf_p;
				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
				goto yy_match;

			case EOB_ACT_LAST_MATCH:
				yyg->yy_c_buf_p =
				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];

				yy_current_state = yy_get_previous_state( yyscanner );

				yy_cp = yyg->yy_c_buf_p;
				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
				goto yy_find_action;
			}
		break;
		}

	default:
		YY_FATAL_ERROR(
			"fatal flex scanner internal error--no action found" );
	} /* end of action switch */
		} /* end of scanning one token */
} /* end of core_yylex */

/* yy_get_next_buffer - try to read in a new buffer
 *
 * Returns a code representing an action:
 *	EOB_ACT_LAST_MATCH -
 *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
 *	EOB_ACT_END_OF_FILE - end of file
 */
static int yy_get_next_buffer (yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
	char *source = yyg->yytext_ptr;
	int number_to_move, i;
	int ret_val;

	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
		YY_FATAL_ERROR(
		"fatal flex scanner internal error--end of buffer missed" );

	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
		{ /* Don't try to fill the buffer, so this is an EOF. */
		if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
			{
			/* We matched a single character, the EOB, so
			 * treat this as a final EOF.
			 */
			return EOB_ACT_END_OF_FILE;
			}

		else
			{
			/* We matched some text prior to the EOB, first
			 * process it.
			 */
			return EOB_ACT_LAST_MATCH;
			}
		}

	/* Try to read more data. */

	/* First move last chars to start of buffer. */
	number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;

	for ( i = 0; i < number_to_move; ++i )
		*(dest++) = *(source++);

	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
		/* don't do the read, it's not guaranteed to return an EOF,
		 * just force an EOF
		 */
		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;

	else
		{
			yy_size_t num_to_read =
			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;

		while ( num_to_read <= 0 )
			{ /* Not enough room in the buffer - grow it. */

			/* just a shorter name for the current buffer */
			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;

			int yy_c_buf_p_offset =
				(int) (yyg->yy_c_buf_p - b->yy_ch_buf);

			if ( b->yy_is_our_buffer )
				{
				yy_size_t new_size = b->yy_buf_size * 2;

				if ( new_size <= 0 )
					b->yy_buf_size += b->yy_buf_size / 8;
				else
					b->yy_buf_size *= 2;

				b->yy_ch_buf = (char *)
					/* Include room in for 2 EOB chars. */
					core_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
				}
			else
				/* Can't grow it, we don't own it. */
				b->yy_ch_buf = 0;

			if ( ! b->yy_ch_buf )
				YY_FATAL_ERROR(
				"fatal error - scanner input buffer overflow" );

			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];

			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
						number_to_move - 1;

			}

		if ( num_to_read > YY_READ_BUF_SIZE )
			num_to_read = YY_READ_BUF_SIZE;

		/* Read in more data. */
		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
			yyg->yy_n_chars, num_to_read );

		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
		}

	if ( yyg->yy_n_chars == 0 )
		{
		if ( number_to_move == YY_MORE_ADJ )
			{
			ret_val = EOB_ACT_END_OF_FILE;
			core_yyrestart(yyin  ,yyscanner);
			}

		else
			{
			ret_val = EOB_ACT_LAST_MATCH;
			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
				YY_BUFFER_EOF_PENDING;
			}
		}

	else
		ret_val = EOB_ACT_CONTINUE_SCAN;

	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
		/* Extend the array by 50%, plus the number we really need. */
		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) core_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
	}

	yyg->yy_n_chars += number_to_move;
	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;

	yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];

	return ret_val;
}

/* yy_get_previous_state - get the state just before the EOB char was reached */

    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
{
	yy_state_type yy_current_state;
	char *yy_cp;
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

	yy_current_state = yy_start_state_list[yyg->yy_start];

	for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
		{
		yy_current_state += yy_current_state[(*yy_cp ? YY_SC_TO_UI(*yy_cp) : 256)].yy_nxt;
		}

	return yy_current_state;
}

/* yy_try_NUL_trans - try to make a transition on the NUL character
 *
 * synopsis
 *	next_state = yy_try_NUL_trans( current_state );
 */
    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
{
	int yy_is_jam;
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */

	int yy_c = 256;
	yyconst struct yy_trans_info *yy_trans_info;

	yy_trans_info = &yy_current_state[(unsigned int) yy_c];
	yy_current_state += yy_trans_info->yy_nxt;
	yy_is_jam = (yy_trans_info->yy_verify != yy_c);

	(void) yyg;
	return yy_is_jam ? 0 : yy_current_state;
}

#ifndef YY_NO_INPUT
#ifdef __cplusplus
    static int yyinput (yyscan_t yyscanner)
#else
    static int input  (yyscan_t yyscanner)
#endif

{
	int c;
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

	*yyg->yy_c_buf_p = yyg->yy_hold_char;

	if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
		{
		/* yy_c_buf_p now points to the character we want to return.
		 * If this occurs *before* the EOB characters, then it's a
		 * valid NUL; if not, then we've hit the end of the buffer.
		 */
		if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
			/* This was really a NUL. */
			*yyg->yy_c_buf_p = '\0';

		else
			{ /* need more input */
			yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
			++yyg->yy_c_buf_p;

			switch ( yy_get_next_buffer( yyscanner ) )
				{
				case EOB_ACT_LAST_MATCH:
					/* This happens because yy_g_n_b()
					 * sees that we've accumulated a
					 * token and flags that we need to
					 * try matching the token before
					 * proceeding.  But for input(),
					 * there's no matching to consider.
					 * So convert the EOB_ACT_LAST_MATCH
					 * to EOB_ACT_END_OF_FILE.
					 */

					/* Reset buffer status. */
					core_yyrestart(yyin ,yyscanner);

					/*FALLTHROUGH*/

				case EOB_ACT_END_OF_FILE:
					{
					if ( core_yywrap(yyscanner ) )
						return 0;

					if ( ! yyg->yy_did_buffer_switch_on_eof )
						YY_NEW_FILE;
#ifdef __cplusplus
					return yyinput(yyscanner);
#else
					return input(yyscanner);
#endif
					}

				case EOB_ACT_CONTINUE_SCAN:
					yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
					break;
				}
			}
		}

	c = *(unsigned char *) yyg->yy_c_buf_p;	/* cast for 8-bit char's */
	*yyg->yy_c_buf_p = '\0';	/* preserve yytext */
	yyg->yy_hold_char = *++yyg->yy_c_buf_p;

	return c;
}
#endif	/* ifndef YY_NO_INPUT */

/** Immediately switch to a different input stream.
 * @param input_file A readable stream.
 * @param yyscanner The scanner object.
 * @note This function does not reset the start condition to @c LEX_INITIAL_STATE .
 */
    void core_yyrestart  (FILE * input_file , yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

	if ( ! YY_CURRENT_BUFFER ){
        core_yyensure_buffer_stack (yyscanner);
		YY_CURRENT_BUFFER_LVALUE =
            core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
	}

	core_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
	core_yy_load_buffer_state(yyscanner );
}

/** Switch to a different input buffer.
 * @param new_buffer The new input buffer.
 * @param yyscanner The scanner object.
 */
    void core_yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

	/* TODO. We should be able to replace this entire function body
	 * with
	 *		core_yypop_buffer_state();
	 *		core_yypush_buffer_state(new_buffer);
     */
	core_yyensure_buffer_stack (yyscanner);
	if ( YY_CURRENT_BUFFER == new_buffer )
		return;

	if ( YY_CURRENT_BUFFER )
		{
		/* Flush out information for old buffer. */
		*yyg->yy_c_buf_p = yyg->yy_hold_char;
		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
		}

	YY_CURRENT_BUFFER_LVALUE = new_buffer;
	core_yy_load_buffer_state(yyscanner );

	/* We don't actually know whether we did this switch during
	 * EOF (core_yywrap()) processing, but the only time this flag
	 * is looked at is after core_yywrap() is called, so it's safe
	 * to go ahead and always set it.
	 */
	yyg->yy_did_buffer_switch_on_eof = 1;
}

static void core_yy_load_buffer_state  (yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
	yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
	yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
	yyg->yy_hold_char = *yyg->yy_c_buf_p;
}

/** Allocate and initialize an input buffer state.
 * @param file A readable stream.
 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
 * @param yyscanner The scanner object.
 * @return the allocated buffer state.
 */
    YY_BUFFER_STATE core_yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
{
	YY_BUFFER_STATE b;

	b = (YY_BUFFER_STATE) core_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
	if ( ! b )
		YY_FATAL_ERROR( "out of dynamic memory in core_yy_create_buffer()" );

	b->yy_buf_size = size;

	/* yy_ch_buf has to be 2 characters longer than the size given because
	 * we need to put in 2 end-of-buffer characters.
	 */
	b->yy_ch_buf = (char *) core_yyalloc(b->yy_buf_size + 2 ,yyscanner );
	if ( ! b->yy_ch_buf )
		YY_FATAL_ERROR( "out of dynamic memory in core_yy_create_buffer()" );

	b->yy_is_our_buffer = 1;

	core_yy_init_buffer(b,file ,yyscanner);

	return b;
}

/** Destroy the buffer.
 * @param b a buffer created with core_yy_create_buffer()
 * @param yyscanner The scanner object.
 */



/* Initializes or reinitializes a buffer.
 * This function is sometimes called more than once on the same buffer,
 * such as during a core_yyrestart() or at EOF.
 */
    static void core_yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)

{
	int oerrno = errno;
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

	core_yy_flush_buffer(b ,yyscanner);

	b->yy_input_file = file;
	b->yy_fill_buffer = 1;

    /* If b is the current buffer, then core_yy_init_buffer was _probably_
     * called from core_yyrestart() or through yy_get_next_buffer.
     * In that case, we don't want to reset the lineno or column.
     */
    if (b != YY_CURRENT_BUFFER){
        b->yy_bs_lineno = 1;
        b->yy_bs_column = 0;
    }

        b->yy_is_interactive = 0;

	errno = oerrno;
}

/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
 * @param yyscanner The scanner object.
 */
    void core_yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
	if ( ! b )
		return;

	b->yy_n_chars = 0;

	/* We always need two end-of-buffer characters.  The first causes
	 * a transition to the end-of-buffer state.  The second causes
	 * a jam in that state.
	 */
	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;

	b->yy_buf_pos = &b->yy_ch_buf[0];

	b->yy_at_bol = 1;
	b->yy_buffer_status = YY_BUFFER_NEW;

	if ( b == YY_CURRENT_BUFFER )
		core_yy_load_buffer_state(yyscanner );
}

/** Pushes the new state onto the stack. The new state becomes
 *  the current state. This function will allocate the stack
 *  if necessary.
 *  @param new_buffer The new state.
 *  @param yyscanner The scanner object.
 */


/** Removes and deletes the top of the stack, if present.
 *  The next element becomes the new top.
 *  @param yyscanner The scanner object.
 */


/* Allocates the stack if it does not exist.
 *  Guarantees space for at least one push.
 */
static void core_yyensure_buffer_stack (yyscan_t yyscanner)
{
	yy_size_t num_to_alloc;
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;

	if (!yyg->yy_buffer_stack) {

		/* First allocation is just for 2 elements, since we don't know if this
		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
		 * immediate realloc on the next call.
         */
		num_to_alloc = 1;
		yyg->yy_buffer_stack = (struct yy_buffer_state**)core_yyalloc
								(num_to_alloc * sizeof(struct yy_buffer_state*)
								, yyscanner);
		if ( ! yyg->yy_buffer_stack )
			YY_FATAL_ERROR( "out of dynamic memory in core_yyensure_buffer_stack()" );

		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));

		yyg->yy_buffer_stack_max = num_to_alloc;
		yyg->yy_buffer_stack_top = 0;
		return;
	}

	if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){

		/* Increase the buffer to prepare for a possible push. */
		int grow_size = 8 /* arbitrary grow size */;

		num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
		yyg->yy_buffer_stack = (struct yy_buffer_state**)core_yyrealloc
								(yyg->yy_buffer_stack,
								num_to_alloc * sizeof(struct yy_buffer_state*)
								, yyscanner);
		if ( ! yyg->yy_buffer_stack )
			YY_FATAL_ERROR( "out of dynamic memory in core_yyensure_buffer_stack()" );

		/* zero only the new slots.*/
		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
		yyg->yy_buffer_stack_max = num_to_alloc;
	}
}

/** Setup the input buffer state to scan directly from a user-specified character buffer.
 * @param base the character buffer
 * @param size the size in bytes of the character buffer
 * @param yyscanner The scanner object.
 * @return the newly allocated buffer state object.
 */
YY_BUFFER_STATE core_yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
{
	YY_BUFFER_STATE b;

	if ( size < 2 ||
	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
	     base[size-1] != YY_END_OF_BUFFER_CHAR )
		/* They forgot to leave room for the EOB's. */
		return 0;

	b = (YY_BUFFER_STATE) core_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
	if ( ! b )
		YY_FATAL_ERROR( "out of dynamic memory in core_yy_scan_buffer()" );

	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
	b->yy_buf_pos = b->yy_ch_buf = base;
	b->yy_is_our_buffer = 0;
	b->yy_input_file = 0;
	b->yy_n_chars = b->yy_buf_size;
	b->yy_is_interactive = 0;
	b->yy_at_bol = 1;
	b->yy_fill_buffer = 0;
	b->yy_buffer_status = YY_BUFFER_NEW;

	core_yy_switch_to_buffer(b ,yyscanner );

	return b;
}

/** Setup the input buffer state to scan a string. The next call to core_yylex() will
 * scan from a @e copy of @a str.
 * @param yystr a NUL-terminated string to scan
 * @param yyscanner The scanner object.
 * @return the newly allocated buffer state object.
 * @note If you want to scan bytes that may contain NUL values, then use
 *       core_yy_scan_bytes() instead.
 */


/** Setup the input buffer state to scan the given bytes. The next call to core_yylex() will
 * scan from a @e copy of @a bytes.
 * @param bytes the byte buffer to scan
 * @param len the number of bytes in the buffer pointed to by @a bytes.
 * @param yyscanner The scanner object.
 * @return the newly allocated buffer state object.
 */


#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif

#include <stdexcept>

static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
{
//    fprintf_to_ereport("%s\n", msg );
//	exit( YY_EXIT_FAILURE );
	throw std::runtime_error(msg);
}

/* Redefine yyless() so it works in section 3 code. */

#undef yyless
#define yyless(n) \
	do \
		{ \
		/* Undo effects of setting up yytext. */ \
        int yyless_macro_arg = (n); \
        YY_LESS_LINENO(yyless_macro_arg);\
		yytext[yyleng] = yyg->yy_hold_char; \
		yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
		yyg->yy_hold_char = *yyg->yy_c_buf_p; \
		*yyg->yy_c_buf_p = '\0'; \
		yyleng = yyless_macro_arg; \
		} \
	while ( 0 )

/* Accessor  methods (get/set functions) to struct members. */

/** Get the user-defined data for this scanner.
 * @param yyscanner The scanner object.
 */


/** Get the current line number.
 * @param yyscanner The scanner object.
 */


/** Get the current column number.
 * @param yyscanner The scanner object.
 */


/** Get the input stream.
 * @param yyscanner The scanner object.
 */


/** Get the output stream.
 * @param yyscanner The scanner object.
 */


/** Get the length of the current token.
 * @param yyscanner The scanner object.
 */


/** Get the current token.
 * @param yyscanner The scanner object.
 */



/** Set the user-defined data. This data is never touched by the scanner.
 * @param user_defined The data to be associated with this scanner.
 * @param yyscanner The scanner object.
 */
void core_yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    yyextra = user_defined ;
}

/** Set the current line number.
 * @param line_number
 * @param yyscanner The scanner object.
 */


/** Set the current column.
 * @param line_number
 * @param yyscanner The scanner object.
 */


/** Set the input stream. This does not discard the current
 * input buffer.
 * @param in_str A readable stream.
 * @param yyscanner The scanner object.
 * @see core_yy_switch_to_buffer
 */








/* Accessor methods for yylval and yylloc */









/* User-visible API */

/* core_yylex_init is special because it creates the scanner itself, so it is
 * the ONLY reentrant function that doesn't take the scanner as the last argument.
 * That's why we explicitly handle the declaration, instead of using our macros.
 */

int core_yylex_init(yyscan_t* ptr_yy_globals)

{
    if (ptr_yy_globals == NULL){
        errno = EINVAL;
        return 1;
    }

    *ptr_yy_globals = (yyscan_t) core_yyalloc ( sizeof( struct yyguts_t ), NULL );

    if (*ptr_yy_globals == NULL){
        errno = ENOMEM;
        return 1;
    }

    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));

    return yy_init_globals ( *ptr_yy_globals );
}

/* core_yylex_init_extra has the same functionality as core_yylex_init, but follows the
 * convention of taking the scanner as the last argument. Note however, that
 * this is a *pointer* to a scanner, as it will be allocated by this call (and
 * is the reason, too, why this function also must handle its own declaration).
 * The user defined value in the first argument will be available to core_yyalloc in
 * the yyextra field.
 */



static int yy_init_globals (yyscan_t yyscanner)
{
    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    /* Initialization is the same as for the non-reentrant scanner.
     * This function is called from core_yylex_destroy(), so don't allocate here.
     */

    yyg->yy_buffer_stack = 0;
    yyg->yy_buffer_stack_top = 0;
    yyg->yy_buffer_stack_max = 0;
    yyg->yy_c_buf_p = (char *) 0;
    yyg->yy_init = 0;
    yyg->yy_start = 0;

    yyg->yy_start_stack_ptr = 0;
    yyg->yy_start_stack_depth = 0;
    yyg->yy_start_stack =  NULL;

/* Defined in main.c */
#ifdef YY_STDINIT
    yyin = stdin;
    yyout = stdout;
#else
    yyin = (FILE *) 0;
    yyout = (FILE *) 0;
#endif

    /* For future reference: Set errno on error, since we are called by
     * core_yylex_init()
     */
    return 0;
}

/* core_yylex_destroy is for both reentrant and non-reentrant scanners. */


/*
 * Internal utility routines.
 */

#ifndef yytext_ptr
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
{
	int i;
	for ( i = 0; i < n; ++i )
		s1[i] = s2[i];
}
#endif

#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
{
	int n;
	for ( n = 0; s[n]; ++n )
		;

	return n;
}
#endif

#define YYTABLES_NAME "yytables"





/*
 * Arrange access to yyextra for subroutines of the main core_yylex() function.
 * We expect each subroutine to have a yyscanner parameter.  Rather than
 * use the yyget_xxx functions, which might or might not get inlined by the
 * compiler, we cheat just a bit and cast yyscanner to the right type.
 */
#undef yyextra
#define yyextra  (((struct yyguts_t *) yyscanner)->yyextra_r)

/* Likewise for a couple of other things we need. */
#undef yylloc
#define yylloc	(((struct yyguts_t *) yyscanner)->yylloc_r)
#undef yyleng
#define yyleng	(((struct yyguts_t *) yyscanner)->yyleng_r)


/*
 * scanner_errposition
 *		Report a lexer or grammar error cursor position, if possible.
 *
 * This is expected to be used within an ereport() call.  The return value
 * is a dummy (always 0, in fact).
 *
 * Note that this can only be used for messages emitted during raw parsing
 * (essentially, scan.l and gram.y), since it requires the yyscanner struct
 * to still be available.
 */
int
scanner_errposition(int location, core_yyscan_t yyscanner)
{
	int			pos;

	if (location < 0)
		return 0;				/* no-op if location is unknown */

	/* Convert byte offset to character number */
	pos = pg_mbstrlen_with_len(yyextra->scanbuf, location) + 1;
	/* And pass it to the ereport mechanism */
	return errposition(pos);
}

/*
 * scanner_yyerror
 *		Report a lexer or grammar error.
 *
 * The message's cursor position is whatever YYLLOC was last set to,
 * ie, the start of the current token if called within core_yylex(), or the
 * most recently lexed token if called from the grammar.
 * This is OK for syntax error messages from the Bison parser, because Bison
 * parsers report error as soon as the first unparsable token is reached.
 * Beware of using yyerror for other purposes, as the cursor position might
 * be misleading!
 */
void
scanner_yyerror(const char *message, core_yyscan_t yyscanner)
{
	const char *loc = yyextra->scanbuf + *yylloc;

	if (*loc == YY_END_OF_BUFFER_CHAR)
	{
		ereport(ERROR,
				(errcode(PG_ERRCODE_SYNTAX_ERROR),
		/* translator: %s is typically the translation of "syntax error" */
				 errmsg("%s at end of input", _(message)),
				 lexer_errposition()));
	}
	else
	{
		ereport(ERROR,
				(errcode(PG_ERRCODE_SYNTAX_ERROR),
		/* translator: first %s is typically the translation of "syntax error" */
				 errmsg("%s at or near \"%s\"", _(message), loc),
				 lexer_errposition()));
	}
}


/*
 * Called before any actual parsing is done
 */
core_yyscan_t
scanner_init(const char *str,
			 core_yy_extra_type *yyext,
			 const PGScanKeyword *keywords,
			 int num_keywords)
{
	PGSize		slen = strlen(str);
	yyscan_t	scanner;

	if (core_yylex_init(&scanner) != 0)
		elog(ERROR, "core_yylex_init() failed: %m");

	core_yyset_extra(yyext, scanner);

	yyext->keywords = keywords;
	yyext->num_keywords = num_keywords;

	yyext->backslash_quote = backslash_quote;
	yyext->escape_string_warning = escape_string_warning;
	yyext->standard_conforming_strings = standard_conforming_strings;

	/*
	 * Make a scan buffer with special termination needed by flex.
	 */
	yyext->scanbuf = (char *) palloc(slen + 2);
	yyext->scanbuflen = slen;
	memcpy(yyext->scanbuf, str, slen);
	yyext->scanbuf[slen] = yyext->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
	core_yy_scan_buffer(yyext->scanbuf,slen + 2,scanner);

	/* initialize literal buffer to a reasonable but expansible size */
	yyext->literalalloc = 1024;
	yyext->literalbuf = (char *) palloc(yyext->literalalloc);
	yyext->literallen = 0;

	return scanner;
}


/*
 * Called after parsing is done to clean up after scanner_init()
 */
void
scanner_finish(core_yyscan_t yyscanner)
{
	/*
	 * We don't bother to call core_yylex_destroy(), because all it would do is
	 * pfree a small amount of control storage.  It's cheaper to leak the
	 * storage until the parsing context is destroyed.  The amount of space
	 * involved is usually negligible compared to the output parse tree
	 * anyway.
	 *
	 * We do bother to pfree the scanbuf and literal buffer, but only if they
	 * represent a nontrivial amount of space.  The 8K cutoff is arbitrary.
	 */
	if (yyextra->scanbuflen >= 8192)
		pfree(yyextra->scanbuf);
	if (yyextra->literalalloc >= 8192)
		pfree(yyextra->literalbuf);
}


static void
addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
{
	/* enlarge buffer if needed */
	if ((yyextra->literallen + yleng) >= yyextra->literalalloc)
	{
		do
		{
			yyextra->literalalloc *= 2;
		} while ((yyextra->literallen + yleng) >= yyextra->literalalloc);
		yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
												yyextra->literalalloc);
	}
	/* append new data */
	memcpy(yyextra->literalbuf + yyextra->literallen, ytext, yleng);
	yyextra->literallen += yleng;
}


static void
addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
{
	/* enlarge buffer if needed */
	if ((yyextra->literallen + 1) >= yyextra->literalalloc)
	{
		yyextra->literalalloc *= 2;
		yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
												yyextra->literalalloc);
	}
	/* append new data */
	yyextra->literalbuf[yyextra->literallen] = ychar;
	yyextra->literallen += 1;
}


/*
 * Create a palloc'd copy of literalbuf, adding a trailing null.
 */
static char *
litbufdup(core_yyscan_t yyscanner)
{
	int			llen = yyextra->literallen;
	char	   *newbuf;

	newbuf = (char*) palloc(llen + 1);
	memcpy(newbuf, yyextra->literalbuf, llen);
	newbuf[llen] = '\0';
	return newbuf;
}

static int
process_integer_literal(const char *token, YYSTYPE *lval)
{
	long		val;
	char	   *endptr;

	errno = 0;
	val = strtol(token, &endptr, 10);
	if (*endptr != '\0' || errno == ERANGE
	/* if long > 32 bits, check for overflow of int4_t */
		|| val != (long) ((int32_t) val) )
	{
		/* integer too large, treat it as a float */
		lval->str = pstrdup(token);
		return FCONST;
	}
	lval->ival = val;
	return ICONST;
}

static unsigned int
hexval(unsigned char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 0xA;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 0xA;
	elog(ERROR, "invalid hexadecimal digit");
	return 0;					/* not reached */
}

static bool
is_utf16_surrogate_first(pg_wchar c)
{
	return (c >= 0xD800 && c <= 0xDBFF);
}

static bool
is_utf16_surrogate_second(pg_wchar c)
{
	return (c >= 0xDC00 && c <= 0xDFFF);
}

static pg_wchar
surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
{
	return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}

static void
addunicode(pg_wchar c, core_yyscan_t yyscanner)
{
	char		buf[8];

	if (c == 0 || c > 0x10FFFF)
		scan_error("invalid Unicode escape value");
	if (c > 0x7F)
	{
		// if (GetDatabaseEncoding() != PG_UTF8)
		// 	scan_error("Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8");
		yyextra->saw_non_ascii = true;
	}
	unicode_to_utf8(c, (unsigned char *) buf);
	addlit(buf, pg_mblen(buf), yyscanner);
}

/* is 'escape' acceptable as Unicode escape character (UESCAPE syntax) ? */
static bool
check_uescapechar(unsigned char escape)
{
	if (isxdigit(escape)
		|| escape == '+'
		|| escape == '\''
		|| escape == '"'
		|| scanner_isspace(escape))
	{
		return false;
	}
	else
		return true;
}

/* like litbufdup, but handle unicode escapes */
static char *
litbuf_udeescape(unsigned char escape, core_yyscan_t yyscanner)
{
	char	   *newbuf;
	char	   *litbuf,
			   *in,
			   *out;
	pg_wchar	pair_first = 0;

	/* Make literalbuf null-terminated to simplify the scanning loop */
	litbuf = yyextra->literalbuf;
	litbuf[yyextra->literallen] = '\0';

	/*
	 * This relies on the subtle assumption that a UTF-8 expansion cannot be
	 * longer than its escaped representation.
	 */
	newbuf = (char*) palloc(yyextra->literallen + 1);

	in = litbuf;
	out = newbuf;
	while (*in)
	{
		if (in[0] == escape)
		{
			if (in[1] == escape)
			{
				if (pair_first)
				{
					ADVANCE_YYLLOC(in - litbuf + 3);	/* 3 for U&" */
					scan_error("invalid Unicode surrogate pair");
				}
				*out++ = escape;
				in += 2;
			}
			else if (isxdigit((unsigned char) in[1]) &&
					 isxdigit((unsigned char) in[2]) &&
					 isxdigit((unsigned char) in[3]) &&
					 isxdigit((unsigned char) in[4]))
			{
				pg_wchar	unicode;

				unicode = (hexval(in[1]) << 12) +
					(hexval(in[2]) << 8) +
					(hexval(in[3]) << 4) +
					hexval(in[4]);
				if (pair_first)
				{
					if (is_utf16_surrogate_second(unicode))
					{
						unicode = surrogate_pair_to_codepoint(pair_first, unicode);
						pair_first = 0;
					}
					else
					{
						ADVANCE_YYLLOC(in - litbuf + 3);		/* 3 for U&" */
						scan_error("invalid Unicode surrogate pair");
					}
				}
				else if (is_utf16_surrogate_second(unicode))
					scan_error("invalid Unicode surrogate pair");

				if (is_utf16_surrogate_first(unicode))
					pair_first = unicode;
				else
				{
					unicode_to_utf8(unicode, (unsigned char *) out);
					out += pg_mblen(out);
				}
				in += 5;
			}
			else if (in[1] == '+' &&
					 isxdigit((unsigned char) in[2]) &&
					 isxdigit((unsigned char) in[3]) &&
					 isxdigit((unsigned char) in[4]) &&
					 isxdigit((unsigned char) in[5]) &&
					 isxdigit((unsigned char) in[6]) &&
					 isxdigit((unsigned char) in[7]))
			{
				pg_wchar	unicode;

				unicode = (hexval(in[2]) << 20) +
					(hexval(in[3]) << 16) +
					(hexval(in[4]) << 12) +
					(hexval(in[5]) << 8) +
					(hexval(in[6]) << 4) +
					hexval(in[7]);
				if (pair_first)
				{
					if (is_utf16_surrogate_second(unicode))
					{
						unicode = surrogate_pair_to_codepoint(pair_first, unicode);
						pair_first = 0;
					}
					else
					{
						ADVANCE_YYLLOC(in - litbuf + 3);		/* 3 for U&" */
						scan_error("invalid Unicode surrogate pair");
					}
				}
				else if (is_utf16_surrogate_second(unicode))
					scan_error("invalid Unicode surrogate pair");

				if (is_utf16_surrogate_first(unicode))
					pair_first = unicode;
				else
				{
					unicode_to_utf8(unicode, (unsigned char *) out);
					out += pg_mblen(out);
				}
				in += 8;
			}
			else
			{
				ADVANCE_YYLLOC(in - litbuf + 3);		/* 3 for U&" */
				scan_error("invalid Unicode escape value");
			}
		}
		else
		{
			if (pair_first)
			{
				ADVANCE_YYLLOC(in - litbuf + 3);		/* 3 for U&" */
				scan_error("invalid Unicode surrogate pair");
			}
			*out++ = *in++;
		}
	}

	/* unfinished surrogate pair? */
	if (pair_first)
	{
		ADVANCE_YYLLOC(in - litbuf + 3);				/* 3 for U&" */
		scan_error("invalid Unicode surrogate pair");
	}

	*out = '\0';

	/*
	 * We could skip pg_verifymbstr if we didn't process any non-7-bit-ASCII
	 * codes; but it's probably not worth the trouble, since this isn't likely
	 * to be a performance-critical path.
	 */
	pg_verifymbstr(newbuf, out - newbuf, false);
	return newbuf;
}

static unsigned char
unescape_single_char(unsigned char c, core_yyscan_t yyscanner)
{
	switch (c)
	{
		case 'b':
			return '\b';
		case 'f':
			return '\f';
		case 'n':
			return '\n';
		case 'r':
			return '\r';
		case 't':
			return '\t';
		default:
			/* check for backslash followed by non-7-bit-ASCII */
			if (c == '\0' || IS_HIGHBIT_SET(c))
				yyextra->saw_non_ascii = true;

			return c;
	}
}

static void
check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner)
{
	if (ychar == '\'')
	{
		if (yyextra->warn_on_first_escape && yyextra->escape_string_warning)
			ereport(PGWARNING,
					(errcode(PG_ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
					 errmsg("nonstandard use of \\' in a string literal"),
					 errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."),
					 lexer_errposition()));
		yyextra->warn_on_first_escape = false;	/* warn only once per string */
	}
	else if (ychar == '\\')
	{
		if (yyextra->warn_on_first_escape && yyextra->escape_string_warning)
			ereport(PGWARNING,
					(errcode(PG_ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
					 errmsg("nonstandard use of \\\\ in a string literal"),
					 errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."),
					 lexer_errposition()));
		yyextra->warn_on_first_escape = false;	/* warn only once per string */
	}
	else
		check_escape_warning(yyscanner);
}

static void
check_escape_warning(core_yyscan_t yyscanner)
{
	if (yyextra->warn_on_first_escape && yyextra->escape_string_warning)
		ereport(PGWARNING,
				(errcode(PG_ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
				 errmsg("nonstandard use of escape in a string literal"),
		errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."),
				 lexer_errposition()));
	yyextra->warn_on_first_escape = false;		/* warn only once per string */
}

/*
 * Interface functions to make flex use palloc() instead of malloc().
 * It'd be better to make these static, but flex insists otherwise.
 */

void *
core_yyalloc(yy_size_t bytes, core_yyscan_t yyscanner)
{
	return palloc(bytes);
}

void *
core_yyrealloc(void *ptr, yy_size_t bytes, core_yyscan_t yyscanner)
{
	if (ptr)
		return repalloc(ptr, bytes);
	else
		return palloc(bytes);
}



/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - truncate_identifier
 * - downcase_truncate_identifier
 * - downcase_identifier
 * - scanner_isspace
 *--------------------------------------------------------------------
 */

/*-------------------------------------------------------------------------
 *
 * scansup.c
 *	  support routines for the lex/flex scanner, used by both the normal
 * backend as well as the bootstrap backend
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/parser/scansup.c
 *
 *-------------------------------------------------------------------------
 */

#include <string.h>

#include <ctype.h>





/* ----------------
 *		scanstr
 *
 * if the string passed in has escaped codes, map the escape codes to actual
 * chars
 *
 * the string returned is palloc'd and should eventually be pfree'd by the
 * caller!
 * ----------------
 */




/*
 * downcase_truncate_identifier() --- do appropriate downcasing and
 * truncation of an unquoted identifier.  Optionally warn of truncation.
 *
 * Returns a palloc'd string containing the adjusted identifier.
 *
 * Note: in some usages the passed string is not null-terminated.
 *
 * Note: the API of this function is designed to allow for downcasing
 * transformations that increase the string length, but we don't yet
 * support that.  If you want to implement it, you'll need to fix
 * SplitIdentifierString() in utils/adt/varlena.c.
 */
char *
downcase_truncate_identifier(const char *ident, int len, bool warn)
{
	return downcase_identifier(ident, len, warn, true);
}

/*
 * a workhorse for downcase_truncate_identifier
 */
char *
downcase_identifier(const char *ident, int len, bool warn, bool truncate)
{
	char	   *result;
	int			i;
	bool		enc_is_single_byte;

	result = (char*) palloc(len + 1);
	enc_is_single_byte = pg_database_encoding_max_length() == 1;

	/*
	 * SQL99 specifies Unicode-aware case normalization, which we don't yet
	 * have the infrastructure for.  Instead we use tolower() to provide a
	 * locale-aware translation.  However, there are some locales where this
	 * is not right either (eg, Turkish may do strange things with 'i' and
	 * 'I').  Our current compromise is to use tolower() for characters with
	 * the high bit set, as long as they aren't part of a multi-byte
	 * character, and use an ASCII-only downcasing for 7-bit characters.
	 */
	for (i = 0; i < len; i++)
	{
		unsigned char ch = (unsigned char) ident[i];

		if (ch >= 'A' && ch <= 'Z')
			ch += 'a' - 'A';
		else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch))
			ch = tolower(ch);
		result[i] = (char) ch;
	}
	result[i] = '\0';

	if (i >= NAMEDATALEN && truncate)
		truncate_identifier(result, i, warn);

	return result;
}


/*
 * truncate_identifier() --- truncate an identifier to NAMEDATALEN-1 bytes.
 *
 * The given string is modified in-place, if necessary.  A warning is
 * issued if requested.
 *
 * We require the caller to pass in the string length since this saves a
 * strlen() call in some common usages.
 */
void
truncate_identifier(char *ident, int len, bool warn)
{
	if (len >= NAMEDATALEN)
	{
		len = pg_mbcliplen(ident, len, NAMEDATALEN - 1);
		if (warn)
		{
			/*
			 * We avoid using %.*s here because it can misbehave if the data
			 * is not valid in what libc thinks is the prevailing encoding.
			 */
			char		buf[NAMEDATALEN];

			memcpy(buf, ident, len);
			buf[len] = '\0';
			ereport(PGNOTICE,
					(errcode(ERRCODE_NAME_TOO_LONG),
					 errmsg("identifier \"%s\" will be truncated to \"%s\"",
							ident, buf)));
		}
		ident[len] = '\0';
	}
}

/*
 * scanner_isspace() --- return true if flex scanner considers char whitespace
 *
 * This should be used instead of the potentially locale-dependent isspace()
 * function when it's important to match the lexer's behavior.
 *
 * In principle we might need similar functions for isalnum etc, but for the
 * moment only isspace seems needed.
 */
bool
scanner_isspace(char ch)
{
	/* This must match scan.l's list of {space} characters */
	if (ch == ' ' ||
		ch == '\t' ||
		ch == '\n' ||
		ch == '\r' ||
		ch == '\f')
		return true;
	return false;
}
/*--------------------------------------------------------------------
 * Symbols referenced in this file:
 * - ScanKeywords
 * - NumScanKeywords
 * - ScanKeywordLookup
 *--------------------------------------------------------------------
 */

/*-------------------------------------------------------------------------
 *
 * keywords.c
 *	  lexical token lookup for key words in PostgreSQL
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/common/keywords.c
 *
 *-------------------------------------------------------------------------
 */

#include <string.h>




#define PG_KEYWORD(a,b,c) {a,b,c},

const PGScanKeyword ScanKeywords[] = {
PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD)
PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD)
PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD)
PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD)
PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD)
PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD)
PG_KEYWORD("all", ALL, RESERVED_KEYWORD)
PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD)
PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD)
PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD)
PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD)
PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD)
PG_KEYWORD("and", AND, RESERVED_KEYWORD)
PG_KEYWORD("any", ANY, RESERVED_KEYWORD)
PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD)
PG_KEYWORD("as", AS, RESERVED_KEYWORD)
PG_KEYWORD("asc", ASC_P, RESERVED_KEYWORD)
PG_KEYWORD("assertion", ASSERTION, UNRESERVED_KEYWORD)
PG_KEYWORD("assignment", ASSIGNMENT, UNRESERVED_KEYWORD)
PG_KEYWORD("asymmetric", ASYMMETRIC, RESERVED_KEYWORD)
PG_KEYWORD("at", AT, UNRESERVED_KEYWORD)
PG_KEYWORD("attach", ATTACH, UNRESERVED_KEYWORD)
PG_KEYWORD("attribute", ATTRIBUTE, UNRESERVED_KEYWORD)
PG_KEYWORD("authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("backward", BACKWARD, UNRESERVED_KEYWORD)
PG_KEYWORD("before", BEFORE, UNRESERVED_KEYWORD)
PG_KEYWORD("begin", BEGIN_P, UNRESERVED_KEYWORD)
PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD)
PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD)
PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD)
PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD)
PG_KEYWORD("both", BOTH, RESERVED_KEYWORD)
PG_KEYWORD("by", BY, UNRESERVED_KEYWORD)
PG_KEYWORD("cache", CACHE, UNRESERVED_KEYWORD)
PG_KEYWORD("called", CALLED, UNRESERVED_KEYWORD)
PG_KEYWORD("cascade", CASCADE, UNRESERVED_KEYWORD)
PG_KEYWORD("cascaded", CASCADED, UNRESERVED_KEYWORD)
PG_KEYWORD("case", CASE, RESERVED_KEYWORD)
PG_KEYWORD("cast", CAST, RESERVED_KEYWORD)
PG_KEYWORD("catalog", CATALOG_P, UNRESERVED_KEYWORD)
PG_KEYWORD("chain", CHAIN, UNRESERVED_KEYWORD)
PG_KEYWORD("char", CHAR_P, COL_NAME_KEYWORD)
PG_KEYWORD("character", CHARACTER, COL_NAME_KEYWORD)
PG_KEYWORD("characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD)
PG_KEYWORD("check", CHECK_P, RESERVED_KEYWORD)
PG_KEYWORD("checkpoint", CHECKPOINT, UNRESERVED_KEYWORD)
PG_KEYWORD("class", CLASS, UNRESERVED_KEYWORD)
PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD)
PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD)
PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD)
PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD)
PG_KEYWORD("collation", COLLATION, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD)
PG_KEYWORD("columns", COLUMNS, UNRESERVED_KEYWORD)
PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD)
PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD)
PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD)
PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD)
PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD)
PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD)
PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD)
PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD)
PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD)
PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD)
PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD)
PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD)
PG_KEYWORD("create", CREATE_P, RESERVED_KEYWORD)
PG_KEYWORD("cross", CROSS, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("csv", CSV, UNRESERVED_KEYWORD)
PG_KEYWORD("cube", CUBE, UNRESERVED_KEYWORD)
PG_KEYWORD("current", CURRENT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("current_catalog", CURRENT_CATALOG, RESERVED_KEYWORD)
PG_KEYWORD("current_date", CURRENT_DATE, RESERVED_KEYWORD)
PG_KEYWORD("current_role", CURRENT_ROLE, RESERVED_KEYWORD)
PG_KEYWORD("current_schema", CURRENT_SCHEMA, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("current_time", CURRENT_TIME, RESERVED_KEYWORD)
PG_KEYWORD("current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD)
PG_KEYWORD("current_user", CURRENT_USER, RESERVED_KEYWORD)
PG_KEYWORD("cursor", CURSOR, UNRESERVED_KEYWORD)
PG_KEYWORD("cycle", CYCLE, UNRESERVED_KEYWORD)
PG_KEYWORD("data", DATA_P, UNRESERVED_KEYWORD)
PG_KEYWORD("database", DATABASE, UNRESERVED_KEYWORD)
PG_KEYWORD("day", DAY_P, UNRESERVED_KEYWORD)
PG_KEYWORD("deallocate", DEALLOCATE, UNRESERVED_KEYWORD)
PG_KEYWORD("dec", DEC, COL_NAME_KEYWORD)
PG_KEYWORD("decimal", DECIMAL_P, COL_NAME_KEYWORD)
PG_KEYWORD("declare", DECLARE, UNRESERVED_KEYWORD)
PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD)
PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD)
PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD)
PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD)
PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD)
PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD)
PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD)
PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD)
PG_KEYWORD("desc", DESC_P, RESERVED_KEYWORD)
PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD)
PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD)
PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD)
PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD)
PG_KEYWORD("do", DO, RESERVED_KEYWORD)
PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD)
PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD)
PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD)
PG_KEYWORD("else", ELSE, RESERVED_KEYWORD)
PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD)
PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD)
PG_KEYWORD("end", END_P, RESERVED_KEYWORD)
PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD)
PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD)
PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD)
PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD)
PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD)
PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD)
PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD)
PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD)
PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD)
PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD)
PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD)
PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD)
PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD)
PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD)
PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD)
PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD)
PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD)
PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD)
PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD)
PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD)
PG_KEYWORD("for", FOR, RESERVED_KEYWORD)
PG_KEYWORD("force", FORCE, UNRESERVED_KEYWORD)
PG_KEYWORD("foreign", FOREIGN, RESERVED_KEYWORD)
PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD)
PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("from", FROM, RESERVED_KEYWORD)
PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD)
PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD)
PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD)
PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD)
PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD)
PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD)
PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD)
PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD)
PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD)
PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD)
PG_KEYWORD("having", HAVING, RESERVED_KEYWORD)
PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD)
PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("import", IMPORT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("in", IN_P, RESERVED_KEYWORD)
PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD)
PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD)
PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD)
PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD)
PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD)
PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD)
PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD)
PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD)
PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD)
PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD)
PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD)
PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD)
PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD)
PG_KEYWORD("intersect", INTERSECT, RESERVED_KEYWORD)
PG_KEYWORD("interval", INTERVAL, COL_NAME_KEYWORD)
PG_KEYWORD("into", INTO, RESERVED_KEYWORD)
PG_KEYWORD("invoker", INVOKER, UNRESERVED_KEYWORD)
PG_KEYWORD("is", IS, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD)
PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD)
PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD)
PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD)
PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD)
PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD)
PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD)
PG_KEYWORD("leakproof", LEAKPROOF, UNRESERVED_KEYWORD)
PG_KEYWORD("least", LEAST, COL_NAME_KEYWORD)
PG_KEYWORD("left", LEFT, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("level", LEVEL, UNRESERVED_KEYWORD)
PG_KEYWORD("like", LIKE, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("limit", LIMIT, RESERVED_KEYWORD)
PG_KEYWORD("listen", LISTEN, UNRESERVED_KEYWORD)
PG_KEYWORD("load", LOAD, UNRESERVED_KEYWORD)
PG_KEYWORD("local", LOCAL, UNRESERVED_KEYWORD)
PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD)
PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD)
PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD)
PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD)
PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD)
PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD)
PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD)
PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD)
PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD)
PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD)
PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD)
PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD)
PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD)
PG_KEYWORD("month", MONTH_P, UNRESERVED_KEYWORD)
PG_KEYWORD("move", MOVE, UNRESERVED_KEYWORD)
PG_KEYWORD("name", NAME_P, UNRESERVED_KEYWORD)
PG_KEYWORD("names", NAMES, UNRESERVED_KEYWORD)
PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD)
PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD)
PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD)
PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD)
PG_KEYWORD("no", NO, UNRESERVED_KEYWORD)
PG_KEYWORD("none", NONE, COL_NAME_KEYWORD)
PG_KEYWORD("not", NOT, RESERVED_KEYWORD)
PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD)
PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD)
PG_KEYWORD("notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD)
PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD)
PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD)
PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD)
PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD)
PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("of", OF, UNRESERVED_KEYWORD)
PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD)
PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD)
PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD)
PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD)
PG_KEYWORD("on", ON, RESERVED_KEYWORD)
PG_KEYWORD("only", ONLY, RESERVED_KEYWORD)
PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD)
PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD)
PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD)
PG_KEYWORD("or", OR, RESERVED_KEYWORD)
PG_KEYWORD("order", ORDER, RESERVED_KEYWORD)
PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD)
PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD)
PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD)
PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD)
PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD)
PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD)
PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD)
PG_KEYWORD("parallel", PARALLEL, UNRESERVED_KEYWORD)
PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD)
PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD)
PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD)
PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD)
PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD)
PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD)
PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD)
PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD)
PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD)
PG_KEYWORD("pragma", PRAGMA_P, UNRESERVED_KEYWORD)
PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD)
PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD)
PG_KEYWORD("prepare", PREPARE, UNRESERVED_KEYWORD)
PG_KEYWORD("prepared", PREPARED, UNRESERVED_KEYWORD)
PG_KEYWORD("preserve", PRESERVE, UNRESERVED_KEYWORD)
PG_KEYWORD("primary", PRIMARY, RESERVED_KEYWORD)
PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD)
PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD)
PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD)
PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD)
PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD)
PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD)
PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD)
PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD)
PG_KEYWORD("read", READ_P, UNRESERVED_KEYWORD)
PG_KEYWORD("real", REAL, COL_NAME_KEYWORD)
PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD)
PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD)
PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD)
PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD)
PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD)
PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD)
PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD)
PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD)
PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD)
PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD)
PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD)
PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD)
PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD)
PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD)
PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD)
PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD)
PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD)
PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD)
PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD)
PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD)
PG_KEYWORD("rollup", ROLLUP, UNRESERVED_KEYWORD)
PG_KEYWORD("row", ROW, COL_NAME_KEYWORD)
PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD)
PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD)
PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD)
PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD)
PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD)
PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD)
PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD)
PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD)
PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD)
PG_KEYWORD("select", SELECT, RESERVED_KEYWORD)
PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD)
PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD)
PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD)
PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD)
PG_KEYWORD("session_user", SESSION_USER, RESERVED_KEYWORD)
PG_KEYWORD("set", SET, UNRESERVED_KEYWORD)
PG_KEYWORD("setof", SETOF, COL_NAME_KEYWORD)
PG_KEYWORD("sets", SETS, UNRESERVED_KEYWORD)
PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD)
PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD)
PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD)
PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD)
PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD)
PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD)
PG_KEYWORD("some", SOME, RESERVED_KEYWORD)
PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD)
PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("start", START, UNRESERVED_KEYWORD)
PG_KEYWORD("statement", STATEMENT, UNRESERVED_KEYWORD)
PG_KEYWORD("statistics", STATISTICS, UNRESERVED_KEYWORD)
PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD)
PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD)
PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD)
PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD)
PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD)
PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD)
PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD)
PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD)
PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD)
PG_KEYWORD("table", TABLE, RESERVED_KEYWORD)
PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD)
PG_KEYWORD("tablesample", TABLESAMPLE, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD)
PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD)
PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD)
PG_KEYWORD("temporary", TEMPORARY, UNRESERVED_KEYWORD)
PG_KEYWORD("text", TEXT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("then", THEN, RESERVED_KEYWORD)
PG_KEYWORD("time", TIME, COL_NAME_KEYWORD)
PG_KEYWORD("timestamp", TIMESTAMP, COL_NAME_KEYWORD)
PG_KEYWORD("to", TO, RESERVED_KEYWORD)
PG_KEYWORD("trailing", TRAILING, RESERVED_KEYWORD)
PG_KEYWORD("transaction", TRANSACTION, UNRESERVED_KEYWORD)
PG_KEYWORD("transform", TRANSFORM, UNRESERVED_KEYWORD)
PG_KEYWORD("treat", TREAT, COL_NAME_KEYWORD)
PG_KEYWORD("trigger", TRIGGER, UNRESERVED_KEYWORD)
PG_KEYWORD("trim", TRIM, COL_NAME_KEYWORD)
PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD)
PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD)
PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD)
PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD)
PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD)
PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD)
PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD)
PG_KEYWORD("union", UNION, RESERVED_KEYWORD)
PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD)
PG_KEYWORD("unknown", UNKNOWN, UNRESERVED_KEYWORD)
PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD)
PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD)
PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD)
PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD)
PG_KEYWORD("user", USER, RESERVED_KEYWORD)
PG_KEYWORD("using", USING, RESERVED_KEYWORD)
PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD)
PG_KEYWORD("valid", VALID, UNRESERVED_KEYWORD)
PG_KEYWORD("validate", VALIDATE, UNRESERVED_KEYWORD)
PG_KEYWORD("validator", VALIDATOR, UNRESERVED_KEYWORD)
PG_KEYWORD("value", VALUE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("values", VALUES, COL_NAME_KEYWORD)
PG_KEYWORD("varchar", VARCHAR, COL_NAME_KEYWORD)
PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD)
PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD)
PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD)
PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD)
PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD)
PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD)
PG_KEYWORD("when", WHEN, RESERVED_KEYWORD)
PG_KEYWORD("where", WHERE, RESERVED_KEYWORD)
PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD)
PG_KEYWORD("with", WITH, RESERVED_KEYWORD)
PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD)
PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD)
PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD)
PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD)
PG_KEYWORD("write", WRITE_P, UNRESERVED_KEYWORD)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD)
PG_KEYWORD("xmlnamespaces", XMLNAMESPACES, COL_NAME_KEYWORD)
PG_KEYWORD("xmlparse", XMLPARSE, COL_NAME_KEYWORD)
PG_KEYWORD("xmlpi", XMLPI, COL_NAME_KEYWORD)
PG_KEYWORD("xmlroot", XMLROOT, COL_NAME_KEYWORD)
PG_KEYWORD("xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD)
PG_KEYWORD("xmltable", XMLTABLE, COL_NAME_KEYWORD)
PG_KEYWORD("year", YEAR_P, UNRESERVED_KEYWORD)
PG_KEYWORD("yes", YES_P, UNRESERVED_KEYWORD)
PG_KEYWORD("zone", ZONE, UNRESERVED_KEYWORD)

};

const int NumScanKeywords = lengthof(ScanKeywords);



/*
 * ScanKeywordLookup - see if a given word is a keyword
 *
 * The table to be searched is passed explicitly, so that this can be used
 * to search keyword lists other than the standard list appearing above.
 *
 * Returns a pointer to the PGScanKeyword table entry, or NULL if no match.
 *
 * The match is done case-insensitively.  Note that we deliberately use a
 * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
 * even if we are in a locale where tolower() would produce more or different
 * translations.  This is to conform to the SQL99 spec, which says that
 * keywords are to be matched in this way even though non-keyword identifiers
 * receive a different case-normalization mapping.
 */
const PGScanKeyword *
ScanKeywordLookup(const char *text,
				  const PGScanKeyword *keywords,
				  int num_keywords)
{
	int			len,
				i;
	char		word[NAMEDATALEN];
	const PGScanKeyword *low;
	const PGScanKeyword *high;

	len = strlen(text);
	/* We assume all keywords are shorter than NAMEDATALEN. */
	if (len >= NAMEDATALEN)
		return NULL;

	/*
	 * Apply an ASCII-only downcasing.  We must not use tolower() since it may
	 * produce the wrong translation in some locales (eg, Turkish).
	 */
	for (i = 0; i < len; i++)
	{
		char		ch = text[i];

		if (ch >= 'A' && ch <= 'Z')
			ch += 'a' - 'A';
		word[i] = ch;
	}
	word[len] = '\0';

	/*
	 * Now do a binary search using plain strcmp() comparison.
	 */
	low = keywords;
	high = keywords + (num_keywords - 1);
	while (low <= high)
	{
		const PGScanKeyword *middle;
		int			difference;

		middle = low + (high - low) / 2;
		difference = strcmp(middle->name, word);
		if (difference == 0)
			return middle;
		else if (difference < 0)
			low = middle + 1;
		else
			high = middle - 1;
	}

	return NULL;
}









using namespace duckdb;
using namespace std;

#include <cstdio>

FileSystem &FileSystem::GetFileSystem(ClientContext &context) {
	return *context.db.file_system;
}

static void AssertValidFileFlags(uint8_t flags) {
	// cannot combine Read and Write flags
	assert(!(flags & FileFlags::READ && flags & FileFlags::WRITE));
	// cannot combine Read and Append flags
	assert(!(flags & FileFlags::READ && flags & FileFlags::APPEND));
	// cannot combine Read and CREATE flags
	assert(!(flags & FileFlags::READ && flags & FileFlags::CREATE));
}

#ifndef _WIN32
#include <dirent.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

// somehow sometimes this is missing
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif

// Solaris
#ifndef O_DIRECT
# define O_DIRECT 0
#endif

struct UnixFileHandle : public FileHandle {
public:
	UnixFileHandle(FileSystem &file_system, string path, int fd) : FileHandle(file_system, path), fd(fd) {
	}
	virtual ~UnixFileHandle() {
		Close();
	}

protected:
	void Close() override {
		if (fd != -1) {
			close(fd);
		}
	};

public:
	int fd;
};

unique_ptr<FileHandle> FileSystem::OpenFile(const char *path, uint8_t flags, FileLockType lock_type) {
	AssertValidFileFlags(flags);

	int open_flags = 0;
	int rc;
	if (flags & FileFlags::READ) {
		open_flags = O_RDONLY;
	} else {
		// need Read or Write
		assert(flags & FileFlags::WRITE);
		open_flags = O_RDWR | O_CLOEXEC;
		if (flags & FileFlags::CREATE) {
			open_flags |= O_CREAT;
		}
		if (flags & FileFlags::APPEND) {
			open_flags |= O_APPEND;
		}
	}
	if (flags & FileFlags::DIRECT_IO) {
#if defined(__sun) && defined(__SVR4)
		throw Exception("DIRECT_IO not supported on Solaris");
#endif
#if defined(__DARWIN__) || defined(__APPLE__) || defined(__OpenBSD__)
		// OSX does not have O_DIRECT, instead we need to use fcntl afterwards to support direct IO
		open_flags |= O_SYNC;
#else
		open_flags |= O_DIRECT | O_SYNC;
#endif
	}
	int fd = open(path, open_flags, 0666);
	if (fd == -1) {
		throw IOException("Cannot open file \"%s\": %s", path, strerror(errno));
	}
	// #if defined(__DARWIN__) || defined(__APPLE__)
	// 	if (flags & FileFlags::DIRECT_IO) {
	// 		// OSX requires fcntl for Direct IO
	// 		rc = fcntl(fd, F_NOCACHE, 1);
	// 		if (fd == -1) {
	// 			throw IOException("Could not enable direct IO for file \"%s\": %s", path, strerror(errno));
	// 		}
	// 	}
	// #endif
	if (lock_type != FileLockType::NO_LOCK) {
		// set lock on file
		struct flock fl;
		memset(&fl, 0, sizeof fl);
		fl.l_type = lock_type == FileLockType::READ_LOCK ? F_RDLCK : F_WRLCK;
		fl.l_whence = SEEK_SET;
		fl.l_start = 0;
		fl.l_len = 0;
		rc = fcntl(fd, F_SETLK, &fl);
		if (rc == -1) {
			throw IOException("Could not set lock on file \"%s\": %s", path, strerror(errno));
		}
	}
	return make_unique<UnixFileHandle>(*this, path, fd);
}

void FileSystem::SetFilePointer(FileHandle &handle, idx_t location) {
	int fd = ((UnixFileHandle &)handle).fd;
	off_t offset = lseek(fd, location, SEEK_SET);
	if (offset == (off_t)-1) {
		throw IOException("Could not seek to location %lld for file \"%s\": %s", location, handle.path.c_str(),
		                  strerror(errno));
	}
}

int64_t FileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) {
	int fd = ((UnixFileHandle &)handle).fd;
	int64_t bytes_read = read(fd, buffer, nr_bytes);
	if (bytes_read == -1) {
		throw IOException("Could not read from file \"%s\": %s", handle.path.c_str(), strerror(errno));
	}
	return bytes_read;
}

int64_t FileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) {
	int fd = ((UnixFileHandle &)handle).fd;
	int64_t bytes_written = write(fd, buffer, nr_bytes);
	if (bytes_written == -1) {
		throw IOException("Could not write file \"%s\": %s", handle.path.c_str(), strerror(errno));
	}
	return bytes_written;
}

int64_t FileSystem::GetFileSize(FileHandle &handle) {
	int fd = ((UnixFileHandle &)handle).fd;
	struct stat s;
	if (fstat(fd, &s) == -1) {
		return -1;
	}
	return s.st_size;
}

void FileSystem::Truncate(FileHandle &handle, int64_t new_size) {
	int fd = ((UnixFileHandle &)handle).fd;
	if (ftruncate(fd, new_size) != 0) {
		throw IOException("Could not truncate file \"%s\": %s", handle.path.c_str(), strerror(errno));
	}
}

bool FileSystem::DirectoryExists(const string &directory) {
	if (!directory.empty()) {
		if (access(directory.c_str(), 0) == 0) {
			struct stat status;
			stat(directory.c_str(), &status);
			if (status.st_mode & S_IFDIR)
				return true;
		}
	}
	// if any condition fails
	return false;
}

bool FileSystem::FileExists(const string &filename) {
	if (!filename.empty()) {
		if (access(filename.c_str(), 0) == 0) {
			struct stat status;
			stat(filename.c_str(), &status);
			if (!(status.st_mode & S_IFDIR))
				return true;
		}
	}
	// if any condition fails
	return false;
}

void FileSystem::CreateDirectory(const string &directory) {
	struct stat st;

	if (stat(directory.c_str(), &st) != 0) {
		/* Directory does not exist. EEXIST for race condition */
		if (mkdir(directory.c_str(), 0755) != 0 && errno != EEXIST) {
			throw IOException("Failed to create directory \"%s\"!", directory.c_str());
		}
	} else if (!S_ISDIR(st.st_mode)) {
		throw IOException("Failed to create directory \"%s\": path exists but is not a directory!", directory.c_str());
	}
}

int remove_directory_recursively(const char *path) {
	DIR *d = opendir(path);
	idx_t path_len = (idx_t)strlen(path);
	int r = -1;

	if (d) {
		struct dirent *p;
		r = 0;
		while (!r && (p = readdir(d))) {
			int r2 = -1;
			char *buf;
			idx_t len;
			/* Skip the names "." and ".." as we don't want to recurse on them. */
			if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
				continue;
			}
			len = path_len + (idx_t)strlen(p->d_name) + 2;
			buf = new char[len];
			if (buf) {
				struct stat statbuf;
				snprintf(buf, len, "%s/%s", path, p->d_name);
				if (!stat(buf, &statbuf)) {
					if (S_ISDIR(statbuf.st_mode)) {
						r2 = remove_directory_recursively(buf);
					} else {
						r2 = unlink(buf);
					}
				}
				delete[] buf;
			}
			r = r2;
		}
		closedir(d);
	}
	if (!r) {
		r = rmdir(path);
	}
	return r;
}

void FileSystem::RemoveDirectory(const string &directory) {
	remove_directory_recursively(directory.c_str());
}

void FileSystem::RemoveFile(const string &filename) {
	if (std::remove(filename.c_str()) != 0) {
		throw IOException("Could not remove file \"%s\": %s", filename.c_str(), strerror(errno));
	}
}

bool FileSystem::ListFiles(const string &directory, function<void(string)> callback) {
	if (!DirectoryExists(directory)) {
		return false;
	}
	DIR *dir;
	struct dirent *ent;
	if ((dir = opendir(directory.c_str())) != NULL) {
		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			string name = string(ent->d_name);
			if (!name.empty() && name[0] != '.') {
				callback(name);
			}
		}
		closedir(dir);
	} else {
		return false;
	}
	return true;
}

string FileSystem::PathSeparator() {
	return "/";
}

void FileSystem::FileSync(FileHandle &handle) {
	int fd = ((UnixFileHandle &)handle).fd;
	if (fsync(fd) != 0) {
		throw FatalException("fsync failed!");
	}
}

void FileSystem::MoveFile(const string &source, const string &target) {
	//! FIXME: rename does not guarantee atomicity or overwriting target file if it exists
	if (rename(source.c_str(), target.c_str()) != 0) {
		throw IOException("Could not rename file!");
	}
}

#else

#include <string>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>

#undef CreateDirectory
#undef MoveFile
#undef RemoveDirectory

// Returns the last Win32 error, in string format. Returns an empty string if there is no error.
std::string GetLastErrorAsString() {
	// Get the error message, if any.
	DWORD errorMessageID = ::GetLastError();
	if (errorMessageID == 0)
		return std::string(); // No error message has been recorded

	LPSTR messageBuffer = nullptr;
	idx_t size =
	    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
	                   NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

	std::string message(messageBuffer, size);

	// Free the buffer.
	LocalFree(messageBuffer);

	return message;
}

struct WindowsFileHandle : public FileHandle {
public:
	WindowsFileHandle(FileSystem &file_system, string path, HANDLE fd) : FileHandle(file_system, path), fd(fd) {
	}
	virtual ~WindowsFileHandle() {
		Close();
	}

protected:
	void Close() override {
		CloseHandle(fd);
	};

public:
	HANDLE fd;
};

unique_ptr<FileHandle> FileSystem::OpenFile(const char *path, uint8_t flags, FileLockType lock_type) {
	AssertValidFileFlags(flags);

	DWORD desired_access;
	DWORD share_mode;
	DWORD creation_disposition = OPEN_EXISTING;
	DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
	if (flags & FileFlags::READ) {
		desired_access = GENERIC_READ;
		share_mode = FILE_SHARE_READ;
	} else {
		// need Read or Write
		assert(flags & FileFlags::WRITE);
		desired_access = GENERIC_READ | GENERIC_WRITE;
		share_mode = 0;
		if (flags & FileFlags::CREATE) {
			creation_disposition = OPEN_ALWAYS;
		}
		if (flags & FileFlags::DIRECT_IO) {
			flags_and_attributes |= FILE_FLAG_WRITE_THROUGH;
		}
	}
	if (flags & FileFlags::DIRECT_IO) {
		flags_and_attributes |= FILE_FLAG_NO_BUFFERING;
	}
	HANDLE hFile =
	    CreateFileA(path, desired_access, share_mode, NULL, creation_disposition, flags_and_attributes, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
		auto error = GetLastErrorAsString();
		throw IOException("Cannot open file \"%s\": %s", path, error.c_str());
	}
	auto handle = make_unique<WindowsFileHandle>(*this, path, hFile);
	if (flags & FileFlags::APPEND) {
		SetFilePointer(*handle, GetFileSize(*handle));
	}
	return move(handle);
}

void FileSystem::SetFilePointer(FileHandle &handle, idx_t location) {
	HANDLE hFile = ((WindowsFileHandle &)handle).fd;
	LARGE_INTEGER loc;
	loc.QuadPart = location;
	auto rc = SetFilePointerEx(hFile, loc, NULL, FILE_BEGIN);
	if (rc == 0) {
		auto error = GetLastErrorAsString();
		throw IOException("Could not seek to location %lld for file \"%s\": %s", location, handle.path.c_str(),
		                  error.c_str());
	}
}

int64_t FileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) {
	HANDLE hFile = ((WindowsFileHandle &)handle).fd;
	DWORD bytes_read;
	auto rc = ReadFile(hFile, buffer, (DWORD)nr_bytes, &bytes_read, NULL);
	if (rc == 0) {
		auto error = GetLastErrorAsString();
		throw IOException("Could not write file \"%s\": %s", handle.path.c_str(), error.c_str());
	}
	return bytes_read;
}

int64_t FileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) {
	HANDLE hFile = ((WindowsFileHandle &)handle).fd;
	DWORD bytes_read;
	auto rc = WriteFile(hFile, buffer, (DWORD)nr_bytes, &bytes_read, NULL);
	if (rc == 0) {
		auto error = GetLastErrorAsString();
		throw IOException("Could not write file \"%s\": %s", handle.path.c_str(), error.c_str());
	}
	return bytes_read;
}

int64_t FileSystem::GetFileSize(FileHandle &handle) {
	HANDLE hFile = ((WindowsFileHandle &)handle).fd;
	LARGE_INTEGER result;
	if (!GetFileSizeEx(hFile, &result)) {
		return -1;
	}
	return result.QuadPart;
}

void FileSystem::Truncate(FileHandle &handle, int64_t new_size) {
	HANDLE hFile = ((WindowsFileHandle &)handle).fd;
	// seek to the location
	SetFilePointer(handle, new_size);
	// now set the end of file position
	if (!SetEndOfFile(hFile)) {
		auto error = GetLastErrorAsString();
		throw IOException("Failure in SetEndOfFile call on file \"%s\": %s", handle.path.c_str(), error.c_str());
	}
}

bool FileSystem::DirectoryExists(const string &directory) {
	DWORD attrs = GetFileAttributesA(directory.c_str());
	return (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY));
}

bool FileSystem::FileExists(const string &filename) {
	DWORD attrs = GetFileAttributesA(filename.c_str());
	return (attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY));
}

void FileSystem::CreateDirectory(const string &directory) {
	if (DirectoryExists(directory)) {
		return;
	}
	if (directory.empty() || !CreateDirectoryA(directory.c_str(), NULL) || !DirectoryExists(directory)) {
		throw IOException("Could not create directory!");
	}
}

static void delete_dir_special_snowflake_windows(string directory) {
	if (directory.size() + 3 > MAX_PATH) {
		throw IOException("Pathname too long");
	}
	// create search pattern
	TCHAR szDir[MAX_PATH];
	snprintf(szDir, MAX_PATH, "%s\\*", directory.c_str());

	WIN32_FIND_DATA ffd;
	HANDLE hFind = FindFirstFile(szDir, &ffd);
	if (hFind == INVALID_HANDLE_VALUE) {
		return;
	}

	do {
		if (string(ffd.cFileName) == "." || string(ffd.cFileName) == "..") {
			continue;
		}
		if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			// recurse to zap directory contents
			FileSystem fs;
			delete_dir_special_snowflake_windows(fs.JoinPath(directory, ffd.cFileName));
		} else {
			if (strlen(ffd.cFileName) + directory.size() + 1 > MAX_PATH) {
				throw IOException("Pathname too long");
			}
			// create search pattern
			TCHAR del_path[MAX_PATH];
			snprintf(del_path, MAX_PATH, "%s\\%s", directory.c_str(), ffd.cFileName);
			if (!DeleteFileA(del_path)) {
				throw IOException("Failed to delete directory entry");
			}
		}
	} while (FindNextFile(hFind, &ffd) != 0);

	DWORD dwError = GetLastError();
	if (dwError != ERROR_NO_MORE_FILES) {
		throw IOException("Something went wrong");
	}
	FindClose(hFind);

	if (!RemoveDirectoryA(directory.c_str())) {
		throw IOException("Failed to delete directory");
	}
}

void FileSystem::RemoveDirectory(const string &directory) {
	delete_dir_special_snowflake_windows(directory.c_str());
}

void FileSystem::RemoveFile(const string &filename) {
	DeleteFileA(filename.c_str());
}

bool FileSystem::ListFiles(const string &directory, function<void(string)> callback) {
	string search_dir = JoinPath(directory, "*");

	WIN32_FIND_DATA ffd;
	HANDLE hFind = FindFirstFile(search_dir.c_str(), &ffd);
	if (hFind == INVALID_HANDLE_VALUE) {
		return false;
	}
	do {
		if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			continue;
		}

		callback(string(ffd.cFileName));
	} while (FindNextFile(hFind, &ffd) != 0);

	DWORD dwError = GetLastError();
	if (dwError != ERROR_NO_MORE_FILES) {
		FindClose(hFind);
		return false;
	}

	FindClose(hFind);
	return true;
}

string FileSystem::PathSeparator() {
	return "\\";
}

void FileSystem::FileSync(FileHandle &handle) {
	HANDLE hFile = ((WindowsFileHandle &)handle).fd;
	if (FlushFileBuffers(hFile) == 0) {
		throw IOException("Could not flush file handle to disk!");
	}
}

void FileSystem::MoveFile(const string &source, const string &target) {
	if (!MoveFileA(source.c_str(), target.c_str())) {
		throw IOException("Could not move file");
	}
}
#endif

void FileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) {
	// seek to the location
	SetFilePointer(handle, location);
	// now read from the location
	int64_t bytes_read = Read(handle, buffer, nr_bytes);
	if (bytes_read != nr_bytes) {
		throw IOException("Could not read sufficient bytes from file \"%s\"", handle.path.c_str());
	}
}

void FileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) {
	// seek to the location
	SetFilePointer(handle, location);
	// now write to the location
	int64_t bytes_written = Write(handle, buffer, nr_bytes);
	if (bytes_written != nr_bytes) {
		throw IOException("Could not write sufficient bytes from file \"%s\"", handle.path.c_str());
	}
}

string FileSystem::JoinPath(const string &a, const string &b) {
	// FIXME: sanitize paths
	return a + PathSeparator() + b;
}

void FileHandle::Read(void *buffer, idx_t nr_bytes, idx_t location) {
	file_system.Read(*this, buffer, nr_bytes, location);
}

void FileHandle::Write(void *buffer, idx_t nr_bytes, idx_t location) {
	file_system.Write(*this, buffer, nr_bytes, location);
}

void FileHandle::Sync() {
	file_system.FileSync(*this);
}

void FileHandle::Truncate(int64_t new_size) {
	file_system.Truncate(*this, new_size);
}
