/*!
* re2js
* RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching
*
* @version v2.8.3
* @author Oleksii Vasyliev
* @homepage https://github.com/le0pard/re2js#readme
* @repository github:le0pard/re2js
* @license MIT
*/
(function(global, factory) {
	typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.RE2JS = {}));
})(this, function(exports) {
	Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
	//#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 = 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 = 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 Utils.toArray(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 {MatcherInputBase} input
		* @returns {Matcher} the {@code Matcher} itself, for chained method calls
		*/
		resetMatcherInput(input) {
			if (input === null) throw new Error("input is null");
			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]) 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;
			for (let i = 0; i < m - 1; i++) {
				if (replacement.codePointAt(i) === Codepoint.CODES.get("\\")) {
					if (last < i) res += replacement.substring(last, i);
					i++;
					last = i;
					continue;
				}
				if (replacement.codePointAt(i) === Codepoint.CODES.get("$")) {
					let c = replacement.codePointAt(i + 1);
					if (Codepoint.CODES.get("0") <= 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) throw new RE2JSGroupException(`n > number of groups: ${n}`);
						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("}")) throw new RE2JSGroupException("named capture group is missing trailing '}'");
						const groupName = replacement.substring(i + 1, j);
						const groupVal = this.group(groupName);
						if (groupVal !== null) res += groupVal;
						last = j + 1;
						i = j;
						continue;
					}
				}
			}
			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 Thread = class {
		constructor() {
			this.inst = null;
			this.cap = null;
		}
	};
	var Queue = class {
		constructor(numInst) {
			this.sparse = new Int32Array(numInst);
			this.densePcs = new Int32Array(numInst);
			this.denseThreads = new Array(numInst);
			this.size = 0;
		}
		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.denseThreads[j] = null;
			this.densePcs[j] = pc;
			return j;
		}
		clear() {
			for (let i = 0; i < this.size; i++) this.denseThreads[i] = null;
			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 THREADS_CHUNK_SIZE = 128;
		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.pool = [];
			m.poolSize = 0;
			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.pool = [];
			this.poolSize = 0;
			this.matched = false;
			this.matchcap = null;
			this.ncap = 0;
			this.lbTable = null;
		}
		init(ncap) {
			this.ncap = ncap;
			if (ncap > this.matchcap.length) this.initNewCap(ncap);
			else this.resetCap();
			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);
			}
		}
		resetCap() {
			for (let i = 0; i < this.poolSize; i++) this.pool[i].cap.fill(-1);
		}
		initNewCap(ncap) {
			for (let i = 0; i < this.poolSize; i++) {
				const t = this.pool[i];
				t.cap = new Int32Array(ncap).fill(-1);
			}
			this.matchcap = new Int32Array(ncap).fill(-1);
		}
		submatches() {
			if (this.ncap === 0) return Utils.emptyInts();
			return Utils.toArray(this.matchcap.subarray(0, this.ncap));
		}
		alloc(inst) {
			if (this.poolSize === 0) {
				const capLen = this.matchcap.length;
				for (let i = 0; i < Machine.THREADS_CHUNK_SIZE; i++) {
					const t = new Thread();
					t.cap = new Int32Array(capLen);
					this.pool[this.poolSize++] = t;
				}
			}
			this.poolSize--;
			const t = this.pool[this.poolSize];
			t.inst = inst;
			return t;
		}
		freeQueue(queue, from = 0) {
			for (let i = from; i < queue.size; i++) {
				const t = queue.denseThreads[i];
				if (t !== null) this.pool[this.poolSize++] = t;
			}
			queue.clear();
		}
		freeThread(t) {
			this.pool[this.poolSize++] = t;
		}
		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;
					}
				}
				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, flag, null);
				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, flag, null);
					}
				}
				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;
			}
			this.freeQueue(nextq);
			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, flag, null);
				if (currentPos === 0 || anchor === RE2Flags.UNANCHORED) {
					if (currentPos >= matchStartPos) this.add(runq, this.prog.start, currentPos, this.matchcap, flag, null);
				}
				const nextPos = currentPos + width;
				flag = input.context(nextPos);
				for (let j = 0; j < runq.size; j++) {
					let t = runq.denseThreads[j];
					if (t === null) continue;
					const i = t.inst;
					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 !== Codepoint.CODES.get("\n");
							break;
						default: throw new RE2JSInternalException("bad inst");
					}
					if (add) t = this.add(nextq, i.out, nextPos, t.cap, flag, t);
					if (t !== null) {
						this.freeThread(t);
						runq.denseThreads[j] = null;
					}
				}
				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;
			}
			this.freeQueue(nextq);
			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++) {
				let t = runq.denseThreads[j];
				if (t === null) continue;
				if (longest && this.matched && this.ncap > 0 && this.matchcap[0] < t.cap[0]) {
					this.freeThread(t);
					continue;
				}
				const i = t.inst;
				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)) {
							t.cap[1] = pos;
							this.matchcap.set(t.cap.subarray(0, this.ncap));
						}
						if (!longest) this.freeQueue(runq, j + 1);
						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 !== Codepoint.CODES.get("\n");
						break;
					default: throw new RE2JSInternalException("bad inst");
				}
				if (add) t = this.add(nextq, i.out, nextPos, t.cap, nextCond, t);
				if (t !== null) {
					this.freeThread(t);
					runq.denseThreads[j] = null;
				}
			}
			runq.clear();
		}
		add(q, pc, pos, cap, cond, t) {
			while (true) {
				if (pc === 0) return t;
				if (q.contains(pc)) return t;
				const d = q.add(pc);
				const inst = this.prog.inst[pc];
				switch (inst.op) {
					case Inst.FAIL: return t;
					case Inst.ALT:
					case Inst.ALT_MATCH:
						t = this.add(q, inst.out, pos, cap, cond, t);
						pc = inst.arg;
						continue;
					case Inst.EMPTY_WIDTH:
						if ((inst.arg & ~cond) === 0) {
							pc = inst.out;
							continue;
						}
						return t;
					case Inst.NOP:
						pc = inst.out;
						continue;
					case Inst.CAPTURE: if (inst.arg < this.ncap) {
						const opos = cap[inst.arg];
						cap[inst.arg] = pos;
						this.add(q, inst.out, pos, cap, cond, null);
						cap[inst.arg] = opos;
						return t;
					} 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 t;
					case Inst.MATCH:
					case Inst.RUNE:
					case Inst.RUNE1:
					case Inst.RUNE_ANY:
					case Inst.RUNE_ANY_NOT_NL:
						if (t === null) t = this.alloc(inst);
						else t.inst = inst;
						if (this.ncap > 0 && t.cap !== cap) for (let c = 0; c < this.ncap; c++) t.cap[c] = cap[c];
						q.denseThreads[d] = t;
						t = null;
						return t;
					default: throw new Error("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 = new Int32Array(0);
			this.matchcap = 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 = 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 mergeRes = mergeRuneSets(onePassRunes[inst.out] || [], onePassRunes[inst.arg] || [], 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 = 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 = 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
	var AtomicReference = class {
		constructor(initialValue) {
			this.value = initialValue;
		}
		get() {
			return this.value;
		}
		set(newValue) {
			this.value = newValue;
		}
		compareAndSet(expect, update) {
			if (this.value === expect) {
				this.value = update;
				return true;
			}
			return false;
		}
	};
	/**
	* 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.pooled = new AtomicReference();
			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() {
			let head;
			do
				head = this.pooled.get();
			while (head && !this.pooled.compareAndSet(head, head.next));
			return head;
		}
		reset() {
			this.pooled.set(null);
		}
		put(m, isNew) {
			let head = this.pooled.get();
			do {
				head = this.pooled.get();
				if (!isNew && head) {
					m = Machine.fromMachine(m);
					isNew = true;
				}
				if (m.next !== head) m.next = head;
			} while (!this.pooled.compareAndSet(head, m));
		}
		toString() {
			return this.expr;
		}
		doExecuteNFA(input, pos, anchor, ncap) {
			let m = this.get();
			let isNew = false;
			if (!m) {
				m = Machine.fromRE2(this);
				isNew = true;
			} else if (m.next !== null) {
				m = Machine.fromMachine(m);
				isNew = true;
			}
			m.init(ncap);
			const cap = m.match(input, pos, anchor) ? m.submatches() : null;
			this.put(m, isNew);
			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;
		}
		/**
		* 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) 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<Array>}
		*/
		*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
	exports.Matcher = Matcher;
	exports.MatcherInput = MatcherInput;
	exports.MatcherInputBase = MatcherInputBase;
	exports.RE2JS = RE2JS;
	exports.RE2JSCompileException = RE2JSCompileException;
	exports.RE2JSException = RE2JSException;
	exports.RE2JSFlagsException = RE2JSFlagsException;
	exports.RE2JSGroupException = RE2JSGroupException;
	exports.RE2JSInternalException = RE2JSInternalException;
	exports.RE2JSSyntaxException = RE2JSSyntaxException;
	exports.RE2Set = RE2Set;
	exports.re = re;
});
