/*!
* re2js
* RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching
*
* @version v2.8.6
* @author Oleksii Vasyliev
* @homepage https://github.com/le0pard/re2js#readme
* @repository github:le0pard/re2js
* @license MIT
*/
//#region src/RE2Flags.js
var RE2Flags = class RE2Flags {
	static FOLD_CASE = 1;
	static LITERAL = 2;
	static CLASS_NL = 4;
	static DOT_NL = 8;
	static ONE_LINE = 16;
	static NON_GREEDY = 32;
	static PERL_X = 64;
	static UNICODE_GROUPS = 128;
	static WAS_DOLLAR = 256;
	static LOOKBEHIND = 512;
	static MATCH_NL = RE2Flags.CLASS_NL | RE2Flags.DOT_NL;
	static PERL = RE2Flags.CLASS_NL | RE2Flags.ONE_LINE | RE2Flags.PERL_X | RE2Flags.UNICODE_GROUPS;
	static POSIX = 0;
	static UNANCHORED = 0;
	static ANCHOR_START = 1;
	static ANCHOR_BOTH = 2;
};
//#endregion
//#region src/PublicFlags.js
/**
* Public flags for RE2JS and RE2Set compilation.
*/
const PublicFlags = {
	CASE_INSENSITIVE: 1,
	DOTALL: 2,
	MULTILINE: 4,
	DISABLE_UNICODE_GROUPS: 8,
	LONGEST_MATCH: 16,
	LOOKBEHINDS: 512
};
//#endregion
//#region src/Codepoint.js
/**
* Various constants and helper for unicode codepoints.
*/
const ASCII_SIZE = 128;
const ASCII_TO_UPPER = new Int32Array(ASCII_SIZE);
const ASCII_TO_LOWER = new Int32Array(ASCII_SIZE);
const MAX_BMP = 65535;
for (let i = 0; i < ASCII_SIZE; i++) {
	if (i >= 97 && i <= 122) ASCII_TO_UPPER[i] = i - 32;
	else ASCII_TO_UPPER[i] = i;
	if (i >= 65 && i <= 90) ASCII_TO_LOWER[i] = i + 32;
	else ASCII_TO_LOWER[i] = i;
}
var Codepoint = class {
	static CODES = /* @__PURE__ */ new Map([
		["\x07", 7],
		["\b", 8],
		["	", 9],
		["\n", 10],
		["\v", 11],
		["\f", 12],
		["\r", 13],
		[" ", 32],
		["\"", 34],
		["$", 36],
		["&", 38],
		["'", 39],
		["(", 40],
		[")", 41],
		["*", 42],
		["+", 43],
		["-", 45],
		[".", 46],
		["0", 48],
		["1", 49],
		["2", 50],
		["3", 51],
		["4", 52],
		["5", 53],
		["6", 54],
		["7", 55],
		["8", 56],
		["9", 57],
		[":", 58],
		["<", 60],
		[">", 62],
		["?", 63],
		["A", 65],
		["B", 66],
		["C", 67],
		["F", 70],
		["P", 80],
		["Q", 81],
		["U", 85],
		["Z", 90],
		["[", 91],
		["\\", 92],
		["]", 93],
		["^", 94],
		["_", 95],
		["`", 96],
		["a", 97],
		["b", 98],
		["f", 102],
		["i", 105],
		["m", 109],
		["n", 110],
		["r", 114],
		["s", 115],
		["t", 116],
		["v", 118],
		["x", 120],
		["z", 122],
		["{", 123],
		["|", 124],
		["}", 125]
	]);
	static toUpperCase(codepoint) {
		if (codepoint < ASCII_SIZE) return ASCII_TO_UPPER[codepoint];
		const s = String.fromCodePoint(codepoint).toUpperCase();
		const expectedLen = s.codePointAt(0) > MAX_BMP ? 2 : 1;
		if (s.length > expectedLen) return codepoint;
		const sOrigin = String.fromCodePoint(s.codePointAt(0)).toLowerCase();
		const originExpectedLen = sOrigin.codePointAt(0) > MAX_BMP ? 2 : 1;
		if (sOrigin.length > originExpectedLen || sOrigin.codePointAt(0) !== codepoint) return codepoint;
		return s.codePointAt(0);
	}
	static toLowerCase(codepoint) {
		if (codepoint < ASCII_SIZE) return ASCII_TO_LOWER[codepoint];
		const s = String.fromCodePoint(codepoint).toLowerCase();
		const expectedLen = s.codePointAt(0) > MAX_BMP ? 2 : 1;
		if (s.length > expectedLen) return codepoint;
		const sOrigin = String.fromCodePoint(s.codePointAt(0)).toUpperCase();
		const originExpectedLen = sOrigin.codePointAt(0) > MAX_BMP ? 2 : 1;
		if (sOrigin.length > originExpectedLen || sOrigin.codePointAt(0) !== codepoint) return codepoint;
		return s.codePointAt(0);
	}
};
//#endregion
//#region src/UnicodeRangeTable.js
var UnicodeRangeTable = class {
	/**
	* @param {Uint32Array | number[]} data
	* @param {boolean} isStride1
	*/
	constructor(data, isStride1 = false) {
		this.data = data;
		this.isStride1 = isStride1;
		this.SIZE = isStride1 ? 2 : 3;
	}
	getLo(index) {
		return this.data[index * this.SIZE];
	}
	getHi(index) {
		return this.data[index * this.SIZE + 1];
	}
	getStride(index) {
		return this.isStride1 ? 1 : this.data[index * this.SIZE + 2];
	}
	get length() {
		return this.data.length / this.SIZE;
	}
};
//#endregion
//#region src/UnicodeTables.js
const B64_MAP = /* @__PURE__ */ new Uint8Array(256);
for (let i = 0, b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; i < 64; i++) B64_MAP[b.charCodeAt(i)] = i;
const decodeVLQ = (str) => {
	const res = [];
	let value = 0, shift = 0;
	for (let i = 0; i < str.length; i++) {
		let digit = B64_MAP[str.charCodeAt(i)];
		value |= (digit & 31) << shift;
		if ((digit & 32) === 0) {
			res.push(value);
			value = 0;
			shift = 0;
		} else shift += 5;
	}
	return res;
};
const decodeRanges = (str, isStride1) => {
	const res = decodeVLQ(str);
	const numRanges = isStride1 ? res.length / 2 : res.length / 3;
	const out = new Uint32Array(numRanges * 3);
	let current = 0, resIdx = 0;
	for (let i = 0; i < numRanges; i++) {
		current += res[resIdx++];
		out[i * 3] = current;
		current += res[resIdx++];
		out[i * 3 + 1] = current;
		out[i * 3 + 2] = isStride1 ? 1 : res[resIdx++];
	}
	return out;
};
const decodeOrbit = (str) => {
	const res = decodeVLQ(str);
	const map = /* @__PURE__ */ new Map();
	let currentKey = 0;
	for (let i = 0; i < res.length; i += 2) {
		currentKey += res[i];
		const zz = res[i + 1];
		const delta = zz >>> 1 ^ -(zz & 1);
		map.set(currentKey, currentKey + delta);
	}
	return map;
};
var LazyMap = class {
	constructor(initializer) {
		this.initializer = initializer;
		this.cache = /* @__PURE__ */ new Map();
	}
	has(key) {
		return key in this.initializer;
	}
	get(key) {
		if (this.cache.has(key)) return this.cache.get(key);
		const fn = this.initializer[key];
		const val = fn ? fn() : null;
		this.cache.set(key, val);
		return val;
	}
};
var UnicodeTables = class {
	static _CASE_ORBIT = null;
	static get CASE_ORBIT() {
		if (!this._CASE_ORBIT) this._CASE_ORBIT = decodeOrbit(" ");
		return this._CASE_ORBIT;
	}
	static _Print = null;
	static get Print() {
		if (!this._Print) this._Print = new UnicodeRangeTable(decodeRanges("hB9CBjBLBCpWBDFBFGBCCCBSBCsMBClBBDxBBDCBC2BBJaBFFBSVBC-FBCvBBD6BBDkDBP6BBDwBBDOBCbBDCCBJBGfBIqCBCgFBCHBDBBDVBCGBCEEBCBDIBDBBDDBJFFBCCBDBDYBDCBCFBFBBDVBCGBCBBCBBCBBDCCBDBFBBDCBEIIBCBCIIBPBLCBCIBCCBCVBCGBCBBCEBDJBCCBCCBDQQBCBDLBIGBCCBCHBDBBDVBCGBCBBCEBDIBDBBDCBICBFBBCEBDRBLBBCFBECBCDBEBBCCCBEEBEEBBBELBFEBECBCDBDHHPUBGMBCCBCWBCPBDIBCCBCDBIBBCCBCBBDDBDJBIVBCCBCWBCJBCEBDIBCCBCDBIBBGCBCDBDJBCCBNMBCCBCyBBCCBCFBFPBDZBCCBCRBEXBCIBCDDBFBEFFBEBCCCBGBHJBDCBN5BBFcBmBBBCCCBDBCXBCCCBVBDEBCCCBFBCJBDDBhBnCBCjBBFmBBCjBBCOBCMBmBlGBCGGD4LBCDBDGBCCCBCBDoBBCDBDgBBCDBDGBCCCBCBDOBC4BBCDBDiCBDfBEZBH1CBDFBD-TBCbBE4CBIVBKXBKTBNMBCCBCBBN9CBDJBHJBHNBCKBH4CBIqBBGlCBLeBCLBFLBFEEBoBBDEBMrBBFZBHKBE9BBDgCBCcBDKBHJBHNBDtBBDLBVsCBClFBJ7BBEOBE9BBGqBBDKBJqBBG1QBDFBDlBBDFBDHBCGCBdBD0BBCOBCNBDFBCSBDCBCIBSXBJuBBSBBDaBCMBEhBBPgBBQrEBF5UBXKBWz4BBD9LBGsBBCGGD3BBIBBPXBKGBCGBCGBCGBCGBCGBCGBCGBC9DBjBZBC4CBN1GBbPBC+BBC1CBDmDBGqBBC9CBC1CBKvBBCszcBE2BBK7KBV3FBJ8GBV7BBEJBH3BBJlCBJLBHzDBMdBEtCBCKBFgBBC2BBKNBDJBDmDBZbBLFBDFBDFBKGBCGBC7BBF9DBDJBHj9KBNWBFwBBloItLBDpDBnBGBNEBGZBCEBCCCBCCBCCBoUBhBpBBHyBBCSBCDBFEBCmEBF9FBEFBDFBDFBDCBEGBCGBOBBDLBCZBCSBCBBCOBDNBjB6DBGCBFsBBE3CBCMBEwBwBBsBBjEcBEwBBQbBFjBBKdBGqBBGdBCkBBFNBrB9EBDJBHjBBFjBBFnBBJzBBMLBCOBCGBCBBCKBCOBCGBCBBEzBBN2JBKVBLHBZFBCpBBCIBmCFBDCCBqBBCBBEDDBVBCnCBJIBxBSBCBBGgBBEaBGaBnB3BBFTBDxBBCBBGHBCCBCcBDCBFJBIIBI-BBhBmBBFLBK1BBEcBDaBGZBIDBNGBxCoCB4ByBBOyBBItBBJJBHlBBEcBJBBxGeBCpBBCCBDBBRFBJIBiBtBBJpBBXZBnBbBVWBKtCBFjBBK9BBCEBOYBIJBH0BBCRBJmBBK-CBCTBMRBCuBB-BGBCCCBCBCOBCKBH6BBGJBHDBCHBDBBDVBCGBCBBCEBCJBDBBDCBDHHGGBDGBEEBMJBCDDClBBCJBCDDCDBCJBCBBJBBe7CBCEBfnCBJJBnF1BBDlBBjBkCBMJBHMBU5BBHJBHTBdaBDOBFWB6F7BBlDyCBNHBDDDBGBCBBCdBCBBDLBKJBnCHBDtBBDKBcnCBJyCBOoCBIJB3CHB5ChBBPJBHIBCsBBCNBLcBEfBDVBCNBqCGBCBBCrBBECCBCCBHBJJBHFBCBBCkBBCBBCFBIJBHrBBFJB3HYBIQBCoBBEcB2CQQBwBBO6cBnDuDBCEBMjGBtyCiDBOvhBBRVBL68DBGmSB61G5BBn2B4RBIeBCJBFwCBCJBHdBDFBLlCBLJBCGBCUBGSBxN5BBnG6CBGYBDYBtBqCBF4BBIQBhCEBMGBK1mHBqBfBiDyDB+vIDBCGBCBBCiJBQeeBBBDPPBCBJrMBloCqDBGMBEIBIJBDDBh7D8HBEzNBHWBQQBQtBBDWBKzDB9B1HBLmBBDpCBJvDBWlCB7DTBNTBN2CBKYBoE0CBCmCBCBBDDDBDDBCBCLBCCCBFBCgCBCDBDHBCGBCbBCDBCEBCEEBFBCzKBDjJBD9VBQEBCOBxiBeBHFB2GGBCQBDGBCBBCEBG9BBiBxDxDBrBBENBDJBFBBhKeBS5BBGxOxOBoBB3GqBBFhGhGBdBCVBJBBhHGBCDBCBBCOBCkGBDPBqBrCBFJBFBByYjCBtC8BBjGDBCaBCBBCDDCJBCDBCCCHFFCECBBBCBBCDDCICBCCDDBCGBCDBCDBCCCBIBCQBGCBCEBCQB1BBBvIrBBFjDBNOBDOBCOBCkBBLtFB5BcBOrBBFIBIBBPFB7E4eBEQBEMBE5GBHLBFQQBKBF3BBJJBHnBBJdBDLBFBBPIBoB3KBJNBDMBEKBE4BBCFFBOBDLBFJBIyEBCmDBmgB-2pBBhB9oEBDt0FBDwpHBQtTBjtC9QBjvBq6EBGppIBnkzVvHB", false));
		return this._Print;
	}
	static CATEGORIES = new LazyMap({
		C: () => new UnicodeRangeTable(decodeRanges("AfBgDgBBOrWrWBHHBCBICCVuMuMnBBBzBBBE4B4BBGBcDBHQBXhGhGxBBB8BBBmDNB8BBByBBBQddBCCMEBhBGBsCiFiFJBBDBBXIICCBFBBKBBDBBFHBCDBDGGBaaBEEHDBDBBXIIDGDBCCGDBDBBECBCGBFCCBFBSJBEKKEXXIDDGBBLIEBCCBNBFBBNGBIEEJBBDBBXIIDGGBKKBDDBEEBFBEDBDGGBTTBIBDHHBBBEFFBBBDCCDCBDCBECBNDBGCBEFFBCCBEBCNBWEBOEEYRRBKKEFFBFBDEEDBBFBBLGBXEEYLLGBBKEEFGBDEBEFFBLLELBOEE0BEEHDBRBBbEETCBZKKCBBICBCDBHCCJFBLBBELB7BDBekBBDCCGZZCYYBGGCIILBBFfBpClBlBBCBoBlBlBQOOBjBBnGCCBDBCBB6LFFBIICFFBqBqBFBBiBFFBIICFFBQQ6BFFBkCkCBhBhBBBBbFB3CBBHBB+UCB6CGBXIBZIBVLBOEEDLB-CBBLFBLFBPMMBEB6CGBsBEBnCJBgBNNBCBNDBCCBrBBBGKBtBDBbFBMCB-BBBiCeeBMMBEBLFBPBBvBBBNTBuCnFnFBGB9BCBQCB-BEBsBBBMHBsBEB3QBBHBBnBBBHBBJGCgBBB2BQQPBBHUUBEEKMMBDBbEByBPBDBBcOOBBBjBNBiBOBtEDB7UVBMUB14BBB-LEBuBCCBDBCBB5BGBDNBZIBI4BI-DhBBb6C6CBKB3GZBxC3C3CBoDoDBDBsB-C-C3CIBxBuzcuzcBBB4BIB9KTB5FHB+GTB9BCBLFB5BHBnCHBNFB1DKBfCBvCMMBCBiB4B4BBHBPBBLBBoDXBdJBHBBHBBHIBIII9BDB-DBBLFBl9KLBYDByBjoIBvLBBrDlBBILBGEBbGGCGDrUfBrBFB0BUUFDBGoEoEBCB-FCBHBBHBBHBBECBIIIBLBDBBNbbUDDQBBPhBB8DEBEDBuBCB5COOBBBCuBBvBhEBeCByBOBdDBlBIBfEBsBEBfmBmBBCBPpBB-EBBLFBlBDBlBDBpBHB1BKBNQQIDDMQQIDDBBB1BLB4JIBXJBJXBHrBrBKkCBHBBCtBtBDCBCBBYpCpCBGBKvBBUDDBDBiBCBcEBclBB5BDBVBBzBDDBDBJEEeBBEDBLGBKGBhCfBoBDBNIB3BCBeBBcEBbGBFLBIvCBqC2BB0BMB0BGBvBHBLFBnBCBeHBDvGBgBrBrBEBBDPBHHBKgBBvBHBrBVBblBBdTBYIBvCDBlBIB-BGGBLBaGBLFB2BTTBGBoBIBhDVVBJBTwBwBB8BBICCFQQMFB8BEBLFBFJJBDDBXXIDDGLLBDDBEEBCCBEBCEBIBBICBGKBLCCBCCnBLLCBBCFFLDDBGBDcB9CGGBcBpCHBLlFB3BBBnBhBBmCKBLFBOSB7BFBLFBVbBcBBQDBY4FB9BjDB0CLBJBBCBBJDDfDDBNNBHBLlCBJBBvBBBMaBpCHB0CMBqCGBL1CBJ3CBjBNBLFBKuBuBPJBeCBhBBBXPPBnCBIDDtBCBCDDKHBLFBHDDmBDDHGBLFBtBDBL1HBaGBSqBqBBBBe0CBCOBzBMB8clDBwDGGBJBlGryCBkDMBxhBPBXJB88DEBoS41GB7Bl2BB6RGBgBLLBCByCLLBEBfBBHJBnCJBLIIWEBUvNB7BlGB8CEBaBBarBBsCDB6BGBS-BBGKBIIB3mHoBBhBgDB0D8vIBFIIDkJkJBNBCcBEBBCNBFHBtMjoCBsDEBOCBKGBLBBF-6DB+HCB1NFBYOBSOBvBBBYIB1D7BB3HJBoBBBrCHBxDUBnC5DBVLBVLB4CIBamEB2CoCoCDBBCBBDBBFNNCIIiCFFBJJIddFGGCCBI1K1KBlJlJB-V-VBNBGQQBuiBBgBFBH0GBISSBIIDGGBDB-BgBBCvDBuBCBPBBLDBD-JBgBQB7BEBCvOBrB1GBsBDBC-FBgBXXBGBD-GBIFFDQQmGBBRoBBtCDBLDBDwYBlCrCB+BhGBFccDCCBCCLFFCCCBEBCDBCECEDDCBBCICDCCBFFIKFCLLSEBEGGSzBBDtIBtBDBlDLBQBBQQQmBJBvF3BBeMBtBDBKGBDNBH5EB6eCBSCBOCB7GFBNDBCOBNDB5BHBLFBpBHBfBBNDBDNBKmBB5KHBPBBOCBMCB6BCCBCBRBBNDBLGB0EoDoDBjgBBh3pBfB-oEBBv0FBBypHOBvThtCB-QhvBBs6EEBrpIlkzVBxHvw-FB", false)),
		Cc: () => new UnicodeRangeTable(decodeRanges("AfgDgB", true)),
		Cf: () => new UnicodeRangeTable(decodeRanges("tFzqBzqBBEBXhGhGyBhMhMBxCxCs5D9-B9-BBDBbEByBEBCJBw03B6H6HBBBimEQQj7IPBhjiBDBwmFHBn0rYffB+CB", false)),
		Cn: () => new UnicodeRangeTable(decodeRanges("4bBBHDBICCVuMuMnBBBzBBBE4B4BBGBcDBHKBvI9B9BBmDmDBMB8BBByBBBQddBCCMEBjBEBuHJJBDDBXXICCBBBFBBKBBDBBFHBCDBDGGBaaBEEHDBDBBXIIDGDBCCGDBDBBECBCGBFCCBFBSJBEKKEXXIDDGBBLIEBCCBNBFBBNGBIEEJBBDBBXIIDGGBKKBDDBEEBFBEDBDGGBTTBIBDHHBBBEFFBBBDCCDCBDCBECBNDBGCBEFFBCCBEBCNBWEBOEEYRRBKKEFFBFBDEEDBBFBBLGBXEEYLLGBBKEEFGBDEBEFFBLLELBOEE0BEEHDBRBBbEETCBZKKCBBICBCDBHCCJFBLBBELB7BDBekBBDCCGZZCYYBGGCIILBBFfBpClBlBBCBoBlBlBQOOBjBBnGCCBDBCBB6LFFBIICFFBqBqBFBBiBFFBIICFFBQQ6BFFBkCkCBhBhBBBBbFB3CBBHBB+UCB6CGBXIBZIBVLBOEEDLB-CBBLFBLFBbFB6CGBsBEBnCJBgBNNBCBNDBCCBrBBBGKBtBDBbFBMCB-BBBiCeeBMMBEBLFBPBBvBBBNTBuCnFnFBGB9BCBQCB-BEBsBBBMHBsBEB3QBBHBBnBBBHBBJGCgBBB2BQQPBBHUUBEEKmDmDNBBcOOBBBjBNBiBOBtEDB7UVBMUB14BBB-LEBuBCCBDBCBB5BGBDNBZIBI4BI-DhBBb6C6CBKB3GZBxC3C3CBoDoDBDBsB-C-C3CIBxBuzcuzcBBB4BIB9KTB5FHB+GTB9BCBLFB5BHBnCHBNFB1DKBfCBvCMMBCBiB4B4BBHBPBBLBBoDXBdJBHBBHBBHIBIII9BDB-DBBLFBl9KLBYDByBDBvzIBBrDlBBILBGEBbGGCGDrUfBrBFB0BUUFDBGoEoEBCC-FCBHBBHBBHBBECBIIIBIBGBBNbbUDDQBBPhBB8DEBEDBuBCB5COOBBBCuBBvBhEBeCByBOBdDBlBIBfEBsBEBfmBmBBCBPpBB-EBBLFBlBDBlBDBpBHB1BKBNQQIDDMQQIDDBBB1BLB4JIBXJBJXBHrBrBKkCBHBBCtBtBDCBCBBYpCpCBGBKvBBUDDBDBiBCBcEBclBB5BDBVBBzBDDBDBJEEeBBEDBLGBKGBhCfBoBDBNIB3BCBeBBcEBbGBFLBIvCBqC2BB0BMB0BGBvBHBLFBnBCBeHBDvGBgBrBrBEBBDPBHHBKgBBvBHBrBVBblBBdTBYIBvCDBlBIBlCJBCBBaGBLFB2BTTBGBoBIBhDVVBJBTwBwBB8BBICCFQQMFB8BEBLFBFJJBDDBXXIDDGLLBDDBEEBCCBEBCEBIBBICBGKBLCCBCCnBLLCBBCFFLDDBGBDcB9CGGBcBpCHBLlFB3BBBnBhBBmCKBLFBOSB7BFBLFBVbBcBBQDBY4FB9BjDB0CLBJBBCBBJDDfDDBNNBHBLlCBJBBvBBBMaBpCHB0CMBqCGBL1CBJ3CBjBNBLFBKuBuBPJBeCBhBBBXPPBnCBIDDtBCBCDDKHBLFBHDDmBDDHGBLFBtBDBL1HBaGBSqBqBBBBe0CBCOBzBMB8clDBwDGGBJBlGryCBkDMB3iBJB88DEBoS41GB7Bl2BB6RGBgBLLBCByCLLBEBfBBHJBnCJBLIIWEBUvNB7BlGB8CEBaBBarBBsCDB6BGBS-BBGKBIIB3mHoBBhBgDB0D8vIBFIIDkJkJBNBCcBEBBCNBFHBtMjoCBsDEBOCBKGBLBBJ76DB+HCB1NFBYOBSOBvBBBYIB1D7BB3HJBoBBBjGUBnC5DBVLBVLB4CIBamEB2CoCoCDBBCBBDBBFNNCIIiCFFBJJIddFGGCCBI1K1KBlJlJB-V-VBNBGQQBuiBBgBFBH0GBISSBIIDGGBDB-BgBBCvDBuBCBPBBLDBD-JBgBQB7BEBCvOBrB1GBsBDBC-FBgBXXBGBD-GBIFFDQQmGBBRoBBtCDBLDBDwYBlCrCB+BhGBFccDCCBCCLFFCCCBEBCDBCECEDDCBBCICDCCBFFIKFCLLSEBEGGSzBBDtIBtBDBlDLBQBBQQQmBJBvF3BBeMBtBDBKGBDNBH5EB6eCBSCBOCB7GFBNDBCOBNDB5BHBLFBpBHBfBBNDBDNBKmBB5KHBPBBOCBMCB6BCCBCBRBBNDBLGB0EoDoDBjgBBh3pBfB-oEBBv0FBBypHOBvThtCB-QhvBBs6EEBrpIm8yVBCdBhD-DBxHvw-BB---BBB---BBB", false)),
		Co: () => new UnicodeRangeTable(decodeRanges("gg4B-nGh4hc9--BD9--B", true)),
		Cs: () => new UnicodeRangeTable(decodeRanges("gg2B--B", true)),
		L: () => new UnicodeRangeTable(decodeRanges("hCZBHZBwBLLFGGBVBCeBCpOBFLBPEBICCiEEBCBBDDBCHHCCBCCCBSBCyCBCqEBJlFBClBBDHHBnBBoCaBFDBuBqBBkBBBCiDBCQQBIIBLLBBBDRRCdBe4CBMZZBfBKBBFGGBUBFKKEYYBXBIKBGXBCGBRpBB7B1BBETTIJBQPBFHBDBBDVBCGBCEEBCBERROBBCCBPBBLJJBEBFBBDVBCGBCBBCBBCBBgBDBCUUBBBRIBCCBCVBCGBCBBCEBETTQBBYMMBGBDBBDVBCGBCBBCEBEffBCCBBBQSSCFBECBCDBEBBCCCBEEBEEBBBELBX1B1BBGBCCBCWBCPBEbbBBBCBBDBBfFFBGBCCBCWBCJBCEBEffBBBCBBQBBSIBCCBCoBBDRRGCBJCBZFBGRBEXBCIBCDDBFB7BvBBCBBNGB7BBBCCCBDBCXBCCCBIBCBBKDDBDBCWWBCBhBgCgCBGBCjBBcEB0DqBBVRRBEBFDBEEEBIIBBBFMBNSSBkBBCGGDqBBCsKBCDBDGBCCCBCBDoBBCDBDgBBCDBDGBCCCBCBDOBC4BBCDBDiCBmBPBR1CBDFBErTBDQBCZBGqCBHHBIRBOSBPRBPMBCCBQzBBkBFFkC4CBIEBDhBBCGGBkCBLeByBdBDEBMrBBFZB3BWBK0BBzC+C+CBtBBSHB3BdBOBBLrBBbjBBqBCBLjBBDKBGqBBDCBqBDBCFBCBBEGGB+FBhC1IBDFBDlBBDFBDHBCGCBdBD0BBCGBCEEBBBCGBEDBDFBFMBGCBCGB1DOORMBmDFFDJBCEEBDBHGCBCBCKBDDBGEBF1B1BB8zC8zCBjHBHDBEBBNlBBCGGD3BBIRRBVBKGBCGBCGBCGBCGBCGBCGBCGBxC2O2OBrBrBBDBGBBF1CBHCBC5CBCDBGqBBC9CBSfBxBPBhQ-tGBhCs0VBkCtBBDsIBEPBLBBVuBBReBDlCByBIBDmDBDxCBVQBCCBCDBCWBezBBPxBB-BFBECCBMMBaBLWBacBIuBBdRRBDBCJBLEBCoBBYCBCHBVWBEEEBwBBCEEBDDBDBDCCZCBDKBICBNFBDFBDFBKGBCGBCqBBCNBHyDBej9KBNWBFwBBloItLBDpDBnBGBNEBGCCBIBCMBCEBCCCBCCBCCBqDBiBqLBT-BBD1BBpBLB1DEBCmEBlBZBHZBM4CBEFBDFBDFBDCBkBLBCZBCSBCBBCOBDNBjB6DBmMcBEwBBwBfBOTBCHBHlBBLdBDjBBFHBxB9EBTjBBFjBBFnBBJzBBNKBCOBCGBCBBCKBCOBCGBCBBEzBBN2JBKVBLHBZFBCpBBCIBmCFBDCCBqBBCBBEDDBVBLWBKeBiCSBCBBLVBLZBHZBnB3BBHBBhCQQBCBCCBCcBrBcBEcBkBHBCbBc1BBLVBLSBORBvDoCB4ByBBOyBBOjBBnBbBKWB7HpBBHBBRFB5BcBLJJBUBrBRBvBUBcWBN0BB6BBBDOOBrBBhBYBbjBBeDDJiBBENNBuBBPDBWCCkBRBCYBUBBgCGBCCCBCBCOBCJBIuBBnBHBDBBDVBCGBCBBCEBETTNEBfJBCDDClBBCaaCtBtBBzBBTDBVCBfvBBVBBC5F5FBtBBqBDBlBvBBV8B8BBpBBOoCoCBZBmBGB6FrBB1D-BBgBHBDDDBGBCBBCXBQCC-CHBDmBBRCCdLLBmBBIWWMtBBUTTBnCBoGgBBgBIBCkBBSyByBBcBxDGBCBBClBBWaaBEBCBBCfBPYYBqBBlISBQCCBLBChBB9DwCwCB4cBnHjGBtyCgDBQvhBBSFBa68DBGmSB61GdBj3B4RBIeBSuCBSdBTvBBRDBgBUBGSBxNsBB0G-BBhBYBDYBtBqCBGjCjCBLBhCBBCPPBNNB0mHBqBfBiDyDB+vIDBCGBCBBCiJBQeeBBBDPPBCBJrMBloCqDBGMBEIBIJBn7F0CBCmCBCBBDDDBDDBCBCLBCCCBFBCgCBCDBDHBCGBCbBCDBCEBCEEBFBCzKBDYBCYBCeBCYBCeBCYBCeBCYBCeBCYBCHB15BeBHFBmI9BBzEsBBLGBRiKiKBcBTrBBlPbBlHdBDwGwGBdBCCBCBBCGBDEBKBBhHGBCDBCBBCOBCkGB8BjCBI1lB1lBBCBCaBCBBCDDCJBCDBCCCHFFCECBBBCBBCDDCICBCCDDBCGBCDBCDBCCCBIBCQBGCBCEBCQBlqE-2pBBhB9oEBDt0FBDwpHBQtTBjtC9QBjvBq6EBGppIB", false)),
		LC: () => new UnicodeRangeTable(decodeRanges("hCZBHZB7BLLBVBCeBCiGBCDBFvGBDZBhGDBDBBECBCHHCCBCCCBSBCyCBCqEBJlFBClBBKoBB44ClBBCGGDqBBDCBhV1CBDFBjkCKBGqBBDCBhCrBBgCMBChBBmD1IBDFBDlBBDFBDHBCGCBdBD0BBCGBCEEBBBCGBEDBDFBFMBGCBCGBmIFFDJBCEEBDBHGCBCBCFBFDDBCBGEBF1B1BB8zC8zCB6DBDmDBHDBEBBNlBBCGGzoetBBTbBnEtCBCWBEDBCsCBZBBE2Z2ZBpBBGIBIvCBh6TGBNEBqgBZBHZBmlBvCBhDjBBFjBB1DKBCOBCGBCBBCKBCOBCGBCBBk2ByBBOyBB+CVBLVB74C-BBhrV-BBhBYBDYBtpZ0CBCmCBCBBDDDBDDBCBCLBCCCBFBCgCBCDBDHBCGBCbBCDBCEBCEEBFBCzKBDYBCYBCeBCYBCeBCYBCeBCYBCeBCYBCHB15BJBCTBHFB2uCjCB", false)),
		Ll: () => new UnicodeRangeTable(decodeRanges("hDZB7BqBqBBWBCHBC2BCBQCBuBCDECBBBDCCDEEBFFDEEBBBDDDCCCDCCBCCDEECDDBDDBBBHGDCOCBSCBDDCEEC4BCBFBDDDBCCFICBjCBDZBiGCCEEEBBBTccBhBBCBBECBCWCBDBCGDB0B0BBuBBCgBCK0BCDMCBgDCxBoBBo6CqBBDCB5XFBjkCIBC2D2DBqBBgCMBChBBnD0ECBHBCgDCBHBJFBLHBJHBJFBLHBJHBJNBDHBJHBJHBJEBCBBHEEBBBCBBJDBDBBJHBLCBCBBzIEEBEEcKFDBBJDBF2B2Bs1CvBBCEEBGCFCCBCCBEBGiDCBIICFFNlBBCGG0oesBCUaCoEMCBBBC+BCBGBCCCDICFCCDCCBBBCSCGGGCMCFCCDOCbEE2ZqBBGIBIvCBh6TGBNEBqhBZBumBnBBpEjBB8EKBCOBCGBCBBk4ByBB+DVB75CfBhsVfB8BYBnqZZBbGBCRBbZBbDBCCCBFBCKBbZBbZBbZBbZBbZBbZBbZBbZBbbBdYBCFBbYBCFBbYBCFBbYBCFBbYBCFBC15B15BBIBCTBHFB4vChBB", false)),
		Lm: () => new UnicodeRangeTable(decodeRanges("wVRBFLBPEBICCmEGG-OnHnHlFBBuIBBFgBgBKEEhFoFoF1mBgEgE2R72B72BsDkTkTxOFBvF+BBOjBjBBjBByVOORMBg-CBByHgGgG2OsBsBBDBGiDiDB+C+CBBB34bjnBjnBBEBvIzDzDdBB6DIBxCYYpDDBEBB2OXXqEtDtDWBBoDDBKngVngVuBBBh-BFBCpBBCIB0sBhBhB2K04D04DnrTDB9PCBpBBBnRMBhCBBCPPB9-P9-PBCBCGBCBByhM9BBqGGBud0Q0QsSAB", false)),
		Lo: () => new UnicodeRangeTable(decodeRanges("qFQQhIFFBCBxGBB7ZaBFDBuBfBCJBkBBBCiDBCZZBLLBBBDRRCdBe4CBMZZBfBWVBrBYBIKBGXBCGBRoBB8B1BBETTIJBROBFHBDBBDVBCGBCEEBCBERROBBCCBPBBLJJBEBFBBDVBCGBCBBCBBCBBgBDBCUUBBBRIBCCBCVBCGBCBBCEBETTQBBYMMBGBDBBDVBCGBCBBCEBEffBCCBBBQSSCFBECBCDBEBBCCCBEEBEEBBBELBX1B1BBGBCCBCWBCPBEbbBBBCBBDBBfFFBGBCCBCWBCJBCEBEffBBBCBBQBBSIBCCBCoBBDRRGCBJCBZFBGRBEXBCIBCDDBFB7BvBBCBBNFB8BBBCCCBDBCXBCCCBIBCBBKDDBDBYDBhBgCgCBGBCjBBcEB0DqBBVRRBEBFDBEEEBIIBBBFMBNyDyDBnKBCDBDGBCCCBCBDoBBCDBDgBBCDBDGBCCCBCBDOBC4BBCDBDiCBmBPByDrTBDQBCZBGqCBHHBIRBOSBPRBPMBCCBQzBBpBkCkCBhBBC0BBIEBDhBBCGGBkCBLeByBdBDEBMrBBFZB3BWBK0BBxFuBBSHB3BdBOBBLrBBbjBBqBCBLdByDDBCFBCBBE7hB7hBBCB4-C3BBZWBKGBCGBCGBCGBCGBCGBCGBCGBoR2B2BF1CBJCCB4CBFGGBpBBC9CBSfBxBPBhQ-tGBhC0wUBC2jBBkCnBBJrIBFPBLBBjCyByBBkCBqFoDoDEGBCCBCDBCWBezBBPxBB-BFBECCBMMBaBLWBacBIuBBuBEBDIBLEBCoBBYCBCHBVPBCFBEEEBwBBCEEBDDBDBDCCZBBEKBIPPBEBDFBDFBKGBCGByEiBBej9KBNWBFwBBloItLBDpDBkCCCBIBCMBCEBCCCBCCBCCBqDBiBqLBT-BBD1BBpBLB1DEBCmEBqDJBCsBBDeBEFBDFBDFBDCBkBLBCZBCSBCBBCOBDNBjB6DBmMcBEwBBwBfBOTBCHBHlBBLdBDjBBFHBhEtCBjDnBBJzBB9CzBBN2JBKVBLHB5EFBDCCBqBBCBBEDDBVBLWBKeBiCSBCBBLVBLZBHZBnB3BBHBBhCQQBCBCCBCcBrBcBEcBkBHBCbBc1BBLVBLSBORBvDoCB4FjBBnBDBCxJxJBoBBHBBRCBCBB5BcBLJJBUBrBRBvBUBcWBN0BB6BBBDOOBrBBhBYBbjBBeDDJiBBENNBuBBPDBWCCkBRBCYBUBBgCGBCCCBCBCOBCJBIuBBnBHBDBBDVBCGBCBBCEBETTNEBfJBCDDClBBCaaCtBtBBzBBTDBVCBfvBBVBBC5F5FBtBBqBDBlBvBBV8B8BBpBBOoCoCBZBmBGB6FrBB0GHBDDDBGBCBBCXBQCC-CHBDmBBRCCdLLBmBBIWWMtBBUTTBnCBoGgBBgBIBCkBBSyByBBcBxDGBCBBClBBWaaBEBCBBCfBPYYBnBBCBBlISBQCCBLBChBB9DwCwCB4cBnHjGBtyCgDBQvhBBSFBa68DBGmSB61GdBj3B4RBIeBSuCBSdBTvBB0BUBGSB0NnBB2MqCBGwFwFB0mHBqBfBiDyDBuwIiJBQeeBBBDPPBCBJrMBloCqDBGMBEIBIJBxzI2P2PBrBBiBiKiKBcBTrBBlPaBmHdBDwGwGBdBCCBCBBCGBDEBKiHiHBFBCDBCBBCOBCkGB8pBDBCaBCBBCDDCJBCDBCCCHFFCECBBBCBBCDDCICBCCDDBCGBCDBCDBCCCBIBCQBGCBCEBCQBlqE-2pBBhB9oEBDt0FBDwpHBQtTBjtC9QBjvBq6EBGppIB", false)),
		Lt: () => new UnicodeRangeTable(decodeRanges("lOGDnB2sH2sHBGBJHBJHBNQQwBAB", false)),
		Lu: () => new UnicodeRangeTable(decodeRanges("hCZBmDWBCGBiB2BCDOCDuBCBECEBBCCCBCCBBBDDBCBBCCBEBBCBBCECBCCDCCBCCBBBCCCBEEIJDCMCDQCDDDCCBC4BCIBBCBBDCCBCBCGCiJCCEJJHCCBBBCCCBCCBPBCIBkBDDBBBEWCGDDCBBDyBBxBgBCK2BCBMCD+CCDlBBq6ClBBCGGzW1CB0kCHHBpBBDCBhK0ECKgDCKHBJFBLHBJHBJFBMGCJHBpCDBNDBNDBNEBMDBnIFFECBDCBDEEBDBHGCBCBDDBLBBG+B+B9zCvBBxBCCBBBDGCBCBCDDJCBCgDCJCCFuqeuqeCqBCUaCoEMCE8BCLECBICFCCDCCEUCBDBCEBCOCBCBCCCBQCZs5Vs5VBYBmmBnBBpEjBB9EKBCOBCGBCBBr3ByBB+EVB75CfBhsVfBhCYBoqZZBbZBbZBbCCBGDBDDBCBCHBbZBbBBCDBDHBCGBcBBCDBCEBCEEBFBcZBbZBbZBbZBbZBbZBfYBiBYBiBYBiBYBiBYBiB2pE2pEBgBB", false)),
		M: () => new UnicodeRangeTable(decodeRanges("gYvDB0IGBoIsBBCCCBCCBCCpCKBxBUBRmDmDBFBDFBDBBCDBkBffBZB8CKB7BIBKZZBCBCIBCCBCEBsBCB8BIBrBXBCgBB3BCBCRBCGBLBBeCB5BCCBFBDBBDCBKLLBbbDCB5BCCBDBFBBDCBEffBEEMCB5BCCBGBCCBCCBVBBXFBCCB5BCCBFBDBBDCBICBLBBf8B8BBDBECBCDBKpBpBBDB4BCCBFBCCBCDBIBBMBBeCB5BCCBFBCCBCDBIBBMBBQNNBCB4BBBCGBCCBCDBKLLBeeBBBnCFFBEBCCCBGBTBB+BDDBFBNHBjDDDBHBMGBqCBBcECFBByBTBCBBGKBCjBBKlDlDBSBYDBFCBCCBDGBEDBOLBCLLBCBgWCBzdDBdCBeBBfBBhCfBKuBuBBBBC2D2DBjBjB3DLBFLB8GEB6BJBCcBDxBxBBsBBDLBVEBwBQBnBIBNCBfMB5BNBxBTB5ECBCUBFHHDCBnG-BBxWgBB--CCBuEhDhDBeBrRFBqDBB1udDBCJBhBBBxCBBxIEEFYYBDBF0C0CBzBzBBQBbRBOnBnBBGBaMBtBDBwBNBlBkCkCBMBNJJBuBuBBBBzBCCBBBDBBGBBCqBqBBDBGBBtHHBCBBx5TiXiXBOBRPBuejHjH2EEBn0BCBCBBGDBpBCBFmFmFB+R+RBCBiCEB+JBBuCFBnCKByBDB7DCB2BOBqBDDBLLBCBuBKBI+B+BBBBlBNBRBBtBNNBBBxBNBJDBCBB9CLBHDD+ELBWDB4BBBCGBDBBDCBKLLBDDBFBEEBkCIBCDDCDBCEBCPPBzCzCBQBYyCyCBSBsHGBDIBcBBzCQBrDMBmDOBhIOB2HFBCBBDDBCCCBuEuEBFBDGBEddBIBpBGBCDBJKKBJBvBPBnGHBoGHBCHBzCVBCNB7DFBECCBCCBFBCjCjCBDBCBBCEB8KDBKBBCxBxBBFBEEBYmnFmnFHOBpmLRBhuCEB8BGB5gBCCB1BBIDByCMMBslTslTBizEizEBsBBDWB-QEBEFBJHBDGBfDB1ECB89B2BBFxBBJPPXEBCOBxqBGBCQBDGBCBBCEBlDhFhFBFB4L+B+BBCB9PDB-HBB0HDDIBBG7O7OBFBuDGB29lYvHB", false)),
		Mc: () => new UnicodeRangeTable(decodeRanges("joC4B4BDCBJDBCBBzBBB7BCBHBBDBBLsBsB7BCBjC7B7BBBBJCCB2B2BB7B7BCHHBDDBLLnDBBCBBECBCCBLqBqBBBB+BDB+BBB7BCCBDBDBBCBBKBBdPPB7B7BBBBGCBCCBLrBrBBsCsCBBBHHBTBBrKBBgCsFsFBFFHDDBaaBLLBBBDGBWBBDFBDLLBBB5zBffiEIIBGBCBB7KDBDCBFBBCFBhHBB7BCCKCCBJJBEByExBxBGCCBDBCBB+BffFBBD9B9BDCBCEEBxBxBBGBJBBsFWW35EBB0-dBBD5C5CBzBzBBOBvEBBwBxBxBBFFBDDBBBvDBBDBBZuBuBCuDuDDBBGuHuHBCCBCCBCC0gZCCgEuBuBBBBFBB0DZZB8B8BxBCBKBBO+C+CBBBEBBCrFrFBBBgBBB7BBBCDBDBBDCBKLLB1C1CBBBIDDCDBCBBCmDmDBBBJBBErDrDBBBHCCBCBDuHuHBBBHDBDyDyDBBBJBBCuDuDCBBHoDoDCBBFmImIBBBK4H4HBEBCBBFDDCvEvEBBBJDBF1C1CeBB-BqGqGECCoGPPrDIID2G2GBDBFBBC-K-KBNNxBBBJBBCpvQpvQBBBlxD2BBpDBB0rYBBHFB", false)),
		Me: () => new UnicodeRangeTable(decodeRanges("okBBB1xF-wB-wBBCBCCBsshBCB", false)),
		Mn: () => new UnicodeRangeTable(decodeRanges("gYvDB0IEBqIsBBCCCBCCBCCpCKBxBUBRmDmDBFBDFBDBBCDBkBffBZB8CKB7BIBKZZBCBCIBCCBCEBsBCB8BIBrBXBCfB4BCCFHBFEEBFBLBBe7B7BFDBJVVBbbDBB6BFFBFFBDDBBBEffBEEMBB6BFFBDBCBBFVVBXXBEBC7B7BDCCBCBJIIBMMBff+BNNzBEE4BCCBBBGCBCDBIBBMBBe7B7BDHHGBBVBBdBB6BBBFDBJVVBeepCIIBBBC7C7CDGBNHBjDDDBHBMGBqCBBcEC4BNBCEBCBBGKBCjBBKnDnDBCBCFBCBBDBBaBBFCBRDBODDBHHQgWgWBBBzdCBeBBfBBfBBhCBBCGBJDDBJBKuBuBBBBC2D2DBjBjB3DCBFBBKHHBBB8GBBD7B7BCGBCCCDHBHJBDxBxBBMBCeBDLBVDBxBCCBDBCGGpBIBNBBhBDBDBBCCB5BCCBEECCB7BHBDBB5ECBCMBCGBFHHEBBnG-BBxWMBFEEBKB--CCBuEhDhDBeBrRDBsDBB1udFFBIBhBBBxCBBxIEEFaaBGG4EBBbRBOnBnBBGBaKBvBCBxBDDBCBDBBoBkCkCBEBDBBDBBNJJwB0B0BCCBDBBGBBCrBrBBJJvHDDFx5Tx5TiXPBRPBuejHjH2EEBn0BCBCBBGDBpBCBFmFmFB+R+RBCBiCEB+JBBuCFBnCKByBDB8D3B3BBNBqBDDBLLBBByBDBDBBI+B+BBBBlBEBCHB-BNNB1B1BBHBLDBDgDgDBBBDCCBHHD+E+EEHBWBB6BBBEmBmBBFBEEBnCFBOECPBB2CHBDCBCYY1CFBCFFBCCBvHvHBCBHBBCBBcBB2CHBDCCBrDrDCDDBEBCmDmDCDDBCBCEBkIIBCBBhIBBCFFxEDBDBBFhBhBBIBpBFBDDBJKKBEBDCBvBMBCBBnGCCBBBCqGqGBFBCFBCzCzCBUBDGBCBBCBB7DFBECCBCCBFBCpCpCBEEC8K8KBMMB1B1BBDBGCCYmnFmnFHOBpmLLBECBhuCEB8BGB5gBgCgCBCByC5lT5lTBizEizEBsBBDWBhRCBSHBDGBfDB1ECB89B2BBFxBBJPPXEBCOBxqBGBCQBDGBCBBCEBlDhFhFBFB4L+B+BBCB9PDB-HBB0HDDIBBG7O7OBFBuDGB29lYvHB", false)),
		N: () => new UnicodeRangeTable(decodeRanges("wBJB5DBBGDDBBBitBJBnEJBnGJB9MJB3DJBFFBtDJB3DJB3DJBDFBvDMB0DJBJGBoDJBpDGBISBuDJBhDJB3DJBnCTBtIJBnCJBwWTBybCBwHJBHJBXJBtJJBhEKBmFJBHJB3FJB3CJBnEJBHJB3gBEEBEBHJBnGyBBDEB3W7BBvCVB3TdBqrBqYqYaIBPCB4KDBrEJBfHBCOBhBJBoBOBh7cJB9FJBhKFB7EJBnBJBnGJBXJB3CJB3MJB34UJBuPsBBN4BBSBB2KaBlBDBeJJnEEBrGJBvdHBaGBoBIBsCEBXFBhFBBDPBDtBBhCIB1BBBfCBsCEBpDHBZHBqBGBrKFBxBJBHJB3IeB-EJBrBDBxDGBnEdBhEJB9BJBxEJBITB8HJB3KJB3DJB3LJBnDJBHTBtCLBlNSB+CJB3UJB3CcBkHJBnCJB3BJBnLJBnDUBshBuDBimPJBnpCJB3CJBnEJBCGBvQJBnIWB+KCB6nXJBnuBTBNTBtDYB2iBxBBhqCJBnNJB3PJB4HJBtWIBhEJB4Y6BBCCBCDBtCsBBCOBjeMBk3CJB", false)),
		Nd: () => new UnicodeRangeTable(decodeRanges("wBJnxBJnEJnGJ9MJ3DJ3DJ3DJ3DJ3DJ3DJ3DJ3DJ3DJhDJ3DJnCJ3IJnCJn6BJnBJtJJhEJnFJHJ3FJ3CJnEJHJnuiBJnVJnBJnGJXJ3CJ3MJ34UJnsBJnkCJHJ9YJhEJ9BJxEJ3IJ3KJ3DJ3LJnDJHTtCJnNJnDJ3UJ3CJ3HJnCJ3BJnLJ3uQJnpCJ3CJnEJ3QJ37XJ12CxBhqCJnNJ3PJ4HJ2aJ30EJ", true)),
		Nl: () => new UnicodeRangeTable(decodeRanges("u3FCBwzCiBBDDB-zDaaBHBPCBs1dJBxyW0BBtOJJnEEBrhIuDBm8SCB", false)),
		No: () => new UnicodeRangeTable(decodeRanges("yFBBGDDBBB2pCFB5LFB5DCBmEGB6GGBSIByNJB2hBTB0jBJBhP20B20BEFBHJBnGPBqB3W3WB6BBvCVB3TdBqrB1kB1kBBCBrEJBfHBCOBhBJBoBOBxrdFBymWsBBiCDBSBB2KaBlBDB1pBHBaGBoBIBsCEBXFBhFBBDPBDtBBhCIB1BBBfCBsCEBpDHBZHBqBGBrKFBhLeB-EJBrBDBxDGBnETB8LTBmqBBBvNIBobSB0aUBn8SGB-YWBqhZTBNTBtDYBvqFIBid6BBCCBCDBtCsBBCOBjeMB", false)),
		P: () => new UnicodeRangeTable(decodeRanges("hBCBCFBCDBLBBEBBbCBCccCkBkBGEELBBEEE-VJJzOFBqBBB0BCCDDDtBBBVBBCBBOCCBBBrCDBnDsBsBBMBqHCB3BOBgBmImIBLLtE5D5D6DnMnMNwLwL7CLLBpFpFBNBCmBmBBCBoCrCrCBDBFBBwDFBsFlTlTBHB4EuTuTtBBBvCCBoCBB+ECBCCBmBKB6JBB5GBBhEGBCFBhFBBLGBdCB9DDB8BEB-BBBhCHBM9Z9ZBWBJTBCMBCLBfBBPBB6TDBeBB+hBNBwCBBgBJB0MVBgCDBhBBB8XDBCBBxDwEwEBtBBCfBDLBkNCBFJBDLBRNNjD7C7CjgdBBuICBkDLL0DFB9LDB3CBBpBCBCyByBBwBwBiDMBRBB9DDB-DBBRBB6HzqUzqUBxGxGBIBXiBBCNBCFFCBB2ECBCFBCDBLBBEBBbCBCccCCCBFB7MCB9UxBxB-MoXoXoGgBgBxIIBnBxDxDBFBjCGB6CDByO-J-JjBlElEBDBtBDB+FGBuDBBCDB-DDBxBBBwCDBFOOCCB5CFBsDrJrJBCCBzDzDBDBLBBCpDpD7HWBqDCBdMBtCjEjEBBB9HpIpIBBB8E9C9CBGB0CCBCEB+CJB4GgDgDBDBrBBBmUBBrCMBwFxjBxjBBDB97CBB8zOBBmEiCiCBDBJpRpRBBBoJDBoK9lT9lTovHEB07C-a-aBAB", false)),
		Pc: () => new UnicodeRangeTable(decodeRanges("-Cg-Hg-HBUU-u3BBBZCBwHAB", false)),
		Pd: () => new UnicodeRangeTable(decodeRanges("tB9qB9qB0BiyDiyDmgBqgCqgCBEBiwDDDgBBBFdd-NUUwDxszBxszBBmBmBLqFqFhzD-J-J", false)),
		Pe: () => new UnicodeRangeTable(decodeRanges("pB0B0BgB+1D+1DC-6B-6BqtC4B4BQ7T7TCff-hBMCxChBhBCGC1MUChCCCiBmhBmhBCECtBGCtNICEGCDBB-ozB6G6GeOCESSCCCrF0B0BgBGD", false)),
		Pf: () => new UnicodeRangeTable(decodeRanges("7F+6H+6HEddpuDCCFDDQEE", false)),
		Pi: () => new UnicodeRangeTable(decodeRanges("rFt7Ht7HDBBDaapuDCCFDDQEE", false)),
		Po: () => new UnicodeRangeTable(decodeRanges("hBCBCCBDECBLLBEEBcclCGGPBBI-V-VJzOzOBEBqB3B3BDDDtBBBVBBCBBOCCBBBrCDBnDsBsBBMBqHCB3BOBgBmImIBLLtE5D5D6DnMnMNwLwL7CLLBpFpFBNBCxDxDrCEBFBBwDFBsFlTlTBHBmY9D9DBBBoCBB+ECBCCBmBFBCDB6JBB5GBBhEGBCFBhFBBLGBdCB9DDB8BEB-BBBhCHBMjajaBJJBGBJIBDDBDCBEKBCCCBIB7kDDBCBBxDwEwEBFFBBBDDDBHBCBBCDDBLLBDBCJBDDBCCCBLBDCBtNCB6B+F+FjgdBBuICBkDLL0DFB9LDB3CBBpBCBCyByBBwBwBiDMBRBB9DDB-DBBRBB6HlxUlxUBFBDXXVBBDDBECBCDBICBHCCB2E2EBBBCCBDECBLLBEEBcclBDDB7M7MBBB9UxBxB-MoXoXoGgBgBxIIBnBxDxDBFBjCGB6CDB0ZlElEBDBtBDB+FGBuDBBCDB-DDBxBBBwCDBFOOCCB5CFBsDrJrJBCCBzDzDBDBLBBCpDpD7HWBqDCBdMBtCjEjEBBB9HpIpIBBB8E9C9CBGB0CCBCEB+CJB4GgDgDBDBrBBBmUBBrCMBwFxjBxjBBDB97CBB8zOBBmEiCiCBDBJpRpRBBBoJDBoK9lT9lTovHEB07C-a-aBAB", false)),
		Ps: () => new UnicodeRangeTable(decodeRanges("oBzBzBgB-1D-1DC-6B-6B-rCEEnB4B4BQ7T7TCff-hBMCxChBhBCGC1MUChCCCiBmhBmhBCECaTTCECtNICEGCDipzBipzB4GeeCMCESSCCCrFzBzBgBEEDAB", false)),
		S: () => new UnicodeRangeTable(decodeRanges("kBHHRCBgBCCcCCkBEBCBBDCCBCBDEEfgBgBrODBNNBGGBCCCBPB2DPPBxDxDsErIrIBBB3DCBDDDBvGvGLUUB4H4HIBBpEqLqLBHHB2H2H-DjEjEBGBlEwGwGqBmGmGiGCBQCCBBBDFBVECmEHBCFBCBBGDBmGBBxXJB0WuLuLlL+E+EBgBBiLJBKIBhiBCCBBBMCBOCBOCBOBBmCOOoBCBOCBUhBB-BBBCDBCBBLCCBBBGFBCECFMMBFFBDBGDBC7B7BBFFB2LBFcBD+HBXKByCtCBXnTBtBwBBDeBLyMBX+BBFfBD1LBDpEBmHFBmLBBvBZBC4CBN1GBbPBFOOBNNWBBHBB8CBB0HBBFJBhBlBBKRRBdBMdBJQQBeBLmBBQ-JBhuG-BBx0V2BB6RWBKBBoDBB+EDBLDB+RCBiHPPB+9T+9TpEgBBuLPBhCBB3BHBtBDBjDCCBBBD7E7EHRRBBBgBCCcCCiEGBCGBOBB6JIB6BQBDCBCMBEwBwBBrBB7zBBBwSmWmWBiKiKBGBnjC2kC2kCBbBr6SDBG3qU3qUk7DvHBLCBEzNBHWBQQBgDzDB9B1HBLmBBD7BBGCBXBBIdBF8BBWhCBE7F7FB1CBrbaagBaagBaagBaagBaa9B-PB4BDBzBHBCNBCBBp2BwNwNttCEE+DiOiOBvIvIBqBBFjDBNOBDOBCOBCkBBYgFB5BcBOrBBFIBIBBPFB7E4eBEQBEMBE5GBHLBFQQBKBF3BBJJBHnBBJdBDLBFBBPIBoB3KBJNBDMBEKBE4BBCFFBOBDLBFJBIyEBC7CBLAB", false)),
		Sc: () => new UnicodeRangeTable(decodeRanges("kB+D+DBCBqnB8D8DzPBBzPBBI2H2HoImSmS8sClmClmCBgBB37hBkuVkuVtD7E7E8GBBEBB3-HDB-4wBxtCxtC", false)),
		Sk: () => new UnicodeRangeTable(decodeRanges("+CCCoCHHFEEqQDBNNBGGBCCCBPB2DPPBjoBjoB15FCCBBBMCBOCBOCBOBB9kEBBkzdWBKBBoDBBxePPBniUniUBPB8bCCjF4g9B4g9BBDB", false)),
		Sm: () => new UnicodeRangeTable(decodeRanges("rBRRBBB+BCCuBFFmBgBgB-XwQwQBBB8xGOOoBCBOCBsEoBoBBDBHlClCBDBGBBFGDIgBgBBDDCgBgBBqIBhBBB7CffBXBpBFB2OKK3BHBwDxKxKBDBDeBLPBhIiEBX+BBFfBDhIBxBUBDFB9+zB5Z5ZCCBlFRRBBB+BCCkEHHBCBitDBBhrwBx+Bx+BagBgBagBgBagBgBagBgBat5Ft5FB-uC-uCBHB", false)),
		So: () => new UnicodeRangeTable(decodeRanges("mFDDFCCyerIrIBgEgEBvGvGLUUB4H4HkQ2L2LjEFBClElEwGqBqBoMCBQCCBBBDFBVECmEHBCFBCBBGDBmGBBxXJB0WzWzW+EhBBiLJBKIBksBBBCDBCBBLCCBHHBEBCECFMMBPPCBBC7B7BBKKBDBDDBCBBCBBCGBCeBDBBCCCBdBtIHBFTBDGBDwCBCdBanBBHnCBXKByCtCBX2FBCIBC1BBJuDBC3HBtBrBBhC-HBhQvBBWBBHmBBDpEBmHFBmLBBvBZBC4CBN1GBbPBFOOBNNWBBHBBxKBBFJBhBlBBKRRBdBMdBJQQBeBLmBBQ-JBhuG-BBx0V2BBibDBLBBC+R+RBBBqqUPBuLPBhCBB3BHBuBCBlPEEFBBOBB6JIB6BQBDCBCMBEwBwBBrBB7zBBBwSpgBpgBBGBnjC2kC2kCBGBFQBr6SDBG3qU3qUk7DvHBLCBEzNBHWBQPBhDzDB9B1HBLmBBD7BBGCBXBBIdBF8BBWhCBE7F7FB1CBqlB-PB4BDBzBHBCNBCBBp2B96C96CiEyWyWBqBBFjDBNOBDOBCOBCkBBYgFB5BcBOrBBFIBIBBPFB7E6HBG4WBEQBEMBE5GBHLBFQQBKBF3BBJJBHnBBJdBDLBFBB-B3KBJNBDMBEKBE4BBCFFBOBDLBFJBIyEBC7CBLAB", false)),
		Z: () => new UnicodeRangeTable(decodeRanges("gBgEgEgvFgsCgsCBJBeBBGwBwBh9DAB", false)),
		Zl: () => new UnicodeRangeTable(decodeRanges("ohIA", true)),
		Zp: () => new UnicodeRangeTable(decodeRanges("phIA", true)),
		Zs: () => new UnicodeRangeTable(decodeRanges("gBgEgEgvFgsCgsCBJBlBwBwBh9DAB", false)),
		ASCII_Hex_Digit: () => new UnicodeRangeTable(decodeRanges("wBJIFbF", true)),
		Alphabetic: () => new UnicodeRangeTable(decodeRanges("hCZBHZBwBLLFGGBVBCeBCpOBFLBPEBICC3CeeBQBCBBDDBCHHCCBCCCBSBCyCBCqEBJlFBClBBDHHBnBBoBNBCCCBCCBCCJaBFDBeKBG3BBCGBPlDBCHBFHBFCBLCBDRRBuBBOkDBZgBBKBBFGGBWBDSBUYBIKBGXBCGBIJJBoBBLLBEGBHrCBCPBCCBFOBOSBCHBDBBDVBCGBCEEBCBEHBDBBDBBCJJFBBCEBNBBLFFBBBCFBFBBDVBCGBCBBCBBCBBFEBFBBDBBFIIBCBCSSBEBMCBCIBCCBCVBCGBCBBCEBEIBCCBCBBEQQBCBWDBFCBCHBDBBDVBCGBCBBCEBEHBDBBDBBKBBFBBCEBORRBCCBEBECBCDBEBBCCCBEEBEEBBBELBFEBECBCCBEHHpBMBCCBCWBCPBEHBCCBCCBJBBCCBCBBDDBdDBCHBCCBCWBCJBCEBEHBCCBCCBJBBGCBCDBOCBNMBCCBCoBBDHBCCBCCBCGGBCBIEBXFBCCBCRBEXBCIBCDDBFBJFBCCCBGBTBBO5BBGGBH0B0BBECBDBCXBCCCBRBCCBDEBCHHPDBhBgCgCBGBCjBBFSBFPBCjBBkC2BBCDDBDBR-BBLDBDlBBCGGDqBBCsKBCDBDGBCCCBCBDoBBCDBDgBBCDBDGBCCCBCBDOBC4BBCDBDiCBmBPBR1CBDFBErTBDQBCZBGqCBEKBITBMUBNTBNMBCCBCBBNzBBDSBPFFkC4CBIqBBGlCBLeBCLBFIBYdBDEBMrBBFZB3BbBF+BBDTBzBYYBMMBBByBzBBCOBCHB0BpBBDDBLrBBCKBP2BBXCBLjBBDKBGqBBDCBqBDBCFBCBBEGGB+FBUhBBM1IBDFBDlBBDFBDHBCGCBdBD0BBCGBCEEBBBCGBEDBDFBFMBGCBCGB1DOORMBmDFFDJBCEEBDBHGCBCBCKBDDBGEBFSSBnBBuZzBB34BkHBHDBEBBNlBBCGGD3BBIRRBVBKGBCGBCGBCGBCGBCGBCGBCGBCfBwB2O2OBBBaIBIEBDEBF1CBHCBC5CBCDBGqBBC9CBSfBxBPBhQ-tGBhCs0VBkCtBBDsIBEPBLBBVuBBGHBEwDBoBIBDmDBDxCBVUBCgBBZzBBNjCBCtBtBBEBECCBBBLgBBGiBBOcBEyBBCLBQRRBOBLEBC2BBKNBTWBEkCBCCCZCBDPBDDBMFBDFBDFBKGBCGBCqBBCNBH6DBWj9KBNWBFwBBloItLBDpDBnBGBNEBGLBCMBCEBCCCBCCBCCBqDBiBqLBT-BBD1BBpBLB1DEBCmEBlBZBHZBM4CBEFBDFBDFBDCBkBLBCZBCSBCBBCOBDNBjB6DBmC0BBsIcBEwBBwBfBOdBGqBBGdBDjBBFHBCEBrB9EBTjBBFjBBFnBBJzBBNKBCOBCGBCBBCKBCOBCGBCBBEzBBN2JBKVBLHBZFBCpBBCIBmCFBDCCBqBBCBBEDDBVBLWBKeBiCSBCBBLVBLZBHZBnB3BBHBBhCDBCBBGHBCCBCcBrBcBEcBkBHBCbBc1BBLVBLSBORBvDoCB4ByBBOyBBOnBBjBbBEGGBVB7HpBBCBBEBBRFBzBCBEcBLJJBUBrBRBvBUBcWBKlCBsBEBL4BBKOOBXBYyBBSDBJiBBEKKB+BBCDBKBBLCCkBRBChBBDHHBCB-BGBCCCBCBCOBCJBI4BBYDBCHBDBBDVBCGBCBBCEBEHBDBBDBBEHHGGBdJBCDDClBBCJBCDDCDBCBBECCtBhCBCCBCDBVCBfhCBDBBC5F5FB0BBDGBaFBjB+BBCEE8B1BBDoCoCBZBDNBWGB6F4BBoD-BBgBHBDDDBGBCBBCdBCBBDBBDDB+CHBDtBBDFBCCCBccBxBBDJBSnCBGTTBnCBoDHB5CgBBgBIBCsBBCGBCyByBBcBDVBCNBqCGBCBBCrBBECCBCCBBBCDDBZZBEBCBBCkBBCBBCDBCYYBqBBlIWBKQBCoBBECBwDwCwCB4cBnDuDBSjGBtyCgDBQvhBBSFBa68DBGmSB61GuBBy2B4RBIeBSuCBSdBTvBBRDBgBUBGSBxNsBB0G-BBhBYBDYBtBqCBF4BBIQBhCBBCNNBFBK1mHBqBfBiDyDB+vIDBCGBCBBCiJBQeeBBBDPPBCBJrMBloCqDBGMBEIBIJBFi7Fi7FBzCBCmCBCBBDDDBDDBCBCLBCCCBFBCgCBCDBDHBCGBCbBCDBCEBCEEBFBCzKBDYBCYBCeBCYBCeBCYBCeBCYBCeBCYBCHB15BeBHFB2GGBCQBDGBCBBCEBG9BBiBxDxDBrBBLGBRiKiKBcBTrBBlPbBlHdBDwGwGBdBCVBJBBhHGBCDBCBBCOBCkGB8BjCBEEE1lBDBCaBCBBCDDCJBCDBCCCHFFCECBBBCBBCDDCICBCCDDBCGBCDBCDBCCCBIBCQBGCBCEBCQB1TZBHZBHZB3zD-2pBBhB9oEBDt0FBDwpHBQtTBjtC9QBjvBq6EBGppIB", false)),
		Dash: () => new UnicodeRangeTable(decodeRanges("tB9qB9qB0BiyDiyDmgBqgCqgCBEB+BoBoBQnMnMlgDDDgBBBFdd-NUUwDxszBxszBBmBmBLqFqFhzD-J-J", false)),
		Emoji: () => new UnicodeRangeTable(decodeRanges("jBHHGJBwDFFu8HNN5GXX7CFBQBBwLBBNnFnFaKBFCBoGoHoHBLLK7B7BBCBCEBKGDBDDFDDCBBDIEBJJBBBGCCGLBMBBDCCBCCTDDBTTBEBCCCBEEBGGDBBFBBMBBGBBDGGBECBVVBGGBEBCDBDFFDDDBEBCDDCCCHEEHLLBQQDFFCFFBBBCMMBxBxBBBBKeP1LBBwOCBUBB0BFF7mBNN6SCCrrvDrGrGhFBBNBBPDDBIBsCZBCBBYVVDIBWBBvFhBBDvDBDBBCCBDyCBDCBCmIBC+BBMFBCXBIBBDHBNDDBCBDFFBOOBDDJBBKGGBBBNCBJCBDCCFHHEHHB0CBxBlCBGHBDDBEJBECCBEEDJBkHLBF8I8IBtBBCJBC4FBxDMBEKBE4BBCFFBOBDLBFJB", false)),
		Emoji_Component: () => new UnicodeRangeTable(decodeRanges("jBHHGJB0+H2G2Gsp3B3+8B3+8BBYB8PEBxtBDBtzhY-CB", false)),
		Emoji_Modifier: () => new UnicodeRangeTable(decodeRanges("7-8DE", true)),
		Emoji_Modifier_Base: () => new UnicodeRangeTable(decodeRanges("9wJ8G8GRDB4jzD9B9BBBBDDDBBB2DBBDKBWSBEFFBBBCCBICCZqGqGBFFWFFBvFvFBBBEEB0CRRBBBKMMgSDDJHBHKKBIBDCB5B+B+BBCCBCCSCBCMBmHCBrBIB", false)),
		Emoji_Presentation: () => new UnicodeRangeTable(decodeRanges("64IBBuGDBEDDqQBBWBBzBLBsBUUOJJBSSBGGBJJGWWIBBCFFDIIFBBdkBkBCFFBBBC+B+BBBBZPP8aBB0BFFvlxDrGrG-FDDBIBsCZBCZZVDDBDBCCBWBBvFgBBNIBClCBCVBNqBBFEBNQBEEEBlCBCCCB5FBD+BBODBCXBTbbBOO3C0CBxBlCBHEEBBBDDBEDBMBBIIBkHLBF8I8IBtBBCJBC4FBxDMBEKBE4BBCFFBOBDLBFJB", false)),
		Extended_Pictographic: () => new UnicodeRangeTable(decodeRanges("pFFFu8HNN5GXX7CFBQBBwLBBNnFnFaKBFCBoGoHoHBLLK7B7BBCBCEBKGDBDDFDDCBBDIEBJJBBBGCCGLBMBBDCCBCCTDDBTTBEBCCCBEEBGGDBBFBBMBBGBBDGGBECBVVBGGBEBCDBDFFDDDBEBCDDCCCHEEHLLBQQDFFCFFBBBCMMBxBxBBBBKeP1LBBwOCBUBB0BFF7mBNN6SCCrrvDoBoBBCBlDLBQBBQPPBmBmBBIBxDBBNBBPDDBIBU3BBcOBLVVDIBCDBKWBH7FBDvDBDBBCCBDyCBDCBCDBG9HBC+BBMFBCXBIBBDHBNDDBCBDFFBOOBDDJBBKGGBBBNCBJCBDCCFHHEHHB0CBxBlCBGHBDQBECCBEBDMB7GlBBNDB5BHBLFBpBHBfBBNDBDNBKmBBNuBBCJBC4FB5CHBPxEBhI9fB", false)),
		Hex_Digit: () => new UnicodeRangeTable(decodeRanges("wBJIFbFq1-BJIFbF", true)),
		Lowercase: () => new UnicodeRangeTable(decodeRanges("hDZBwBLLFlBlBBWBCHBC2BCBQCBuBCDECBBBDCCDEEBFFDEEBBBDDDCCCDCCBCCDEECDDBDDBBBHGDCOCBSCBDDCEEC4BCBFBDDDBCCFICBjCBDiBBIBBfEBhDsBsBCEEDDBTccBhBBCBBECBCWCBDBCGDB0B0BBuBBCgBCK0BCDMCBgDCxBoBBo6CqBBCDB5XFBjkCIBC2D2DB+FBiC0ECBHBCgDCBHBJFBLHBJHBJFBLHBJHBJNBDHBJHBJHBJEBCBBHEEBBBCBBJDBDBBJHBLCBCBB6DOORMBuDEEBEEcKFDBBJDBFiBiBBOBFsasaBYBn6BvBBCEEBGCFCCBCCBGBEiDCBIICFFNlBBCGG0oesBCUaCBBBmEMCBBBC8BCBIBCCCDICFCCDCCBBBCSCGGGCMCFCCDOCWDBCCCBBB2ZqBBCNBHvCBh6TGBNEBqhBZBumBnBBpEjBB8EKBCOBCGBCBBkODDBBBCpBBCIBmoByBB+DVB75CfBhsVfB8BYBnqZZBbGBCRBbZBbDBCCCBFBCKBbZBbZBbZBbZBbZBbZBbZBbZBbbBdYBCFBbYBCFBbYBCFBbYBCFBbYBCFBC15B15BBIBCTBHFBmI9BB1lChBB", false)),
		Math: () => new UnicodeRangeTable(decodeRanges("rBRRBBBgBeeCuBuBFmBmBgB5W5WBBBDbbBDDBBBwQCBuwGccBBBMEEOPPBCBWEBMEBiCMBFEEBFFBDBTFFDJBCDDBEBHEEBDDBCCBBBCFBENBClClCBWBCFBCBBFBBFfBCHHBPPBqIBJDBVBB7CffBZBCZZMGB+NBBNJBFFBFBBDBBEEBPCCDFBMHBGBB6BCCeDBKCBxK-BBhI-PBxBUBDFB9+zB4Z4ZBEBCjFjFRCBeCCeCCkEHHBCBitDBBhrwBwoBwoBBzCBCmCBCBBDDDBDDBCBCLBCCCBFBCgCBCDBDHBCGBCbBCDBCEBCEEBFBCzKBDjJBDxBBhwFDBCaBCBBCDDCJBCDBCCCHFFCECBBBCBBCDDCICBCCDDBCGBCDBCDBCCCBIBCQBGCBCEBCQB1BBB-uCIB", false)),
		Quotation_Mark: () => new UnicodeRangeTable(decodeRanges("iBFFkEQQ96HHBaBBowDqOqOBCBOCBixzBDB+FFF7CBB", false)),
		Terminal_Punctuation: () => new UnicodeRangeTable(decodeRanges("hBLLCMMBEE-ZJJiQ6B6BpCPPCCB1FsBsBBJBCsHsHB3B3BBEBCHBgBmImIB1nB1nBBtFtFFFB4JBB2YHBmY9D9DBBBoCBB+ECBEoBoBBCBDBB7JBBjLDBjFBBLBBCCBeCB8FEB-BBBldYYBKKBBBwlDCBzJOOFLLCBBEBBtNBB8ndBBuICBkHEB-LBB3CBBgD4E4EBBB0ECBgERRB6H6HnxUDDB6B6BBBBCDBqFLLCMMBEEiCDD7hBxBxBnkBoGoG3JBB5EFBlCFB6CDB5dEBtBDB+FGBxDDBgECBiEBBHRRB5C5CBDBtDrJrJB2D2DBBBNBBnLDBEOBqDBB6HCBmQCC8HBB4CBBFBB-MCBuBmUmUBrCrCBspBspBBDB6vRBBmEiCiCBBBLqRqRBoJoJBnwTnwTovHDB", false)),
		Uppercase: () => new UnicodeRangeTable(decodeRanges("hCZBmDWBCGBiB2BCDOCDuBCBECEBBCCCBCCBBBDDBCBBCCBEBBCBBCECBCCDCCBCCBBBCCCBEEIJDCMCDQCDDDCCBC4BCIBBCBBDCCBCBCGCiJCCEJJHCCBBBCCCBCCBPBCIBkBDDBBBEWCGDDCBBDyBBxBgBCK2BCBMCD+CCDlBBq6ClBBCGGzW1CB0kCHHBpBBDCBhK0ECKgDCKHBJFBLHBJHBJFBMGCJHBpCDBNDBNDBNEBMDBnIFFECBDCBDEEBDBHGCBCBDDBLBBGbbBOBUzZzZBYBx5BvBBxBCCBBBDGCBCBCDDJCBCgDCJCCFuqeuqeCqBCUaCoEMCE8BCLECBICFCCDCCEUCBDBCEBCOCBCBCCCBQCZs5Vs5VBYBmmBnBBpEjBB9EKBCOBCGBCBBr3ByBB+EVB75CfBhsVfBhCYBoqZZBbZBbZBbCCBGDBDDBCBCHBbZBbBBCDBDHBCGBcBBCDBCEBCEEBFBcZBbZBbZBbZBbZBbZBfYBiBYBiBYBiBYBiBYBiB2pE2pEBgBBvgCZBHZBHZB", false)),
		White_Space: () => new UnicodeRangeTable(decodeRanges("JEBTlDlDbgvFgvFgsCKBeBBGwBwBh9DAB", false))
	});
	static get Upper() {
		return this.CATEGORIES.get("Lu");
	}
	static SCRIPTS = new LazyMap({
		Adlam: () => new UnicodeRangeTable(decodeRanges("go6DrCFJFB", true)),
		Ahom: () => new UnicodeRangeTable(decodeRanges("g4lCaDOFW", true)),
		Anatolian_Hieroglyphs: () => new UnicodeRangeTable(decodeRanges("ggxCmS", true)),
		Arabic: () => new UnicodeRangeTable(decodeRanges("gwBEBCFBCNBCCBCfBCJBMZBCrDBChBBxCvBBxHhBBGqCBCcBxy8BtPBDvEBhBPBxDEBCmEBk7DeBkCFBJIBiBFBh43BDBCaBCBBCDDCJBCDBCCCHFFCECBBBCBBCDDCICBCCDDBCGBCDBCDBCCCBIBCQBGCBCEBCQB1BBB", false)),
		Armenian: () => new UnicodeRangeTable(decodeRanges("xpBlBDxBDCks9BE", true)),
		Avestan: () => new UnicodeRangeTable(decodeRanges("g4iC1BEG", true)),
		Balinese: () => new UnicodeRangeTable(decodeRanges("g4GsCCxB", true)),
		Bamum: () => new UnicodeRangeTable(decodeRanges("g1pB3CpowB4R", true)),
		Bassa_Vah: () => new UnicodeRangeTable(decodeRanges("w26CdDF", true)),
		Batak: () => new UnicodeRangeTable(decodeRanges("g+GzBJD", true)),
		Bengali: () => new UnicodeRangeTable(decodeRanges("gsCDBCHBDBBDVBCGBCEEBCBDIBDBBDDBJFFBCCBDBDYB", false)),
		Beria_Erfe: () => new UnicodeRangeTable(decodeRanges("g17CYDY", true)),
		Bhaiksuki: () => new UnicodeRangeTable(decodeRanges("ggnCICsBCNLc", true)),
		Bopomofo: () => new UnicodeRangeTable(decodeRanges("qXB6wLqBxDf", true)),
		Brahmi: () => new UnicodeRangeTable(decodeRanges("ggkCtCFjBKA", true)),
		Braille: () => new UnicodeRangeTable(decodeRanges("ggK-H", true)),
		Buginese: () => new UnicodeRangeTable(decodeRanges("gwGbDB", true)),
		Buhid: () => new UnicodeRangeTable(decodeRanges("g6FT", true)),
		Canadian_Aboriginal: () => new UnicodeRangeTable(decodeRanges("ggF-TxRlC7tgCP", true)),
		Carian: () => new UnicodeRangeTable(decodeRanges("g1gCwB", true)),
		Caucasian_Albanian: () => new UnicodeRangeTable(decodeRanges("wphCzBMA", true)),
		Chakma: () => new UnicodeRangeTable(decodeRanges("gokC0BCR", true)),
		Cham: () => new UnicodeRangeTable(decodeRanges("gwqB2BKNDJDD", true)),
		Cherokee: () => new UnicodeRangeTable(decodeRanges("g9E1CDFz7lBvC", true)),
		Chorasmian: () => new UnicodeRangeTable(decodeRanges("w9jCb", true)),
		Common: () => new UnicodeRangeTable(decodeRanges("AgCBbFBbuBBCOBCEBYgBgBiOmBBGEBDTB1DKKHCC+THHPEEhB9E9ElQiEiEB6mB6mB2MDBjJwvBwvBBBBoCBBsGBBCumBumBOIIBCBCFBCCBDmYmYBKBD2CBCKBEKBCOBShBB-BlBBCCBDFBCaBCQBqBCBF5UBXKBW-cBhIzTBDpEBhQ9CBzMUBCCCBXBQHBFDB8CBBE7C7CB0E0EBOBhBlBBKxBxBB+BBgBwCBwB5C5CBmFBhuG-BBhoWhBBnDCBmFJB1HhFhFsMPPBzuUzuUBxGxGBIBXiBBCSBCDB0ECCBeBbFBbKBLuBuBBhChCBFBCGBLEBjICBFsBBEIBxCMB0BsBBlHaBltuBDB96D8HBEzNBHWBQQBgDzDB9B1HBLmBBD9BBEQBJBBIdBF8BB2GTBNTBN2CBKYBoE0CBCmCBCBBDDDBDDBCBCLBCCCBFBCgCBCDBDHBCGBCbBCDBCEBCEEBFBCzKBDjJBDxBByjFjCBtC8BBjWrBBFjDBNOBDOBCOBCkBBLtFB5BZBCBBOrBBFIBIBBPFB7E4eBEQBEMBE5GBHLBFQQBKBF3BBJJBHnBBJdBDLBFBBPIBoB3KBJNBDMBEKBE4BBCFFBOBDLBFJBIyEBCmDBnghYffB+CB", false)),
		Coptic: () => new UnicodeRangeTable(decodeRanges("ifNxkKzDGG", true)),
		Cuneiform: () => new UnicodeRangeTable(decodeRanges("ggoC5cnDuDCEMjG", true)),
		Cypriot: () => new UnicodeRangeTable(decodeRanges("ggiCFBDCCBqBBCBBEDD", false)),
		Cypro_Minoan: () => new UnicodeRangeTable(decodeRanges("w8rCiD", true)),
		Cyrillic: () => new UnicodeRangeTable(decodeRanges("ggBkEBDoFBx6FKBhFtCtCojEfBhie-CBv8VBBhw4B9BBiBAB", false)),
		Deseret: () => new UnicodeRangeTable(decodeRanges("gghCvC", true)),
		Devanagari: () => new UnicodeRangeTable(decodeRanges("goCwCFODZh7nBfhwcJ", true)),
		Dives_Akuru: () => new UnicodeRangeTable(decodeRanges("gomCGBDDDBGBCBBCdBCBBDLBKJB", false)),
		Dogra: () => new UnicodeRangeTable(decodeRanges("ggmC7B", true)),
		Duployan: () => new UnicodeRangeTable(decodeRanges("ggvDqDGMEIIJDD", true)),
		Egyptian_Hieroglyphs: () => new UnicodeRangeTable(decodeRanges("ggsC1iBL68D", true)),
		Elbasan: () => new UnicodeRangeTable(decodeRanges("gohCnB", true)),
		Elymaic: () => new UnicodeRangeTable(decodeRanges("g-jCW", true)),
		Ethiopic: () => new UnicodeRangeTable(decodeRanges("gwEoCBCDBDGBCCCBCBDoBBCDBDgBBCDBDGBCCCBCBDOBC4BBCDBDiCBDfBEZBnvGWBKGBCGBCGBCGBCGBCGBCGBCGBjpfFBDFBDFBKGBCGBylvCGBCDBCBBCOB", false)),
		Garay: () => new UnicodeRangeTable(decodeRanges("gqjClBEcJB", true)),
		Georgian: () => new UnicodeRangeTable(decodeRanges("glElBBCGGDqBBCDBx8CqBBDCBhiElBBCGG", false)),
		Glagolitic: () => new UnicodeRangeTable(decodeRanges("ggL-Ch9sDGCQDGCBCE", true)),
		Gothic: () => new UnicodeRangeTable(decodeRanges("w5gCa", true)),
		Grantha: () => new UnicodeRangeTable(decodeRanges("g4kCDBCHBDBBDVBCGBCBBCEBDIBDBBDCBDHHGGBDGBEEB", false)),
		Greek: () => new UnicodeRangeTable(decodeRanges("wbDBCCBDDBCFFCCCBBBCCCBSBC+BBPPBnpGEBzBEBFEB1ChKhKBUBDFBDlBBDFBDHBCGCBdBD0BBCOBCNBDFBCSBDCBCIBoJ-xiB-xiB7uVuCBSgj0Bgj0BBkCB", false)),
		Gujarati: () => new UnicodeRangeTable(decodeRanges("h0CCBCIBCCBCVBCGBCBBCEBDJBCCBCCBDQQBCBDLBIGB", false)),
		Gunjala_Gondi: () => new UnicodeRangeTable(decodeRanges("grnCFCBCkBCBCFIJ", true)),
		Gurmukhi: () => new UnicodeRangeTable(decodeRanges("hwCCBCFBFBBDVBCGBCBBCBBCBBDCCBDBFBBDCBEIIBCBCIIBPB", false)),
		Gurung_Khema: () => new UnicodeRangeTable(decodeRanges("go4C5B", true)),
		Han: () => new UnicodeRangeTable(decodeRanges("g0LZBC4CBN1GBwBCCaIBPDBle-tGBhC-vUBhoWtLBDpDBpodBBNGBqgkB-2pBBhB9oEBDt0FBDwpHBQtTBjtC9QBjvBq6EBGppIB", false)),
		Hangul: () => new UnicodeRangeTable(decodeRanges("goE-HvxHBiI9CyDeiCei3dckUj9KNWFwBl9JeEFDFDFDC", true)),
		Hanifi_Rohingya: () => new UnicodeRangeTable(decodeRanges("gojCnBJJ", true)),
		Hanunoo: () => new UnicodeRangeTable(decodeRanges("g5FU", true)),
		Hatran: () => new UnicodeRangeTable(decodeRanges("gniCSCBGE", true)),
		Hebrew: () => new UnicodeRangeTable(decodeRanges("xsB2BBJaBFFBpp9BZBCEBCCCBCCBCCBIB", false)),
		Hiragana: () => new UnicodeRangeTable(decodeRanges("hiM1CBHCBi7-C+IBTeeBBBulQAB", false)),
		Imperial_Aramaic: () => new UnicodeRangeTable(decodeRanges("giiCVCI", true)),
		Inherited: () => new UnicodeRangeTable(decodeRanges("gYvDB2IBBlOKBbhXhXBCB8qEtBBDLBlPCBCMBCGBFHHEBBnG-BBtQBBjGgBB65DDBsDBBmrzBPBRNBwejHjH7iEl+uBl+uBBsBBDWBhRCBSHBDGBfDBz6rYvHB", false)),
		Inscriptional_Pahlavi: () => new UnicodeRangeTable(decodeRanges("g7iCSGH", true)),
		Inscriptional_Parthian: () => new UnicodeRangeTable(decodeRanges("g6iCVDH", true)),
		Javanese: () => new UnicodeRangeTable(decodeRanges("gsqBtCDJFB", true)),
		Kaithi: () => new UnicodeRangeTable(decodeRanges("gkkCiCLA", true)),
		Kannada: () => new UnicodeRangeTable(decodeRanges("gkDMCCCWCJCEDICCCDIBGCCDDJCC", true)),
		Katakana: () => new UnicodeRangeTable(decodeRanges("hlM5CBDCBxHPBxGuBBC3CBvgzBJBCsBBzisBDBCGBCBBCgJgJBBBzBPPBCB", false)),
		Kawi: () => new UnicodeRangeTable(decodeRanges("g4nCQCoBEc", true)),
		Kayah_Li: () => new UnicodeRangeTable(decodeRanges("goqBtBCA", true)),
		Kharoshthi: () => new UnicodeRangeTable(decodeRanges("gwiCDCBGHCCCcDCFJII", true)),
		Khitan_Small_Script: () => new UnicodeRangeTable(decodeRanges("k-7C84G84GB0OBqBAB", false)),
		Khmer: () => new UnicodeRangeTable(decodeRanges("g8F9CDJHJnPf", true)),
		Khojki: () => new UnicodeRangeTable(decodeRanges("gwkCRCuB", true)),
		Khudawadi: () => new UnicodeRangeTable(decodeRanges("w1kC6BGJ", true)),
		Kirat_Rai: () => new UnicodeRangeTable(decodeRanges("gq7C5B", true)),
		Lao: () => new UnicodeRangeTable(decodeRanges("h0DBBCCCBDBCXBCCCBVBDEBCCCBFBCJBDDB", false)),
		Latin: () => new UnicodeRangeTable(decodeRanges("hCZBHZBwBQQGWBCeBCgOBoBEB8wGlBBHwBBGDBGMBClCBiC-HByLOORMBuEBBHccSoBB42CfBj1elDBExCBVOBxZqBBCIBCDB38TGB7gBZBHZBmhCFBCpBBCIBm61BeBHFB", false)),
		Lepcha: () => new UnicodeRangeTable(decodeRanges("ggH3BEOEC", true)),
		Limbu: () => new UnicodeRangeTable(decodeRanges("goGeBCLBFLBFEEBKB", false)),
		Linear_A: () => new UnicodeRangeTable(decodeRanges("gwhC2JKVLH", true)),
		Linear_B: () => new UnicodeRangeTable(decodeRanges("gggCLCZCSCBCODNjB6D", true)),
		Lisu: () => new UnicodeRangeTable(decodeRanges("wmpBvBx1eA", true)),
		Lycian: () => new UnicodeRangeTable(decodeRanges("g0gCc", true)),
		Lydian: () => new UnicodeRangeTable(decodeRanges("gpiCZGA", true)),
		Mahajani: () => new UnicodeRangeTable(decodeRanges("wqkCmB", true)),
		Makasar: () => new UnicodeRangeTable(decodeRanges("g3nCY", true)),
		Malayalam: () => new UnicodeRangeTable(decodeRanges("goDMCCCyBCCCFFPDZ", true)),
		Mandaic: () => new UnicodeRangeTable(decodeRanges("giCbDA", true)),
		Manichaean: () => new UnicodeRangeTable(decodeRanges("g2iCmBFL", true)),
		Marchen: () => new UnicodeRangeTable(decodeRanges("wjnCfDVCN", true)),
		Masaram_Gondi: () => new UnicodeRangeTable(decodeRanges("gonCGBCBBCrBBECCBCCBHBJJB", false)),
		Medefaidrin: () => new UnicodeRangeTable(decodeRanges("gy7C6C", true)),
		Meetei_Mayek: () => new UnicodeRangeTable(decodeRanges("g3qBWqGtBDJ", true)),
		Mende_Kikakui: () => new UnicodeRangeTable(decodeRanges("gg6DkGDP", true)),
		Meroitic_Cursive: () => new UnicodeRangeTable(decodeRanges("gtiCXFTDtB", true)),
		Meroitic_Hieroglyphs: () => new UnicodeRangeTable(decodeRanges("gsiCf", true)),
		Miao: () => new UnicodeRangeTable(decodeRanges("g47CqCF4BIQ", true)),
		Modi: () => new UnicodeRangeTable(decodeRanges("gwlCkCMJ", true)),
		Mongolian: () => new UnicodeRangeTable(decodeRanges("ggGBBDCCBSBH4CBIqBB2t-BMB", false)),
		Mro: () => new UnicodeRangeTable(decodeRanges("gy6CeCJFB", true)),
		Multani: () => new UnicodeRangeTable(decodeRanges("g0kCGBCCCBCBCOBCKB", false)),
		Myanmar: () => new UnicodeRangeTable(decodeRanges("ggE-EhqmBeiDfxibT", true)),
		Nabataean: () => new UnicodeRangeTable(decodeRanges("gkiCeJI", true)),
		Nag_Mundari: () => new UnicodeRangeTable(decodeRanges("wm5DpB", true)),
		Nandinagari: () => new UnicodeRangeTable(decodeRanges("gtmCHDtBDK", true)),
		New_Tai_Lue: () => new UnicodeRangeTable(decodeRanges("gsGrBFZHKEB", true)),
		Newa: () => new UnicodeRangeTable(decodeRanges("gglC7CCE", true)),
		Nko: () => new UnicodeRangeTable(decodeRanges("g+B6BDC", true)),
		Nushu: () => new UnicodeRangeTable(decodeRanges("h-7CvsQvsQBqMB", false)),
		Nyiakeng_Puachue_Hmong: () => new UnicodeRangeTable(decodeRanges("go4DsBENDJFB", true)),
		Ogham: () => new UnicodeRangeTable(decodeRanges("g0Fc", true)),
		Ol_Chiki: () => new UnicodeRangeTable(decodeRanges("wiHvB", true)),
		Ol_Onal: () => new UnicodeRangeTable(decodeRanges("wu5DqBFA", true)),
		Old_Hungarian: () => new UnicodeRangeTable(decodeRanges("gkjCyBOyBIF", true)),
		Old_Italic: () => new UnicodeRangeTable(decodeRanges("g4gCjBKC", true)),
		Old_North_Arabian: () => new UnicodeRangeTable(decodeRanges("g0iCf", true)),
		Old_Permic: () => new UnicodeRangeTable(decodeRanges("w6gCqB", true)),
		Old_Persian: () => new UnicodeRangeTable(decodeRanges("g9gCjBFN", true)),
		Old_Sogdian: () => new UnicodeRangeTable(decodeRanges("g4jCnB", true)),
		Old_South_Arabian: () => new UnicodeRangeTable(decodeRanges("gziCf", true)),
		Old_Turkic: () => new UnicodeRangeTable(decodeRanges("ggjCoC", true)),
		Old_Uyghur: () => new UnicodeRangeTable(decodeRanges("w7jCZ", true)),
		Oriya: () => new UnicodeRangeTable(decodeRanges("h4CCCHDBDVCGCBCEDIDBDCICFBCEDR", true)),
		Osage: () => new UnicodeRangeTable(decodeRanges("wlhCjBFjB", true)),
		Osmanya: () => new UnicodeRangeTable(decodeRanges("gkhCdDJ", true)),
		Pahawh_Hmong: () => new UnicodeRangeTable(decodeRanges("g46ClCLJCGCUGS", true)),
		Palmyrene: () => new UnicodeRangeTable(decodeRanges("gjiCf", true)),
		Pau_Cin_Hau: () => new UnicodeRangeTable(decodeRanges("g2mC4B", true)),
		Phags_Pa: () => new UnicodeRangeTable(decodeRanges("giqB3B", true)),
		Phoenician: () => new UnicodeRangeTable(decodeRanges("goiCbEA", true)),
		Psalter_Pahlavi: () => new UnicodeRangeTable(decodeRanges("g8iCRIDNG", true)),
		Rejang: () => new UnicodeRangeTable(decodeRanges("wpqBjBMA", true)),
		Runic: () => new UnicodeRangeTable(decodeRanges("g1FqCEK", true)),
		Samaritan: () => new UnicodeRangeTable(decodeRanges("ggCtBDO", true)),
		Saurashtra: () => new UnicodeRangeTable(decodeRanges("gkqBlCJL", true)),
		Sharada: () => new UnicodeRangeTable(decodeRanges("gskC-ChsCH", true)),
		Shavian: () => new UnicodeRangeTable(decodeRanges("wihCvB", true)),
		Siddham: () => new UnicodeRangeTable(decodeRanges("gslC1BDlB", true)),
		Sidetic: () => new UnicodeRangeTable(decodeRanges("gqiCZ", true)),
		SignWriting: () => new UnicodeRangeTable(decodeRanges("gg2DrUQECO", true)),
		Sinhala: () => new UnicodeRangeTable(decodeRanges("hsDCBCRBEXBCIBCDDBFBEFFBEBCCCBGBHJBDCBt-gCTB", false)),
		Sogdian: () => new UnicodeRangeTable(decodeRanges("w5jCpB", true)),
		Sora_Sompeng: () => new UnicodeRangeTable(decodeRanges("wmkCYIJ", true)),
		Soyombo: () => new UnicodeRangeTable(decodeRanges("wymCyC", true)),
		Sundanese: () => new UnicodeRangeTable(decodeRanges("g8G-BhIH", true)),
		Sunuwar: () => new UnicodeRangeTable(decodeRanges("g+mChBPJ", true)),
		Syloti_Nagri: () => new UnicodeRangeTable(decodeRanges("ggqBsB", true)),
		Syriac: () => new UnicodeRangeTable(decodeRanges("g4BNC7BDCxIK", true)),
		Tagalog: () => new UnicodeRangeTable(decodeRanges("g4FVKA", true)),
		Tagbanwa: () => new UnicodeRangeTable(decodeRanges("g7FMCCCB", true)),
		Tai_Le: () => new UnicodeRangeTable(decodeRanges("wqGdDE", true)),
		Tai_Tham: () => new UnicodeRangeTable(decodeRanges("gxG+BCcDKHJHN", true)),
		Tai_Viet: () => new UnicodeRangeTable(decodeRanges("g0qBiCZE", true)),
		Tai_Yo: () => new UnicodeRangeTable(decodeRanges("g25DeCVJB", true)),
		Takri: () => new UnicodeRangeTable(decodeRanges("g0lC5BHJ", true)),
		Tamil: () => new UnicodeRangeTable(decodeRanges("i8CBBCFBECBCDBEBBCCCBEEBEEBBBELBFEBECBCDBDHHPUBm+kCxBBOAB", false)),
		Tangsa: () => new UnicodeRangeTable(decodeRanges("wz6CuCCJ", true)),
		Tangut: () => new UnicodeRangeTable(decodeRanges("g-7CgBgBB+3GBhQeBiDyDB", false)),
		Telugu: () => new UnicodeRangeTable(decodeRanges("ggDMCCCWCPDICCCDIBCCCBDDDJII", true)),
		Thaana: () => new UnicodeRangeTable(decodeRanges("g8BxB", true)),
		Thai: () => new UnicodeRangeTable(decodeRanges("hwD5BGb", true)),
		Tibetan: () => new UnicodeRangeTable(decodeRanges("g4DnCCjBFmBCjBCOCGFB", true)),
		Tifinagh: () => new UnicodeRangeTable(decodeRanges("wpL3BIBPA", true)),
		Tirhuta: () => new UnicodeRangeTable(decodeRanges("gklCnCJJ", true)),
		Todhri: () => new UnicodeRangeTable(decodeRanges("guhCzB", true)),
		Tolong_Siki: () => new UnicodeRangeTable(decodeRanges("wtnCrBFJ", true)),
		Toto: () => new UnicodeRangeTable(decodeRanges("w04De", true)),
		Tulu_Tigalari: () => new UnicodeRangeTable(decodeRanges("g8kCJBCDDClBBCJBCDDCDBCJBCBBJBB", false)),
		Ugaritic: () => new UnicodeRangeTable(decodeRanges("g8gCdCA", true)),
		Unknown: () => new UnicodeRangeTable(decodeRanges("4bBBHDBICCVuMuMnBBBzBBBE4B4BBGBcDBHKBvI9B9BBmDmDBMB8BBByBBBQddBCCMEBjBEBuHJJBDDBXXICCBBBFBBKBBDBBFHBCDBDGGBaaBEEHDBDBBXIIDGDBCCGDBDBBECBCGBFCCBFBSJBEKKEXXIDDGBBLIEBCCBNBFBBNGBIEEJBBDBBXIIDGGBKKBDDBEEBFBEDBDGGBTTBIBDHHBBBEFFBBBDCCDCBDCBECBNDBGCBEFFBCCBEBCNBWEBOEEYRRBKKEFFBFBDEEDBBFBBLGBXEEYLLGBBKEEFGBDEBEFFBLLELBOEE0BEEHDBRBBbEETCBZKKCBBICBCDBHCCJFBLBBELB7BDBekBBDCCGZZCYYBGGCIILBBFfBpClBlBBCBoBlBlBQOOBjBBnGCCBDBCBB6LFFBIICFFBqBqBFBBiBFFBIICFFBQQ6BFFBkCkCBhBhBBBBbFB3CBBHBB+UCB6CGBXIBZIBVLBOEEDLB-CBBLFBLFBbFB6CGBsBEBnCJBgBNNBCBNDBCCBrBBBGKBtBDBbFBMCB-BBBiCeeBMMBEBLFBPBBvBBBNTBuCnFnFBGB9BCBQCB-BEBsBBBMHBsBEB3QBBHBBnBBBHBBJGCgBBB2BQQPBBHUUBEEKmDmDNBBcOOBBBjBNBiBOBtEDB7UVBMUB14BBB-LEBuBCCBDBCBB5BGBDNBZIBI4BI-DhBBb6C6CBKB3GZBxC3C3CBoDoDBDBsB-C-C3CIBxBuzcuzcBBB4BIB9KTB5FHB+GTB9BCBLFB5BHBnCHBNFB1DKBfCBvCMMBCBiB4B4BBHBPBBLBBoDXBdJBHBBHBBHIBIII9BDB-DBBLFBl9KLBYDByBjoIBvLBBrDlBBILBGEBbGGCGDrUfBrBFB0BUUFDBGoEoEBCC-FCBHBBHBBHBBECBIIIBIBGBBNbbUDDQBBPhBB8DEBEDBuBCB5COOBBBCuBBvBhEBeCByBOBdDBlBIBfEBsBEBfmBmBBCBPpBB-EBBLFBlBDBlBDBpBHB1BKBNQQIDDMQQIDDBBB1BLB4JIBXJBJXBHrBrBKkCBHBBCtBtBDCBCBBYpCpCBGBKvBBUDDBDBiBCBcEBclBB5BDBVBBzBDDBDBJEEeBBEDBLGBKGBhCfBoBDBNIB3BCBeBBcEBbGBFLBIvCBqC2BB0BMB0BGBvBHBLFBnBCBeHBDvGBgBrBrBEBBDPBHHBKgBBvBHBrBVBblBBdTBYIBvCDBlBIBlCJBCBBaGBLFB2BTTBGBoBIBhDVVBJBTwBwBB8BBICCFQQMFB8BEBLFBFJJBDDBXXIDDGLLBDDBEEBCCBEBCEBIBBICBGKBLCCBCCnBLLCBBCFFLDDBGBDcB9CGGBcBpCHBLlFB3BBBnBhBBmCKBLFBOSB7BFBLFBVbBcBBQDBY4FB9BjDB0CLBJBBCBBJDDfDDBNNBHBLlCBJBBvBBBMaBpCHB0CMBqCGBL1CBJ3CBjBNBLFBKuBuBPJBeCBhBBBXPPBnCBIDDtBCBCDDKHBLFBHDDmBDDHGBLFBtBDBL1HBaGBSqBqBBBBe0CBCOBzBMB8clDBwDGGBJBlGryCBkDMB3iBJB88DEBoS41GB7Bl2BB6RGBgBLLBCByCLLBEBfBBHJBnCJBLIIWEBUvNB7BlGB8CEBaBBarBBsCDB6BGBS-BBGKBIIB3mHoBBhBgDB0D8vIBFIIDkJkJBNBCcBEBBCNBFHBtMjoCBsDEBOCBKGBLBBJ76DB+HCB1NFBYOBSOBvBBBYIB1D7BB3HJBoBBBjGUBnC5DBVLBVLB4CIBamEB2CoCoCDBBCBBDBBFNNCIIiCFFBJJIddFGGCCBI1K1KBlJlJB-V-VBNBGQQBuiBBgBFBH0GBISSBIIDGGBDB-BgBBCvDBuBCBPBBLDBD-JBgBQB7BEBCvOBrB1GBsBDBC-FBgBXXBGBD-GBIFFDQQmGBBRoBBtCDBLDBDwYBlCrCB+BhGBFccDCCBCCLFFCCCBEBCDBCECEDDCBBCICDCCBFFIKFCLLSEBEGGSzBBDtIBtBDBlDLBQBBQQQmBJBvF3BBeMBtBDBKGBDNBH5EB6eCBSCBOCB7GFBNDBCOBNDB5BHBLFBpBHBfBBNDBDNBKmBB5KHBPBBOCBMCB6BCCBCBRBBNDBLGB0EoDoDBjgBBh3pBfB-oEBBv0FBBypHOBvThtCB-QhvBBs6EEBrpIm8yVBCdBhD-DBxHvw-FB", false)),
		Vai: () => new UnicodeRangeTable(decodeRanges("gopBrJ", true)),
		Vithkuqi: () => new UnicodeRangeTable(decodeRanges("wrhCKCOCGCBCKCOCGCB", true)),
		Wancho: () => new UnicodeRangeTable(decodeRanges("g24D5BGA", true)),
		Warang_Citi: () => new UnicodeRangeTable(decodeRanges("glmCyCNA", true)),
		Yezidi: () => new UnicodeRangeTable(decodeRanges("g0jCpBCCDB", true)),
		Yi: () => new UnicodeRangeTable(decodeRanges("ggoBskBE2B", true)),
		Zanabazar_Square: () => new UnicodeRangeTable(decodeRanges("gwmCnC", true))
	});
	static FOLD_CATEGORIES = new LazyMap({
		L: () => new UnicodeRangeTable(decodeRanges("laA", true)),
		LC: () => new UnicodeRangeTable(decodeRanges("laA", true)),
		Ll: () => new UnicodeRangeTable(decodeRanges("hCZBmDWBCGBiBuBCEECDOCDuBCBECEBBCCCBCCBBBDDBCBBCCBEBBCBBCECBCCDCCBCCBBBCCCBEEIBBCBBCBBCOCDQCDBBCCCBBBC4BCIBBCBBDCCBCBCGC3HrBrBCEEJHHCCBCCCBCCBPBCIBkBJJCUCGDDCBBDyBBxBgBCK2BCBMCD+CCDlBBq6ClBBCGGzW1CB0kCHHBpBBDCBhK0ECKgDCKHBJFBLHBJHBJFBMGCJHBZHBJHBJHBJEBMEBMDBNEBMEBqJEEBHHxC9zC9zCBuBBxBCCBBBDGCBCBCDDJCBCgDCJCCFuqeuqeCqBCUaCoEMCE8BCLECBICFCCDCCEUCBDBCEBCOCBCBCCCBQCZs5Vs5VBYBmmBnBBpEjBB9EKBCOBCGBCBBr3ByBB+EVB75CfBhsVfBhCYBoyehBB", false)),
		Lt: () => new UnicodeRangeTable(decodeRanges("kOCCBCCBCClBCCtsHHBJHBJHBMQQwBAB", false)),
		Lu: () => new UnicodeRangeTable(decodeRanges("hDZB7BqBqBBWBCHBCuBCEECDOCDsBCDECBBBDCCDEEGDDECBDDDCCCDFFDEECDDECCGBBCBBCBBCOCBSCDBBCEECkBCEQCJDDBCCFICBEBCBBCCCBEEBCCBCBCEBDCCBDDIDDCBBEFBGLLBnFnFsBCCEEEBBBvBDBCdBCBBECBCWCBDBCGD1BvBBCgBCK0BCDMCBgDCyBlBBq6CqBBDCB5XFBjkCIBCvHvHERRzD0ECGGGC8CCBHBJFBLHBJHBJFBMGCJHBJNBzBBBNSSBPPBEEpL2B2Bs1CvBBCEEBGCHDDLiDCJCCFNNBkBBCGG0oesBCUaCoEMCE8BCLCCDICFFFCBBDSCMOCFCCDOCb9a9advCBi8UZBumBnBBpEjBB8EKBCOBCGBCBBk4ByBB+DVB75CfBhsVfB8BYBvyehBB", false)),
		M: () => new UnicodeRangeTable(decodeRanges("5cgBgBlgHAB", false)),
		Mn: () => new UnicodeRangeTable(decodeRanges("5cgBgBlgHAB", false)),
		Emoji: () => new UnicodeRangeTable(decodeRanges("8mJA", true)),
		Extended_Pictographic: () => new UnicodeRangeTable(decodeRanges("8mJA", true)),
		Lowercase: () => new UnicodeRangeTable(decodeRanges("hCZBmDWBCGBiBuBCEECDOCDuBCBECEBBCCCBCCBBBDDBCBBCCBEBBCBBCECBCCDCCBCCBBBCCCBEEIBBCBBCBBCOCDQCDBBCCCBBBC4BCIBBCBBDCCBCBCGCiJCCEJJHCCBBBCCCBCCBPBCIBkBJJCUCGDDCBBDyBBxBgBCK2BCBMCD+CCDlBBq6ClBBCGGzW1CB0kCHHBpBBDCBhK0ECKgDCKHBJFBLHBJHBJFBMGCJHBZHBJHBJHBJEBMEBMDBNEBMEBqJEEBHHuBPBUzZzZBYBx5BvBBxBCCBBBDGCBCBCDDJCBCgDCJCCFuqeuqeCqBCUaCoEMCE8BCLECBICFCCDCCEUCBDBCEBCOCBCBCCCBQCZs5Vs5VBYBmmBnBBpEjBB9EKBCOBCGBCBBr3ByBB+EVB75CfBhsVfBhCYBoyehBB", false)),
		Math: () => new UnicodeRangeTable(decodeRanges("ycGDCHHFMMDDDCHHFAB", false)),
		Uppercase: () => new UnicodeRangeTable(decodeRanges("hDZB7BqBqBBWBCHBCuBCEECDOCDsBCDECBBBDCCDEEGDDECBDDDCCCDFFDEECDDECCGBBCBBCBBCOCBSCDBBCEECkBCEQCJDDBCCFICBEBCBBCCCBEEBCCBCBCEBDCCBDDIDDCBBEFBGLLBnFnFsBCCEEEBBBvBDBCdBCBBECBCWCBDBCGD1BvBBCgBCK0BCDMCBgDCyBlBBq6CqBBDCB5XFBjkCIBCvHvHERRzD0ECGGGC8CCBHBJFBLHBJHBJFBMGCJHBJNBzBBBNSSBPPBEEpLiBiBBOBFsasaBYBn6BvBBCEEBGCHDDLiDCJCCFNNBkBBCGG0oesBCUaCoEMCE8BCLCCDICFFFCBBDSCMOCFCCDOCb9a9advCBi8UZBumBnBBpEjBB8EKBCOBCGBCBBk4ByBB+DVB75CfBhsVfB8BYBvyehBB", false))
	});
	static FOLD_SCRIPT = new LazyMap({
		Common: () => new UnicodeRangeTable(decodeRanges("8cgBgB", false)),
		Greek: () => new UnicodeRangeTable(decodeRanges("1FwUwU", false)),
		Inherited: () => new UnicodeRangeTable(decodeRanges("5cgBgBlgHAB", false))
	});
};
//#endregion
//#region src/Unicode.js
/**
* Utilities for dealing with Unicode better than JS does.
*/
var Unicode = class Unicode {
	static MAX_RUNE = 1114111;
	static MAX_ASCII = 127;
	static MAX_LATIN1 = 255;
	static MAX_BMP = 65535;
	static MIN_FOLD = 65;
	static MAX_FOLD = 125251;
	static MIN_HIGH_SURROGATE = 55296;
	static MAX_HIGH_SURROGATE = 56319;
	static MIN_LOW_SURROGATE = 56320;
	static MAX_LOW_SURROGATE = 57343;
	static MIN_SUPPLEMENTARY_CODE_POINT = 65536;
	static is32(ranges, r) {
		let lo = 0;
		let hi = ranges.length;
		while (lo < hi) {
			const m = lo + Math.floor((hi - lo) / 2);
			const rlo = ranges.getLo(m);
			const rhi = ranges.getHi(m);
			if (rlo <= r && r <= rhi) {
				const stride = ranges.getStride(m);
				return (r - rlo) % stride === 0;
			}
			if (r < rlo) hi = m;
			else lo = m + 1;
		}
		return false;
	}
	static is(ranges, r) {
		if (r <= Unicode.MAX_LATIN1) {
			for (let i = 0; i < ranges.length; i++) {
				if (r > ranges.getHi(i)) continue;
				const rlo = ranges.getLo(i);
				if (r < rlo) return false;
				const stride = ranges.getStride(i);
				return (r - rlo) % stride === 0;
			}
			return false;
		}
		return ranges.length > 0 && r >= ranges.getLo(0) && Unicode.is32(ranges, r);
	}
	static isUpper(r) {
		if (r <= Unicode.MAX_LATIN1) {
			const s = String.fromCodePoint(r);
			return s.toUpperCase() === s && s.toLowerCase() !== s;
		}
		return Unicode.is(UnicodeTables.Upper, r);
	}
	static isPrint(r) {
		if (r <= Unicode.MAX_LATIN1) return r >= 32 && r < Unicode.MAX_ASCII || r >= 161 && r !== 173;
		return Unicode.is(UnicodeTables.Print, r);
	}
	static simpleFold(r) {
		if (UnicodeTables.CASE_ORBIT.has(r)) return UnicodeTables.CASE_ORBIT.get(r);
		const l = Codepoint.toLowerCase(r);
		if (l !== r) return l;
		return Codepoint.toUpperCase(r);
	}
	static equalsIgnoreCase(r1, r2) {
		if (r1 === r2) return true;
		if (r1 < 0 || r2 < 0) return false;
		if (r1 <= Unicode.MAX_ASCII && r2 <= Unicode.MAX_ASCII) {
			if (65 <= r1 && r1 <= 90) r1 |= 32;
			if (65 <= r2 && r2 <= 90) r2 |= 32;
			return r1 === r2;
		}
		for (let r = Unicode.simpleFold(r1); r !== r1; r = Unicode.simpleFold(r)) if (r === r2) return true;
		return false;
	}
};
//#endregion
//#region src/Utils.js
/**
* Size of the precomputed single-byte lookup table.
* Covers standard ASCII and Latin-1 characters for fast-path execution.
*/
const FAST_PATH_TABLE_SIZE = 256;
/**
* Precomputed lookup table for Word Boundary (\b, \B) assertions.
* * By precomputing the boolean results for standard ASCII word ranges
* ('a'-'z', 'A'-'Z', '0'-'9', '_'), we completely eliminate 4 logical
* branches from the NFA's hot execution loop. This prevents costly
* CPU branch mispredictions when scanning large strings.
*/
const WORD_RUNE_TABLE = new Uint8Array(FAST_PATH_TABLE_SIZE);
for (let i = 0; i < FAST_PATH_TABLE_SIZE; i++) WORD_RUNE_TABLE[i] = 97 <= i && i <= 122 || 65 <= i && i <= 90 || 48 <= i && i <= 57 || i === 95 ? 1 : 0;
let cachedNativeEncoder = null;
let cachedNativeDecoder = null;
/**
* Various constants and helper utilities.
*/
var Utils = class Utils {
	static METACHARACTERS = "\\.+*?()|[]{}^$";
	static EMPTY_BEGIN_LINE = 1;
	static EMPTY_END_LINE = 2;
	static EMPTY_BEGIN_TEXT = 4;
	static EMPTY_END_TEXT = 8;
	static EMPTY_WORD_BOUNDARY = 16;
	static EMPTY_NO_WORD_BOUNDARY = 32;
	static EMPTY_ALL = -1;
	static emptyInts() {
		return [];
	}
	static isByteArray(input) {
		return Array.isArray(input) || input instanceof Uint8Array;
	}
	static isalnum(c) {
		return Codepoint.CODES.get("0") <= c && c <= Codepoint.CODES.get("9") || Codepoint.CODES.get("a") <= c && c <= Codepoint.CODES.get("z") || Codepoint.CODES.get("A") <= c && c <= Codepoint.CODES.get("Z");
	}
	static unhex(c) {
		if (Codepoint.CODES.get("0") <= c && c <= Codepoint.CODES.get("9")) return c - Codepoint.CODES.get("0");
		if (Codepoint.CODES.get("a") <= c && c <= Codepoint.CODES.get("f")) return c - Codepoint.CODES.get("a") + 10;
		if (Codepoint.CODES.get("A") <= c && c <= Codepoint.CODES.get("F")) return c - Codepoint.CODES.get("A") + 10;
		return -1;
	}
	static escapeRune(rune) {
		let out = "";
		if (Unicode.isPrint(rune)) {
			if (Utils.METACHARACTERS.indexOf(String.fromCodePoint(rune)) >= 0) out += "\\";
			out += String.fromCodePoint(rune);
		} else switch (rune) {
			case Codepoint.CODES.get("\""):
				out += "\\\"";
				break;
			case Codepoint.CODES.get("\\"):
				out += "\\\\";
				break;
			case Codepoint.CODES.get("	"):
				out += "\\t";
				break;
			case Codepoint.CODES.get("\n"):
				out += "\\n";
				break;
			case Codepoint.CODES.get("\r"):
				out += "\\r";
				break;
			case Codepoint.CODES.get("\b"):
				out += "\\b";
				break;
			case Codepoint.CODES.get("\f"):
				out += "\\f";
				break;
			default: {
				let s = rune.toString(16);
				if (rune < 256) {
					out += "\\x";
					if (s.length === 1) out += "0";
					out += s;
				} else out += `\\x{${s}}`;
				break;
			}
		}
		return out;
	}
	static stringToRunes(str) {
		const string = String(str);
		const runes = [];
		let i = 0;
		while (i < string.length) {
			const cp = string.codePointAt(i);
			runes.push(cp);
			i += cp > Unicode.MAX_BMP ? 2 : 1;
		}
		return runes;
	}
	static runeToString(r) {
		return String.fromCodePoint(r);
	}
	static isWordRune(r) {
		return r < FAST_PATH_TABLE_SIZE ? WORD_RUNE_TABLE[r] === 1 : false;
	}
	static emptyOpContext(r1, r2) {
		let op = 0;
		if (r1 < 0) op |= Utils.EMPTY_BEGIN_TEXT | Utils.EMPTY_BEGIN_LINE;
		if (r1 === 10) op |= Utils.EMPTY_BEGIN_LINE;
		if (r2 < 0) op |= Utils.EMPTY_END_TEXT | Utils.EMPTY_END_LINE;
		if (r2 === 10) op |= Utils.EMPTY_END_LINE;
		if (Utils.isWordRune(r1) !== Utils.isWordRune(r2)) op |= Utils.EMPTY_WORD_BOUNDARY;
		else op |= Utils.EMPTY_NO_WORD_BOUNDARY;
		return op;
	}
	/**
	* Returns a string that quotes all regular expression metacharacters inside the argument text;
	* the returned string is a regular expression matching the literal text. For example,
	* {@code quoteMeta("[foo]").equals("\\[foo\\]")}.
	* @param {string} str
	* @returns {string}
	*/
	static quoteMeta(str) {
		return str.split("").map((s) => {
			if (Utils.METACHARACTERS.indexOf(s) >= 0) return `\\${s}`;
			return s;
		}).join("");
	}
	static charCount(codePoint) {
		return codePoint > Unicode.MAX_BMP ? 2 : 1;
	}
	/**
	* High-speed conversion from TypedArrays to standard JS Arrays.
	* Bypasses the expensive Symbol.iterator overhead of Array.from()
	*/
	static toArray(typedArray) {
		const len = typedArray.length;
		const res = new Array(len);
		for (let i = 0; i < len; i++) res[i] = typedArray[i];
		return res;
	}
	static stringToUtf8ByteArray(str) {
		if (globalThis.TextEncoder) {
			if (!cachedNativeEncoder) cachedNativeEncoder = new TextEncoder();
			return cachedNativeEncoder.encode(str);
		} else {
			let out = [], p = 0;
			for (let i = 0; i < str.length; i++) {
				let c = str.charCodeAt(i);
				if (c < 128) out[p++] = c;
				else if (c < 2048) {
					out[p++] = c >> 6 | 192;
					out[p++] = c & 63 | 128;
				} else if ((c & 64512) === Unicode.MIN_HIGH_SURROGATE && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) === Unicode.MIN_LOW_SURROGATE) {
					c = Unicode.MIN_SUPPLEMENTARY_CODE_POINT + ((c & 1023) << 10) + (str.charCodeAt(++i) & 1023);
					out[p++] = c >> 18 | 240;
					out[p++] = c >> 12 & 63 | 128;
					out[p++] = c >> 6 & 63 | 128;
					out[p++] = c & 63 | 128;
				} else {
					out[p++] = c >> 12 | 224;
					out[p++] = c >> 6 & 63 | 128;
					out[p++] = c & 63 | 128;
				}
			}
			return out;
		}
	}
	static utf8ByteArrayToString(bytes) {
		if (globalThis.TextDecoder) {
			if (!cachedNativeDecoder) cachedNativeDecoder = new TextDecoder("utf-8");
			const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
			return cachedNativeDecoder.decode(view);
		} else {
			let out = [], pos = 0, c = 0;
			while (pos < bytes.length) {
				let c1 = bytes[pos++];
				if (c1 < 128) out[c++] = String.fromCharCode(c1);
				else if (c1 > 191 && c1 < 224) {
					let c2 = bytes[pos++];
					out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
				} else if (c1 > 239 && c1 < 365) {
					let c2 = bytes[pos++];
					let c3 = bytes[pos++];
					let c4 = bytes[pos++];
					let u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - Unicode.MIN_SUPPLEMENTARY_CODE_POINT;
					out[c++] = String.fromCharCode(Unicode.MIN_HIGH_SURROGATE + (u >> 10));
					out[c++] = String.fromCharCode(Unicode.MIN_LOW_SURROGATE + (u & 1023));
				} else {
					let c2 = bytes[pos++];
					let c3 = bytes[pos++];
					out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
				}
			}
			return out.join("");
		}
	}
};
//#endregion
//#region src/helpers.js
const createEnum = (values = [], initNum = 0) => {
	const enumObject = Object.create(null);
	for (let i = 0; i < values.length; i++) {
		const val = values[i];
		const keyVal = initNum + i;
		enumObject[val] = keyVal;
		enumObject[keyVal] = val;
	}
	return Object.freeze(enumObject);
};
//#endregion
//#region src/MatcherInput.js
/**
* Abstract the representations of input text supplied to Matcher.
*/
var MatcherInputBase = class MatcherInputBase {
	static Encoding = createEnum(["UTF_16", "UTF_8"]);
	getEncoding() {
		throw Error("not implemented");
	}
	/** @returns {string} */
	asCharSequence() {
		throw Error("not implemented");
	}
	/** @returns {Uint8Array|number[]} */
	asBytes() {
		throw Error("not implemented");
	}
	/** @returns {number} */
	length() {
		throw Error("not implemented");
	}
	/**
	*
	* @returns {boolean}
	*/
	isUTF8Encoding() {
		return this.getEncoding() === MatcherInputBase.Encoding.UTF_8;
	}
	/**
	*
	* @returns {boolean}
	*/
	isUTF16Encoding() {
		return this.getEncoding() === MatcherInputBase.Encoding.UTF_16;
	}
};
var Utf8MatcherInput = class extends MatcherInputBase {
	/** @param {Uint8Array|number[]|null} bytes */
	constructor(bytes = null) {
		super();
		this.bytes = bytes;
	}
	getEncoding() {
		return MatcherInputBase.Encoding.UTF_8;
	}
	/**
	*
	* @returns {string}
	*/
	asCharSequence() {
		return Utils.utf8ByteArrayToString(this.bytes);
	}
	/**
	*
	* @returns {Uint8Array|number[]|null}
	*/
	asBytes() {
		return this.bytes;
	}
	/**
	*
	* @returns {number}
	*/
	length() {
		return this.bytes.length;
	}
};
var Utf16MatcherInput = class extends MatcherInputBase {
	/** @param {string|null} charSequence */
	constructor(charSequence = null) {
		super();
		this.charSequence = charSequence;
	}
	getEncoding() {
		return MatcherInputBase.Encoding.UTF_16;
	}
	/**
	*
	* @returns {string}
	*/
	asCharSequence() {
		return this.charSequence;
	}
	/**
	*
	* @returns {number[]}
	*/
	asBytes() {
		return Utils.stringToUtf8ByteArray(this.charSequence.toString());
	}
	/**
	*
	* @returns {number}
	*/
	length() {
		return this.charSequence.length;
	}
};
var MatcherInput = class {
	/**
	* Return the MatcherInput for UTF_16 encoding.
	* @returns {Utf16MatcherInput}
	*/
	static utf16(charSequence) {
		return new Utf16MatcherInput(charSequence);
	}
	/**
	* Return the MatcherInput for UTF_8 encoding.
	* @returns {Utf8MatcherInput}
	*/
	static utf8(input) {
		if (Utils.isByteArray(input)) return new Utf8MatcherInput(input);
		return new Utf8MatcherInput(Utils.stringToUtf8ByteArray(input));
	}
};
//#endregion
//#region src/MachineInput.js
/**
* MachineInput abstracts different representations of the input text supplied to the Machine. It
* provides one-character lookahead.
*/
var MachineInputBase = class {
	static EOF() {
		return -8;
	}
	constructor() {
		this.end = 0;
	}
	canCheckPrefix() {
		return true;
	}
	endPos() {
		return this.end;
	}
	hasString() {
		return false;
	}
	hasAnyString() {
		return false;
	}
	prefixLength() {
		return 0;
	}
};
var MachineUTF8Input = class extends MachineInputBase {
	constructor(bytes, start = 0, end = bytes.length) {
		super();
		this.bytes = bytes;
		this.start = start;
		this.end = end;
	}
	hasString(prefilter, pos) {
		const target = prefilter.bytes;
		if (target.length === 0) return true;
		const idx = this.indexOf(this.bytes, target, this.start + pos);
		return idx !== -1 && idx <= this.end - target.length;
	}
	hasAnyString(prefilter, pos) {
		if (!prefilter.ac8) return false;
		return prefilter.ac8.searchUTF8(this.bytes, this.start + pos, this.end);
	}
	step(pos) {
		pos += this.start;
		if (pos >= this.end) return MachineInputBase.EOF();
		const c = this.bytes[pos] & 255;
		if (c < 128) return c << 3 | 1;
		else if (c >= 194 && c <= 223 && pos + 1 < this.end) {
			const c1 = this.bytes[pos + 1] & 255;
			if ((c1 & 192) !== 128) return c << 3 | 1;
			return ((c & 31) << 6 | c1 & 63) << 3 | 2;
		} else if (c >= 224 && c <= 239 && pos + 2 < this.end) {
			const c1 = this.bytes[pos + 1] & 255;
			if ((c1 & 192) !== 128) return c << 3 | 1;
			const c2 = this.bytes[pos + 2] & 255;
			if ((c2 & 192) !== 128) return c << 3 | 1;
			return ((c & 15) << 12 | (c1 & 63) << 6 | c2 & 63) << 3 | 3;
		} else if (c >= 240 && c <= 244 && pos + 3 < this.end) {
			const c1 = this.bytes[pos + 1] & 255;
			if ((c1 & 192) !== 128) return c << 3 | 1;
			const c2 = this.bytes[pos + 2] & 255;
			if ((c2 & 192) !== 128) return c << 3 | 1;
			const c3 = this.bytes[pos + 3] & 255;
			if ((c3 & 192) !== 128) return c << 3 | 1;
			return ((c & 7) << 18 | (c1 & 63) << 12 | (c2 & 63) << 6 | c3 & 63) << 3 | 4;
		} else return c << 3 | 1;
	}
	index(re2, pos) {
		pos += this.start;
		const i = this.indexOf(this.bytes, re2.prefixUTF8, pos);
		return i < 0 ? i : i - pos;
	}
	context(pos) {
		pos += this.start;
		let r1 = -1;
		if (pos > this.start && pos <= this.end) {
			let start = pos - 1;
			r1 = this.bytes[start--];
			if (r1 >= 128) {
				let lim = pos - 4;
				if (lim < this.start) lim = this.start;
				while (start >= lim && (this.bytes[start] & 192) === 128) start--;
				if (start < this.start) start = this.start;
				r1 = this.step(start - this.start) >> 3;
			}
		}
		const r2 = pos < this.end ? this.step(pos - this.start) >> 3 : -1;
		return Utils.emptyOpContext(r1, r2);
	}
	indexOf(source, target, fromIndex = 0) {
		let targetLength = target.length;
		if (targetLength === 0) return fromIndex <= this.end ? fromIndex : -1;
		const firstByte = target[0];
		let limit = this.end - targetLength;
		const hasNativeIndexOf = typeof source.indexOf === "function";
		let i = fromIndex;
		while (i <= limit) {
			if (hasNativeIndexOf) {
				i = source.indexOf(firstByte, i);
				if (i === -1 || i > limit) return -1;
			} else {
				while (i <= limit && source[i] !== firstByte) i++;
				if (i > limit) return -1;
			}
			let match = true;
			for (let j = 1; j < targetLength; j++) if (source[i + j] !== target[j]) {
				match = false;
				break;
			}
			if (match) return i;
			i++;
		}
		return -1;
	}
	prefixLength(re2) {
		return re2.prefixUTF8.length;
	}
};
var MachineUTF16Input = class extends MachineInputBase {
	constructor(charSequence, start = 0, end = charSequence.length) {
		super();
		this.charSequence = charSequence;
		this.start = start;
		this.end = end;
	}
	hasString(prefilter, pos) {
		const idx = this.charSequence.indexOf(prefilter.str, this.start + pos);
		return idx !== -1 && idx <= this.end - prefilter.str.length;
	}
	hasAnyString(prefilter, pos) {
		if (!prefilter.ac16) return false;
		return prefilter.ac16.searchUTF16(this.charSequence, this.start + pos, this.end);
	}
	step(pos) {
		pos += this.start;
		if (pos >= this.end) return MachineInputBase.EOF();
		const c1 = this.charSequence.charCodeAt(pos);
		if (c1 < Unicode.MIN_HIGH_SURROGATE || c1 > Unicode.MAX_HIGH_SURROGATE || pos + 1 >= this.end) return c1 << 3 | 1;
		const c2 = this.charSequence.charCodeAt(pos + 1);
		if (c2 >= Unicode.MIN_LOW_SURROGATE && c2 <= Unicode.MAX_LOW_SURROGATE) return (c1 - Unicode.MIN_HIGH_SURROGATE) * 1024 + (c2 - Unicode.MIN_LOW_SURROGATE) + Unicode.MIN_SUPPLEMENTARY_CODE_POINT << 3 | 2;
		return c1 << 3 | 1;
	}
	index(re2, pos) {
		pos += this.start;
		const i = this.charSequence.indexOf(re2.prefix, pos);
		if (i < 0 || i > this.end - re2.prefix.length) return -1;
		return i - pos;
	}
	context(pos) {
		pos += this.start;
		const r1 = pos > this.start && pos <= this.end ? this.charSequence.charCodeAt(pos - 1) : -1;
		const r2 = pos < this.end ? this.charSequence.charCodeAt(pos) : -1;
		return Utils.emptyOpContext(r1, r2);
	}
	prefixLength(re2) {
		return re2.prefix.length;
	}
};
var MachineInput = class {
	static fromUTF8(bytes, start = 0, end = bytes.length) {
		return new MachineUTF8Input(bytes, start, end);
	}
	static fromUTF16(charSequence, start = 0, end = charSequence.length) {
		return new MachineUTF16Input(charSequence, start, end);
	}
};
//#endregion
//#region src/exceptions.js
var RE2JSException = class extends Error {
	/** @param {string} message */
	constructor(message) {
		super(message);
		this.name = "RE2JSException";
	}
};
/**
* An exception thrown by the parser if the pattern was invalid.
*/
var RE2JSSyntaxException = class extends RE2JSException {
	/**
	* @param {string} error
	* @param {string|null} [input=null]
	*/
	constructor(error, input = null) {
		let message = `error parsing regexp: ${error}`;
		if (input) message += `: \`${input}\``;
		super(message);
		this.name = "RE2JSSyntaxException";
		this.message = message;
		/** @type {string} */
		this.error = error;
		/** @type {string|null} */
		this.input = input;
	}
	/**
	* Retrieves the description of the error.
	* @returns {string}
	*/
	getDescription() {
		return this.error;
	}
	/**
	* Retrieves the erroneous regular-expression pattern.
	* @returns {string|null}
	*/
	getPattern() {
		return this.input;
	}
};
/**
* An exception thrown by the compiler
*/
var RE2JSCompileException = class extends RE2JSException {
	/** @param {string} message */
	constructor(message) {
		super(message);
		this.name = "RE2JSCompileException";
	}
};
/**
* An exception thrown by using groups
*/
var RE2JSGroupException = class extends RE2JSException {
	/** @param {string} message */
	constructor(message) {
		super(message);
		this.name = "RE2JSGroupException";
	}
};
/**
* An exception thrown by flags
*/
var RE2JSFlagsException = class extends RE2JSException {
	/** @param {string} message */
	constructor(message) {
		super(message);
		this.name = "RE2JSFlagsException";
	}
};
/**
* An exception thrown for internal engine errors, such as corrupted bytecodes.
*/
var RE2JSInternalException = class extends RE2JSException {
	/** @param {string} message */
	constructor(message) {
		super(message);
		this.name = "RE2JSInternalException";
	}
};
//#endregion
//#region src/Matcher.js
/**
* A stateful iterator that interprets a regex {@code RE2JS} on a specific input.
*
* Conceptually, a Matcher consists of four parts:
* <ol>
* <li>A compiled regular expression {@code RE2JS}, set at construction and fixed for the lifetime
* of the matcher.</li>
*
* <li>The remainder of the input string, set at construction or {@link #reset()} and advanced by
* each match operation such as {@link #find}, {@link #matches} or {@link #lookingAt}.</li>
*
* <li>The current match information, accessible via {@link #start}, {@link #end}, and
* {@link #group}, and updated by each match operation.</li>
*
* <li>The append position, used and advanced by {@link #appendReplacement} and {@link #appendTail}
* if performing a search and replace from the input to an external {@code StringBuffer}.
*
* </ol>
*
*
* @author rsc@google.com (Russ Cox)
*/
var Matcher = class Matcher {
	/**
	* V8 and WebKit have historical hard limits on the number of arguments
	* that can be passed to a function. We cap replacer arguments to prevent
	* Call Stack Overflow (DoS) vulnerabilities on massive ASTs.
	*/
	static MAX_REPLACER_ARGS = 65535;
	/**
	* Quotes '\' and '$' in {@code s}, so that the returned string could be used in
	* {@link #appendReplacement} as a literal replacement of {@code s}.
	*
	* @param {string} str the string to be quoted
	* @param {boolean} [javaMode=false] whether the replacement will be used in javaMode
	* @returns {string} the quoted string
	*/
	static quoteReplacement(str, javaMode = false) {
		if (javaMode) {
			if (str.indexOf("\\") < 0 && str.indexOf("$") < 0) return str;
			return str.split("").map((s) => {
				const c = s.codePointAt(0);
				if (c === Codepoint.CODES.get("\\") || c === Codepoint.CODES.get("$")) return `\\${s}`;
				return s;
			}).join("");
		}
		if (str.indexOf("$") < 0) return str;
		return str.split("").map((s) => {
			if (s.codePointAt(0) === Codepoint.CODES.get("$")) return "$$";
			return s;
		}).join("");
	}
	/**
	*
	* @param {import('./index.js').RE2JS} pattern
	* @param {string|number[]|Uint8Array|MatcherInputBase} input
	*/
	constructor(pattern, input) {
		if (pattern === null) throw new Error("pattern is null");
		/**
		* The pattern being matched.
		* @type {import('./index.js').RE2JS}
		*/
		this.patternInput = pattern;
		const re2 = this.patternInput.re2();
		/** @type {number} */
		this.patternGroupCount = re2.numberOfCapturingGroups();
		/** @type {number[]} */
		this.groups = [];
		/** @type {Record<string, number>} */
		this.namedGroups = re2.namedGroups;
		/** @type {number} */
		this.numberOfInstructions = re2.numberOfInstructions();
		if (input instanceof MatcherInputBase) this.resetMatcherInput(input);
		else if (Utils.isByteArray(input)) this.resetMatcherInput(MatcherInput.utf8(input));
		else this.resetMatcherInput(MatcherInput.utf16(input));
	}
	/**
	* Returns the {@code RE2JS} associated with this {@code Matcher}.
	* @returns {import('./index.js').RE2JS}
	*/
	pattern() {
		return this.patternInput;
	}
	/**
	* Resets the {@code Matcher}, rewinding input and discarding any match information.
	*
	* @returns {Matcher} the {@code Matcher} itself, for chained method calls
	*/
	reset() {
		/** @type {number} */
		this.matcherInputLength = this.matcherInput.length();
		/** @type {number} */
		this.appendPos = 0;
		this.hasMatch = false;
		this.hasGroups = false;
		this.anchorFlag = 0;
		return this;
	}
	/**
	* Resets the {@code Matcher} and changes the input.
	* @param {string|number[]|Uint8Array|MatcherInputBase} input
	* @returns {Matcher} the {@code Matcher} itself, for chained method calls
	*/
	resetMatcherInput(input) {
		if (input === null) throw new Error("input is null");
		if (!(input instanceof MatcherInputBase)) if (Utils.isByteArray(input)) input = MatcherInput.utf8(input);
		else input = MatcherInput.utf16(input);
		this.matcherInput = input;
		this.reset();
		return this;
	}
	/**
	* Returns the start of the named group of the most recent match, or -1 if the group was not
	* matched.
	* @param {string|number} [group=0]
	* @returns {number}
	*/
	start(group = 0) {
		if (typeof group === "string") {
			const groupInt = this.namedGroups[group];
			if (!Number.isFinite(groupInt)) throw new RE2JSGroupException(`group '${group}' not found`);
			group = groupInt;
		}
		this.loadGroup(group);
		return this.groups[2 * group];
	}
	/**
	* Returns the end of the named group of the most recent match, or -1 if the group was not
	* matched.
	* @param {string|number} [group=0]
	* @returns {number}
	*/
	end(group = 0) {
		if (typeof group === "string") {
			const groupInt = this.namedGroups[group];
			if (!Number.isFinite(groupInt)) throw new RE2JSGroupException(`group '${group}' not found`);
			group = groupInt;
		}
		this.loadGroup(group);
		return this.groups[2 * group + 1];
	}
	/**
	* Returns the program size of this pattern.
	*
	* <p>
	* Similar to the C++ implementation, the program size is a very approximate measure of a regexp's
	* "cost". Larger numbers are more expensive than smaller numbers.
	* </p>
	*
	* @returns {number} the program size of this pattern
	*/
	programSize() {
		return this.numberOfInstructions;
	}
	/**
	* Returns the named group of the most recent match, or {@code null} if the group was not matched.
	* @param {string|number} [group=0]
	* @returns {string|null}
	*/
	group(group = 0) {
		if (typeof group === "string") {
			const groupInt = this.namedGroups[group];
			if (!Number.isFinite(groupInt)) throw new RE2JSGroupException(`group '${group}' not found`);
			group = groupInt;
		}
		const start = this.start(group);
		const end = this.end(group);
		if (start < 0 && end < 0) return null;
		return this.substring(start, end);
	}
	/**
	* Returns a dictionary map of all named capturing groups and their matched values.
	* If a group was not matched, its value will be `null`.
	* @returns {Record<string, string|null>}
	*/
	getNamedGroups() {
		if (!this.hasMatch) throw new RE2JSGroupException("perhaps no match attempted");
		const result = Object.create(null);
		for (const name of Object.keys(this.namedGroups)) result[name] = this.group(name);
		return result;
	}
	/**
	* Returns the number of subgroups in this pattern.
	*
	* @returns {number} the number of subgroups; the overall match (group 0) does not count
	*/
	groupCount() {
		return this.patternGroupCount;
	}
	/**
	* Helper: finds subgroup information if needed for group.
	* @param {number} group
	* @private
	*/
	loadGroup(group) {
		if (group < 0 || group > this.patternGroupCount) throw new RE2JSGroupException(`Group index out of bounds: ${group}`);
		if (!this.hasMatch) throw new RE2JSGroupException("perhaps no match attempted");
		if (group === 0 || this.hasGroups) return;
		const end = this.matcherInputLength;
		const res = this.patternInput.re2().matchMachineInput(this.matcherInput, this.groups[0], end, this.anchorFlag, 1 + this.patternGroupCount);
		if (!res[0]) throw new RE2JSGroupException("inconsistency in matching group data");
		this.groups = res[1];
		this.hasGroups = true;
	}
	/**
	* Matches the entire input against the pattern (anchored start and end). If there is a match,
	* {@code matches} sets the match state to describe it.
	*
	* @returns {boolean} true if the entire input matches the pattern
	*/
	matches() {
		return this.genMatch(0, RE2Flags.ANCHOR_BOTH);
	}
	/**
	* Matches the beginning of input against the pattern (anchored start). If there is a match,
	* {@code lookingAt} sets the match state to describe it.
	*
	* @returns {boolean} true if the beginning of the input matches the pattern
	*/
	lookingAt() {
		return this.genMatch(0, RE2Flags.ANCHOR_START);
	}
	/**
	* Matches the input against the pattern (unanchored), starting at a specified position. If there
	* is a match, {@code find} sets the match state to describe it.
	*
	* @param {number|null} [start=null] the input position where the search begins
	* @returns {boolean} if it finds a match
	* @throws IndexOutOfBoundsException if start is not a valid input position
	*/
	find(start = null) {
		if (start !== null) {
			if (start < 0 || start > this.matcherInputLength) throw new RE2JSGroupException(`start index out of bounds: ${start}`);
			this.reset();
			return this.genMatch(start, 0);
		}
		start = 0;
		if (this.hasMatch) {
			start = this.groups[1];
			if (this.groups[0] === this.groups[1]) {
				const r = (this.matcherInput.isUTF16Encoding() ? MachineInput.fromUTF16(this.matcherInput.asCharSequence(), 0, this.matcherInputLength) : MachineInput.fromUTF8(this.matcherInput.asBytes(), 0, this.matcherInputLength)).step(start);
				if (r < 0) start++;
				else start += r & 7;
			}
		}
		return this.genMatch(start, RE2Flags.UNANCHORED);
	}
	/**
	* Helper: does match starting at start, with RE2 anchor flag.
	* @param {number} startByte
	* @param {number} anchor
	* @returns {boolean}
	* @private
	*/
	genMatch(startByte, anchor) {
		const res = this.patternInput.re2().matchMachineInput(this.matcherInput, startByte, this.matcherInputLength, anchor, 1);
		if (!res[0]) {
			this.hasMatch = false;
			return false;
		}
		this.groups = res[1];
		this.hasMatch = true;
		this.hasGroups = this.patternGroupCount === 0;
		this.anchorFlag = anchor;
		return true;
	}
	/**
	* Helper: return substring for [start, end).
	* @param {number} start
	* @param {number} end
	* @returns {string}
	*/
	substring(start, end) {
		if (this.matcherInput.isUTF8Encoding()) return Utils.utf8ByteArrayToString(this.matcherInput.asBytes().slice(start, end));
		return this.matcherInput.asCharSequence().substring(start, end).toString();
	}
	/**
	* Helper for Pattern: return input length.
	* @returns {number}
	*/
	inputLength() {
		return this.matcherInputLength;
	}
	/**
	* Appends to result two strings: the text from the append position up to the beginning of the
	* most recent match, and then the replacement with submatch groups substituted for references of
	* the form {@code $n}, where {@code n} is the group number in decimal. It advances the append
	* position to where the most recent match ended.
	*
	* To embed a literal {@code $}, use \$ (actually {@code "\\$"} with string escapes). The escape
	* is only necessary when {@code $} is followed by a digit, but it is always allowed. Only
	* {@code $} and {@code \} need escaping, but any character can be escaped.
	*
	* The group number {@code n} in {@code $n} is always at least one digit and expands to use more
	* digits as long as the resulting number is a valid group number for this pattern. To cut it off
	* earlier, escape the first digit that should not be used.
	*
	* @param {string} replacement the replacement string
	* @param {boolean} [javaMode=false] activate java mode (different behaviour for capture groups and special characters)
	* @returns {string}
	* @throws IllegalStateException if there was no most recent match
	* @throws IndexOutOfBoundsException if replacement refers to an invalid group
	* @private
	*/
	appendReplacement(replacement, javaMode = false) {
		let res = "";
		const s = this.start();
		const e = this.end();
		if (this.appendPos < s) res += this.substring(this.appendPos, s);
		this.appendPos = e;
		res += javaMode ? this.appendReplacementInternalJava(replacement) : this.appendReplacementInternalJs(replacement);
		return res;
	}
	/**
	* @param {string} replacement - the replacement string
	* @returns {string}
	* @private
	*/
	appendReplacementInternalJava(replacement) {
		let res = "";
		let last = 0;
		const m = replacement.length;
		let i = 0;
		while (i < m) {
			const cCode = replacement.codePointAt(i);
			if (cCode === Codepoint.CODES.get("\\")) {
				if (last < i) res += replacement.substring(last, i);
				i++;
				if (i >= m) throw new RE2JSGroupException("character to be escaped is missing");
				last = i;
				i++;
				continue;
			}
			if (cCode === Codepoint.CODES.get("$")) {
				if (last < i) res += replacement.substring(last, i);
				if (i + 1 >= m) throw new RE2JSGroupException("Illegal group reference: group index is missing");
				const nextCode = replacement.codePointAt(i + 1);
				if (Codepoint.CODES.get("0") <= nextCode && nextCode <= Codepoint.CODES.get("9")) {
					let n = nextCode - Codepoint.CODES.get("0");
					let j = i + 2;
					for (; j < m; j++) {
						const digit = replacement.codePointAt(j);
						if (digit < Codepoint.CODES.get("0") || digit > Codepoint.CODES.get("9") || n * 10 + digit - Codepoint.CODES.get("0") > this.patternGroupCount) break;
						n = n * 10 + digit - Codepoint.CODES.get("0");
					}
					if (n > this.patternGroupCount) throw new RE2JSGroupException(`n > number of groups: ${n}`);
					const group = this.group(n);
					if (group !== null) res += group;
					i = j;
					last = i;
				} else if (nextCode === Codepoint.CODES.get("{")) {
					let j = i + 2;
					while (j < m && replacement.codePointAt(j) !== Codepoint.CODES.get("}")) j++;
					if (j >= m) throw new RE2JSGroupException("named capture group is missing trailing '}'");
					const groupName = replacement.substring(i + 2, j);
					const groupVal = this.group(groupName);
					if (groupVal !== null) res += groupVal;
					i = j + 1;
					last = i;
				} else throw new RE2JSGroupException("Illegal group reference");
				continue;
			}
			i++;
		}
		if (last < m) res += replacement.substring(last, m);
		return res;
	}
	/**
	* @param {string} replacement - the replacement string
	* @returns {string}
	* @private
	*/
	appendReplacementInternalJs(replacement) {
		let res = "";
		let last = 0;
		const m = replacement.length;
		for (let i = 0; i < m - 1; i++) if (replacement.codePointAt(i) === Codepoint.CODES.get("$")) {
			let c = replacement.codePointAt(i + 1);
			if (Codepoint.CODES.get("$") === c) {
				if (last < i) res += replacement.substring(last, i);
				res += "$";
				i++;
				last = i + 1;
				continue;
			} else if (Codepoint.CODES.get("&") === c) {
				if (last < i) res += replacement.substring(last, i);
				const group = this.group(0);
				if (group !== null) res += group;
				else res += "$&";
				i++;
				last = i + 1;
				continue;
			} else if (Codepoint.CODES.get("`") === c) {
				if (last < i) res += replacement.substring(last, i);
				res += this.substring(0, this.start(0));
				i++;
				last = i + 1;
				continue;
			} else if (Codepoint.CODES.get("'") === c) {
				if (last < i) res += replacement.substring(last, i);
				res += this.substring(this.end(0), this.matcherInputLength);
				i++;
				last = i + 1;
				continue;
			} else if (Codepoint.CODES.get("1") <= c && c <= Codepoint.CODES.get("9")) {
				let n = c - Codepoint.CODES.get("0");
				if (last < i) res += replacement.substring(last, i);
				for (i += 2; i < m; i++) {
					c = replacement.codePointAt(i);
					if (c < Codepoint.CODES.get("0") || c > Codepoint.CODES.get("9") || n * 10 + c - Codepoint.CODES.get("0") > this.patternGroupCount) break;
					n = n * 10 + c - Codepoint.CODES.get("0");
				}
				if (n > this.patternGroupCount) {
					res += `$${n}`;
					last = i;
					i--;
					continue;
				}
				const group = this.group(n);
				if (group !== null) res += group;
				last = i;
				i--;
				continue;
			} else if (c === Codepoint.CODES.get("<")) {
				if (last < i) res += replacement.substring(last, i);
				i++;
				let j = i + 1;
				while (j < replacement.length && replacement.codePointAt(j) !== Codepoint.CODES.get(">") && replacement.codePointAt(j) !== Codepoint.CODES.get(" ")) j++;
				if (j === replacement.length || replacement.codePointAt(j) !== Codepoint.CODES.get(">")) {
					res += replacement.substring(i - 1, j + 1);
					last = j + 1;
					i = j;
					continue;
				}
				const groupName = replacement.substring(i + 1, j);
				if (Object.prototype.hasOwnProperty.call(this.namedGroups, groupName)) {
					const groupVal = this.group(groupName);
					if (groupVal !== null) res += groupVal;
				} else res += `$<${groupName}>`;
				last = j + 1;
				i = j;
				continue;
			}
		}
		if (last < m) res += replacement.substring(last, m);
		return res;
	}
	/**
	* Return the substring of the input from the append position to the end of the
	* input.
	* @returns {string}
	*/
	appendTail() {
		return this.substring(this.appendPos, this.matcherInputLength);
	}
	/**
	* Returns the input with all matches replaced by {@code replacement}, interpreted as for
	* {@code appendReplacement}.
	*
	* @param {string|((...args: any[]) => string)} replacement - the replacement string or a replacer function
	* @param {boolean} [javaMode=false] - activate java mode (different behaviour for capture groups and special characters)
	* @returns {string} the input string with the matches replaced
	* @throws IndexOutOfBoundsException if replacement refers to an invalid group and javaMode is true
	*/
	replaceAll(replacement, javaMode = false) {
		return this.replace(replacement, true, javaMode);
	}
	/**
	* Returns the input with the first match replaced by {@code replacement}, interpreted as for
	* {@code appendReplacement}.
	*
	* @param {string|((...args: any[]) => string)} replacement - the replacement string or a replacer function
	* @param {boolean} [javaMode=false] - activate java mode (different behaviour for capture groups and special characters)
	* @returns {string} the input string with the first match replaced
	* @throws IndexOutOfBoundsException if replacement refers to an invalid group and javaMode is true
	*/
	replaceFirst(replacement, javaMode = false) {
		return this.replace(replacement, false, javaMode);
	}
	/**
	* Helper: replaceAll/replaceFirst hybrid.
	* @param {string|((...args: any[]) => string)} replacement - the replacement string or a replacer function
	* @param {boolean} [all=true] - replace all matches
	* @param {boolean} [javaMode=false] - activate java mode (different behaviour for capture groups and special characters)
	* @returns {string}
	* @private
	*/
	replace(replacement, all = true, javaMode = false) {
		let res = "";
		this.reset();
		const isFunc = typeof replacement === "function";
		const hasNamedGroups = Object.keys(this.namedGroups).length > 0;
		let originalInput = null;
		if (isFunc) {
			if (this.groupCount() >= Matcher.MAX_REPLACER_ARGS) throw new RE2JSGroupException("Too many capture groups to safely invoke replacer function");
			originalInput = this.matcherInput.isUTF8Encoding() ? this.matcherInput.asBytes() : this.matcherInput.asCharSequence();
		}
		while (this.find()) {
			res += isFunc ? this.appendReplacementFunc(replacement, hasNamedGroups, originalInput) : this.appendReplacement(replacement, javaMode);
			if (!all) break;
		}
		res += this.appendTail();
		return res;
	}
	/**
	* Evaluates a replacer function for the current match and appends the result,
	* along with any un-matched preceding text, advancing the append position.
	* @param {Function} replacer - the replacer function
	* @param {boolean} hasNamedGroups - cached flag if pattern has named groups
	* @param {string|Uint8Array|number[]} originalInput - the cached original input reference
	* @returns {string} the evaluated string to append
	* @private
	*/
	appendReplacementFunc(replacer, hasNamedGroups, originalInput) {
		let res = "";
		const s = this.start();
		const e = this.end();
		if (this.appendPos < s) res += this.substring(this.appendPos, s);
		this.appendPos = e;
		const args = this.buildReplacerArgs(s, hasNamedGroups, originalInput);
		res += String(replacer(...args));
		return res;
	}
	/**
	* Builds the argument array for the replacer function matching the standard
	* JS String.prototype.replace(regex, replacer) signature.
	* @param {number} matchStart - the start index of the match
	* @param {boolean} hasNamedGroups - cached flag if pattern has named groups
	* @param {string|Uint8Array|number[]} originalInput - the cached original input reference
	* @returns {Array} array of arguments
	* @private
	*/
	buildReplacerArgs(matchStart, hasNamedGroups, originalInput) {
		const args = [this.group(0)];
		const numGroups = this.groupCount();
		for (let i = 1; i <= numGroups; i++) {
			const start = this.start(i);
			if (start < 0) args.push(void 0);
			else args.push(this.substring(start, this.end(i)));
		}
		args.push(matchStart);
		args.push(originalInput);
		if (hasNamedGroups) {
			const parsedGroups = this.getNamedGroups();
			for (const key in parsedGroups) if (parsedGroups[key] === null) parsedGroups[key] = void 0;
			args.push(parsedGroups);
		}
		return args;
	}
};
//#endregion
//#region src/Inst.js
/**
* A single instruction in the regular expression virtual machine.
*
* @see http://swtch.com/~rsc/regexp/regexp2.html
*/
var Inst = class Inst {
	static ALT = 1;
	static ALT_MATCH = 2;
	static CAPTURE = 3;
	static EMPTY_WIDTH = 4;
	static FAIL = 5;
	static MATCH = 6;
	static NOP = 7;
	static RUNE = 8;
	static RUNE1 = 9;
	static RUNE_ANY = 10;
	static RUNE_ANY_NOT_NL = 11;
	static LB_WRITE = 12;
	static LB_CHECK = 13;
	static isRuneOp(op) {
		return Inst.RUNE <= op && op <= Inst.RUNE_ANY_NOT_NL;
	}
	static escapeRunes(runes) {
		let out = "\"";
		for (let rune of runes) out += Utils.escapeRune(rune);
		out += "\"";
		return out;
	}
	constructor(op) {
		this.op = op;
		this.out = 0;
		this.arg = 0;
		this.runes = [];
		/** @type {Uint32Array | number[] | null} */
		this.next = null;
	}
	matchRune(r) {
		if (this.runes.length === 1) {
			const r0 = this.runes[0];
			if ((this.arg & RE2Flags.FOLD_CASE) !== 0) return Unicode.equalsIgnoreCase(r0, r);
			return r === r0;
		}
		const len = this.runes.length;
		if (len === 0) return false;
		if (len === 2 || len === 4 || len === 6 || len === 8) {
			for (let j = 0; j < len; j += 2) {
				if (r < this.runes[j]) return false;
				if (r <= this.runes[j + 1]) return true;
			}
			return false;
		}
		let base = 0;
		let n = len >> 1;
		while (n > 1) {
			const half = n >> 1;
			base += this.runes[base + half << 1] <= r ? half : 0;
			n -= half;
		}
		base += this.runes[base << 1] <= r ? 1 : 0;
		const m = base - 1;
		return m >= 0 && r <= this.runes[m << 1 | 1];
	}
	matchRunePos(r) {
		if (this.runes.length === 1) {
			const r0 = this.runes[0];
			if ((this.arg & RE2Flags.FOLD_CASE) !== 0) return Unicode.equalsIgnoreCase(r0, r) ? 0 : -1;
			return r === r0 ? 0 : -1;
		}
		const len = this.runes.length;
		if (len === 0) return -1;
		if (len === 2 || len === 4 || len === 6 || len === 8) {
			for (let j = 0; j < len; j += 2) {
				if (r < this.runes[j]) return -1;
				if (r <= this.runes[j + 1]) return Math.floor(j / 2);
			}
			return -1;
		}
		let base = 0;
		let n = len >> 1;
		while (n > 1) {
			const half = n >> 1;
			base += this.runes[base + half << 1] <= r ? half : 0;
			n -= half;
		}
		base += this.runes[base << 1] <= r ? 1 : 0;
		const m = base - 1;
		return m >= 0 && r <= this.runes[m << 1 | 1] ? m : -1;
	}
	/**
	*
	* @returns {string}
	*/
	toString() {
		switch (this.op) {
			case Inst.ALT: return `alt -> ${this.out}, ${this.arg}`;
			case Inst.ALT_MATCH: return `altmatch -> ${this.out}, ${this.arg}`;
			case Inst.CAPTURE: return `cap ${this.arg} -> ${this.out}`;
			case Inst.EMPTY_WIDTH: return `empty ${this.arg} -> ${this.out}`;
			case Inst.MATCH: return `match${this.arg !== 0 ? ` ${this.arg}` : ""}`;
			case Inst.FAIL: return "fail";
			case Inst.NOP: return `nop -> ${this.out}`;
			case Inst.LB_WRITE: return `lbwrite ${this.arg} -> ${this.out}`;
			case Inst.LB_CHECK: return `lbcheck ${this.arg} -> ${this.out}`;
			case Inst.RUNE:
				if (this.runes === null) return "rune <null>";
				return [
					"rune ",
					Inst.escapeRunes(this.runes),
					(this.arg & RE2Flags.FOLD_CASE) !== 0 ? "/i" : "",
					" -> ",
					this.out
				].join("");
			case Inst.RUNE1: return `rune1 ${Inst.escapeRunes(this.runes)} -> ${this.out}`;
			case Inst.RUNE_ANY: return `any -> ${this.out}`;
			case Inst.RUNE_ANY_NOT_NL: return `anynotnl -> ${this.out}`;
			default: throw new Error("unhandled case in Inst.toString");
		}
	}
};
//#endregion
//#region src/Machine.js
var Queue = class {
	constructor(numInst) {
		this.sparse = new Int32Array(numInst);
		this.densePcs = new Int32Array(numInst);
		this.denseCaps = null;
		this.size = 0;
		this.ncap = 0;
	}
	init(ncap) {
		this.ncap = ncap;
		const needed = this.densePcs.length * ncap;
		if (!this.denseCaps || this.denseCaps.length < needed) this.denseCaps = new Int32Array(needed);
	}
	contains(pc) {
		const j = this.sparse[pc];
		return j < this.size && this.densePcs[j] === pc;
	}
	isEmpty() {
		return this.size === 0;
	}
	add(pc) {
		const j = this.size++;
		this.sparse[pc] = j;
		this.densePcs[j] = pc;
		return j;
	}
	clear() {
		this.size = 0;
	}
	toString() {
		let out = "{";
		for (let i = 0; i < this.size; i++) {
			if (i !== 0) out += ", ";
			out += this.densePcs[i];
		}
		out += "}";
		return out;
	}
};
var Machine = class Machine {
	static fromRE2(re2) {
		const m = new Machine();
		m.prog = re2.prog;
		m.re2 = re2;
		m.q0 = new Queue(m.prog.numInst());
		m.q1 = new Queue(m.prog.numInst());
		m.matched = false;
		m.matchcap = new Int32Array(m.prog.numCap < 2 ? 2 : m.prog.numCap);
		m.ncap = 0;
		return m;
	}
	static fromMachine(machine) {
		return Machine.fromRE2(machine.re2);
	}
	constructor() {
		this.prog = null;
		this.re2 = null;
		this.q0 = null;
		this.q1 = null;
		this.matched = false;
		this.matchcap = null;
		this.ncap = 0;
		this.lbTable = null;
	}
	init(ncap) {
		this.ncap = ncap;
		if (ncap > this.matchcap.length) this.matchcap = new Int32Array(ncap).fill(-1);
		else this.matchcap.fill(-1);
		this.q0.init(ncap);
		this.q1.init(ncap);
		if (this.prog.numLb > 0) {
			if (!this.lbTable || this.lbTable.length < this.prog.numLb + 1) this.lbTable = new Int32Array(this.prog.numLb + 1);
			this.lbTable.fill(-1);
		}
	}
	submatches() {
		if (this.ncap === 0) return Utils.emptyInts();
		return Utils.toArray(this.matchcap.subarray(0, this.ncap));
	}
	match(input, pos, anchor) {
		const startCond = this.re2.cond;
		if (startCond === Utils.EMPTY_ALL) return false;
		if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && pos !== 0) return false;
		this.matched = false;
		this.matchcap.fill(-1);
		let currentPos = this.prog.numLb > 0 ? 0 : pos;
		let matchStartPos = pos;
		let runq = this.q0;
		let nextq = this.q1;
		let r = input.step(currentPos);
		let rune = r >> 3;
		let width = r & 7;
		let rune1 = -1;
		let width1 = 0;
		if (r !== MachineInputBase.EOF()) {
			r = input.step(currentPos + width);
			rune1 = r >> 3;
			width1 = r & 7;
		}
		let flag;
		if (currentPos === 0) flag = Utils.emptyOpContext(-1, rune);
		else flag = input.context(currentPos);
		while (true) {
			if (runq.isEmpty()) {
				if ((startCond & Utils.EMPTY_BEGIN_TEXT) !== 0 && currentPos !== 0) break;
				if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && currentPos !== 0) break;
				if (this.matched) break;
				if (this.prog.numLb === 0 && !(this.re2.prefix.length === 0) && rune1 !== this.re2.prefixRune && input.canCheckPrefix()) {
					const advance = input.index(this.re2, currentPos);
					if (advance < 0) break;
					currentPos += advance;
					r = input.step(currentPos);
					rune = r >> 3;
					width = r & 7;
					r = input.step(currentPos + width);
					rune1 = r >> 3;
					width1 = r & 7;
					flag = input.context(currentPos);
				}
			}
			if (currentPos === 0 && this.prog.numLb > 0) for (let i = 0; i < this.prog.lbStarts.length; i++) this.add(runq, this.prog.lbStarts[i], currentPos, this.matchcap, 0, flag);
			if (!this.matched && (currentPos === 0 || anchor === RE2Flags.UNANCHORED)) {
				if (currentPos >= matchStartPos) {
					if (this.ncap > 0) this.matchcap[0] = currentPos;
					this.add(runq, this.prog.start, currentPos, this.matchcap, 0, flag);
				}
			}
			const nextPos = currentPos + width;
			flag = input.context(nextPos);
			this.step(runq, nextq, currentPos, nextPos, rune, flag, anchor, currentPos === input.endPos());
			if (width === 0) break;
			if (this.ncap === 0 && this.matched) break;
			currentPos += width;
			rune = rune1;
			width = width1;
			if (rune !== -1) {
				r = input.step(currentPos + width);
				rune1 = r >> 3;
				width1 = r & 7;
			}
			const tmpq = runq;
			runq = nextq;
			nextq = tmpq;
		}
		nextq.clear();
		return this.matched;
	}
	matchSet(input, pos, anchor) {
		const startCond = this.re2.cond;
		if (startCond === Utils.EMPTY_ALL) return [];
		if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && pos !== 0) return [];
		let currentPos = this.prog.numLb > 0 ? 0 : pos;
		let matchStartPos = pos;
		let runq = this.q0;
		let nextq = this.q1;
		let r = input.step(currentPos);
		let rune = r >> 3;
		let width = r & 7;
		let rune1 = -1;
		let width1 = 0;
		if (r !== MachineInputBase.EOF()) {
			r = input.step(currentPos + width);
			rune1 = r >> 3;
			width1 = r & 7;
		}
		let flag = currentPos === 0 ? Utils.emptyOpContext(-1, rune) : input.context(currentPos);
		const matches = /* @__PURE__ */ new Set();
		while (true) {
			if (runq.isEmpty()) {
				if ((startCond & Utils.EMPTY_BEGIN_TEXT) !== 0 && currentPos !== 0) break;
				if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && currentPos !== 0) break;
			}
			if (currentPos === 0 && this.prog.numLb > 0) for (let i = 0; i < this.prog.lbStarts.length; i++) this.add(runq, this.prog.lbStarts[i], currentPos, this.matchcap, 0, flag);
			if (currentPos === 0 || anchor === RE2Flags.UNANCHORED) {
				if (currentPos >= matchStartPos) this.add(runq, this.prog.start, currentPos, this.matchcap, 0, flag);
			}
			const nextPos = currentPos + width;
			flag = input.context(nextPos);
			for (let j = 0; j < runq.size; j++) {
				const pc = runq.densePcs[j];
				const i = this.prog.inst[pc];
				const capOffset = j * this.ncap;
				let add = false;
				switch (i.op) {
					case Inst.MATCH:
						if (anchor === RE2Flags.ANCHOR_BOTH && currentPos !== input.endPos()) break;
						matches.add(i.arg);
						break;
					case Inst.RUNE:
						add = i.matchRune(rune);
						break;
					case Inst.RUNE1:
						add = rune === i.runes[0];
						break;
					case Inst.RUNE_ANY:
						add = true;
						break;
					case Inst.RUNE_ANY_NOT_NL:
						add = rune !== 10;
						break;
					default: continue;
				}
				if (add) this.add(nextq, i.out, nextPos, runq.denseCaps, capOffset, flag);
			}
			runq.clear();
			if (width === 0) break;
			currentPos += width;
			rune = rune1;
			width = width1;
			if (rune !== -1) {
				r = input.step(currentPos + width);
				rune1 = r >> 3;
				width1 = r & 7;
			}
			const tmpq = runq;
			runq = nextq;
			nextq = tmpq;
		}
		nextq.clear();
		return Array.from(matches).sort((a, b) => a - b);
	}
	step(runq, nextq, pos, nextPos, c, nextCond, anchor, atEnd) {
		const longest = this.re2.longest;
		for (let j = 0; j < runq.size; j++) {
			const pc = runq.densePcs[j];
			const capOffset = j * this.ncap;
			if (longest && this.matched && this.ncap > 0 && this.matchcap[0] < runq.denseCaps[capOffset]) continue;
			const i = this.prog.inst[pc];
			let add = false;
			switch (i.op) {
				case Inst.MATCH:
					if (anchor === RE2Flags.ANCHOR_BOTH && !atEnd) break;
					if (this.ncap > 0 && (!longest || !this.matched || this.matchcap[1] < pos)) {
						runq.denseCaps[capOffset + 1] = pos;
						for (let k = 0; k < this.ncap; k++) this.matchcap[k] = runq.denseCaps[capOffset + k];
					}
					if (!longest) runq.size = 0;
					this.matched = true;
					break;
				case Inst.RUNE:
					add = i.matchRune(c);
					break;
				case Inst.RUNE1:
					add = c === i.runes[0];
					break;
				case Inst.RUNE_ANY:
					add = true;
					break;
				case Inst.RUNE_ANY_NOT_NL:
					add = c !== 10;
					break;
				default: continue;
			}
			if (add) this.add(nextq, i.out, nextPos, runq.denseCaps, capOffset, nextCond);
		}
		runq.clear();
	}
	add(q, pc, pos, capArray, capOffset, cond) {
		while (true) {
			if (pc === 0) return;
			if (q.contains(pc)) return;
			const d = q.add(pc);
			const inst = this.prog.inst[pc];
			switch (inst.op) {
				case Inst.FAIL: return;
				case Inst.ALT:
				case Inst.ALT_MATCH:
					this.add(q, inst.out, pos, capArray, capOffset, cond);
					pc = inst.arg;
					continue;
				case Inst.EMPTY_WIDTH:
					if ((inst.arg & ~cond) === 0) {
						pc = inst.out;
						continue;
					}
					return;
				case Inst.NOP:
					pc = inst.out;
					continue;
				case Inst.CAPTURE: if (inst.arg < this.ncap) {
					const opos = capArray[capOffset + inst.arg];
					capArray[capOffset + inst.arg] = pos;
					this.add(q, inst.out, pos, capArray, capOffset, cond);
					capArray[capOffset + inst.arg] = opos;
					return;
				} else {
					pc = inst.out;
					continue;
				}
				case Inst.LB_WRITE:
					this.lbTable[Math.abs(inst.arg)] = pos;
					pc = inst.out;
					continue;
				case Inst.LB_CHECK:
					if (inst.arg > 0) {
						if (this.lbTable[inst.arg] === pos) {
							pc = inst.out;
							continue;
						}
					} else if (this.lbTable[-inst.arg] !== pos) {
						pc = inst.out;
						continue;
					}
					return;
				case Inst.MATCH:
				case Inst.RUNE:
				case Inst.RUNE1:
				case Inst.RUNE_ANY:
				case Inst.RUNE_ANY_NOT_NL:
					if (this.ncap > 0) {
						const destOffset = d * this.ncap;
						for (let c = 0; c < this.ncap; c++) q.denseCaps[destOffset + c] = capArray[capOffset + c];
					}
					return;
				default: throw new RE2JSInternalException("unhandled");
			}
		}
	}
};
//#endregion
//#region src/DFA.js
const hashPCs = (pcs) => {
	let h = -2128831035;
	for (let i = 0; i < pcs.length; i++) {
		h ^= pcs[i];
		h = Math.imul(h, 16777619);
	}
	return h;
};
const arraysEqual = (a, b) => {
	if (a.length !== b.length) return false;
	for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
	return true;
};
var DFAState = class {
	constructor(nfaStates, isMatch, matchIDs = []) {
		this.nfaStates = nfaStates;
		this.isMatch = isMatch;
		this.matchIDs = matchIDs;
		this.nextLatin1 = new Array(Unicode.MAX_LATIN1 + 1).fill(null);
		this.nextLatin1Anchored = new Array(Unicode.MAX_LATIN1 + 1).fill(null);
		this.transKeys = [];
		this.transVals = [];
		this.lastSeen = 0;
	}
};
var DFA = class DFA {
	static MAX_CACHE_CLEARS = 5;
	static STATE_MEMORY_ESTIMATE = 838;
	constructor(prog, maxMem = 8388608) {
		this.prog = prog;
		this.stateCache = /* @__PURE__ */ new Map();
		this.stateCount = 0;
		this.startState = null;
		this.stateLimit = Math.max(1, Math.floor(maxMem / DFA.STATE_MEMORY_ESTIMATE));
		this.cacheClears = 0;
		this.failed = false;
		this.clock = 0;
	}
	computeClosure(pcs) {
		const closure = /* @__PURE__ */ new Set();
		const stack = [...pcs];
		let isMatch = false;
		const matchIDs = [];
		while (stack.length > 0) {
			const pc = stack.pop();
			if (closure.has(pc)) continue;
			closure.add(pc);
			const inst = this.prog.getInst(pc);
			switch (inst.op) {
				case Inst.MATCH:
					isMatch = true;
					if (!matchIDs.includes(inst.arg)) matchIDs.push(inst.arg);
					break;
				case Inst.ALT:
				case Inst.ALT_MATCH:
					stack.push(inst.out);
					stack.push(inst.arg);
					break;
				case Inst.NOP:
				case Inst.CAPTURE:
					stack.push(inst.out);
					break;
				case Inst.EMPTY_WIDTH:
				case Inst.LB_WRITE:
				case Inst.LB_CHECK: return null;
			}
		}
		const sortedPCs = Int32Array.from(closure).sort();
		matchIDs.sort((a, b) => a - b);
		return {
			pcs: sortedPCs,
			isMatch,
			matchIDs
		};
	}
	getState(pcs) {
		const closureResult = this.computeClosure(pcs);
		if (!closureResult) return null;
		const sortedPCs = closureResult.pcs;
		const hash = hashPCs(sortedPCs);
		let bucket = this.stateCache.get(hash);
		if (bucket) for (let i = 0; i < bucket.length; i++) {
			const state = bucket[i];
			if (arraysEqual(state.nfaStates, sortedPCs)) {
				state.lastSeen = ++this.clock;
				return state;
			}
		}
		else {
			bucket = [];
			this.stateCache.set(hash, bucket);
		}
		if (this.failed) return null;
		if (this.stateCount >= this.stateLimit) {
			this.cacheClears++;
			if (this.cacheClears >= DFA.MAX_CACHE_CLEARS) {
				this.failed = true;
				this.stateCache.clear();
				this.stateCount = 0;
				this.startState = null;
				return null;
			}
			this.evictCache();
			bucket = this.stateCache.get(hash);
			if (!bucket) {
				bucket = [];
				this.stateCache.set(hash, bucket);
			}
		}
		const state = new DFAState(sortedPCs, closureResult.isMatch, closureResult.matchIDs);
		state.lastSeen = ++this.clock;
		bucket.push(state);
		this.stateCount++;
		return state;
	}
	evictCache() {
		const allStates = [];
		for (const bucket of this.stateCache.values()) for (let i = 0; i < bucket.length; i++) allStates.push(bucket[i]);
		allStates.sort((a, b) => a.lastSeen - b.lastSeen);
		const keepCount = Math.max(1, Math.floor(this.stateLimit / 2));
		const startIndex = allStates.length - keepCount;
		const survivorsArray = allStates.slice(startIndex);
		const survivors = new Set(survivorsArray);
		this.stateCache.clear();
		this.stateCount = 0;
		for (let i = 0; i < survivorsArray.length; i++) {
			const state = survivorsArray[i];
			state.nextLatin1.fill(null);
			state.nextLatin1Anchored.fill(null);
			state.transKeys.length = 0;
			state.transVals.length = 0;
			const hash = hashPCs(state.nfaStates);
			let bucket = this.stateCache.get(hash);
			if (!bucket) {
				bucket = [];
				this.stateCache.set(hash, bucket);
			}
			bucket.push(state);
			this.stateCount++;
		}
		if (this.startState && !survivors.has(this.startState)) this.startState = null;
	}
	step(state, charCode, anchor) {
		if (charCode <= Unicode.MAX_LATIN1) if (anchor === RE2Flags.UNANCHORED) {
			const next = state.nextLatin1[charCode];
			if (next !== null) return next;
		} else {
			const next = state.nextLatin1Anchored[charCode];
			if (next !== null) return next;
		}
		else {
			const key = charCode + (anchor === RE2Flags.UNANCHORED ? 0 : Unicode.MAX_RUNE + 1);
			const keys = state.transKeys;
			const len = keys.length;
			for (let i = 0; i < len; i++) if (keys[i] === key) return state.transVals[i];
		}
		const nextPCs = [];
		for (let i = 0; i < state.nfaStates.length; i++) {
			const pc = state.nfaStates[i];
			const inst = this.prog.getInst(pc);
			if (Inst.isRuneOp(inst.op) && inst.matchRune(charCode)) nextPCs.push(inst.out);
		}
		if (anchor === RE2Flags.UNANCHORED) nextPCs.push(this.prog.start);
		const nextState = this.getState(nextPCs);
		if (charCode <= Unicode.MAX_LATIN1) if (anchor === RE2Flags.UNANCHORED) state.nextLatin1[charCode] = nextState;
		else state.nextLatin1Anchored[charCode] = nextState;
		else {
			const key = charCode + (anchor === RE2Flags.UNANCHORED ? 0 : Unicode.MAX_RUNE + 1);
			state.transKeys.push(key);
			state.transVals.push(nextState);
		}
		return nextState;
	}
	match(input, pos, anchor) {
		if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && pos !== 0) return false;
		if (!this.startState) {
			this.startState = this.getState([this.prog.start]);
			if (!this.startState) return null;
		}
		let endPos = input.endPos();
		let currentState = this.startState;
		if (currentState.isMatch) if (anchor === RE2Flags.ANCHOR_BOTH) {
			if (pos === endPos) return true;
		} else return true;
		let i = pos;
		while (i < endPos) {
			const r = input.step(i);
			const rune = r >> 3;
			const width = r & 7;
			if (width === 0) break;
			currentState = anchor === RE2Flags.UNANCHORED && rune <= Unicode.MAX_LATIN1 && currentState.nextLatin1[rune] || this.step(currentState, rune, anchor);
			if (currentState === null) return null;
			currentState.lastSeen = ++this.clock;
			if (currentState.isMatch) if (anchor === RE2Flags.ANCHOR_BOTH) {
				if (i + width === endPos) return true;
			} else return true;
			if (currentState.nfaStates.length === 0) {
				if (anchor !== RE2Flags.UNANCHORED) return false;
			}
			i += width;
		}
		return false;
	}
	matchSet(input, pos, anchor) {
		if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && pos !== 0) return [];
		if (!this.startState) {
			this.startState = this.getState([this.prog.start]);
			if (!this.startState) return null;
		}
		let endPos = input.endPos();
		let currentState = this.startState;
		const matches = /* @__PURE__ */ new Set();
		const checkMatch = (state, currentPos) => {
			if (state.isMatch) if (anchor === RE2Flags.ANCHOR_BOTH) {
				if (currentPos === endPos) state.matchIDs.forEach((id) => matches.add(id));
			} else state.matchIDs.forEach((id) => matches.add(id));
		};
		checkMatch(currentState, pos);
		let i = pos;
		while (i < endPos) {
			const r = input.step(i);
			const rune = r >> 3;
			const width = r & 7;
			if (width === 0) break;
			currentState = anchor === RE2Flags.UNANCHORED && rune <= Unicode.MAX_LATIN1 && currentState.nextLatin1[rune] || this.step(currentState, rune, anchor);
			if (currentState === null) return null;
			currentState.lastSeen = ++this.clock;
			i += width;
			checkMatch(currentState, i);
			if (currentState.nfaStates.length === 0) {
				if (anchor !== RE2Flags.UNANCHORED) break;
			}
		}
		return Array.from(matches).sort((a, b) => a - b);
	}
};
//#endregion
//#region src/Backtracker.js
const VISITED_BITS = 32;
const MAX_BACKTRACK_PROG = 500;
const INITIAL_JOB_CAPACITY = 256;
const MAX_BACKTRACK_VECTOR = 256 * 1024;
var BitState = class {
	constructor() {
		this.end = 0;
		this.cap = /* @__PURE__ */ new Int32Array(0);
		this.matchcap = /* @__PURE__ */ new Int32Array(0);
		this.ncap = 0;
		this.jobPc = new Int32Array(INITIAL_JOB_CAPACITY);
		this.jobArg = new Uint8Array(INITIAL_JOB_CAPACITY);
		this.jobPos = new Int32Array(INITIAL_JOB_CAPACITY);
		this.jobLen = 0;
		this.visited = /* @__PURE__ */ new Uint32Array(0);
	}
	reset(prog, end, ncap) {
		this.end = end;
		this.jobLen = 0;
		this.ncap = ncap;
		const visitedSize = prog.numInst() * (end + 1) + VISITED_BITS - 1 >>> 5;
		if (this.visited.length < visitedSize) this.visited = new Uint32Array(visitedSize);
		else this.visited.fill(0, 0, visitedSize);
		if (this.cap.length < ncap) this.cap = new Int32Array(ncap).fill(-1);
		else this.cap.fill(-1, 0, ncap);
		if (this.matchcap.length < ncap) this.matchcap = new Int32Array(ncap).fill(-1);
		else this.matchcap.fill(-1, 0, ncap);
	}
	shouldVisit(pc, pos) {
		const n = pc * (this.end + 1) + pos;
		const idx = n >>> 5;
		const mask = 1 << (n & 31);
		if ((this.visited[idx] & mask) !== 0) return false;
		this.visited[idx] |= mask;
		return true;
	}
	push(re2, pc, pos, arg) {
		if (re2.prog.getInst(pc).op !== Inst.FAIL && (arg || this.shouldVisit(pc, pos))) {
			if (this.jobLen >= this.jobPc.length) {
				const newSize = this.jobPc.length * 2;
				const newPc = new Int32Array(newSize);
				newPc.set(this.jobPc);
				this.jobPc = newPc;
				const newArg = new Uint8Array(newSize);
				newArg.set(this.jobArg);
				this.jobArg = newArg;
				const newPos = new Int32Array(newSize);
				newPos.set(this.jobPos);
				this.jobPos = newPos;
			}
			this.jobPc[this.jobLen] = pc;
			this.jobArg[this.jobLen] = arg ? 1 : 0;
			this.jobPos[this.jobLen] = pos;
			this.jobLen++;
		}
	}
	tryBacktrack(re2, input, pc, pos, anchor) {
		const longest = re2.longest;
		this.push(re2, pc, pos, false);
		while (this.jobLen > 0) {
			this.jobLen--;
			let currentPc = this.jobPc[this.jobLen];
			let arg = this.jobArg[this.jobLen] === 1;
			let currentPos = this.jobPos[this.jobLen];
			let skipShouldVisit = true;
			while (true) {
				if (!skipShouldVisit) {
					if (!this.shouldVisit(currentPc, currentPos)) break;
				}
				skipShouldVisit = false;
				const inst = re2.prog.getInst(currentPc);
				switch (inst.op) {
					case Inst.FAIL: throw new RE2JSInternalException("unexpected InstFail");
					case Inst.ALT: if (arg) {
						arg = false;
						currentPc = inst.arg;
						continue;
					} else {
						this.push(re2, currentPc, currentPos, true);
						currentPc = inst.out;
						continue;
					}
					case Inst.ALT_MATCH: {
						const outInst = re2.prog.getInst(inst.out);
						if (Inst.isRuneOp(outInst.op)) {
							this.push(re2, inst.arg, currentPos, false);
							currentPc = inst.arg;
							currentPos = this.end;
							continue;
						}
						this.push(re2, inst.out, this.end, false);
						currentPc = inst.out;
						continue;
					}
					case Inst.RUNE: {
						const r = input.step(currentPos);
						if (r === MachineInputBase.EOF()) break;
						if (!inst.matchRune(r >> 3)) break;
						currentPos += r & 7;
						currentPc = inst.out;
						continue;
					}
					case Inst.RUNE1: {
						const r = input.step(currentPos);
						if (r === MachineInputBase.EOF()) break;
						if (r >> 3 !== inst.runes[0]) break;
						currentPos += r & 7;
						currentPc = inst.out;
						continue;
					}
					case Inst.RUNE_ANY_NOT_NL: {
						const r = input.step(currentPos);
						if (r === MachineInputBase.EOF()) break;
						if (r >> 3 === 10) break;
						currentPos += r & 7;
						currentPc = inst.out;
						continue;
					}
					case Inst.RUNE_ANY: {
						const r = input.step(currentPos);
						if (r === MachineInputBase.EOF()) break;
						currentPos += r & 7;
						currentPc = inst.out;
						continue;
					}
					case Inst.CAPTURE: if (arg) {
						this.cap[inst.arg] = currentPos;
						break;
					} else {
						if (inst.arg < this.ncap) {
							this.push(re2, currentPc, this.cap[inst.arg], true);
							this.cap[inst.arg] = currentPos;
						}
						currentPc = inst.out;
						continue;
					}
					case Inst.EMPTY_WIDTH: {
						const flag = input.context(currentPos);
						if ((inst.arg & ~flag) !== 0) break;
						currentPc = inst.out;
						continue;
					}
					case Inst.NOP:
						currentPc = inst.out;
						continue;
					case Inst.MATCH: {
						if (anchor === RE2Flags.ANCHOR_BOTH && currentPos !== this.end) break;
						if (this.ncap === 0) return true;
						if (this.ncap > 1) this.cap[1] = currentPos;
						const old = this.matchcap[1];
						if (old === -1 || longest && currentPos > 0 && currentPos > old) this.matchcap.set(this.cap);
						if (!longest) return true;
						if (currentPos === this.end) return true;
						break;
					}
					case Inst.LB_WRITE:
					case Inst.LB_CHECK: throw new RE2JSInternalException("Backtracker cannot evaluate Lookbehind instructions");
					default: throw new RE2JSInternalException("bad inst");
				}
				break;
			}
		}
		return longest && this.matchcap.length > 1 && this.matchcap[1] >= 0;
	}
};
const bitStatePool = [];
var Backtracker = class Backtracker {
	static shouldBacktrack(prog) {
		return prog.numInst() <= MAX_BACKTRACK_PROG;
	}
	static maxBitStateLen(prog) {
		if (!Backtracker.shouldBacktrack(prog)) return 0;
		return Math.floor(MAX_BACKTRACK_VECTOR / prog.numInst());
	}
	static execute(re2, input, pos, anchor, ncap) {
		const startCond = re2.cond;
		if (startCond === Utils.EMPTY_ALL) return null;
		if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && pos !== 0) return null;
		if ((startCond & Utils.EMPTY_BEGIN_TEXT) !== 0 && pos !== 0) return null;
		const b = bitStatePool.length > 0 ? bitStatePool.pop() : new BitState();
		const end = input.endPos();
		b.reset(re2.prog, end, ncap);
		let matched = false;
		if ((startCond & Utils.EMPTY_BEGIN_TEXT) !== 0 || anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) {
			if (b.ncap > 0) b.cap[0] = pos;
			if (b.tryBacktrack(re2, input, re2.prog.start, pos, anchor)) matched = true;
		} else {
			let width = -1;
			for (; pos <= end && width !== 0; pos += width) {
				if (re2.prefix.length > 0) {
					const advance = input.index(re2, pos);
					if (advance < 0) break;
					pos += advance;
				}
				if (b.ncap > 0) b.cap[0] = pos;
				if (b.tryBacktrack(re2, input, re2.prog.start, pos, anchor)) {
					matched = true;
					break;
				}
				const r = input.step(pos);
				width = r === MachineInputBase.EOF() ? 0 : r & 7;
			}
		}
		if (!matched) {
			bitStatePool.push(b);
			return null;
		}
		const result = ncap === 0 ? [] : Utils.toArray(b.matchcap.subarray(0, ncap));
		bitStatePool.push(b);
		return result;
	}
};
//#endregion
//#region src/OnePass.js
var QueueOnePass = class {
	constructor(size) {
		this.sparse = new Uint32Array(size);
		this.dense = new Uint32Array(size);
		this.size = 0;
		this.nextIndex = 0;
	}
	empty() {
		return this.nextIndex >= this.size;
	}
	next() {
		return this.dense[this.nextIndex++];
	}
	clear() {
		this.size = 0;
		this.nextIndex = 0;
	}
	contains(u) {
		return u < this.sparse.length && this.sparse[u] < this.size && this.dense[this.sparse[u]] === u;
	}
	insert(u) {
		if (!this.contains(u)) this.insertNew(u);
	}
	insertNew(u) {
		if (u >= this.sparse.length) return;
		this.sparse[u] = this.size;
		this.dense[this.size] = u;
		this.size++;
	}
};
const mergeRuneSets = (leftRunes, rightRunes, leftPC, rightPC) => {
	const leftLen = leftRunes.length;
	const rightLen = rightRunes.length;
	let lx = 0, rx = 0;
	const merged = [];
	const next = [];
	let ok = true;
	let ix = -1;
	const extend = (isLeft) => {
		const newArray = isLeft ? leftRunes : rightRunes;
		const low = isLeft ? lx : rx;
		const pc = isLeft ? leftPC : rightPC;
		if (ix > 0 && newArray[low] <= merged[ix]) return false;
		merged.push(newArray[low], newArray[low + 1]);
		if (isLeft) lx += 2;
		else rx += 2;
		ix += 2;
		next.push(pc);
		return true;
	};
	while (lx < leftLen || rx < rightLen) {
		if (rx >= rightLen) ok = extend(true);
		else if (lx >= leftLen) ok = extend(false);
		else if (rightRunes[rx] < leftRunes[lx]) ok = extend(false);
		else ok = extend(true);
		if (!ok) return null;
	}
	return {
		merged,
		next
	};
};
var OnePassProg = class {
	constructor(prog) {
		this.start = prog.start;
		this.numCap = prog.numCap;
		this.inst = new Array(prog.inst.length);
		for (let i = 0; i < prog.inst.length; i++) {
			const orig = prog.inst[i];
			const inst = new Inst(orig.op);
			inst.out = orig.out;
			inst.arg = orig.arg;
			inst.runes = orig.runes ? orig.runes.slice() : [];
			inst.next = null;
			this.inst[i] = inst;
		}
	}
};
const onePassCopy = (prog) => {
	const p = new OnePassProg(prog);
	for (let pc = 0; pc < p.inst.length; pc++) {
		const inst = p.inst[pc];
		if (inst.op !== Inst.ALT && inst.op !== Inst.ALT_MATCH) continue;
		let pAOther = "out";
		let pAAlt = "arg";
		let instAlt = p.inst[inst[pAAlt]];
		if (instAlt.op !== Inst.ALT && instAlt.op !== Inst.ALT_MATCH) {
			pAOther = "arg";
			pAAlt = "out";
			instAlt = p.inst[inst[pAAlt]];
			if (instAlt.op !== Inst.ALT && instAlt.op !== Inst.ALT_MATCH) continue;
		}
		const instOther = p.inst[inst[pAOther]];
		if (instOther.op === Inst.ALT || instOther.op === Inst.ALT_MATCH) continue;
		let pBAlt = "out";
		let pBOther = "arg";
		let patch = false;
		if (instAlt.out === pc) patch = true;
		else if (instAlt.arg === pc) {
			patch = true;
			pBAlt = "arg";
			pBOther = "out";
		}
		if (patch) instAlt[pBAlt] = inst[pAOther];
		if (inst[pAOther] === instAlt[pBAlt]) inst[pAAlt] = instAlt[pBOther];
	}
	return p;
};
const makeOnePass = (p) => {
	if (p.inst.length >= 1e3) return null;
	const instQueue = new QueueOnePass(p.inst.length);
	const visitQueue = new QueueOnePass(p.inst.length);
	const onePassRunes = new Array(p.inst.length);
	const m = new Array(p.inst.length).fill(false);
	const check = (pc) => {
		let ok = true;
		const inst = p.inst[pc];
		if (visitQueue.contains(pc)) return true;
		visitQueue.insert(pc);
		switch (inst.op) {
			case Inst.ALT:
			case Inst.ALT_MATCH: {
				ok = check(inst.out) && check(inst.arg);
				let matchOut = m[inst.out];
				let matchArg = m[inst.arg];
				if (matchOut && matchArg) return false;
				if (matchArg) {
					const tempOut = inst.out;
					inst.out = inst.arg;
					inst.arg = tempOut;
					const tempMatch = matchOut;
					matchOut = matchArg;
					matchArg = tempMatch;
				}
				if (matchOut) {
					m[pc] = true;
					inst.op = Inst.ALT_MATCH;
				}
				const leftRunes = onePassRunes[inst.out] || [];
				const rightRunes = onePassRunes[inst.arg] || [];
				const mergeRes = mergeRuneSets(leftRunes, rightRunes, inst.out, inst.arg);
				if (!mergeRes) return false;
				onePassRunes[pc] = mergeRes.merged;
				inst.next = new Uint32Array(mergeRes.next);
				break;
			}
			case Inst.CAPTURE:
			case Inst.EMPTY_WIDTH:
			case Inst.NOP:
				ok = check(inst.out);
				m[pc] = m[inst.out];
				onePassRunes[pc] = onePassRunes[inst.out] ? onePassRunes[inst.out].slice() : [];
				inst.next = new Uint32Array(Math.floor(onePassRunes[pc].length / 2) + 1).fill(inst.out);
				break;
			case Inst.MATCH:
			case Inst.FAIL:
				m[pc] = inst.op === Inst.MATCH;
				break;
			case Inst.RUNE: {
				m[pc] = false;
				if (inst.next && inst.next.length > 0) break;
				instQueue.insert(inst.out);
				if (!inst.runes || inst.runes.length === 0) {
					onePassRunes[pc] = [];
					inst.next = new Uint32Array([inst.out]);
					break;
				}
				let runes = [];
				if (inst.runes.length === 1 && (inst.arg & RE2Flags.FOLD_CASE) !== 0) {
					const r0 = inst.runes[0];
					runes.push(r0, r0);
					for (let r1 = Unicode.simpleFold(r0); r1 !== r0; r1 = Unicode.simpleFold(r1)) runes.push(r1, r1);
					runes.sort((a, b) => a - b);
				} else for (let j = 0; j < inst.runes.length; j++) runes.push(inst.runes[j]);
				onePassRunes[pc] = runes;
				inst.next = new Uint32Array(Math.floor(runes.length / 2) + 1).fill(inst.out);
				inst.op = Inst.RUNE;
				break;
			}
			case Inst.RUNE1: {
				m[pc] = false;
				if (inst.next && inst.next.length > 0) break;
				instQueue.insert(inst.out);
				let runes = [];
				if ((inst.arg & RE2Flags.FOLD_CASE) !== 0) {
					const r0 = inst.runes[0];
					runes.push(r0, r0);
					for (let r1 = Unicode.simpleFold(r0); r1 !== r0; r1 = Unicode.simpleFold(r1)) runes.push(r1, r1);
					runes.sort((a, b) => a - b);
				} else runes.push(inst.runes[0], inst.runes[0]);
				onePassRunes[pc] = runes;
				inst.next = new Uint32Array(Math.floor(runes.length / 2) + 1).fill(inst.out);
				inst.op = Inst.RUNE;
				break;
			}
			case Inst.RUNE_ANY:
				m[pc] = false;
				if (inst.next && inst.next.length > 0) break;
				instQueue.insert(inst.out);
				onePassRunes[pc] = [0, Unicode.MAX_RUNE];
				inst.next = new Uint32Array([inst.out]);
				break;
			case Inst.RUNE_ANY_NOT_NL:
				m[pc] = false;
				if (inst.next && inst.next.length > 0) break;
				instQueue.insert(inst.out);
				onePassRunes[pc] = [
					0,
					9,
					11,
					Unicode.MAX_RUNE
				];
				inst.next = new Uint32Array(Math.floor(onePassRunes[pc].length / 2) + 1).fill(inst.out);
				break;
		}
		return ok;
	};
	instQueue.clear();
	instQueue.insert(p.start);
	while (!instQueue.empty()) {
		visitQueue.clear();
		if (!check(instQueue.next())) return null;
	}
	for (let i = 0; i < p.inst.length; i++) if (onePassRunes[i]) p.inst[i].runes = onePassRunes[i];
	return p;
};
const cleanupOnePass = (p, original) => {
	for (let ix = 0; ix < original.inst.length; ix++) {
		const instOriginal = original.inst[ix];
		switch (instOriginal.op) {
			case Inst.ALT:
			case Inst.ALT_MATCH:
			case Inst.RUNE: break;
			case Inst.CAPTURE:
			case Inst.EMPTY_WIDTH:
			case Inst.NOP:
			case Inst.MATCH:
			case Inst.FAIL:
				p.inst[ix].next = null;
				break;
			case Inst.RUNE1:
			case Inst.RUNE_ANY:
			case Inst.RUNE_ANY_NOT_NL:
				p.inst[ix].next = null;
				p.inst[ix].op = instOriginal.op;
				p.inst[ix].runes = instOriginal.runes ? instOriginal.runes.slice() : [];
				break;
		}
	}
};
var OnePass = class OnePass {
	static compile(prog) {
		if (prog.start === 0) return null;
		if (prog.numLb > 0) return null;
		const startInst = prog.inst[prog.start];
		if (startInst.op !== Inst.EMPTY_WIDTH || (startInst.arg & Utils.EMPTY_BEGIN_TEXT) === 0) return null;
		let hasAlt = false;
		for (let i = 0; i < prog.inst.length; i++) if (prog.inst[i].op === Inst.ALT || prog.inst[i].op === Inst.ALT_MATCH) {
			hasAlt = true;
			break;
		}
		for (let i = 0; i < prog.inst.length; i++) {
			const inst = prog.inst[i];
			const opOut = prog.inst[inst.out].op;
			switch (inst.op) {
				case Inst.ALT:
				case Inst.ALT_MATCH:
					if (opOut === Inst.MATCH || prog.inst[inst.arg].op === Inst.MATCH) return null;
					break;
				case Inst.EMPTY_WIDTH:
					if (opOut === Inst.MATCH) {
						if ((inst.arg & Utils.EMPTY_END_TEXT) === Utils.EMPTY_END_TEXT) continue;
						return null;
					}
					break;
				default:
					if (opOut === Inst.MATCH && hasAlt) return null;
					break;
			}
		}
		let p = onePassCopy(prog);
		p = makeOnePass(p);
		if (p !== null) cleanupOnePass(p, prog);
		return p;
	}
	static next(inst, r) {
		const nextIdx = inst.matchRunePos(r);
		if (nextIdx >= 0) return inst.next[nextIdx];
		if (inst.op === Inst.ALT_MATCH) return inst.out;
		return 0;
	}
	static execute(re2, input, pos, anchor, ncap) {
		const onepass = re2.onepass;
		if (!onepass) return null;
		const matchcap = new Int32Array(ncap).fill(-1);
		let matched = false;
		let r = input.step(pos);
		let rune = r >> 3;
		let width = r & 7;
		let r1 = MachineInputBase.EOF();
		let rune1 = -1;
		let width1 = 0;
		if (r !== MachineInputBase.EOF()) {
			r1 = input.step(pos + width);
			if (r1 !== MachineInputBase.EOF()) {
				rune1 = r1 >> 3;
				width1 = r1 & 7;
			}
		}
		let flag = pos === 0 ? Utils.emptyOpContext(-1, rune) : input.context(pos);
		let pc = onepass.start;
		let inst;
		while (true) {
			inst = onepass.inst[pc];
			pc = inst.out;
			switch (inst.op) {
				case Inst.MATCH:
					if (anchor === RE2Flags.ANCHOR_BOTH && pos !== input.endPos()) return null;
					matched = true;
					if (matchcap.length > 0) {
						matchcap[0] = 0;
						matchcap[1] = pos;
					}
					return ncap === 0 ? [] : Utils.toArray(matchcap);
				case Inst.RUNE:
					if (!inst.matchRune(rune)) return null;
					break;
				case Inst.RUNE1:
					if (rune !== inst.runes[0]) return null;
					break;
				case Inst.RUNE_ANY: break;
				case Inst.RUNE_ANY_NOT_NL:
					if (rune === 10) return null;
					break;
				case Inst.ALT:
				case Inst.ALT_MATCH:
					pc = OnePass.next(inst, rune);
					continue;
				case Inst.FAIL: return null;
				case Inst.NOP: continue;
				case Inst.EMPTY_WIDTH:
					if ((inst.arg & ~flag) !== 0) return null;
					continue;
				case Inst.CAPTURE:
					if (inst.arg < matchcap.length) matchcap[inst.arg] = pos;
					continue;
				default: throw new RE2JSInternalException("bad inst");
			}
			if (width === 0) break;
			flag = Utils.emptyOpContext(rune, rune1);
			pos += width;
			rune = rune1;
			width = width1;
			if (rune !== -1) {
				r1 = input.step(pos + width);
				if (r1 !== MachineInputBase.EOF()) {
					rune1 = r1 >> 3;
					width1 = r1 & 7;
				} else {
					rune1 = -1;
					width1 = 0;
				}
			}
		}
		if (!matched) return null;
		return ncap === 0 ? [] : Utils.toArray(matchcap);
	}
};
//#endregion
//#region src/Regexp.js
/**
* Regular expression abstract syntax tree. Produced by parser, used by compiler. NB, this
* corresponds to {@code syntax.regexp} in the Go implementation; Go's {@code regexp} is called
* {@code RE2} in Java.
*/
var Regexp = class Regexp {
	static Op = createEnum([
		"NO_MATCH",
		"EMPTY_MATCH",
		"LITERAL",
		"CHAR_CLASS",
		"ANY_CHAR_NOT_NL",
		"ANY_CHAR",
		"BEGIN_LINE",
		"END_LINE",
		"BEGIN_TEXT",
		"END_TEXT",
		"WORD_BOUNDARY",
		"NO_WORD_BOUNDARY",
		"CAPTURE",
		"STAR",
		"PLUS",
		"QUEST",
		"REPEAT",
		"CONCAT",
		"ALTERNATE",
		"PLB",
		"NLB",
		"LEFT_PAREN",
		"VERTICAL_BAR"
	]);
	static isPseudoOp(op) {
		return op >= Regexp.Op.LEFT_PAREN;
	}
	static emptySubs() {
		return [];
	}
	static quoteIfHyphen(rune) {
		if (rune === Codepoint.CODES.get("-")) return "\\";
		return "";
	}
	static fromRegexp(re) {
		const regex = new Regexp(re.op);
		regex.flags = re.flags;
		regex.subs = re.subs;
		regex.runes = re.runes;
		regex.cap = re.cap;
		regex.min = re.min;
		regex.max = re.max;
		regex.name = re.name;
		regex.namedGroups = re.namedGroups;
		regex.lb = re.lb;
		return regex;
	}
	constructor(op) {
		this.op = op;
		this.flags = 0;
		this.subs = Regexp.emptySubs();
		this.runes = [];
		this.min = 0;
		this.max = 0;
		this.cap = 0;
		this.name = null;
		this.namedGroups = Object.create(null);
		this.lb = 0;
	}
	reinit() {
		this.flags = 0;
		this.subs = Regexp.emptySubs();
		this.runes = [];
		this.cap = 0;
		this.min = 0;
		this.max = 0;
		this.name = null;
		this.namedGroups = Object.create(null);
		this.lb = 0;
	}
	toString() {
		return this.appendTo();
	}
	appendTo() {
		let out = "";
		switch (this.op) {
			case Regexp.Op.NO_MATCH:
				out += "[^\\x00-\\x{10FFFF}]";
				break;
			case Regexp.Op.EMPTY_MATCH:
				out += "(?:)";
				break;
			case Regexp.Op.STAR:
			case Regexp.Op.PLUS:
			case Regexp.Op.QUEST:
			case Regexp.Op.REPEAT: {
				const sub = this.subs[0];
				if (sub.op > Regexp.Op.CAPTURE || sub.op === Regexp.Op.LITERAL && sub.runes.length > 1) out += `(?:${sub.appendTo()})`;
				else out += sub.appendTo();
				switch (this.op) {
					case Regexp.Op.STAR:
						out += "*";
						break;
					case Regexp.Op.PLUS:
						out += "+";
						break;
					case Regexp.Op.QUEST:
						out += "?";
						break;
					case Regexp.Op.REPEAT:
						out += `{${this.min}`;
						if (this.min !== this.max) {
							out += ",";
							if (this.max >= 0) out += this.max;
						}
						out += "}";
						break;
				}
				if ((this.flags & RE2Flags.NON_GREEDY) !== 0) out += "?";
				break;
			}
			case Regexp.Op.CONCAT:
				for (let sub of this.subs) if (sub.op === Regexp.Op.ALTERNATE) out += `(?:${sub.appendTo()})`;
				else out += sub.appendTo();
				break;
			case Regexp.Op.ALTERNATE: {
				let sep = "";
				for (let sub of this.subs) {
					out += sep;
					sep = "|";
					out += sub.appendTo();
				}
				break;
			}
			case Regexp.Op.LITERAL:
				if ((this.flags & RE2Flags.FOLD_CASE) !== 0) out += "(?i:";
				for (let rune of this.runes) out += Utils.escapeRune(rune);
				if ((this.flags & RE2Flags.FOLD_CASE) !== 0) out += ")";
				break;
			case Regexp.Op.ANY_CHAR_NOT_NL:
				out += "(?-s:.)";
				break;
			case Regexp.Op.ANY_CHAR:
				out += "(?s:.)";
				break;
			case Regexp.Op.PLB:
				out += `(?<=${this.subs[0].appendTo()})`;
				break;
			case Regexp.Op.NLB:
				out += `(?<!${this.subs[0].appendTo()})`;
				break;
			case Regexp.Op.CAPTURE:
				if (this.name === null || this.name.length === 0) out += "(";
				else out += `(?P<${this.name}>`;
				if (this.subs[0].op !== Regexp.Op.EMPTY_MATCH) out += this.subs[0].appendTo();
				out += ")";
				break;
			case Regexp.Op.BEGIN_TEXT:
				out += "\\A";
				break;
			case Regexp.Op.END_TEXT:
				if ((this.flags & RE2Flags.WAS_DOLLAR) !== 0) out += "(?-m:$)";
				else out += "\\z";
				break;
			case Regexp.Op.BEGIN_LINE:
				out += "^";
				break;
			case Regexp.Op.END_LINE:
				out += "$";
				break;
			case Regexp.Op.WORD_BOUNDARY:
				out += "\\b";
				break;
			case Regexp.Op.NO_WORD_BOUNDARY:
				out += "\\B";
				break;
			case Regexp.Op.CHAR_CLASS:
				if (this.runes.length % 2 !== 0) {
					out += "[invalid char class]";
					break;
				}
				out += "[";
				if (this.runes.length === 0) out += "^\\x00-\\x{10FFFF}";
				else if (this.runes[0] === 0 && this.runes[this.runes.length - 1] === Unicode.MAX_RUNE) {
					out += "^";
					for (let i = 1; i < this.runes.length - 1; i += 2) {
						const lo = this.runes[i] + 1;
						const hi = this.runes[i + 1] - 1;
						out += Regexp.quoteIfHyphen(lo);
						out += Utils.escapeRune(lo);
						if (lo !== hi) {
							out += "-";
							out += Regexp.quoteIfHyphen(hi);
							out += Utils.escapeRune(hi);
						}
					}
				} else for (let i = 0; i < this.runes.length; i += 2) {
					const lo = this.runes[i];
					const hi = this.runes[i + 1];
					out += Regexp.quoteIfHyphen(lo);
					out += Utils.escapeRune(lo);
					if (lo !== hi) {
						out += "-";
						out += Regexp.quoteIfHyphen(hi);
						out += Utils.escapeRune(hi);
					}
				}
				out += "]";
				break;
			default:
				out += this.op;
				break;
		}
		return out;
	}
	maxCap() {
		let m = 0;
		if (this.op === Regexp.Op.CAPTURE) m = this.cap;
		if (this.subs !== null) for (let sub of this.subs) {
			const n = sub.maxCap();
			if (m < n) m = n;
		}
		return m;
	}
	equals(that) {
		if (!(that !== null && that instanceof Regexp)) return false;
		if (this.op !== that.op) return false;
		switch (this.op) {
			case Regexp.Op.END_TEXT:
				if ((this.flags & RE2Flags.WAS_DOLLAR) !== (that.flags & RE2Flags.WAS_DOLLAR)) return false;
				break;
			case Regexp.Op.LITERAL:
			case Regexp.Op.CHAR_CLASS:
				if (this.runes === null && that.runes === null) break;
				if (this.runes === null || that.runes === null) return false;
				if (this.runes.length !== that.runes.length) return false;
				for (let i = 0; i < this.runes.length; i++) if (this.runes[i] !== that.runes[i]) return false;
				break;
			case Regexp.Op.ALTERNATE:
			case Regexp.Op.CONCAT:
				if (this.subs.length !== that.subs.length) return false;
				for (let i = 0; i < this.subs.length; ++i) if (!this.subs[i].equals(that.subs[i])) return false;
				break;
			case Regexp.Op.STAR:
			case Regexp.Op.PLUS:
			case Regexp.Op.QUEST:
				if ((this.flags & RE2Flags.NON_GREEDY) !== (that.flags & RE2Flags.NON_GREEDY) || !this.subs[0].equals(that.subs[0])) return false;
				break;
			case Regexp.Op.REPEAT:
				if ((this.flags & RE2Flags.NON_GREEDY) !== (that.flags & RE2Flags.NON_GREEDY) || this.min !== that.min || this.max !== that.max || !this.subs[0].equals(that.subs[0])) return false;
				break;
			case Regexp.Op.CAPTURE:
				if (this.cap !== that.cap || (this.name === null ? that.name !== null : this.name !== that.name) || !this.subs[0].equals(that.subs[0])) return false;
				break;
			case Regexp.Op.PLB:
			case Regexp.Op.NLB:
				if (this.lb !== that.lb || !this.subs[0].equals(that.subs[0])) return false;
				break;
		}
		return true;
	}
};
//#endregion
//#region src/Prefilter.js
var AhoCorasick = class {
	constructor(wordArrays) {
		this.next = [Object.create(null)];
		this.fail = [0];
		this.match = [false];
		for (const word of wordArrays) {
			let node = 0;
			for (let i = 0; i < word.length; i++) {
				const val = word[i];
				if (!(val in this.next[node])) {
					this.next.push(Object.create(null));
					this.fail.push(0);
					this.match.push(false);
					this.next[node][val] = this.next.length - 1;
				}
				node = this.next[node][val];
			}
			this.match[node] = true;
		}
		const queue = [];
		for (const val in this.next[0]) if (Object.prototype.hasOwnProperty.call(this.next[0], val)) {
			const child = this.next[0][val];
			this.fail[child] = 0;
			queue.push(child);
		}
		while (queue.length > 0) {
			const curr = queue.shift();
			for (const val in this.next[curr]) if (Object.prototype.hasOwnProperty.call(this.next[curr], val)) {
				const child = this.next[curr][val];
				let failNode = this.fail[curr];
				while (failNode !== 0 && !(val in this.next[failNode])) failNode = this.fail[failNode];
				if (val in this.next[failNode]) this.fail[child] = this.next[failNode][val];
				else this.fail[child] = 0;
				this.match[child] = this.match[child] || this.match[this.fail[child]];
				queue.push(child);
			}
		}
	}
	searchUTF16(charSeq, start, end) {
		let node = 0;
		for (let i = start; i < end; i++) {
			const val = charSeq.charCodeAt(i);
			while (node !== 0 && !(val in this.next[node])) node = this.fail[node];
			if (val in this.next[node]) node = this.next[node][val];
			if (this.match[node]) return true;
		}
		return false;
	}
	searchUTF8(bytes, start, end) {
		let node = 0;
		for (let i = start; i < end; i++) {
			const val = bytes[i];
			while (node !== 0 && !(val in this.next[node])) node = this.fail[node];
			if (val in this.next[node]) node = this.next[node][val];
			if (this.match[node]) return true;
		}
		return false;
	}
};
var Prefilter = class Prefilter {
	static Type = {
		NONE: 0,
		EXACT: 1,
		AND: 2,
		OR: 3
	};
	constructor(type) {
		this.type = type;
		this.subs = [];
		this.str = "";
		this.bytes = null;
		this.ac16 = null;
		this.ac8 = null;
	}
	eval(input, pos) {
		switch (this.type) {
			case Prefilter.Type.NONE: return true;
			case Prefilter.Type.EXACT: return input.hasString(this, pos);
			case Prefilter.Type.AND:
				for (let i = 0; i < this.subs.length; i++) if (!this.subs[i].eval(input, pos)) return false;
				return true;
			case Prefilter.Type.OR:
				if (this.ac16 && this.ac8) return input.hasAnyString(this, pos);
				for (let i = 0; i < this.subs.length; i++) if (this.subs[i].eval(input, pos)) return true;
				return false;
			default: return true;
		}
	}
};
var PrefilterTree = class PrefilterTree {
	static build(re) {
		const pf = PrefilterTree.fromRegexp(re);
		return PrefilterTree.simplify(pf);
	}
	static fromRegexp(re) {
		if (!re) return new Prefilter(Prefilter.Type.NONE);
		switch (re.op) {
			case Regexp.Op.PLB:
			case Regexp.Op.NLB:
			case Regexp.Op.NO_MATCH:
			case Regexp.Op.EMPTY_MATCH:
			case Regexp.Op.BEGIN_LINE:
			case Regexp.Op.END_LINE:
			case Regexp.Op.BEGIN_TEXT:
			case Regexp.Op.END_TEXT:
			case Regexp.Op.WORD_BOUNDARY:
			case Regexp.Op.NO_WORD_BOUNDARY:
			case Regexp.Op.CHAR_CLASS:
			case Regexp.Op.ANY_CHAR_NOT_NL:
			case Regexp.Op.ANY_CHAR: return new Prefilter(Prefilter.Type.NONE);
			case Regexp.Op.LITERAL: {
				if (re.runes.length === 0 || (re.flags & RE2Flags.FOLD_CASE) !== 0) return new Prefilter(Prefilter.Type.NONE);
				const pf = new Prefilter(Prefilter.Type.EXACT);
				let str = "";
				for (let i = 0; i < re.runes.length; i++) str += String.fromCodePoint(re.runes[i]);
				pf.str = str;
				pf.bytes = Utils.stringToUtf8ByteArray(pf.str);
				return pf;
			}
			case Regexp.Op.CAPTURE:
			case Regexp.Op.PLUS: return PrefilterTree.fromRegexp(re.subs[0]);
			case Regexp.Op.REPEAT:
				if (re.min >= 1) return PrefilterTree.fromRegexp(re.subs[0]);
				return new Prefilter(Prefilter.Type.NONE);
			case Regexp.Op.CONCAT: {
				const pf = new Prefilter(Prefilter.Type.AND);
				for (const sub of re.subs) pf.subs.push(PrefilterTree.fromRegexp(sub));
				return pf;
			}
			case Regexp.Op.ALTERNATE: {
				const pf = new Prefilter(Prefilter.Type.OR);
				for (const sub of re.subs) pf.subs.push(PrefilterTree.fromRegexp(sub));
				return pf;
			}
			default: return new Prefilter(Prefilter.Type.NONE);
		}
	}
	static simplify(pf) {
		if (pf.type === Prefilter.Type.EXACT || pf.type === Prefilter.Type.NONE) return pf;
		if (pf.type === Prefilter.Type.AND) {
			const newSubs = [];
			for (const sub of pf.subs) {
				const s = PrefilterTree.simplify(sub);
				if (s.type !== Prefilter.Type.NONE) if (s.type === Prefilter.Type.AND) for (let j = 0; j < s.subs.length; j++) newSubs.push(s.subs[j]);
				else newSubs.push(s);
			}
			if (newSubs.length === 0) return new Prefilter(Prefilter.Type.NONE);
			if (newSubs.length === 1) return newSubs[0];
			pf.subs = newSubs;
			return pf;
		}
		if (pf.type === Prefilter.Type.OR) {
			const newSubs = [];
			for (const sub of pf.subs) {
				const s = PrefilterTree.simplify(sub);
				if (s.type === Prefilter.Type.NONE) return new Prefilter(Prefilter.Type.NONE);
				if (s.type === Prefilter.Type.OR) for (let j = 0; j < s.subs.length; j++) newSubs.push(s.subs[j]);
				else newSubs.push(s);
			}
			if (newSubs.length === 0) return new Prefilter(Prefilter.Type.NONE);
			if (newSubs.length === 1) return newSubs[0];
			const seen = /* @__PURE__ */ new Set();
			const uniqueSubs = [];
			for (const sub of newSubs) if (sub.type === Prefilter.Type.EXACT) {
				if (!seen.has(sub.str)) {
					seen.add(sub.str);
					uniqueSubs.push(sub);
				}
			} else uniqueSubs.push(sub);
			pf.subs = uniqueSubs;
			let allExact = true;
			for (const sub of uniqueSubs) if (sub.type !== Prefilter.Type.EXACT) {
				allExact = false;
				break;
			}
			if (allExact && uniqueSubs.length > 1) {
				pf.ac16 = new AhoCorasick(uniqueSubs.map((s) => {
					const arr = [];
					for (let i = 0; i < s.str.length; i++) arr.push(s.str.charCodeAt(i));
					return arr;
				}));
				pf.ac8 = new AhoCorasick(uniqueSubs.map((s) => s.bytes));
			}
			return pf;
		}
		return pf;
	}
};
//#endregion
//#region src/Prog.js
/**
* A list of instruction pointers waiting to be patched.
* Tracks both `head` and `tail` to allow O(1) appending during compilation.
* * Values are encoded integers, not standard memory pointers:
* - Program instruction index: `l >> 1`
* - Patch `.out` field if: `(l & 1) === 0`
* - Patch `.arg` field if: `(l & 1) === 1`
* - `0` denotes an empty list.
* * @see https://swtch.com/~rsc/regexp/regexp1.html
*/
var PatchList = class {
	/**
	* @param {number} head - Encoded pointer to the start of the patch list.
	* @param {number} tail - Encoded pointer to the end of the patch list.
	*/
	constructor(head = 0, tail = 0) {
		this.head = head;
		this.tail = tail;
	}
};
/**
* A Prog is a compiled regular expression program.
*/
var Prog = class {
	constructor() {
		this.inst = [];
		this.start = 0;
		this.numCap = 2;
		this.lbStarts = [];
		this.numLb = 0;
	}
	getInst(pc) {
		return this.inst[pc];
	}
	numInst() {
		return this.inst.length;
	}
	addInst(op) {
		this.inst.push(new Inst(op));
	}
	skipNop(pc) {
		let i = this.inst[pc];
		while (i.op === Inst.NOP || i.op === Inst.CAPTURE) {
			i = this.inst[pc];
			pc = i.out;
		}
		return i;
	}
	prefix() {
		let prefix = "";
		let i = this.skipNop(this.start);
		if (!Inst.isRuneOp(i.op) || i.runes.length !== 1) return [i.op === Inst.MATCH, prefix];
		while (Inst.isRuneOp(i.op) && i.runes.length === 1 && (i.arg & RE2Flags.FOLD_CASE) === 0) {
			prefix += String.fromCodePoint(i.runes[0]);
			i = this.skipNop(i.out);
		}
		return [i.op === Inst.MATCH, prefix];
	}
	startCond() {
		let flag = 0;
		let pc = this.start;
		loop: for (;;) {
			const i = this.inst[pc];
			switch (i.op) {
				case Inst.EMPTY_WIDTH:
					flag |= i.arg;
					break;
				case Inst.FAIL: return -1;
				case Inst.CAPTURE:
				case Inst.NOP: break;
				default: break loop;
			}
			pc = i.out;
		}
		return flag;
	}
	patch(l, val) {
		let head = l.head;
		while (head !== 0) {
			const i = this.inst[head >> 1];
			if ((head & 1) === 0) {
				head = i.out;
				i.out = val;
			} else {
				head = i.arg;
				i.arg = val;
			}
		}
	}
	append(l1, l2) {
		if (l1.head === 0) return l2;
		if (l2.head === 0) return l1;
		const i = this.inst[l1.tail >> 1];
		if ((l1.tail & 1) === 0) i.out = l2.head;
		else i.arg = l2.head;
		return new PatchList(l1.head, l2.tail);
	}
	/**
	*
	* @returns {string}
	*/
	toString() {
		let out = "";
		for (let pc = 0; pc < this.inst.length; pc++) {
			const len = out.length;
			out += pc;
			if (pc === this.start) out += "*";
			out += "        ".substring(out.length - len);
			out += this.inst[pc];
			out += "\n";
		}
		return out;
	}
};
//#endregion
//#region src/Compiler.js
/**
* A fragment of a compiled regular expression program.
*
* @see http://swtch.com/~rsc/regexp/regexp1.html
* @class
*/
var Frag = class {
	constructor(i = 0, out = new PatchList(), nullable = false) {
		this.i = i;
		this.out = out;
		this.nullable = nullable;
	}
};
/**
* Compiler from {@code Regexp} (RE2 abstract syntax) to {@code RE2} (compiled regular expression).
*
* The only entry point is {@link #compileRegexp}.
*/
var Compiler = class Compiler {
	static ANY_RUNE_NOT_NL() {
		return [
			0,
			Codepoint.CODES.get("\n") - 1,
			Codepoint.CODES.get("\n") + 1,
			Unicode.MAX_RUNE
		];
	}
	static ANY_RUNE() {
		return [0, Unicode.MAX_RUNE];
	}
	static compileRegexp(re) {
		const c = new Compiler();
		const f = c.compile(re);
		c.prog.patch(f.out, c.newInst(Inst.MATCH).i);
		c.prog.start = f.i;
		return c.prog;
	}
	static compileSet(regexps) {
		const c = new Compiler();
		if (regexps.length === 0) {
			c.prog.start = c.newInst(Inst.FAIL).i;
			return c.prog;
		}
		let starts = [];
		for (let i = 0; i < regexps.length; i++) {
			const f = c.compile(regexps[i]);
			const m = c.newInst(Inst.MATCH);
			c.prog.getInst(m.i).arg = i;
			c.prog.patch(f.out, m.i);
			starts.push(f.i);
		}
		let start = starts[0];
		for (let i = 1; i < starts.length; i++) {
			const f = c.newInst(Inst.ALT);
			const inst = c.prog.getInst(f.i);
			inst.out = start;
			inst.arg = starts[i];
			start = f.i;
		}
		c.prog.start = start;
		return c.prog;
	}
	constructor() {
		this.prog = new Prog();
		this.newInst(Inst.FAIL);
	}
	newInst(op) {
		this.prog.addInst(op);
		return new Frag(this.prog.numInst() - 1, new PatchList(), true);
	}
	nop() {
		const f = this.newInst(Inst.NOP);
		f.out = new PatchList(f.i << 1, f.i << 1);
		return f;
	}
	fail() {
		return new Frag();
	}
	cap(arg) {
		const f = this.newInst(Inst.CAPTURE);
		f.out = new PatchList(f.i << 1, f.i << 1);
		this.prog.getInst(f.i).arg = arg;
		if (this.prog.numCap < arg + 1) this.prog.numCap = arg + 1;
		return f;
	}
	cat(f1, f2) {
		if (f1.i === 0 || f2.i === 0) return this.fail();
		this.prog.patch(f1.out, f2.i);
		return new Frag(f1.i, f2.out, f1.nullable && f2.nullable);
	}
	alt(f1, f2) {
		if (f1.i === 0) return f2;
		if (f2.i === 0) return f1;
		const f = this.newInst(Inst.ALT);
		const i = this.prog.getInst(f.i);
		i.out = f1.i;
		i.arg = f2.i;
		f.out = this.prog.append(f1.out, f2.out);
		f.nullable = f1.nullable || f2.nullable;
		return f;
	}
	loop(f1, nongreedy) {
		const f = this.newInst(Inst.ALT);
		const i = this.prog.getInst(f.i);
		if (nongreedy) {
			i.arg = f1.i;
			f.out = new PatchList(f.i << 1, f.i << 1);
		} else {
			i.out = f1.i;
			f.out = new PatchList(f.i << 1 | 1, f.i << 1 | 1);
		}
		this.prog.patch(f1.out, f.i);
		return f;
	}
	quest(f1, nongreedy) {
		const f = this.newInst(Inst.ALT);
		const i = this.prog.getInst(f.i);
		if (nongreedy) {
			i.arg = f1.i;
			f.out = new PatchList(f.i << 1, f.i << 1);
		} else {
			i.out = f1.i;
			f.out = new PatchList(f.i << 1 | 1, f.i << 1 | 1);
		}
		f.out = this.prog.append(f.out, f1.out);
		return f;
	}
	star(f1, nongreedy) {
		if (f1.nullable) return this.quest(this.plus(f1, nongreedy), nongreedy);
		return this.loop(f1, nongreedy);
	}
	plus(f1, nongreedy) {
		return new Frag(f1.i, this.loop(f1, nongreedy).out, f1.nullable);
	}
	empty(op) {
		const f = this.newInst(Inst.EMPTY_WIDTH);
		this.prog.getInst(f.i).arg = op;
		f.out = new PatchList(f.i << 1, f.i << 1);
		return f;
	}
	rune(runes, flags) {
		const f = this.newInst(Inst.RUNE);
		f.nullable = false;
		const i = this.prog.getInst(f.i);
		i.runes = runes;
		flags &= RE2Flags.FOLD_CASE;
		if (runes.length !== 1 || Unicode.simpleFold(runes[0]) === runes[0]) flags &= ~RE2Flags.FOLD_CASE;
		i.arg = flags;
		f.out = new PatchList(f.i << 1, f.i << 1);
		if ((flags & RE2Flags.FOLD_CASE) === 0 && runes.length === 1 || runes.length === 2 && runes[0] === runes[1]) i.op = Inst.RUNE1;
		else if (runes.length === 2 && runes[0] === 0 && runes[1] === Unicode.MAX_RUNE) i.op = Inst.RUNE_ANY;
		else if (runes.length === 4 && runes[0] === 0 && runes[1] === Codepoint.CODES.get("\n") - 1 && runes[2] === Codepoint.CODES.get("\n") + 1 && runes[3] === Unicode.MAX_RUNE) i.op = Inst.RUNE_ANY_NOT_NL;
		return f;
	}
	lookBehind(a, lb) {
		const id = this.newInst(Inst.LB_WRITE);
		this.prog.getInst(id.i).arg = lb;
		const any = this.rune(Compiler.ANY_RUNE(), 0);
		const dotStar = this.star(any, true);
		const lbAutomaton = this.cat(dotStar, a);
		this.prog.patch(lbAutomaton.out, id.i);
		const checkId = this.newInst(Inst.LB_CHECK);
		this.prog.getInst(checkId.i).arg = lb;
		this.prog.lbStarts.push(lbAutomaton.i);
		if (Math.abs(lb) > this.prog.numLb) this.prog.numLb = Math.abs(lb);
		checkId.out = new PatchList(checkId.i << 1, checkId.i << 1);
		return checkId;
	}
	compile(re) {
		switch (re.op) {
			case Regexp.Op.NO_MATCH: return this.fail();
			case Regexp.Op.EMPTY_MATCH: return this.nop();
			case Regexp.Op.LITERAL: if (re.runes.length === 0) return this.nop();
			else {
				let f = null;
				for (let r of re.runes) {
					const f1 = this.rune([r], re.flags);
					f = f === null ? f1 : this.cat(f, f1);
				}
				return f;
			}
			case Regexp.Op.CHAR_CLASS: return this.rune(re.runes, re.flags);
			case Regexp.Op.ANY_CHAR_NOT_NL: return this.rune(Compiler.ANY_RUNE_NOT_NL(), 0);
			case Regexp.Op.ANY_CHAR: return this.rune(Compiler.ANY_RUNE(), 0);
			case Regexp.Op.BEGIN_LINE: return this.empty(Utils.EMPTY_BEGIN_LINE);
			case Regexp.Op.END_LINE: return this.empty(Utils.EMPTY_END_LINE);
			case Regexp.Op.BEGIN_TEXT: return this.empty(Utils.EMPTY_BEGIN_TEXT);
			case Regexp.Op.END_TEXT: return this.empty(Utils.EMPTY_END_TEXT);
			case Regexp.Op.WORD_BOUNDARY: return this.empty(Utils.EMPTY_WORD_BOUNDARY);
			case Regexp.Op.NO_WORD_BOUNDARY: return this.empty(Utils.EMPTY_NO_WORD_BOUNDARY);
			case Regexp.Op.PLB:
			case Regexp.Op.NLB: return this.lookBehind(this.compile(re.subs[0]), re.lb);
			case Regexp.Op.CAPTURE: {
				const bra = this.cap(re.cap << 1);
				const sub = this.compile(re.subs[0]);
				const ket = this.cap(re.cap << 1 | 1);
				return this.cat(this.cat(bra, sub), ket);
			}
			case Regexp.Op.STAR: return this.star(this.compile(re.subs[0]), (re.flags & RE2Flags.NON_GREEDY) !== 0);
			case Regexp.Op.PLUS: return this.plus(this.compile(re.subs[0]), (re.flags & RE2Flags.NON_GREEDY) !== 0);
			case Regexp.Op.QUEST: return this.quest(this.compile(re.subs[0]), (re.flags & RE2Flags.NON_GREEDY) !== 0);
			case Regexp.Op.CONCAT: if (re.subs.length === 0) return this.nop();
			else {
				let f = null;
				for (let sub of re.subs) {
					const f1 = this.compile(sub);
					f = f === null ? f1 : this.cat(f, f1);
				}
				return f;
			}
			case Regexp.Op.ALTERNATE: if (re.subs.length === 0) return this.nop();
			else {
				let f = null;
				for (let sub of re.subs) {
					const f1 = this.compile(sub);
					f = f === null ? f1 : this.alt(f, f1);
				}
				return f;
			}
			default: throw new RE2JSCompileException("regexp: unhandled case in compile");
		}
	}
};
//#endregion
//#region src/Simplify.js
var Simplify = class Simplify {
	static simplify(re) {
		if (re === null) return null;
		switch (re.op) {
			case Regexp.Op.PLB:
			case Regexp.Op.NLB:
			case Regexp.Op.CAPTURE: {
				const sub = Simplify.simplify(re.subs[0]);
				if (sub !== re.subs[0]) {
					const nre = Regexp.fromRegexp(re);
					nre.runes = [];
					nre.subs = [sub];
					return nre;
				}
				return re;
			}
			case Regexp.Op.CONCAT:
			case Regexp.Op.ALTERNATE: {
				const newSubs = [];
				let changed = false;
				for (let i = 0; i < re.subs.length; i++) {
					const sub = re.subs[i];
					const nsub = Simplify.simplify(sub);
					if (nsub !== sub) changed = true;
					if (re.op === Regexp.Op.CONCAT) {
						if (nsub.op === Regexp.Op.NO_MATCH) return new Regexp(Regexp.Op.NO_MATCH);
						if (nsub.op === Regexp.Op.EMPTY_MATCH) {
							changed = true;
							continue;
						}
						if (nsub.op === Regexp.Op.CONCAT) {
							changed = true;
							for (let j = 0; j < nsub.subs.length; j++) newSubs.push(nsub.subs[j]);
							continue;
						}
					} else if (re.op === Regexp.Op.ALTERNATE) {
						if (nsub.op === Regexp.Op.NO_MATCH) {
							changed = true;
							continue;
						}
						if (nsub.op === Regexp.Op.ALTERNATE) {
							changed = true;
							for (let j = 0; j < nsub.subs.length; j++) newSubs.push(nsub.subs[j]);
							continue;
						}
					}
					newSubs.push(nsub);
				}
				if (changed) {
					if (newSubs.length === 0) return new Regexp(re.op === Regexp.Op.CONCAT ? Regexp.Op.EMPTY_MATCH : Regexp.Op.NO_MATCH);
					if (newSubs.length === 1) return newSubs[0];
					const nre = Regexp.fromRegexp(re);
					nre.runes = [];
					nre.subs = newSubs;
					return nre;
				}
				return re;
			}
			case Regexp.Op.CHAR_CLASS:
				if (re.runes === null) return re;
				if (re.runes.length === 0) return new Regexp(Regexp.Op.NO_MATCH);
				if (re.runes.length === 2 && re.runes[0] === 0 && re.runes[1] === Unicode.MAX_RUNE) return new Regexp(Regexp.Op.ANY_CHAR);
				if (re.runes.length === 4 && re.runes[0] === 0 && re.runes[1] === Codepoint.CODES.get("\n") - 1 && re.runes[2] === Codepoint.CODES.get("\n") + 1 && re.runes[3] === Unicode.MAX_RUNE) return new Regexp(Regexp.Op.ANY_CHAR_NOT_NL);
				return re;
			case Regexp.Op.STAR:
			case Regexp.Op.PLUS:
			case Regexp.Op.QUEST: {
				const sub = Simplify.simplify(re.subs[0]);
				return Simplify.simplify1(re.op, re.flags, sub, re);
			}
			case Regexp.Op.REPEAT: {
				if (re.min === 0 && re.max === 0) return new Regexp(Regexp.Op.EMPTY_MATCH);
				const sub = Simplify.simplify(re.subs[0]);
				if (re.max === -1) {
					if (re.min === 0) return Simplify.simplify1(Regexp.Op.STAR, re.flags, sub, null);
					if (re.min === 1) return Simplify.simplify1(Regexp.Op.PLUS, re.flags, sub, null);
					const nre = new Regexp(Regexp.Op.CONCAT);
					const subs = [];
					for (let i = 0; i < re.min - 1; i++) subs.push(sub);
					subs.push(Simplify.simplify1(Regexp.Op.PLUS, re.flags, sub, null));
					nre.subs = subs.slice(0);
					return Simplify.simplify(nre);
				}
				if (re.min === 1 && re.max === 1) return sub;
				let prefixSubs = null;
				if (re.min > 0) {
					prefixSubs = [];
					for (let i = 0; i < re.min; i++) prefixSubs.push(sub);
				}
				if (re.max > re.min) {
					let suffix = Simplify.simplify1(Regexp.Op.QUEST, re.flags, sub, null);
					for (let i = re.min + 1; i < re.max; i++) {
						const nre2 = new Regexp(Regexp.Op.CONCAT);
						nre2.subs = [sub, suffix];
						suffix = Simplify.simplify1(Regexp.Op.QUEST, re.flags, nre2, null);
					}
					if (prefixSubs === null) return suffix;
					prefixSubs.push(suffix);
				}
				if (prefixSubs !== null) {
					const prefix = new Regexp(Regexp.Op.CONCAT);
					prefix.subs = prefixSubs.slice(0);
					return Simplify.simplify(prefix);
				}
				return new Regexp(Regexp.Op.NO_MATCH);
			}
		}
		return re;
	}
	static simplify1(op, flags, sub, re) {
		if (sub.op === Regexp.Op.EMPTY_MATCH) return sub;
		if (sub.op === Regexp.Op.NO_MATCH) {
			if (op === Regexp.Op.PLUS) return sub;
			return new Regexp(Regexp.Op.EMPTY_MATCH);
		}
		if (op === sub.op && (flags & RE2Flags.NON_GREEDY) === (sub.flags & RE2Flags.NON_GREEDY)) return sub;
		if (re !== null && re.op === op && (re.flags & RE2Flags.NON_GREEDY) === (flags & RE2Flags.NON_GREEDY) && sub === re.subs[0]) return re;
		const nre = new Regexp(op);
		nre.flags = flags;
		nre.subs = [sub];
		return nre;
	}
};
//#endregion
//#region src/CharGroup.js
var CharGroup = class {
	constructor(sign, cls) {
		this.sign = sign;
		this.cls = cls;
	}
};
const code1 = [48, 57];
const code2 = [
	9,
	10,
	12,
	13,
	32,
	32
];
const code3 = [
	48,
	57,
	65,
	90,
	95,
	95,
	97,
	122
];
const PERL_GROUPS = /* @__PURE__ */ new Map([
	["\\d", new CharGroup(1, code1)],
	["\\D", new CharGroup(-1, code1)],
	["\\s", new CharGroup(1, code2)],
	["\\S", new CharGroup(-1, code2)],
	["\\w", new CharGroup(1, code3)],
	["\\W", new CharGroup(-1, code3)]
]);
const code4 = [
	48,
	57,
	65,
	90,
	97,
	122
];
const code5 = [
	65,
	90,
	97,
	122
];
const code6 = [0, 127];
const code7 = [
	9,
	9,
	32,
	32
];
const code8 = [
	0,
	31,
	127,
	127
];
const code9 = [48, 57];
const code10 = [33, 126];
const code11 = [97, 122];
const code12 = [32, 126];
const code13 = [
	33,
	47,
	58,
	64,
	91,
	96,
	123,
	126
];
const code14 = [
	9,
	13,
	32,
	32
];
const code15 = [65, 90];
const code16 = [
	48,
	57,
	65,
	90,
	95,
	95,
	97,
	122
];
const code17 = [
	48,
	57,
	65,
	70,
	97,
	102
];
const POSIX_GROUPS = /* @__PURE__ */ new Map([
	["[:alnum:]", new CharGroup(1, code4)],
	["[:^alnum:]", new CharGroup(-1, code4)],
	["[:alpha:]", new CharGroup(1, code5)],
	["[:^alpha:]", new CharGroup(-1, code5)],
	["[:ascii:]", new CharGroup(1, code6)],
	["[:^ascii:]", new CharGroup(-1, code6)],
	["[:blank:]", new CharGroup(1, code7)],
	["[:^blank:]", new CharGroup(-1, code7)],
	["[:cntrl:]", new CharGroup(1, code8)],
	["[:^cntrl:]", new CharGroup(-1, code8)],
	["[:digit:]", new CharGroup(1, code9)],
	["[:^digit:]", new CharGroup(-1, code9)],
	["[:graph:]", new CharGroup(1, code10)],
	["[:^graph:]", new CharGroup(-1, code10)],
	["[:lower:]", new CharGroup(1, code11)],
	["[:^lower:]", new CharGroup(-1, code11)],
	["[:print:]", new CharGroup(1, code12)],
	["[:^print:]", new CharGroup(-1, code12)],
	["[:punct:]", new CharGroup(1, code13)],
	["[:^punct:]", new CharGroup(-1, code13)],
	["[:space:]", new CharGroup(1, code14)],
	["[:^space:]", new CharGroup(-1, code14)],
	["[:upper:]", new CharGroup(1, code15)],
	["[:^upper:]", new CharGroup(-1, code15)],
	["[:word:]", new CharGroup(1, code16)],
	["[:^word:]", new CharGroup(-1, code16)],
	["[:xdigit:]", new CharGroup(1, code17)],
	["[:^xdigit:]", new CharGroup(-1, code17)]
]);
//#endregion
//#region src/CharClass.js
/**
* A "builder"-style helper class for manipulating character classes represented as an array of
* pairs of runes [lo, hi], each denoting an inclusive interval.
*
* All methods mutate the internal state and return {@code this}, allowing operations to be chained.
*/
var CharClass = class CharClass {
	static charClassToString(r, len) {
		let result = "[";
		for (let i = 0; i < len; i += 2) {
			if (i > 0) result += " ";
			const lo = r[i];
			const hi = r[i + 1];
			if (lo === hi) result += `0x${lo.toString(16)}`;
			else result += `0x${lo.toString(16)}-0x${hi.toString(16)}`;
		}
		result += "]";
		return result;
	}
	static cmp(array, i, pivotFrom, pivotTo) {
		const cmp = array[i] - pivotFrom;
		return cmp !== 0 ? cmp : pivotTo - array[i + 1];
	}
	static qsortIntPair(array, left, right) {
		const pivotIndex = ((left + right) / 2 | 0) & -2;
		const pivotFrom = array[pivotIndex];
		const pivotTo = array[pivotIndex + 1];
		let i = left;
		let j = right;
		while (i <= j) {
			while (i < right && CharClass.cmp(array, i, pivotFrom, pivotTo) < 0) i += 2;
			while (j > left && CharClass.cmp(array, j, pivotFrom, pivotTo) > 0) j -= 2;
			if (i <= j) {
				if (i !== j) {
					let temp = array[i];
					array[i] = array[j];
					array[j] = temp;
					temp = array[i + 1];
					array[i + 1] = array[j + 1];
					array[j + 1] = temp;
				}
				i += 2;
				j -= 2;
			}
		}
		if (left < j) CharClass.qsortIntPair(array, left, j);
		if (i < right) CharClass.qsortIntPair(array, i, right);
	}
	constructor(r = Utils.emptyInts()) {
		this.r = r;
		this.len = r.length;
	}
	toArray() {
		if (this.len === this.r.length) return this.r;
		else return this.r.slice(0, this.len);
	}
	cleanClass() {
		if (this.len < 4) return this;
		CharClass.qsortIntPair(this.r, 0, this.len - 2);
		let w = 2;
		for (let i = 2; i < this.len; i += 2) {
			const lo = this.r[i];
			const hi = this.r[i + 1];
			if (lo <= this.r[w - 1] + 1) {
				if (hi > this.r[w - 1]) this.r[w - 1] = hi;
				continue;
			}
			this.r[w] = lo;
			this.r[w + 1] = hi;
			w += 2;
		}
		this.len = w;
		return this;
	}
	appendLiteral(x, flags) {
		return (flags & RE2Flags.FOLD_CASE) !== 0 ? this.appendFoldedRange(x, x) : this.appendRange(x, x);
	}
	appendRange(lo, hi) {
		if (this.len > 0) {
			for (let i = 2; i <= 4; i += 2) if (this.len >= i) {
				const rlo = this.r[this.len - i];
				const rhi = this.r[this.len - i + 1];
				if (lo <= rhi + 1 && rlo <= hi + 1) {
					if (lo < rlo) this.r[this.len - i] = lo;
					if (hi > rhi) this.r[this.len - i + 1] = hi;
					return this;
				}
			}
		}
		this.r[this.len++] = lo;
		this.r[this.len++] = hi;
		return this;
	}
	appendFoldedRange(lo, hi) {
		if (lo <= Unicode.MIN_FOLD && hi >= Unicode.MAX_FOLD) return this.appendRange(lo, hi);
		if (hi < Unicode.MIN_FOLD || lo > Unicode.MAX_FOLD) return this.appendRange(lo, hi);
		if (lo < Unicode.MIN_FOLD) {
			this.appendRange(lo, Unicode.MIN_FOLD - 1);
			lo = Unicode.MIN_FOLD;
		}
		if (hi > Unicode.MAX_FOLD) {
			this.appendRange(Unicode.MAX_FOLD + 1, hi);
			hi = Unicode.MAX_FOLD;
		}
		for (let c = lo; c <= hi; c++) {
			this.appendRange(c, c);
			for (let f = Unicode.simpleFold(c); f !== c; f = Unicode.simpleFold(f)) this.appendRange(f, f);
		}
		return this;
	}
	appendClass(x) {
		for (let i = 0; i < x.length; i += 2) this.appendRange(x[i], x[i + 1]);
		return this;
	}
	appendFoldedClass(x) {
		for (let i = 0; i < x.length; i += 2) this.appendFoldedRange(x[i], x[i + 1]);
		return this;
	}
	appendNegatedClass(x) {
		let nextLo = 0;
		for (let i = 0; i < x.length; i += 2) {
			const lo = x[i];
			const hi = x[i + 1];
			if (nextLo <= lo - 1) this.appendRange(nextLo, lo - 1);
			nextLo = hi + 1;
		}
		if (nextLo <= Unicode.MAX_RUNE) this.appendRange(nextLo, Unicode.MAX_RUNE);
		return this;
	}
	appendTable(table) {
		for (let i = 0; i < table.length; ++i) {
			const lo = table.getLo(i);
			const hi = table.getHi(i);
			const stride = table.getStride(i);
			if (stride === 1) {
				this.appendRange(lo, hi);
				continue;
			}
			for (let c = lo; c <= hi; c += stride) this.appendRange(c, c);
		}
		return this;
	}
	appendNegatedTable(table) {
		let nextLo = 0;
		for (let i = 0; i < table.length; ++i) {
			const lo = table.getLo(i);
			const hi = table.getHi(i);
			const stride = table.getStride(i);
			if (stride === 1) {
				if (nextLo <= lo - 1) this.appendRange(nextLo, lo - 1);
				nextLo = hi + 1;
				continue;
			}
			for (let c = lo; c <= hi; c += stride) {
				if (nextLo <= c - 1) this.appendRange(nextLo, c - 1);
				nextLo = c + 1;
			}
		}
		if (nextLo <= Unicode.MAX_RUNE) this.appendRange(nextLo, Unicode.MAX_RUNE);
		return this;
	}
	appendTableWithSign(table, sign) {
		return sign < 0 ? this.appendNegatedTable(table) : this.appendTable(table);
	}
	negateClass() {
		let nextLo = 0;
		let w = 0;
		for (let i = 0; i < this.len; i += 2) {
			const lo = this.r[i];
			const hi = this.r[i + 1];
			if (nextLo <= lo - 1) {
				this.r[w] = nextLo;
				this.r[w + 1] = lo - 1;
				w += 2;
			}
			nextLo = hi + 1;
		}
		this.len = w;
		if (nextLo <= Unicode.MAX_RUNE) {
			this.r[this.len++] = nextLo;
			this.r[this.len++] = Unicode.MAX_RUNE;
		}
		return this;
	}
	appendClassWithSign(x, sign) {
		return sign < 0 ? this.appendNegatedClass(x) : this.appendClass(x);
	}
	appendGroup(g, foldCase) {
		let cls = g.cls;
		if (foldCase) cls = new CharClass().appendFoldedClass(cls).cleanClass().toArray();
		return this.appendClassWithSign(cls, g.sign);
	}
	toString() {
		return CharClass.charClassToString(this.r, this.len);
	}
};
//#endregion
//#region src/Parser.js
var StringIterator = class {
	constructor(str) {
		this.str = str;
		this.position = 0;
	}
	pos() {
		return this.position;
	}
	rewindTo(pos) {
		this.position = pos;
	}
	more() {
		return this.position < this.str.length;
	}
	peek() {
		return this.str.codePointAt(this.position);
	}
	skip(n) {
		this.position += n;
	}
	skipString(s) {
		this.position += s.length;
	}
	pop() {
		const r = this.str.codePointAt(this.position);
		this.position += Utils.charCount(r);
		return r;
	}
	lookingAt(s) {
		return this.str.startsWith(s, this.position);
	}
	rest() {
		return this.str.substring(this.position);
	}
	from(beforePos) {
		return this.str.substring(beforePos, this.position);
	}
	toString() {
		return this.rest();
	}
};
/**
* A parser of regular expression patterns.
*
* The only public entry point is {@link #parse(String pattern, int flags)}.
*/
var Parser = class Parser {
	static ERR_INTERNAL_ERROR = "regexp/syntax: internal error";
	static ERR_INVALID_CHAR_RANGE = "invalid character class range";
	static ERR_INVALID_ESCAPE = "invalid escape sequence";
	static ERR_INVALID_NAMED_CAPTURE = "invalid named capture";
	static ERR_INVALID_PERL_OP = "invalid or unsupported Perl syntax";
	static ERR_INVALID_REPEAT_OP = "invalid nested repetition operator";
	static ERR_INVALID_REPEAT_SIZE = "invalid repeat count";
	static ERR_MISSING_BRACKET = "missing closing ]";
	static ERR_MISSING_PAREN = "missing closing )";
	static ERR_MISSING_REPEAT_ARGUMENT = "missing argument to repetition operator";
	static ERR_TRAILING_BACKSLASH = "trailing backslash at end of expression";
	static ERR_DUPLICATE_NAMED_CAPTURE = "duplicate capture group name";
	static ERR_UNEXPECTED_PAREN = "unexpected )";
	static ERR_NESTING_DEPTH = "expression nests too deeply";
	static ERR_LARGE = "expression too large";
	static ERR_INVALID_CAPTURE_IN_LOOKBEHIND = "invalid capture in lookbehind";
	static MAX_HEIGHT = 1e3;
	static MAX_SIZE = 3355443;
	static MAX_RUNES = 33554432;
	static ANY_TABLE = new UnicodeRangeTable(new Uint32Array([
		0,
		Unicode.MAX_RUNE,
		1
	]));
	static ASCII_TABLE = new UnicodeRangeTable(new Uint32Array([
		0,
		127,
		1
	]));
	static ASCII_FOLD_TABLE = new UnicodeRangeTable(new Uint32Array([
		0,
		127,
		1,
		383,
		383,
		1,
		8490,
		8490,
		1
	]));
	static unicodeTable(name) {
		if (name === "Any") return {
			tab: Parser.ANY_TABLE,
			fold: Parser.ANY_TABLE,
			sign: 1
		};
		if (name === "Ascii") return {
			tab: Parser.ASCII_TABLE,
			fold: Parser.ASCII_FOLD_TABLE,
			sign: 1
		};
		if (name === "Assigned") return {
			tab: UnicodeTables.CATEGORIES.get("Cn"),
			fold: UnicodeTables.CATEGORIES.get("Cn"),
			sign: -1
		};
		if (name === "Lc") return {
			tab: UnicodeTables.CATEGORIES.get("LC"),
			fold: UnicodeTables.FOLD_CATEGORIES.get("LC"),
			sign: 1
		};
		if (UnicodeTables.CATEGORIES.has(name)) return {
			tab: UnicodeTables.CATEGORIES.get(name),
			fold: UnicodeTables.FOLD_CATEGORIES.get(name),
			sign: 1
		};
		if (UnicodeTables.SCRIPTS.has(name)) return {
			tab: UnicodeTables.SCRIPTS.get(name),
			fold: UnicodeTables.FOLD_SCRIPT.get(name),
			sign: 1
		};
		return null;
	}
	static minFoldRune(r) {
		if (r < Unicode.MIN_FOLD || r > Unicode.MAX_FOLD) return r;
		let min = r;
		const r0 = r;
		for (r = Unicode.simpleFold(r); r !== r0; r = Unicode.simpleFold(r)) if (min > r) min = r;
		return min;
	}
	static leadingRegexp(re) {
		if (re.op === Regexp.Op.EMPTY_MATCH) return null;
		if (re.op === Regexp.Op.CONCAT && re.subs.length > 0) {
			const sub = re.subs[0];
			if (sub.op === Regexp.Op.EMPTY_MATCH) return null;
			return sub;
		}
		return re;
	}
	static literalRegexp(s, flags) {
		const re = new Regexp(Regexp.Op.LITERAL);
		re.flags = flags;
		re.runes = Utils.stringToRunes(s);
		return re;
	}
	/**
	* Parse regular expression pattern {@code pattern} with mode flags {@code flags}.
	* @param {string} pattern
	* @param {number} flags
	*/
	static parse(pattern, flags) {
		return new Parser(pattern, flags).parseInternal();
	}
	static parseRepeat(t) {
		const start = t.pos();
		if (!t.more() || !t.lookingAt("{")) return -1;
		t.skip(1);
		const min = Parser.parseInt(t);
		if (min === -1) return -1;
		if (!t.more()) return -1;
		let max;
		if (!t.lookingAt(",")) max = min;
		else {
			t.skip(1);
			if (!t.more()) return -1;
			if (t.lookingAt("}")) max = -1;
			else if ((max = Parser.parseInt(t)) === -1) return -1;
		}
		if (!t.more() || !t.lookingAt("}")) return -1;
		t.skip(1);
		if (min < 0 || min > 1e3 || max === -2 || max > 1e3 || max >= 0 && min > max) throw new RE2JSSyntaxException(Parser.ERR_INVALID_REPEAT_SIZE, t.from(start));
		return min << 16 | max & Unicode.MAX_BMP;
	}
	static isValidCaptureName(name) {
		if (name.length === 0) return false;
		for (let i = 0; i < name.length; i++) {
			const c = name.codePointAt(i);
			if (c !== Codepoint.CODES.get("_") && !Utils.isalnum(c)) return false;
		}
		return true;
	}
	static parseInt(t) {
		const start = t.pos();
		while (t.more() && t.peek() >= Codepoint.CODES.get("0") && t.peek() <= Codepoint.CODES.get("9")) t.skip(1);
		const n = t.from(start);
		if (n.length === 0 || n.length > 1 && n.codePointAt(0) === Codepoint.CODES.get("0")) return -1;
		if (n.length > 8) return -2;
		return parseInt(n, 10);
	}
	static isCharClass(re) {
		return re.op === Regexp.Op.LITERAL && re.runes.length === 1 || re.op === Regexp.Op.CHAR_CLASS || re.op === Regexp.Op.ANY_CHAR_NOT_NL || re.op === Regexp.Op.ANY_CHAR;
	}
	static matchRune(re, r) {
		switch (re.op) {
			case Regexp.Op.LITERAL: return re.runes.length === 1 && re.runes[0] === r;
			case Regexp.Op.CHAR_CLASS:
				for (let i = 0; i < re.runes.length; i += 2) if (re.runes[i] <= r && r <= re.runes[i + 1]) return true;
				return false;
			case Regexp.Op.ANY_CHAR_NOT_NL: return r !== Codepoint.CODES.get("\n");
			case Regexp.Op.ANY_CHAR: return true;
		}
		return false;
	}
	static mergeCharClass(dst, src) {
		switch (dst.op) {
			case Regexp.Op.ANY_CHAR: break;
			case Regexp.Op.ANY_CHAR_NOT_NL:
				if (Parser.matchRune(src, Codepoint.CODES.get("\n"))) dst.op = Regexp.Op.ANY_CHAR;
				break;
			case Regexp.Op.CHAR_CLASS:
				if (src.op === Regexp.Op.LITERAL) dst.runes = new CharClass(dst.runes).appendLiteral(src.runes[0], src.flags).toArray();
				else dst.runes = new CharClass(dst.runes).appendClass(src.runes).toArray();
				break;
			case Regexp.Op.LITERAL:
				if (src.runes[0] === dst.runes[0] && src.flags === dst.flags) break;
				dst.op = Regexp.Op.CHAR_CLASS;
				dst.runes = new CharClass().appendLiteral(dst.runes[0], dst.flags).appendLiteral(src.runes[0], src.flags).toArray();
				break;
		}
	}
	static parseEscape(t) {
		const startPos = t.pos();
		t.skip(1);
		if (!t.more()) throw new RE2JSSyntaxException(Parser.ERR_TRAILING_BACKSLASH);
		let c = t.pop();
		bigswitch: switch (c) {
			case Codepoint.CODES.get("1"):
			case Codepoint.CODES.get("2"):
			case Codepoint.CODES.get("3"):
			case Codepoint.CODES.get("4"):
			case Codepoint.CODES.get("5"):
			case Codepoint.CODES.get("6"):
			case Codepoint.CODES.get("7"): if (!t.more() || t.peek() < Codepoint.CODES.get("0") || t.peek() > Codepoint.CODES.get("7")) break;
			case Codepoint.CODES.get("0"): {
				let r = c - Codepoint.CODES.get("0");
				for (let i = 1; i < 3; i++) {
					if (!t.more() || t.peek() < Codepoint.CODES.get("0") || t.peek() > Codepoint.CODES.get("7")) break;
					r = r * 8 + t.peek() - Codepoint.CODES.get("0");
					t.skip(1);
				}
				return r;
			}
			case Codepoint.CODES.get("x"): {
				if (!t.more()) break;
				c = t.pop();
				if (c === Codepoint.CODES.get("{")) {
					let nhex = 0;
					let r = 0;
					while (true) {
						if (!t.more()) break bigswitch;
						c = t.pop();
						if (c === Codepoint.CODES.get("}")) break;
						const v = Utils.unhex(c);
						if (v < 0) break bigswitch;
						r = r * 16 + v;
						if (r > Unicode.MAX_RUNE) break bigswitch;
						nhex++;
					}
					if (nhex === 0) break bigswitch;
					return r;
				}
				const x = Utils.unhex(c);
				if (!t.more()) break;
				c = t.pop();
				const y = Utils.unhex(c);
				if (x < 0 || y < 0) break;
				return x * 16 + y;
			}
			case Codepoint.CODES.get("a"): return Codepoint.CODES.get("\x07");
			case Codepoint.CODES.get("f"): return Codepoint.CODES.get("\f");
			case Codepoint.CODES.get("n"): return Codepoint.CODES.get("\n");
			case Codepoint.CODES.get("r"): return Codepoint.CODES.get("\r");
			case Codepoint.CODES.get("t"): return Codepoint.CODES.get("	");
			case Codepoint.CODES.get("v"): return Codepoint.CODES.get("\v");
			default:
				if (c <= Unicode.MAX_ASCII && !Utils.isalnum(c)) return c;
				break;
		}
		throw new RE2JSSyntaxException(Parser.ERR_INVALID_ESCAPE, t.from(startPos));
	}
	static parseClassChar(t, wholeClassPos) {
		if (!t.more()) throw new RE2JSSyntaxException(Parser.ERR_MISSING_BRACKET, t.from(wholeClassPos));
		if (t.lookingAt("\\")) return Parser.parseEscape(t);
		return t.pop();
	}
	static concatRunes(x, y) {
		for (let i = 0; i < y.length; i++) x.push(y[i]);
		return x;
	}
	static hasCapture(re) {
		if (re === null) return false;
		if (re.op === Regexp.Op.CAPTURE) return true;
		if (re.subs) {
			for (let sub of re.subs) if (Parser.hasCapture(sub)) return true;
		}
		return false;
	}
	constructor(wholeRegexp, flags = 0) {
		this.wholeRegexp = wholeRegexp;
		this.flags = flags;
		this.numCap = 0;
		this.namedGroups = Object.create(null);
		this.stack = [];
		this.free = null;
		this.numRegexp = 0;
		this.numRunes = 0;
		this.repeats = 0;
		this.height = null;
		this.size = null;
		this.nlb = 0;
	}
	newRegexp(op) {
		let re = this.free;
		if (re !== null && re.subs !== null && re.subs.length > 0) {
			this.free = re.subs[0];
			re.reinit();
			re.op = op;
		} else {
			re = new Regexp(op);
			this.numRegexp += 1;
		}
		return re;
	}
	reuse(re) {
		if (this.height !== null && this.height.has(re)) this.height.delete(re);
		if (re.subs !== null && re.subs.length > 0) re.subs[0] = this.free;
		this.free = re;
	}
	checkLimits(re) {
		if (this.numRunes > Parser.MAX_RUNES) throw new RE2JSSyntaxException(Parser.ERR_LARGE);
		this.checkSize(re);
		this.checkHeight(re);
	}
	checkSize(re) {
		if (this.size === null) {
			if (this.repeats === 0) this.repeats = 1;
			if (re.op === Regexp.Op.REPEAT) {
				let n = re.max;
				if (n === -1) n = re.min;
				if (n <= 0) n = 1;
				if (n > Math.floor(Parser.MAX_SIZE / this.repeats)) this.repeats = Parser.MAX_SIZE;
				else this.repeats *= n;
			}
			if (this.numRegexp < Math.floor(Parser.MAX_SIZE / this.repeats)) return;
			this.size = /* @__PURE__ */ new Map();
			for (let reEx of this.stack) this.checkSize(reEx);
		}
		if (this.calcSize(re, true) > Parser.MAX_SIZE) throw new RE2JSSyntaxException(Parser.ERR_LARGE);
	}
	calcSize(re, force = false) {
		if (!force && this.size !== null) {
			if (this.size.has(re)) return this.size.get(re);
		}
		let size = 0;
		switch (re.op) {
			case Regexp.Op.LITERAL:
				size = re.runes.length;
				break;
			case Regexp.Op.PLB:
			case Regexp.Op.NLB:
			case Regexp.Op.CAPTURE:
			case Regexp.Op.STAR:
				size = 2 + this.calcSize(re.subs[0]);
				break;
			case Regexp.Op.PLUS:
			case Regexp.Op.QUEST:
				size = 1 + this.calcSize(re.subs[0]);
				break;
			case Regexp.Op.CONCAT:
				for (let sub of re.subs) size = size + this.calcSize(sub);
				break;
			case Regexp.Op.ALTERNATE:
				for (let sub of re.subs) size = size + this.calcSize(sub);
				if (re.subs.length > 1) size = size + re.subs.length - 1;
				break;
			case Regexp.Op.REPEAT: {
				let sub = this.calcSize(re.subs[0]);
				if (re.max === -1) {
					if (re.min === 0) size = 2 + sub;
					else size = 1 + re.min * sub;
					break;
				}
				size = re.max * sub + (re.max - re.min);
				break;
			}
		}
		size = Math.max(1, size);
		if (this.size === null) this.size = /* @__PURE__ */ new Map();
		this.size.set(re, size);
		return size;
	}
	checkHeight(re) {
		if (this.numRegexp < Parser.MAX_HEIGHT) return;
		if (this.height === null) {
			this.height = /* @__PURE__ */ new Map();
			for (let reEx of this.stack) this.checkHeight(reEx);
		}
		if (this.calcHeight(re, true) > Parser.MAX_HEIGHT) throw new RE2JSSyntaxException(Parser.ERR_NESTING_DEPTH);
	}
	calcHeight(re, force = false) {
		if (!force && this.height !== null) {
			if (this.height.has(re)) return this.height.get(re);
		}
		let h = 1;
		for (let sub of re.subs) {
			const hsub = this.calcHeight(sub);
			if (h < 1 + hsub) h = 1 + hsub;
		}
		if (this.height === null) this.height = /* @__PURE__ */ new Map();
		this.height.set(re, h);
		return h;
	}
	pop() {
		return this.stack.pop();
	}
	popToPseudo() {
		const n = this.stack.length;
		let i = n;
		while (i > 0 && !Regexp.isPseudoOp(this.stack[i - 1].op)) i--;
		const r = this.stack.slice(i, n);
		this.stack = this.stack.slice(0, i);
		return r;
	}
	push(re) {
		this.numRunes += re.runes.length;
		if (re.op === Regexp.Op.CHAR_CLASS && re.runes.length === 2 && re.runes[0] === re.runes[1]) {
			if (this.maybeConcat(re.runes[0], this.flags & ~RE2Flags.FOLD_CASE)) return null;
			re.op = Regexp.Op.LITERAL;
			re.runes = [re.runes[0]];
			re.flags = this.flags & ~RE2Flags.FOLD_CASE;
		} else if (re.op === Regexp.Op.CHAR_CLASS && re.runes.length === 4 && re.runes[0] === re.runes[1] && re.runes[2] === re.runes[3] && Unicode.simpleFold(re.runes[0]) === re.runes[2] && Unicode.simpleFold(re.runes[2]) === re.runes[0] || re.op === Regexp.Op.CHAR_CLASS && re.runes.length === 2 && re.runes[0] + 1 === re.runes[1] && Unicode.simpleFold(re.runes[0]) === re.runes[1] && Unicode.simpleFold(re.runes[1]) === re.runes[0]) {
			if (this.maybeConcat(re.runes[0], this.flags | RE2Flags.FOLD_CASE)) return null;
			re.op = Regexp.Op.LITERAL;
			re.runes = [re.runes[0]];
			re.flags = this.flags | RE2Flags.FOLD_CASE;
		} else this.maybeConcat(-1, 0);
		this.stack.push(re);
		this.checkLimits(re);
		return re;
	}
	maybeConcat(r, flags) {
		const n = this.stack.length;
		if (n < 2) return false;
		const re1 = this.stack[n - 1];
		const re2 = this.stack[n - 2];
		if (re1.op !== Regexp.Op.LITERAL || re2.op !== Regexp.Op.LITERAL || (re1.flags & RE2Flags.FOLD_CASE) !== (re2.flags & RE2Flags.FOLD_CASE)) return false;
		re2.runes = Parser.concatRunes(re2.runes, re1.runes);
		if (r >= 0) {
			re1.runes = [r];
			re1.flags = flags;
			return true;
		}
		this.pop();
		this.reuse(re1);
		return false;
	}
	newLiteral(r, flags) {
		const re = this.newRegexp(Regexp.Op.LITERAL);
		re.flags = flags;
		if ((flags & RE2Flags.FOLD_CASE) !== 0) r = Parser.minFoldRune(r);
		re.runes = [r];
		return re;
	}
	literal(r) {
		this.push(this.newLiteral(r, this.flags));
	}
	op(op) {
		const re = this.newRegexp(op);
		re.flags = this.flags;
		return this.push(re);
	}
	repeat(op, min, max, beforePos, t, lastRepeatPos) {
		let flags = this.flags;
		if ((flags & RE2Flags.PERL_X) !== 0) {
			if (t.more() && t.lookingAt("?")) {
				t.skip(1);
				flags ^= RE2Flags.NON_GREEDY;
			}
			if (lastRepeatPos !== -1) throw new RE2JSSyntaxException(Parser.ERR_INVALID_REPEAT_OP, t.from(lastRepeatPos));
		}
		const n = this.stack.length;
		if (n === 0) throw new RE2JSSyntaxException(Parser.ERR_MISSING_REPEAT_ARGUMENT, t.from(beforePos));
		const sub = this.stack[n - 1];
		if (Regexp.isPseudoOp(sub.op)) throw new RE2JSSyntaxException(Parser.ERR_MISSING_REPEAT_ARGUMENT, t.from(beforePos));
		const re = this.newRegexp(op);
		re.min = min;
		re.max = max;
		re.flags = flags;
		re.subs = [sub];
		this.stack[n - 1] = re;
		this.checkLimits(re);
		if (op === Regexp.Op.REPEAT && (min >= 2 || max >= 2) && !this.repeatIsValid(re, 1e3)) throw new RE2JSSyntaxException(Parser.ERR_INVALID_REPEAT_SIZE, t.from(beforePos));
	}
	repeatIsValid(re, n) {
		if (re.op === Regexp.Op.REPEAT) {
			let m = re.max;
			if (m === 0) return true;
			if (m < 0) m = re.min;
			if (m > n) return false;
			if (m > 0) n = Math.trunc(n / m);
		}
		for (let sub of re.subs) if (!this.repeatIsValid(sub, n)) return false;
		return true;
	}
	concat() {
		this.maybeConcat(-1, 0);
		const subs = this.popToPseudo();
		if (subs.length === 0) return this.push(this.newRegexp(Regexp.Op.EMPTY_MATCH));
		return this.push(this.collapse(subs, Regexp.Op.CONCAT));
	}
	alternate() {
		const subs = this.popToPseudo();
		if (subs.length > 0) this.cleanAlt(subs[subs.length - 1]);
		if (subs.length === 0) return this.push(this.newRegexp(Regexp.Op.NO_MATCH));
		return this.push(this.collapse(subs, Regexp.Op.ALTERNATE));
	}
	cleanAlt(re) {
		if (re.op === Regexp.Op.CHAR_CLASS) {
			re.runes = new CharClass(re.runes).cleanClass().toArray();
			if (re.runes.length === 2 && re.runes[0] === 0 && re.runes[1] === Unicode.MAX_RUNE) {
				re.runes = [];
				re.op = Regexp.Op.ANY_CHAR;
			} else if (re.runes.length === 4 && re.runes[0] === 0 && re.runes[1] === Codepoint.CODES.get("\n") - 1 && re.runes[2] === Codepoint.CODES.get("\n") + 1 && re.runes[3] === Unicode.MAX_RUNE) {
				re.runes = [];
				re.op = Regexp.Op.ANY_CHAR_NOT_NL;
			}
		}
	}
	collapse(subs, op) {
		if (subs.length === 1) return subs[0];
		let len = 0;
		for (let sub of subs) len += sub.op === op ? sub.subs.length : 1;
		let newsubs = new Array(len).fill(null);
		let i = 0;
		for (let sub of subs) if (sub.op === op) {
			for (let j = 0; j < sub.subs.length; j++) newsubs[i++] = sub.subs[j];
			this.reuse(sub);
		} else newsubs[i++] = sub;
		let re = this.newRegexp(op);
		re.subs = newsubs;
		if (op === Regexp.Op.ALTERNATE) {
			re.subs = this.factor(re.subs);
			if (re.subs.length === 1) {
				const old = re;
				re = re.subs[0];
				this.reuse(old);
			}
		}
		return re;
	}
	factor(array) {
		if (array.length < 2) return array;
		let s = 0;
		let lensub = array.length;
		let lenout = 0;
		let str = null;
		let strlen = 0;
		let strflags = 0;
		let start = 0;
		for (let i = 0; i <= lensub; i++) {
			let istr = null;
			let istrlen = 0;
			let iflags = 0;
			if (i < lensub) {
				let re = array[s + i];
				if (re.op === Regexp.Op.CONCAT && re.subs.length > 0) re = re.subs[0];
				if (re.op === Regexp.Op.LITERAL) {
					istr = re.runes;
					istrlen = re.runes.length;
					iflags = re.flags & RE2Flags.FOLD_CASE;
				}
				if (iflags === strflags) {
					let same = 0;
					while (same < strlen && same < istrlen && str[same] === istr[same]) same++;
					if (same > 0) {
						strlen = same;
						continue;
					}
				}
			}
			if (i === start) {} else if (i === start + 1) array[lenout++] = array[s + start];
			else {
				const prefix = this.newRegexp(Regexp.Op.LITERAL);
				prefix.flags = strflags;
				prefix.runes = str.slice(0, strlen);
				for (let j = start; j < i; j++) {
					array[s + j] = this.removeLeadingString(array[s + j], strlen);
					this.checkLimits(array[s + j]);
				}
				const suffix = this.collapse(array.slice(s + start, s + i), Regexp.Op.ALTERNATE);
				const re = this.newRegexp(Regexp.Op.CONCAT);
				re.subs = [prefix, suffix];
				array[lenout++] = re;
			}
			start = i;
			str = istr;
			strlen = istrlen;
			strflags = iflags;
		}
		lensub = lenout;
		s = 0;
		start = 0;
		lenout = 0;
		let first = null;
		for (let i = 0; i <= lensub; i++) {
			let ifirst = null;
			if (i < lensub) {
				ifirst = Parser.leadingRegexp(array[s + i]);
				if (first !== null && first.equals(ifirst) && (Parser.isCharClass(first) || first.op === Regexp.Op.REPEAT && first.min === first.max && Parser.isCharClass(first.subs[0]))) continue;
			}
			if (i === start) {} else if (i === start + 1) array[lenout++] = array[s + start];
			else {
				const prefix = first;
				for (let j = start; j < i; j++) {
					const reuse = j !== start;
					array[s + j] = this.removeLeadingRegexp(array[s + j], reuse);
					this.checkLimits(array[s + j]);
				}
				const suffix = this.collapse(array.slice(s + start, s + i), Regexp.Op.ALTERNATE);
				const re = this.newRegexp(Regexp.Op.CONCAT);
				re.subs = [prefix, suffix];
				array[lenout++] = re;
			}
			start = i;
			first = ifirst;
		}
		lensub = lenout;
		s = 0;
		start = 0;
		lenout = 0;
		for (let i = 0; i <= lensub; i++) {
			if (i < lensub && Parser.isCharClass(array[s + i])) continue;
			if (i === start) {} else if (i === start + 1) array[lenout++] = array[s + start];
			else {
				let max = start;
				for (let j = start + 1; j < i; j++) {
					const subMax = array[s + max];
					const subJ = array[s + j];
					if (subMax.op < subJ.op || subMax.op === subJ.op && (subMax.runes !== null ? subMax.runes.length : 0) < (subJ.runes !== null ? subJ.runes.length : 0)) max = j;
				}
				const tmp = array[s + start];
				array[s + start] = array[s + max];
				array[s + max] = tmp;
				for (let j = start + 1; j < i; j++) {
					Parser.mergeCharClass(array[s + start], array[s + j]);
					this.reuse(array[s + j]);
				}
				this.cleanAlt(array[s + start]);
				array[lenout++] = array[s + start];
			}
			if (i < lensub) array[lenout++] = array[s + i];
			start = i + 1;
		}
		lensub = lenout;
		s = 0;
		start = 0;
		lenout = 0;
		for (let i = 0; i < lensub; ++i) {
			if (i + 1 < lensub && array[s + i].op === Regexp.Op.EMPTY_MATCH && array[s + i + 1].op === Regexp.Op.EMPTY_MATCH) continue;
			array[lenout++] = array[s + i];
		}
		lensub = lenout;
		s = 0;
		return array.slice(s, lensub);
	}
	removeLeadingString(re, n) {
		if (re.op === Regexp.Op.CONCAT && re.subs.length > 0) {
			const sub = this.removeLeadingString(re.subs[0], n);
			re.subs[0] = sub;
			if (sub.op === Regexp.Op.EMPTY_MATCH) {
				this.reuse(sub);
				switch (re.subs.length) {
					case 0:
					case 1:
						re.op = Regexp.Op.EMPTY_MATCH;
						re.subs = Regexp.emptySubs();
						break;
					case 2: {
						const old = re;
						re = re.subs[1];
						this.reuse(old);
						break;
					}
					default:
						re.subs = re.subs.slice(1, re.subs.length);
						break;
				}
			}
			return re;
		}
		if (re.op === Regexp.Op.LITERAL) {
			re.runes = re.runes.slice(n, re.runes.length);
			if (re.runes.length === 0) re.op = Regexp.Op.EMPTY_MATCH;
		}
		return re;
	}
	removeLeadingRegexp(re, reuse) {
		if (re.op === Regexp.Op.CONCAT && re.subs.length > 0) {
			if (reuse) this.reuse(re.subs[0]);
			re.subs = re.subs.slice(1, re.subs.length);
			switch (re.subs.length) {
				case 0:
					re.op = Regexp.Op.EMPTY_MATCH;
					re.subs = Regexp.emptySubs();
					break;
				case 1: {
					const old = re;
					re = re.subs[0];
					this.reuse(old);
					break;
				}
			}
			return re;
		}
		if (reuse) this.reuse(re);
		return this.newRegexp(Regexp.Op.EMPTY_MATCH);
	}
	parseInternal() {
		if ((this.flags & RE2Flags.LITERAL) !== 0) return Parser.literalRegexp(this.wholeRegexp, this.flags);
		let lastRepeatPos = -1;
		let min = -1;
		let max = -1;
		const t = new StringIterator(this.wholeRegexp);
		while (t.more()) {
			let repeatPos = -1;
			bigswitch: switch (t.peek()) {
				case Codepoint.CODES.get("("):
					if ((this.flags & RE2Flags.LOOKBEHIND) !== 0) {
						if (t.lookingAt("(?<=")) {
							this.parsePosLookBehind();
							t.skip(4);
							break;
						}
						if (t.lookingAt("(?<!")) {
							this.parseNegLookBehind();
							t.skip(4);
							break;
						}
					}
					if ((this.flags & RE2Flags.PERL_X) !== 0 && t.lookingAt("(?")) {
						this.parsePerlFlags(t);
						break;
					}
					this.op(Regexp.Op.LEFT_PAREN).cap = ++this.numCap;
					t.skip(1);
					break;
				case Codepoint.CODES.get("|"):
					this.parseVerticalBar();
					t.skip(1);
					break;
				case Codepoint.CODES.get(")"):
					this.parseRightParen();
					t.skip(1);
					break;
				case Codepoint.CODES.get("^"):
					if ((this.flags & RE2Flags.ONE_LINE) !== 0) this.op(Regexp.Op.BEGIN_TEXT);
					else this.op(Regexp.Op.BEGIN_LINE);
					t.skip(1);
					break;
				case Codepoint.CODES.get("$"):
					if ((this.flags & RE2Flags.ONE_LINE) !== 0) this.op(Regexp.Op.END_TEXT).flags |= RE2Flags.WAS_DOLLAR;
					else this.op(Regexp.Op.END_LINE);
					t.skip(1);
					break;
				case Codepoint.CODES.get("."):
					if ((this.flags & RE2Flags.DOT_NL) !== 0) this.op(Regexp.Op.ANY_CHAR);
					else this.op(Regexp.Op.ANY_CHAR_NOT_NL);
					t.skip(1);
					break;
				case Codepoint.CODES.get("["):
					this.parseClass(t);
					break;
				case Codepoint.CODES.get("*"):
				case Codepoint.CODES.get("+"):
				case Codepoint.CODES.get("?"): {
					repeatPos = t.pos();
					let op = null;
					switch (t.pop()) {
						case Codepoint.CODES.get("*"):
							op = Regexp.Op.STAR;
							break;
						case Codepoint.CODES.get("+"):
							op = Regexp.Op.PLUS;
							break;
						case Codepoint.CODES.get("?"):
							op = Regexp.Op.QUEST;
							break;
					}
					this.repeat(op, min, max, repeatPos, t, lastRepeatPos);
					break;
				}
				case Codepoint.CODES.get("{"): {
					repeatPos = t.pos();
					const minMax = Parser.parseRepeat(t);
					if (minMax < 0) {
						t.rewindTo(repeatPos);
						this.literal(t.pop());
						break;
					}
					min = minMax >> 16;
					max = (minMax & Unicode.MAX_BMP) << 16 >> 16;
					this.repeat(Regexp.Op.REPEAT, min, max, repeatPos, t, lastRepeatPos);
					break;
				}
				case Codepoint.CODES.get("\\"): {
					const savedPos = t.pos();
					t.skip(1);
					if ((this.flags & RE2Flags.PERL_X) !== 0 && t.more()) switch (t.pop()) {
						case Codepoint.CODES.get("A"):
							this.op(Regexp.Op.BEGIN_TEXT);
							break bigswitch;
						case Codepoint.CODES.get("b"):
							this.op(Regexp.Op.WORD_BOUNDARY);
							break bigswitch;
						case Codepoint.CODES.get("B"):
							this.op(Regexp.Op.NO_WORD_BOUNDARY);
							break bigswitch;
						case Codepoint.CODES.get("C"): throw new RE2JSSyntaxException(Parser.ERR_INVALID_ESCAPE, "\\C");
						case Codepoint.CODES.get("Q"): {
							let lit = t.rest();
							const i = lit.indexOf("\\E");
							if (i >= 0) {
								lit = lit.substring(0, i);
								t.skipString(lit);
								t.skipString("\\E");
							} else t.skipString(lit);
							let j = 0;
							while (j < lit.length) {
								const codepoint = lit.codePointAt(j);
								this.literal(codepoint);
								j += Utils.charCount(codepoint);
							}
							break bigswitch;
						}
						case Codepoint.CODES.get("z"):
							this.op(Regexp.Op.END_TEXT);
							break bigswitch;
						default:
							t.rewindTo(savedPos);
							break;
					}
					else t.rewindTo(savedPos);
					const re = this.newRegexp(Regexp.Op.CHAR_CLASS);
					re.flags = this.flags;
					if (t.lookingAt("\\p") || t.lookingAt("\\P")) {
						const cc = new CharClass();
						if (this.parseUnicodeClass(t, cc)) {
							re.runes = cc.toArray();
							this.push(re);
							break bigswitch;
						}
					}
					const cc = new CharClass();
					if (this.parsePerlClassEscape(t, cc)) {
						re.runes = cc.toArray();
						this.push(re);
						break bigswitch;
					}
					t.rewindTo(savedPos);
					this.reuse(re);
					this.literal(Parser.parseEscape(t));
					break;
				}
				default:
					this.literal(t.pop());
					break;
			}
			lastRepeatPos = repeatPos;
		}
		this.concat();
		if (this.swapVerticalBar()) this.pop();
		this.alternate();
		if (this.stack.length !== 1) throw new RE2JSSyntaxException(Parser.ERR_MISSING_PAREN, this.wholeRegexp);
		this.stack[0].namedGroups = this.namedGroups;
		return this.stack[0];
	}
	parsePerlFlags(t) {
		const startPos = t.pos();
		const s = t.rest();
		if (s.startsWith("(?P<") || s.startsWith("(?<")) {
			const begin = s.charAt(2) === "P" ? 4 : 3;
			const end = s.indexOf(">");
			if (end < 0) throw new RE2JSSyntaxException(Parser.ERR_INVALID_NAMED_CAPTURE, s);
			const name = s.substring(begin, end);
			t.skipString(name);
			t.skip(begin + 1);
			if (!Parser.isValidCaptureName(name)) throw new RE2JSSyntaxException(Parser.ERR_INVALID_NAMED_CAPTURE, s.substring(0, end + 1));
			const re = this.op(Regexp.Op.LEFT_PAREN);
			re.cap = ++this.numCap;
			if (this.namedGroups[name]) throw new RE2JSSyntaxException(Parser.ERR_DUPLICATE_NAMED_CAPTURE, name);
			this.namedGroups[name] = this.numCap;
			re.name = name;
			return;
		}
		t.skip(2);
		let flags = this.flags;
		let sign = 1;
		let sawFlag = false;
		loop: while (t.more()) {
			const c = t.pop();
			switch (c) {
				case Codepoint.CODES.get("i"):
					flags |= RE2Flags.FOLD_CASE;
					sawFlag = true;
					break;
				case Codepoint.CODES.get("m"):
					flags &= ~RE2Flags.ONE_LINE;
					sawFlag = true;
					break;
				case Codepoint.CODES.get("s"):
					flags |= RE2Flags.DOT_NL;
					sawFlag = true;
					break;
				case Codepoint.CODES.get("U"):
					flags |= RE2Flags.NON_GREEDY;
					sawFlag = true;
					break;
				case Codepoint.CODES.get("-"):
					if (sign < 0) break loop;
					sign = -1;
					flags = ~flags;
					sawFlag = false;
					break;
				case Codepoint.CODES.get(":"):
				case Codepoint.CODES.get(")"):
					if (sign < 0) {
						if (!sawFlag) break loop;
						flags = ~flags;
					}
					if (c === Codepoint.CODES.get(":")) this.op(Regexp.Op.LEFT_PAREN);
					this.flags = flags;
					return;
				default: break loop;
			}
		}
		throw new RE2JSSyntaxException(Parser.ERR_INVALID_PERL_OP, t.from(startPos));
	}
	parsePosLookBehind() {
		const re = this.newRegexp(Regexp.Op.LEFT_PAREN);
		re.flags = this.flags;
		re.lb = ++this.nlb;
		return this.push(re);
	}
	parseNegLookBehind() {
		const re = this.newRegexp(Regexp.Op.LEFT_PAREN);
		re.flags = this.flags;
		re.lb = -++this.nlb;
		return this.push(re);
	}
	parseVerticalBar() {
		this.concat();
		if (!this.swapVerticalBar()) this.op(Regexp.Op.VERTICAL_BAR);
	}
	swapVerticalBar() {
		const n = this.stack.length;
		if (n >= 3 && this.stack[n - 2].op === Regexp.Op.VERTICAL_BAR && Parser.isCharClass(this.stack[n - 1]) && Parser.isCharClass(this.stack[n - 3])) {
			let re1 = this.stack[n - 1];
			let re3 = this.stack[n - 3];
			if (re1.op > re3.op) {
				const tmp = re3;
				re3 = re1;
				re1 = tmp;
				this.stack[n - 3] = re3;
			}
			Parser.mergeCharClass(re3, re1);
			this.reuse(re1);
			this.pop();
			return true;
		}
		if (n >= 2) {
			const re1 = this.stack[n - 1];
			const re2 = this.stack[n - 2];
			if (re2.op === Regexp.Op.VERTICAL_BAR) {
				if (n >= 3) this.cleanAlt(this.stack[n - 3]);
				this.stack[n - 2] = re1;
				this.stack[n - 1] = re2;
				return true;
			}
		}
		return false;
	}
	parseRightParen() {
		this.concat();
		if (this.swapVerticalBar()) this.pop();
		this.alternate();
		if (this.stack.length < 2) throw new RE2JSSyntaxException(Parser.ERR_UNEXPECTED_PAREN, this.wholeRegexp);
		const re1 = this.pop();
		const re2 = this.pop();
		if (re2.op !== Regexp.Op.LEFT_PAREN) throw new RE2JSSyntaxException(Parser.ERR_UNEXPECTED_PAREN, this.wholeRegexp);
		this.flags = re2.flags;
		if (re2.lb !== 0) {
			if (Parser.hasCapture(re1)) throw new RE2JSSyntaxException(Parser.ERR_INVALID_CAPTURE_IN_LOOKBEHIND, this.wholeRegexp);
			if (re2.lb > 0) re2.op = Regexp.Op.PLB;
			else re2.op = Regexp.Op.NLB;
			re2.subs = [re1];
			this.push(re2);
			return;
		}
		if (re2.cap === 0) this.push(re1);
		else {
			re2.op = Regexp.Op.CAPTURE;
			re2.subs = [re1];
			this.push(re2);
		}
	}
	parsePerlClassEscape(t, cc) {
		const beforePos = t.pos();
		if ((this.flags & RE2Flags.PERL_X) === 0 || !t.more() || t.pop() !== Codepoint.CODES.get("\\") || !t.more()) return false;
		t.pop();
		const p = t.from(beforePos);
		const g = PERL_GROUPS.has(p) ? PERL_GROUPS.get(p) : null;
		if (g === null) return false;
		cc.appendGroup(g, (this.flags & RE2Flags.FOLD_CASE) !== 0);
		return true;
	}
	parseNamedClass(t, cc) {
		const cls = t.rest();
		const i = cls.indexOf(":]");
		if (i < 0) return false;
		const name = cls.substring(0, i + 2);
		t.skipString(name);
		const g = POSIX_GROUPS.has(name) ? POSIX_GROUPS.get(name) : null;
		if (g === null) throw new RE2JSSyntaxException(Parser.ERR_INVALID_CHAR_RANGE, name);
		cc.appendGroup(g, (this.flags & RE2Flags.FOLD_CASE) !== 0);
		return true;
	}
	parseUnicodeClass(t, cc) {
		const startPos = t.pos();
		if ((this.flags & RE2Flags.UNICODE_GROUPS) === 0 || !t.lookingAt("\\p") && !t.lookingAt("\\P")) return false;
		t.skip(1);
		let sign = 1;
		let c = t.pop();
		if (c === Codepoint.CODES.get("P")) sign = -1;
		if (!t.more()) {
			t.rewindTo(startPos);
			throw new RE2JSSyntaxException(Parser.ERR_INVALID_CHAR_RANGE, t.rest());
		}
		c = t.pop();
		let name;
		if (c !== Codepoint.CODES.get("{")) name = Utils.runeToString(c);
		else {
			const rest = t.rest();
			const end = rest.indexOf("}");
			if (end < 0) {
				t.rewindTo(startPos);
				throw new RE2JSSyntaxException(Parser.ERR_INVALID_CHAR_RANGE, t.rest());
			}
			name = rest.substring(0, end);
			t.skipString(name);
			t.skip(1);
		}
		if (!(name.length === 0) && name.codePointAt(0) === Codepoint.CODES.get("^")) {
			sign = 0 - sign;
			name = name.substring(1);
		}
		const pair = Parser.unicodeTable(name);
		if (pair === null) throw new RE2JSSyntaxException(Parser.ERR_INVALID_CHAR_RANGE, t.from(startPos));
		if (pair.sign < 0) sign = 0 - sign;
		const tab = pair.tab;
		const fold = pair.fold;
		if ((this.flags & RE2Flags.FOLD_CASE) === 0 || fold === null) cc.appendTableWithSign(tab, sign);
		else {
			const tmp = new CharClass().appendTable(tab).appendTable(fold).cleanClass().toArray();
			cc.appendClassWithSign(tmp, sign);
		}
		return true;
	}
	parseClass(t) {
		const startPos = t.pos();
		t.skip(1);
		const re = this.newRegexp(Regexp.Op.CHAR_CLASS);
		re.flags = this.flags;
		const cc = new CharClass();
		let sign = 1;
		if (t.more() && t.lookingAt("^")) {
			sign = -1;
			t.skip(1);
			if ((this.flags & RE2Flags.CLASS_NL) === 0) cc.appendRange(Codepoint.CODES.get("\n"), Codepoint.CODES.get("\n"));
		}
		let first = true;
		while (!t.more() || t.peek() !== Codepoint.CODES.get("]") || first) {
			if (t.more() && t.lookingAt("-") && (this.flags & RE2Flags.PERL_X) === 0 && !first) {
				const s = t.rest();
				if (s === "-" || !s.startsWith("-]")) {
					t.rewindTo(startPos);
					throw new RE2JSSyntaxException(Parser.ERR_INVALID_CHAR_RANGE, t.rest());
				}
			}
			first = false;
			const beforePos = t.pos();
			if (t.lookingAt("[:")) {
				if (this.parseNamedClass(t, cc)) continue;
				t.rewindTo(beforePos);
			}
			if (this.parseUnicodeClass(t, cc)) continue;
			if (this.parsePerlClassEscape(t, cc)) continue;
			t.rewindTo(beforePos);
			const lo = Parser.parseClassChar(t, startPos);
			let hi = lo;
			if (t.more() && t.lookingAt("-")) {
				t.skip(1);
				if (t.more() && t.lookingAt("]")) t.skip(-1);
				else {
					hi = Parser.parseClassChar(t, startPos);
					if (hi < lo) throw new RE2JSSyntaxException(Parser.ERR_INVALID_CHAR_RANGE, t.from(beforePos));
				}
			}
			if ((this.flags & RE2Flags.FOLD_CASE) === 0) cc.appendRange(lo, hi);
			else cc.appendFoldedRange(lo, hi);
		}
		t.skip(1);
		cc.cleanClass();
		if (sign < 0) cc.negateClass();
		re.runes = cc.toArray();
		this.push(re);
	}
};
//#endregion
//#region src/RE2.js
/**
* An RE2 class instance is a compiled representation of an RE2 regular expression, independent of
* the public Java-like Pattern/Matcher API.
*
* This class also contains various implementation helpers for RE2 regular expressions.
*
* Use the {@link #quoteMeta(String)} utility function to quote all regular expression
* metacharacters in an arbitrary string.
*
*/
var RE2 = class RE2 {
	static initTest(expr) {
		const re2 = RE2.compile(expr);
		const res = new RE2(re2.expr, re2.prog, re2.numSubexp, re2.longest);
		res.cond = re2.cond;
		res.prefix = re2.prefix;
		res.prefixUTF8 = re2.prefixUTF8;
		res.prefixComplete = re2.prefixComplete;
		res.prefixRune = re2.prefixRune;
		res.prefilter = re2.prefilter;
		return res;
	}
	/**
	* Parses a regular expression and returns, if successful, an {@code RE2} instance that can be
	* used to match against text.
	*
	* When matching against text, the regexp returns a match that begins as early as possible in the
	* input (leftmost), and among those it chooses the one that a backtracking search would have
	* found first. This so-called leftmost-first matching is the same semantics that Perl, Python,
	* and other implementations use, although this package implements it without the expense of
	* backtracking. For POSIX leftmost-longest matching, see {@link #compilePOSIX}.
	*/
	static compile(expr) {
		return RE2.compileImpl(expr, RE2Flags.PERL, false);
	}
	/**
	* {@code compilePOSIX} is like {@link #compile} but restricts the regular expression to POSIX ERE
	* (egrep) syntax and changes the match semantics to leftmost-longest.
	*
	* That is, when matching against text, the regexp returns a match that begins as early as
	* possible in the input (leftmost), and among those it chooses a match that is as long as
	* possible. This so-called leftmost-longest matching is the same semantics that early regular
	* expression implementations used and that POSIX specifies.
	*
	* However, there can be multiple leftmost-longest matches, with different submatch choices, and
	* here this package diverges from POSIX. Among the possible leftmost-longest matches, this
	* package chooses the one that a backtracking search would have found first, while POSIX
	* specifies that the match be chosen to maximize the length of the first subexpression, then the
	* second, and so on from left to right. The POSIX rule is computationally prohibitive and not
	* even well-defined. See http://swtch.com/~rsc/regexp/regexp2.html#posix
	*/
	static compilePOSIX(expr) {
		return RE2.compileImpl(expr, RE2Flags.POSIX, true);
	}
	static compileImpl(expr, mode, longest) {
		let re = Parser.parse(expr, mode);
		const maxCap = re.maxCap();
		re = Simplify.simplify(re);
		const prefilter = PrefilterTree.build(re);
		const prog = Compiler.compileRegexp(re);
		const re2 = new RE2(expr, prog, maxCap, longest);
		re2.prefilter = prefilter.type === Prefilter.Type.NONE ? null : prefilter;
		const [prefixCompl, prefixStr] = prog.prefix();
		re2.prefixComplete = prefixCompl;
		re2.prefix = prefixStr;
		re2.prefixUTF8 = Utils.stringToUtf8ByteArray(re2.prefix);
		if (re2.prefix.length > 0) re2.prefixRune = re2.prefix.codePointAt(0);
		re2.namedGroups = re.namedGroups;
		return re2;
	}
	/**
	* Returns true iff textual regular expression {@code pattern} matches string {@code s}.
	*
	* More complicated queries need to use {@link #compile} and the full {@code RE2} interface.
	*/
	static match(pattern, s) {
		return RE2.compile(pattern).match(s);
	}
	constructor(expr, prog, numSubexp = 0, longest = 0) {
		this.expr = expr;
		this.prog = prog;
		this.numSubexp = numSubexp;
		this.longest = longest;
		this.cond = prog.startCond();
		this.prefix = null;
		this.prefixUTF8 = null;
		this.prefixComplete = false;
		this.prefixRune = 0;
		this.machinePool = [];
		this.dfa = new DFA(this.prog);
		this.onepass = OnePass.compile(this.prog);
		this.prefilter = null;
	}
	matchPrefixComplete(input, pos, anchor, ncap) {
		if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && pos !== 0) return null;
		let matchStart = -1;
		let matchEnd = -1;
		const pLen = input.prefixLength(this);
		if (anchor === RE2Flags.UNANCHORED) {
			const idx = input.index(this, pos);
			if (idx < 0) return null;
			matchStart = pos + idx;
			matchEnd = matchStart + pLen;
		} else if (anchor === RE2Flags.ANCHOR_BOTH) {
			if (input.endPos() !== pLen) return null;
			if (input.index(this, 0) !== 0) return null;
			matchStart = 0;
			matchEnd = pLen;
		} else if (anchor === RE2Flags.ANCHOR_START) {
			if (input.index(this, 0) !== 0) return null;
			matchStart = 0;
			matchEnd = pLen;
		}
		if (matchStart < 0) return null;
		if (ncap > 0) {
			const matchcap = new Int32Array(ncap).fill(-1);
			matchcap[0] = matchStart;
			matchcap[1] = matchEnd;
			return Array.from(matchcap);
		}
		return [];
	}
	executeEngine(input, pos, anchor, ncap) {
		if (this.prefixComplete && (ncap === 0 || this.numSubexp === 0)) return this.matchPrefixComplete(input, pos, anchor, ncap);
		if (this.prefilter !== null && anchor === RE2Flags.UNANCHORED) {
			if (!this.prefilter.eval(input, pos)) return null;
		}
		if (this.onepass !== null) return OnePass.execute(this, input, pos, anchor, ncap);
		if (ncap > 0) {
			if (this.prog.numLb === 0 && input.endPos() <= Backtracker.maxBitStateLen(this.prog)) return Backtracker.execute(this, input, pos, anchor, ncap);
			return this.doExecuteNFA(input, pos, anchor, ncap);
		}
		if (this.prog.numLb === 0) {
			const dfaResult = this.dfa.match(input, pos, anchor);
			if (dfaResult !== null) return dfaResult ? [] : null;
			if (input.endPos() <= Backtracker.maxBitStateLen(this.prog)) return Backtracker.execute(this, input, pos, anchor, ncap);
		}
		return this.doExecuteNFA(input, pos, anchor, ncap);
	}
	/**
	* Returns the number of parenthesized subexpressions in this regular expression.
	*/
	numberOfCapturingGroups() {
		return this.numSubexp;
	}
	/**
	* Returns the number of instructions in this compiled regular expression program.
	*/
	numberOfInstructions() {
		return this.prog.numInst();
	}
	get() {
		return this.machinePool.length > 0 ? this.machinePool.pop() : null;
	}
	reset() {
		this.machinePool.length = 0;
	}
	put(m) {
		this.machinePool.push(m);
	}
	toString() {
		return this.expr;
	}
	doExecuteNFA(input, pos, anchor, ncap) {
		let m = this.get();
		if (!m) m = Machine.fromRE2(this);
		m.init(ncap);
		const cap = m.match(input, pos, anchor) ? m.submatches() : null;
		this.put(m);
		return cap;
	}
	match(s) {
		return this.executeEngine(MachineInput.fromUTF16(s), 0, RE2Flags.UNANCHORED, 0) !== null;
	}
	/**
	* Matches the regular expression against input starting at position start and ending at position
	* end, with the given anchoring. Records the submatch boundaries in group, which is [start, end)
	* pairs of byte offsets. The number of boundaries needed is inferred from the size of the group
	* array. It is most efficient not to ask for submatch boundaries.
	*
	* @param input the input byte array
	* @param start the beginning position in the input
	* @param end the end position in the input
	* @param anchor the anchoring flag (UNANCHORED, ANCHOR_START, ANCHOR_BOTH)
	* @param group the array to fill with submatch positions
	* @param ngroup the number of array pairs to fill in
	* @returns true if a match was found
	*/
	matchWithGroup(input, start, end, anchor, ngroup) {
		if (!(input instanceof MatcherInputBase)) if (Utils.isByteArray(input)) input = MatcherInput.utf8(input);
		else input = MatcherInput.utf16(input);
		return this.matchMachineInput(input, start, end, anchor, ngroup);
	}
	matchMachineInput(input, start, end, anchor, ngroup) {
		if (start > end) return [false, null];
		const machineInput = input.isUTF16Encoding() ? MachineInput.fromUTF16(input.asCharSequence(), 0, end) : MachineInput.fromUTF8(input.asBytes(), 0, end);
		const groupMatch = this.executeEngine(machineInput, start, anchor, 2 * ngroup);
		if (groupMatch === null) return [false, null];
		return [true, groupMatch];
	}
	/**
	* Returns true iff this regexp matches the UTF-8 byte array {@code b}.
	*/
	matchUTF8(b) {
		return this.executeEngine(MachineInput.fromUTF8(b), 0, RE2Flags.UNANCHORED, 0) !== null;
	}
	/**
	* Returns a copy of {@code src} in which all matches for this regexp have been replaced by
	* {@code repl}. No support is provided for expressions (e.g. {@code \1} or {@code $1}) in the
	* replacement string.
	*/
	replaceAll(src, repl) {
		return this.replaceAllFunc(src, () => repl, 2 * src.length + 1);
	}
	/**
	* Returns a copy of {@code src} in which only the first match for this regexp has been replaced
	* by {@code repl}. No support is provided for expressions (e.g. {@code \1} or {@code $1}) in the
	* replacement string.
	*/
	replaceFirst(src, repl) {
		return this.replaceAllFunc(src, () => repl, 1);
	}
	/**
	* Returns a copy of {@code src} in which at most {@code maxReplaces} matches for this regexp have
	* been replaced by the return value of of function {@code repl} (whose first argument is the
	* matched string). No support is provided for expressions (e.g. {@code \1} or {@code $1}) in the
	* replacement string.
	*/
	replaceAllFunc(src, replFunc, maxReplaces) {
		let lastMatchEnd = 0;
		let searchPos = 0;
		let out = "";
		const input = MachineInput.fromUTF16(src);
		let numReplaces = 0;
		while (searchPos <= src.length) {
			const a = this.executeEngine(input, searchPos, RE2Flags.UNANCHORED, 2);
			if (a === null || a.length === 0) break;
			out += src.substring(lastMatchEnd, a[0]);
			if (a[1] > lastMatchEnd || a[0] === 0) {
				out += replFunc(src.substring(a[0], a[1]));
				numReplaces++;
			}
			lastMatchEnd = a[1];
			const width = input.step(searchPos) & 7;
			if (searchPos + width > a[1]) searchPos += width;
			else if (searchPos + 1 > a[1]) searchPos++;
			else searchPos = a[1];
			if (numReplaces >= maxReplaces) break;
		}
		out += src.substring(lastMatchEnd);
		return out;
	}
	pad(a) {
		if (a === null) return null;
		let n = (1 + this.numSubexp) * 2;
		if (a.length < n) {
			let a2 = new Array(n).fill(-1);
			for (let i = 0; i < a.length; i++) a2[i] = a[i];
			a = a2;
		}
		return a;
	}
	allMatches(input, n, deliverFun = (v) => v) {
		let result = [];
		const end = input.endPos();
		if (n < 0) n = end + 1;
		let pos = 0;
		let i = 0;
		let prevMatchEnd = -1;
		while (i < n && pos <= end) {
			const matches = this.executeEngine(input, pos, RE2Flags.UNANCHORED, this.prog.numCap);
			if (matches === null || matches.length === 0) break;
			let accept = true;
			if (matches[1] === pos) {
				if (matches[0] === prevMatchEnd) accept = false;
				const r = input.step(pos);
				if (r < 0) pos = end + 1;
				else pos += r & 7;
			} else pos = matches[1];
			prevMatchEnd = matches[1];
			if (accept) {
				result.push(deliverFun(this.pad(matches)));
				i++;
			}
		}
		return result;
	}
	/**
	* Returns an array holding the text of the leftmost match in {@code b} of this regular
	* expression.
	*
	* A return value of null indicates no match.
	*/
	findUTF8(b) {
		const a = this.executeEngine(MachineInput.fromUTF8(b), 0, RE2Flags.UNANCHORED, 2);
		if (a === null) return null;
		return b.slice(a[0], a[1]);
	}
	/**
	* Returns a two-element array of integers defining the location of the leftmost match in
	* {@code b} of this regular expression. The match itself is at {@code b[loc[0]...loc[1]]}.
	*
	* A return value of null indicates no match.
	*/
	findUTF8Index(b) {
		const a = this.executeEngine(MachineInput.fromUTF8(b), 0, RE2Flags.UNANCHORED, 2);
		if (a === null) return null;
		return a.slice(0, 2);
	}
	/**
	* Returns a string holding the text of the leftmost match in {@code s} of this regular
	* expression.
	*
	* If there is no match, the return value is an empty string, but it will also be empty if the
	* regular expression successfully matches an empty string. Use {@link #findIndex} or
	* {@link #findSubmatch} if it is necessary to distinguish these cases.
	*/
	find(s) {
		const a = this.executeEngine(MachineInput.fromUTF16(s), 0, RE2Flags.UNANCHORED, 2);
		if (a === null) return "";
		return s.substring(a[0], a[1]);
	}
	/**
	* Returns a two-element array of integers defining the location of the leftmost match in
	* {@code s} of this regular expression. The match itself is at
	* {@code s.substring(loc[0], loc[1])}.
	*
	* A return value of null indicates no match.
	*/
	findIndex(s) {
		return this.executeEngine(MachineInput.fromUTF16(s), 0, RE2Flags.UNANCHORED, 2);
	}
	/**
	* Returns an array of arrays the text of the leftmost match of the regular expression in
	* {@code b} and the matches, if any, of its subexpressions, as defined by the <a
	* href='#submatch'>Submatch</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findUTF8Submatch(b) {
		const a = this.executeEngine(MachineInput.fromUTF8(b), 0, RE2Flags.UNANCHORED, this.prog.numCap);
		if (a === null) return null;
		const ret = new Array(1 + this.numSubexp).fill(null);
		for (let i = 0; i < ret.length; i++) if (2 * i < a.length && a[2 * i] >= 0) ret[i] = b.slice(a[2 * i], a[2 * i + 1]);
		return ret;
	}
	/**
	* Returns an array holding the index pairs identifying the leftmost match of this regular
	* expression in {@code b} and the matches, if any, of its subexpressions, as defined by the the
	* <a href='#submatch'>Submatch</a> and <a href='#index'>Index</a> descriptions above.
	*
	* A return value of null indicates no match.
	*/
	findUTF8SubmatchIndex(b) {
		return this.pad(this.executeEngine(MachineInput.fromUTF8(b), 0, RE2Flags.UNANCHORED, this.prog.numCap));
	}
	/**
	* Returns an array of strings holding the text of the leftmost match of the regular expression in
	* {@code s} and the matches, if any, of its subexpressions, as defined by the <a
	* href='#submatch'>Submatch</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findSubmatch(s) {
		const a = this.executeEngine(MachineInput.fromUTF16(s), 0, RE2Flags.UNANCHORED, this.prog.numCap);
		if (a === null) return null;
		const ret = new Array(1 + this.numSubexp).fill(null);
		for (let i = 0; i < ret.length; i++) if (2 * i < a.length && a[2 * i] >= 0) ret[i] = s.substring(a[2 * i], a[2 * i + 1]);
		return ret;
	}
	/**
	* Returns an array holding the index pairs identifying the leftmost match of this regular
	* expression in {@code s} and the matches, if any, of its subexpressions, as defined by the <a
	* href='#submatch'>Submatch</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findSubmatchIndex(s) {
		return this.pad(this.executeEngine(MachineInput.fromUTF16(s), 0, RE2Flags.UNANCHORED, this.prog.numCap));
	}
	/**
	* {@code findAllUTF8()} is the <a href='#all'>All</a> version of {@link #findUTF8}; it returns a
	* list of up to {@code n} successive matches of the expression, as defined by the <a
	* href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*
	* TODO(adonovan): think about defining a byte slice view class, like a read-only Go slice backed
	* by |b|.
	*/
	findAllUTF8(b, n) {
		const result = this.allMatches(MachineInput.fromUTF8(b), n, (match) => b.slice(match[0], match[1]));
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAllUTF8Index} is the <a href='#all'>All</a> version of {@link #findUTF8Index}; it
	* returns a list of up to {@code n} successive matches of the expression, as defined by the <a
	* href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findAllUTF8Index(b, n) {
		const result = this.allMatches(MachineInput.fromUTF8(b), n, (match) => match.slice(0, 2));
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAll} is the <a href='#all'>All</a> version of {@link #find}; it returns a list of up
	* to {@code n} successive matches of the expression, as defined by the <a href='#all'>All</a>
	* description above.
	*
	* A return value of null indicates no match.
	*/
	findAll(s, n) {
		const result = this.allMatches(MachineInput.fromUTF16(s), n, (match) => s.substring(match[0], match[1]));
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAllIndex} is the <a href='#all'>All</a> version of {@link #findIndex}; it returns a
	* list of up to {@code n} successive matches of the expression, as defined by the <a
	* href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findAllIndex(s, n) {
		const result = this.allMatches(MachineInput.fromUTF16(s), n, (match) => match.slice(0, 2));
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAllUTF8Submatch} is the <a href='#all'>All</a> version of {@link #findUTF8Submatch};
	* it returns a list of up to {@code n} successive matches of the expression, as defined by the <a
	* href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findAllUTF8Submatch(b, n) {
		const result = this.allMatches(MachineInput.fromUTF8(b), n, (match) => {
			let slice = new Array(match.length / 2 | 0).fill(null);
			for (let j = 0; j < slice.length; j++) if (match[2 * j] >= 0) slice[j] = b.slice(match[2 * j], match[2 * j + 1]);
			return slice;
		});
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAllUTF8SubmatchIndex} is the <a href='#all'>All</a> version of
	* {@link #findUTF8SubmatchIndex}; it returns a list of up to {@code n} successive matches of the
	* expression, as defined by the <a href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findAllUTF8SubmatchIndex(b, n) {
		const result = this.allMatches(MachineInput.fromUTF8(b), n);
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAllSubmatch} is the <a href='#all'>All</a> version of {@link #findSubmatch}; it
	* returns a list of up to {@code n} successive matches of the expression, as defined by the <a
	* href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findAllSubmatch(s, n) {
		const result = this.allMatches(MachineInput.fromUTF16(s), n, (match) => {
			let slice = new Array(match.length / 2 | 0).fill(null);
			for (let j = 0; j < slice.length; j++) if (match[2 * j] >= 0) slice[j] = s.substring(match[2 * j], match[2 * j + 1]);
			return slice;
		});
		if (result.length === 0) return null;
		return result;
	}
	/**
	* {@code findAllSubmatchIndex} is the <a href='#all'>All</a> version of
	* {@link #findSubmatchIndex}; it returns a list of up to {@code n} successive matches of the
	* expression, as defined by the <a href='#all'>All</a> description above.
	*
	* A return value of null indicates no match.
	*/
	findAllSubmatchIndex(s, n) {
		const result = this.allMatches(MachineInput.fromUTF16(s), n);
		if (result.length === 0) return null;
		return result;
	}
};
//#endregion
//#region src/Set.js
var RE2Set = class RE2Set {
	/** @type {number} */
	static UNANCHORED = RE2Flags.UNANCHORED;
	/** @type {number} */
	static ANCHOR_START = RE2Flags.ANCHOR_START;
	/** @type {number} */
	static ANCHOR_BOTH = RE2Flags.ANCHOR_BOTH;
	/**
	* Constructs a new RE2Set with the specified anchor mode and flags.
	* @param {number} [anchor=RE2Set.UNANCHORED] - The anchoring mode (e.g., RE2Set.UNANCHORED).
	* @param {number} [flags=0] - The public flags to apply to all patterns in the set.
	* @param {number} [maxMem=8388608] - The maximum memory in bytes to use for the DFA (default 8MB).
	*/
	constructor(anchor = RE2Set.UNANCHORED, flags = 0, maxMem = 8388608) {
		this.anchor = anchor;
		this.jsFlags = flags;
		this.maxMem = maxMem;
		let re2Flags = RE2Flags.PERL;
		if ((flags & PublicFlags.DISABLE_UNICODE_GROUPS) !== 0) re2Flags &= ~RE2Flags.UNICODE_GROUPS;
		if ((flags & PublicFlags.LOOKBEHINDS) !== 0) re2Flags |= RE2Flags.LOOKBEHIND;
		this.re2Flags = re2Flags;
		this.regexps = [];
		this.prog = null;
		this.dfa = null;
		this.dummyRe2 = null;
	}
	/**
	* Adds a new regular expression pattern to the set.
	* Patterns cannot be added after the set has been compiled.
	* @param {string} pattern - The regular expression pattern to add.
	* @returns {number} The integer index assigned to the added pattern.
	* @throws {RE2JSCompileException} If patterns are added after compilation.
	*/
	add(pattern) {
		if (this.prog) throw new RE2JSCompileException("Cannot add patterns after compile");
		let fregex = pattern;
		if ((this.jsFlags & PublicFlags.CASE_INSENSITIVE) !== 0) fregex = `(?i)${fregex}`;
		if ((this.jsFlags & PublicFlags.DOTALL) !== 0) fregex = `(?s)${fregex}`;
		if ((this.jsFlags & PublicFlags.MULTILINE) !== 0) fregex = `(?m)${fregex}`;
		const re = Parser.parse(fregex, this.re2Flags);
		this.regexps.push(Simplify.simplify(re));
		return this.regexps.length - 1;
	}
	/**
	* Compiles the added patterns into a single state machine.
	* This is automatically called on the first match if not called explicitly.
	* @returns {void}
	*/
	compile() {
		if (this.prog) return;
		this.prog = Compiler.compileSet(this.regexps);
		this.dfa = new DFA(this.prog, this.maxMem);
		this.dummyRe2 = {
			prog: this.prog,
			cond: this.prog.startCond(),
			prefix: "",
			prefixRune: 0,
			longest: false
		};
	}
	/**
	* Matches the input against the compiled set of regular expressions.
	* @param {string|number[]|Uint8Array} input - The input string or UTF-8 byte array to match against.
	* @returns {number[]} An array of indices representing the patterns that successfully matched the input.
	*/
	match(input) {
		if (!this.prog) this.compile();
		const machineInput = Utils.isByteArray(input) ? MachineInput.fromUTF8(input) : MachineInput.fromUTF16(input);
		let internalAnchor = RE2Flags.UNANCHORED;
		if (this.anchor === RE2Set.ANCHOR_START) internalAnchor = RE2Flags.ANCHOR_START;
		else if (this.anchor === RE2Set.ANCHOR_BOTH) internalAnchor = RE2Flags.ANCHOR_BOTH;
		const dfaResult = this.dfa.matchSet(machineInput, 0, internalAnchor);
		if (dfaResult !== null) return dfaResult;
		const machine = Machine.fromRE2(this.dummyRe2);
		machine.init(0);
		return machine.matchSet(machineInput, 0, internalAnchor);
	}
};
//#endregion
//#region src/TranslateRegExpString.js
/**
* Transform JS regex string to RE2 regex string
*/
var TranslateRegExpString = class TranslateRegExpString {
	static isHexadecimal(ch) {
		return "0" <= ch && ch <= "9" || "A" <= ch && ch <= "F" || "a" <= ch && ch <= "f";
	}
	static translate(data) {
		let prefixFlags = "";
		if (data instanceof RegExp) {
			if (data.ignoreCase) prefixFlags += "i";
			if (data.multiline) prefixFlags += "m";
			if (data.dotAll) prefixFlags += "s";
			data = data.source;
		}
		if (typeof data !== "string") return data;
		let result = "";
		let changed = false;
		let size = data.length;
		if (size === 0) {
			result = "(?:)";
			changed = true;
		}
		let inCharClass = false;
		let i = 0;
		while (i < size) {
			let ch = data[i];
			if (ch === "\\") {
				if (i + 1 < size) {
					ch = data[i + 1];
					switch (ch) {
						case "\\":
							result += "\\\\";
							i += 2;
							continue;
						case "c":
							if (i + 2 < size) {
								let code = data[i + 2].charCodeAt(0);
								if (code >= 65 && code <= 90 || code >= 97 && code <= 122) {
									let val = code % 32;
									result += "\\x";
									result += (val >> 4).toString(16).toUpperCase();
									result += (val & 15).toString(16).toUpperCase();
									i += 3;
									changed = true;
									continue;
								}
							}
							result += "c";
							i += 2;
							changed = true;
							continue;
						case "u":
							if (i + 2 < size) {
								if (data[i + 2] === "{") {
									let j = i + 3;
									let hasHex = false;
									let closed = false;
									while (j < size) {
										const hexChar = data[j];
										if (hexChar === "}") {
											closed = true;
											break;
										}
										if (!TranslateRegExpString.isHexadecimal(hexChar)) break;
										hasHex = true;
										j++;
									}
									if (closed && hasHex) {
										result += "\\x";
										i += 2;
										changed = true;
										continue;
									}
								} else if (i + 5 < size) {
									let isHex4 = true;
									for (let j = 0; j < 4; j++) if (!TranslateRegExpString.isHexadecimal(data[i + 2 + j])) {
										isHex4 = false;
										break;
									}
									if (isHex4) {
										result += "\\x{" + data.substring(i + 2, i + 6) + "}";
										i += 6;
										changed = true;
										continue;
									}
								}
							}
							result += "u";
							i += 2;
							changed = true;
							continue;
						case "x": {
							let isValidHex = false;
							if (i + 2 < size && data[i + 2] === "{") {
								let j = i + 3;
								let hasHex = false;
								let closed = false;
								while (j < size) {
									const hexChar = data[j];
									if (hexChar === "}") {
										closed = true;
										break;
									}
									if (!TranslateRegExpString.isHexadecimal(hexChar)) break;
									hasHex = true;
									j++;
								}
								if (closed && hasHex) isValidHex = true;
							} else if (i + 3 < size && TranslateRegExpString.isHexadecimal(data[i + 2]) && TranslateRegExpString.isHexadecimal(data[i + 3])) isValidHex = true;
							if (isValidHex) {
								result += "\\x";
								i += 2;
							} else {
								result += "x";
								i += 2;
								changed = true;
							}
							continue;
						}
						case "n":
						case "r":
						case "t":
						case "a":
						case "f":
						case "v":
						case "d":
						case "D":
						case "s":
						case "S":
						case "w":
						case "W":
						case "b":
						case "B":
						case "p":
						case "P":
						case "A":
						case "z":
						case "Q":
						case "E":
						case "0":
						case "1":
						case "2":
						case "3":
						case "4":
						case "5":
						case "6":
						case "7":
							result += "\\" + ch;
							i += 2;
							continue;
						default: {
							let cp = data.codePointAt(i + 1);
							if (cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122) {
								let symSize = Utils.charCount(cp);
								result += data.substring(i + 1, i + 1 + symSize);
								i += symSize + 1;
								changed = true;
							} else {
								result += "\\";
								let symSize = Utils.charCount(cp);
								result += data.substring(i + 1, i + 1 + symSize);
								i += symSize + 1;
							}
							continue;
						}
					}
				}
			} else if (ch === "/") {
				result += "\\/";
				i += 1;
				changed = true;
				continue;
			} else if (ch === "[") inCharClass = true;
			else if (ch === "]") inCharClass = false;
			else if (!inCharClass && ch === "(" && i + 2 < size && data[i + 1] === "?" && data[i + 2] === "<") {
				if (i + 3 < size && !"=!>)".includes(data[i + 3])) {
					result += "(?P<";
					i += 3;
					changed = true;
					continue;
				}
			}
			let cp = data.codePointAt(i);
			let symSize = Utils.charCount(cp);
			result += data.substring(i, i + symSize);
			i += symSize;
		}
		const finalResult = changed ? result : data;
		if (prefixFlags.length > 0) return `(?${prefixFlags})${finalResult}`;
		return finalResult;
	}
};
//#endregion
//#region src/index.js
/**
* A compiled representation of an RE2 regular expression
*
* The matching functions take {@code String} arguments instead of the more general Java
* {@code CharSequence} since the latter doesn't provide UTF-16 decoding.
*
*
* @author rsc@google.com (Russ Cox)
* @class
*/
var RE2JS = class RE2JS {
	/**
	* Flag: case insensitive matching.
	*/
	static CASE_INSENSITIVE = PublicFlags.CASE_INSENSITIVE;
	/**
	* Flag: dot ({@code .}) matches all characters, including newline.
	*/
	static DOTALL = PublicFlags.DOTALL;
	/**
	* Flag: multiline matching: {@code ^} and {@code $} match at beginning and end of line, not just
	* beginning and end of input.
	*/
	static MULTILINE = PublicFlags.MULTILINE;
	/**
	* Flag: Unicode groups (e.g. {@code \p\ Greek\} ) will be syntax errors.
	*/
	static DISABLE_UNICODE_GROUPS = PublicFlags.DISABLE_UNICODE_GROUPS;
	/**
	* Flag: matches longest possible string.
	*/
	static LONGEST_MATCH = PublicFlags.LONGEST_MATCH;
	/**
	* Flag: enable linear-time captureless lookbehinds.
	*/
	static LOOKBEHINDS = PublicFlags.LOOKBEHINDS;
	/**
	* Returns a literal pattern string for the specified string.
	*
	* This method produces a string that can be used to create a <code>RE2JS</code> that would
	* match the string <code>s</code> as if it were a literal pattern.
	*
	* Metacharacters or escape sequences in the input sequence will be given no special meaning.
	*
	* @param {string} str The string to be literalized
	* @returns {string} A literal string replacement
	*/
	static quote(str) {
		return Utils.quoteMeta(str);
	}
	/**
	* Quotes '\' and '$' in {@code str}, so that the returned string could be used in
	* replacement methods as a literal replacement of {@code str}.
	*
	* This is a convenience delegation to {@link Matcher.quoteReplacement}.
	*
	* @param {string} str the string to be quoted
	* @param {boolean} [javaMode=false] whether the replacement will be used in javaMode
	* @returns {string} the quoted string
	*/
	static quoteReplacement(str, javaMode = false) {
		return Matcher.quoteReplacement(str, javaMode);
	}
	/**
	* Translates a given regular expression string to ensure compatibility with RE2JS.
	*
	* This function preprocesses the input regex string by applying necessary transformations,
	* such as escaping special characters (e.g., `/`), converting named capture groups to
	* RE2JS-compatible syntax, and handling Unicode sequences properly. It ensures that the
	* resulting regex is safe and properly formatted before compilation.
	*
	* @param {string|RegExp} expr - The regular expression string to be translated.
	* @returns {string} - The transformed regular expression string, ready for compilation.
	*/
	static translateRegExp(expr) {
		return TranslateRegExpString.translate(expr);
	}
	/**
	* Helper: create new RE2JS with given regex and flags. Flregex is the regex with flags applied.
	* @param {string} regex
	* @param {number} [flags=0]
	* @returns {RE2JS}
	*/
	static compile(regex, flags = 0) {
		let fregex = regex;
		if ((flags & RE2JS.CASE_INSENSITIVE) !== 0) fregex = `(?i)${fregex}`;
		if ((flags & RE2JS.DOTALL) !== 0) fregex = `(?s)${fregex}`;
		if ((flags & RE2JS.MULTILINE) !== 0) fregex = `(?m)${fregex}`;
		if ((flags & ~(RE2JS.MULTILINE | RE2JS.DOTALL | RE2JS.CASE_INSENSITIVE | RE2JS.DISABLE_UNICODE_GROUPS | RE2JS.LONGEST_MATCH | RE2JS.LOOKBEHINDS)) !== 0) throw new RE2JSFlagsException("Flags should only be a combination of MULTILINE, DOTALL, CASE_INSENSITIVE, DISABLE_UNICODE_GROUPS, LONGEST_MATCH, LOOKBEHINDS");
		let re2Flags = RE2Flags.PERL;
		if ((flags & RE2JS.DISABLE_UNICODE_GROUPS) !== 0) re2Flags &= ~RE2Flags.UNICODE_GROUPS;
		if ((flags & RE2JS.LOOKBEHINDS) !== 0) re2Flags |= RE2Flags.LOOKBEHIND;
		const p = new RE2JS(regex, flags);
		p.re2Input = RE2.compileImpl(fregex, re2Flags, (flags & RE2JS.LONGEST_MATCH) !== 0);
		return p;
	}
	/**
	* Matches a string against a regular expression.
	*
	* @param {string} regex the regular expression
	* @param {string|number[]|Uint8Array} input the input
	* @returns {boolean} true if the regular expression matches the entire input
	* @throws RE2JSSyntaxException if the regular expression is malformed
	*/
	static matches(regex, input) {
		return RE2JS.compile(regex).testExact(input);
	}
	/**
	* This is visible for testing.
	* @private
	*/
	static initTest(pattern, flags, re2) {
		if (pattern == null) throw new Error("pattern is null");
		if (re2 == null) throw new Error("re2 is null");
		const p = new RE2JS(pattern, flags);
		p.re2Input = re2;
		return p;
	}
	/**
	*
	* @param {string} pattern
	* @param {number} flags
	*/
	constructor(pattern, flags) {
		this.patternInput = pattern;
		this.flagsInput = flags;
		/** @type {import('./RE2.js').RE2} */
		this.re2Input = null;
	}
	/**
	* Releases memory used by internal caches associated with this pattern. Does not change the
	* observable behaviour. Useful for tests that detect memory leaks via allocation tracking.
	*/
	reset() {
		this.re2Input.reset();
	}
	/**
	* Returns the flags used in the constructor.
	* @returns {number}
	*/
	flags() {
		return this.flagsInput;
	}
	/**
	* Returns the pattern used in the constructor.
	* @returns {string}
	*/
	pattern() {
		return this.patternInput;
	}
	re2() {
		return this.re2Input;
	}
	/**
	* Matches a string against a regular expression.
	*
	* @param {string|number[]|Uint8Array} input the input
	* @returns {boolean} true if the regular expression matches the entire input
	*/
	matches(input) {
		return this.testExact(input);
	}
	/**
	* Creates a new {@code Matcher} matching the pattern against the input.
	*
	* @param {string|number[]|Uint8Array|MatcherInputBase} input the input string
	* @returns {Matcher}
	*/
	matcher(input) {
		if (Utils.isByteArray(input)) input = MatcherInput.utf8(input);
		return new Matcher(this, input);
	}
	/**
	* Tests whether the regular expression matches any part of the input string.
	* Performance Note: This method is highly optimized. Because it only returns
	* a boolean and does not extract capture groups, it bypasses the `Matcher` overhead
	* and guarantees execution on the high-speed DFA engine whenever possible.
	*
	* @param {string|number[]|Uint8Array} input - The input string or UTF-8 byte array to test against.
	* @returns {boolean} `true` if the pattern is found anywhere in the input, `false` otherwise.
	*/
	test(input) {
		if (Utils.isByteArray(input)) return this.re2Input.matchUTF8(input);
		return this.re2Input.match(input);
	}
	/**
	* Tests whether the regular expression matches the ENTIRE input string.
	* * **Performance Note:** This operates identically to `.matches()`, but is significantly
	* faster because it does not request capture group data. By requesting 0 capture groups,
	* it securely routes execution through the DFA fast-path.
	*
	* @param {string|number[]|Uint8Array} input - The input string or UTF-8 byte array to test against.
	* @returns {boolean} `true` if the exact input string fully matches the pattern, `false` otherwise.
	*/
	testExact(input) {
		const machineInput = Utils.isByteArray(input) ? MachineInput.fromUTF8(input) : MachineInput.fromUTF16(input);
		return this.re2Input.executeEngine(machineInput, 0, RE2Flags.ANCHOR_BOTH, 0) !== null;
	}
	/**
	* Executes a search for a match in a specified string.
	* Returns a result array, or null if no match is found.
	* The returned array perfectly mirrors standard JavaScript `RegExpExecArray`,
	* including `.index`, `.input`, and `.groups` properties.
	*
	* @param {string|number[]|Uint8Array} input the input string or byte array
	* @returns {Array|null} the match array with index, input, and groups properties, or null
	*/
	exec(input) {
		const m = this.matcher(input);
		if (!m.find()) return null;
		const result = [m.group(0)];
		for (let i = 1; i <= m.groupCount(); i++) {
			const val = m.group(i);
			result.push(val === null ? void 0 : val);
		}
		result.index = m.start(0);
		result.input = input;
		const namedGroups = this.namedGroups();
		if (Object.keys(namedGroups).length > 0) {
			const parsedGroups = m.getNamedGroups();
			for (const key in parsedGroups) if (parsedGroups[key] === null) parsedGroups[key] = void 0;
			result.groups = parsedGroups;
		} else result.groups = void 0;
		return result;
	}
	/**
	* Splits input around instances of the regular expression. It returns an array giving the strings
	* that occur before, between, and after instances of the regular expression.
	*
	* If {@code limit <= 0}, there is no limit on the size of the returned array. If
	* {@code limit == 0}, empty strings that would occur at the end of the array are omitted. If
	* {@code limit > 0}, at most limit strings are returned. The final string contains the remainder
	* of the input, possibly including additional matches of the pattern.
	*
	* @param {string} input the input string to be split
	* @param {number} [limit=0] the limit
	* @returns {string[]} the split strings
	*/
	split(input, limit = 0) {
		const m = this.matcher(input);
		const result = [];
		let emptiesSkipped = 0;
		let last = 0;
		while (m.find()) {
			if (last === 0 && m.end() === 0) {
				last = m.end();
				continue;
			}
			if (limit > 0 && result.length === limit - 1) break;
			if (last === m.start()) {
				if (limit === 0) {
					emptiesSkipped += 1;
					last = m.end();
					continue;
				}
			} else while (emptiesSkipped > 0) {
				result.push("");
				emptiesSkipped -= 1;
			}
			result.push(m.substring(last, m.start()));
			last = m.end();
		}
		if (limit === 0 && last !== m.inputLength()) {
			while (emptiesSkipped > 0) {
				result.push("");
				emptiesSkipped -= 1;
			}
			result.push(m.substring(last, m.inputLength()));
		}
		if (limit !== 0 || result.length === 0 && !(last === m.inputLength() && last > 0)) result.push(m.substring(last, m.inputLength()));
		return result;
	}
	/**
	* Returns an iterator of all results matching a string against the regular expression,
	* including capturing groups.
	*
	* @param {string|number[]|Uint8Array} input the input string or byte array
	* @returns {IterableIterator<RegExpMatchArray>}
	*/
	*matchAll(input) {
		const m = this.matcher(input);
		while (m.find()) {
			const result = [m.group(0)];
			for (let i = 1; i <= m.groupCount(); i++) {
				const groupVal = m.group(i);
				result.push(groupVal === null ? void 0 : groupVal);
			}
			result.index = m.start(0);
			result.input = input;
			const namedGroups = this.namedGroups();
			if (Object.keys(namedGroups).length > 0) {
				const parsedGroups = m.getNamedGroups();
				for (const key in parsedGroups) if (parsedGroups[key] === null) parsedGroups[key] = void 0;
				result.groups = parsedGroups;
			} else result.groups = void 0;
			yield result;
		}
	}
	/**
	*
	* @returns {string}
	*/
	toString() {
		return this.patternInput;
	}
	/**
	* Returns the program size of this pattern.
	*
	* <p>
	* Similar to the C++ implementation, the program size is a very approximate measure of a regexp's
	* "cost". Larger numbers are more expensive than smaller numbers.
	* </p>
	*
	* @returns {number} the program size of this pattern
	*/
	programSize() {
		return this.re2Input.numberOfInstructions();
	}
	/**
	* Returns the number of capturing groups in this matcher's pattern. Group zero denotes the entire
	* pattern and is excluded from this count.
	*
	* @returns {number} the number of capturing groups in this pattern
	*/
	groupCount() {
		return this.re2Input.numberOfCapturingGroups();
	}
	/**
	* Return a map of the capturing groups in this matcher's pattern, where key is the name and value
	* is the index of the group in the pattern.
	* @returns {Record<string, number>}
	*/
	namedGroups() {
		return this.re2Input.namedGroups;
	}
	/**
	*
	* @param {*} other
	* @returns {boolean}
	*/
	equals(other) {
		if (this === other) return true;
		if (other === null || this.constructor !== other.constructor) return false;
		return this.flagsInput === other.flagsInput && this.patternInput === other.patternInput;
	}
};
/**
* Creates an RE2JS regex directly from a template literal.
* @overload
* @param {TemplateStringsArray} stringsOrFlags - The raw string segments of the template literal.
* @param {...any} values - The interpolated values.
* @returns {RE2JS}
*/
/**
* Creates a template literal tag function with specific RE2JS flags.
* @overload
* @param {number} stringsOrFlags - The RE2JS flags to apply (e.g., RE2JS.CASE_INSENSITIVE).
* @returns {(strings: TemplateStringsArray, ...tagValues: any[]) => RE2JS}
*/
/**
* Implementation signature
* @param {TemplateStringsArray | number} stringsOrFlags
* @param {...any} values
* @returns {RE2JS | ((strings: TemplateStringsArray, ...tagValues: any[]) => RE2JS)}
*/
const re = (stringsOrFlags, ...values) => {
	if (Array.isArray(stringsOrFlags) && "raw" in stringsOrFlags) {
		const pattern = String.raw(stringsOrFlags, ...values);
		return RE2JS.compile(pattern);
	}
	const flags = typeof stringsOrFlags === "number" ? stringsOrFlags : 0;
	return (strings, ...tagValues) => {
		const pattern = String.raw(strings, ...tagValues);
		return RE2JS.compile(pattern, flags);
	};
};
//#endregion
export { Matcher, MatcherInput, MatcherInputBase, RE2JS, RE2JSCompileException, RE2JSException, RE2JSFlagsException, RE2JSGroupException, RE2JSInternalException, RE2JSSyntaxException, RE2Set, re };
