New Upstream Snapshot - node-regexpu-core

Ready changes

Summary

Merged new upstream version: 5.3.1 (was: 5.2.2).

Diff

diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 6f9f40f..0000000
--- a/.editorconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-indent_style = tab
-end_of_line = lf
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[{README.md,.travis.yml}]
-indent_style = space
-indent_size = 2
diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index 43c97e7..0000000
--- a/.npmrc
+++ /dev/null
@@ -1 +0,0 @@
-package-lock=false
diff --git a/README.md b/README.md
index fe5419f..bab65e2 100644
--- a/README.md
+++ b/README.md
@@ -146,6 +146,14 @@ Once these features become stable (when the proposals are accepted as part of EC
   // → '(?:(?![f-h])[\s\S])' (to be used without /u)
   ```
 
+- `modifiers` - [Inline `m`/`s`/`i` modifiers](https://github.com/tc39/proposal-regexp-modifiers)
+
+  ```js
+  rewritePattern('(?i:[a-z])[a-z]', '', {
+    modifiers: 'transform'
+  });
+  // → '(?:[a-zA-Z])([a-z])'
+  ```
 
 #### Miscellaneous options
 
@@ -163,6 +171,20 @@ Once these features become stable (when the proposals are accepted as part of EC
   });
   ```
 
+- `onNewFlags`
+
+  This option is a function that gets called to pass the flags that the resulting pattern must be interpreted with.
+
+  ```js
+  rewritePattern('abc', 'um', '', {
+    unicodeFlag: 'transform',
+    onNewFlags(flags) {
+      console.log(flags);
+      // → 'm'
+    }
+  })
+  ```
+
 ### Caveats
 
 - [Lookbehind assertions](https://github.com/tc39/proposal-regexp-lookbehind) cannot be transformed to older syntax.
diff --git a/debian/changelog b/debian/changelog
index 69b5a78..c057352 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+node-regexpu-core (5.3.1-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 26 Feb 2023 23:00:55 -0000
+
 node-regexpu-core (5.2.2-2) unstable; urgency=medium
 
   [ Debian Janitor ]
diff --git a/demo.js b/demo.js
deleted file mode 100644
index 1fb999f..0000000
--- a/demo.js
+++ /dev/null
@@ -1,15 +0,0 @@
-'use strict';
-
-const rewritePattern = require('./rewrite-pattern.js');
-const parse = require('regjsparser').parse;
-const generate = require('regjsgen').generate;
-const regenerate = require('regenerate');
-
-const pattern = String.raw`\p{RGI_Emoji}`;
-
-const processedPattern = rewritePattern(pattern, 'v', {
-	'unicodeSetsFlag': 'transform'
-});
-
-console.log(JSON.stringify(processedPattern));
-
diff --git a/package.json b/package.json
index 2791e50..b483113 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "regexpu-core",
-	"version": "5.2.2",
+	"version": "5.3.1",
 	"description": "regexpu’s core functionality (i.e. `rewritePattern(pattern, flag)`), capable of translating ES6 Unicode regular expressions to ES5.",
 	"homepage": "https://mths.be/regexpu",
 	"main": "rewrite-pattern.js",
@@ -50,7 +50,7 @@
 	"dependencies": {
 		"regenerate": "^1.4.2",
 		"regenerate-unicode-properties": "^10.1.0",
-		"regjsgen": "^0.7.1",
+		"@babel/regjsgen": "^0.8.0",
 		"regjsparser": "^0.9.1",
 		"unicode-match-property-ecmascript": "^2.0.0",
 		"unicode-match-property-value-ecmascript": "^2.1.0"
@@ -61,7 +61,7 @@
 		"jsesc": "^3.0.2",
 		"lodash": "^4.17.21",
 		"mocha": "^10.1.0",
-		"regexpu-fixtures": "2.1.4",
+		"regexpu-fixtures": "^2.1.6",
 		"@unicode/unicode-15.0.0": "^1.3.1"
 	}
 }
diff --git a/property-escapes.md b/property-escapes.md
deleted file mode 100644
index 88b8163..0000000
--- a/property-escapes.md
+++ /dev/null
@@ -1,312 +0,0 @@
-# Unicode property escapes in _regexpu_
-
-To opt-in to experimental support for [Unicode property escapes](https://github.com/mathiasbynens/es-regexp-unicode-property-escapes), enable [the `unicodePropertyEscape` option](README.md#unicodepropertyescape-default-false).
-
-```js
-rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', {
-  'unicodePropertyEscape': true
-});
-// → '(?:\\uD811[\\uDC00-\\uDE46])'
-```
-
-If you’re targeting ES2015 environments exclusively, consider enabling [the `useUnicodeFlag` option](README.md#useunicodeflag-default-false) for simpler (but not necessarily more compact) output.
-
-```js
-rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', {
-  'unicodePropertyEscape': true,
-  'useUnicodeFlag': true
-});
-// → '[\\u{14400}-\\u{14646}]'
-```
-
-[An online demo is available.](https://mothereff.in/regexpu#input=var+regex+%3D+/%5Cp%7BScript_Extensions%3DGreek%7D/u%3B&unicodePropertyEscape=1)
-
-Note that this feature is non-standard. This implementation may or may not reflect what eventually gets specified.
-
-What follows is an exhaustive overview of the Unicode properties and values that _regexpu_ supports in `\p{…}` and `\P{…}` expressions in regular expressions with the `u` flag.
-
-## Non-binary properties
-
-### `General_Category`
-
-Possible values:
-
-```sh
-$ node -e 'require("regenerate-unicode-properties").get("General_Category").forEach(c => { console.log(`\\p{${c}}`); })'
-\p{Cased_Letter}
-\p{Close_Punctuation}
-\p{Connector_Punctuation}
-\p{Control}
-\p{Currency_Symbol}
-\p{Dash_Punctuation}
-\p{Decimal_Number}
-\p{Enclosing_Mark}
-\p{Final_Punctuation}
-\p{Format}
-\p{Initial_Punctuation}
-\p{Letter}
-\p{Letter_Number}
-\p{Line_Separator}
-\p{Lowercase_Letter}
-\p{Mark}
-\p{Math_Symbol}
-\p{Modifier_Letter}
-\p{Modifier_Symbol}
-\p{Nonspacing_Mark}
-\p{Number}
-\p{Open_Punctuation}
-\p{Other}
-\p{Other_Letter}
-\p{Other_Number}
-\p{Other_Punctuation}
-\p{Other_Symbol}
-\p{Paragraph_Separator}
-\p{Private_Use}
-\p{Punctuation}
-\p{Separator}
-\p{Space_Separator}
-\p{Spacing_Mark}
-\p{Surrogate}
-\p{Symbol}
-\p{Titlecase_Letter}
-\p{Unassigned}
-\p{Uppercase_Letter}
-```
-
-Note that the `General_Category=` prefix may be used, e.g. `\p{General_Category=Cased_Letter}`.
-
-Category aliases may be used, e.g. `\p{Lc}` or `\p{General_Category=Lc}`, although IMHO it’s more readable to stick to the canonical category names listed above.
-
-### `Script` & `Script_Extensions`
-
-The sets of possible values for `Script` and `Script_Extensions` are identical:
-
-```sh
-$ node -e 'require("regenerate-unicode-properties").get("Script_Extensions").forEach(s => { console.log(`\\p{Script_Extensions=${s}}`); })'
-\p{Script_Extensions=Adlam}
-\p{Script_Extensions=Ahom}
-\p{Script_Extensions=Anatolian_Hieroglyphs}
-\p{Script_Extensions=Arabic}
-\p{Script_Extensions=Armenian}
-\p{Script_Extensions=Avestan}
-\p{Script_Extensions=Balinese}
-\p{Script_Extensions=Bamum}
-\p{Script_Extensions=Bassa_Vah}
-\p{Script_Extensions=Batak}
-\p{Script_Extensions=Bengali}
-\p{Script_Extensions=Bhaiksuki}
-\p{Script_Extensions=Bopomofo}
-\p{Script_Extensions=Brahmi}
-\p{Script_Extensions=Braille}
-\p{Script_Extensions=Buginese}
-\p{Script_Extensions=Buhid}
-\p{Script_Extensions=Canadian_Aboriginal}
-\p{Script_Extensions=Carian}
-\p{Script_Extensions=Caucasian_Albanian}
-\p{Script_Extensions=Chakma}
-\p{Script_Extensions=Cham}
-\p{Script_Extensions=Cherokee}
-\p{Script_Extensions=Chorasmian}
-\p{Script_Extensions=Common}
-\p{Script_Extensions=Coptic}
-\p{Script_Extensions=Cuneiform}
-\p{Script_Extensions=Cypriot}
-\p{Script_Extensions=Cypro_Minoan}
-\p{Script_Extensions=Cyrillic}
-\p{Script_Extensions=Deseret}
-\p{Script_Extensions=Devanagari}
-\p{Script_Extensions=Dives_Akuru}
-\p{Script_Extensions=Dogra}
-\p{Script_Extensions=Duployan}
-\p{Script_Extensions=Egyptian_Hieroglyphs}
-\p{Script_Extensions=Elbasan}
-\p{Script_Extensions=Elymaic}
-\p{Script_Extensions=Ethiopic}
-\p{Script_Extensions=Georgian}
-\p{Script_Extensions=Glagolitic}
-\p{Script_Extensions=Gothic}
-\p{Script_Extensions=Grantha}
-\p{Script_Extensions=Greek}
-\p{Script_Extensions=Gujarati}
-\p{Script_Extensions=Gunjala_Gondi}
-\p{Script_Extensions=Gurmukhi}
-\p{Script_Extensions=Han}
-\p{Script_Extensions=Hangul}
-\p{Script_Extensions=Hanifi_Rohingya}
-\p{Script_Extensions=Hanunoo}
-\p{Script_Extensions=Hatran}
-\p{Script_Extensions=Hebrew}
-\p{Script_Extensions=Hiragana}
-\p{Script_Extensions=Imperial_Aramaic}
-\p{Script_Extensions=Inherited}
-\p{Script_Extensions=Inscriptional_Pahlavi}
-\p{Script_Extensions=Inscriptional_Parthian}
-\p{Script_Extensions=Javanese}
-\p{Script_Extensions=Kaithi}
-\p{Script_Extensions=Kannada}
-\p{Script_Extensions=Katakana}
-\p{Script_Extensions=Kayah_Li}
-\p{Script_Extensions=Kharoshthi}
-\p{Script_Extensions=Khitan_Small_Script}
-\p{Script_Extensions=Khmer}
-\p{Script_Extensions=Khojki}
-\p{Script_Extensions=Khudawadi}
-\p{Script_Extensions=Lao}
-\p{Script_Extensions=Latin}
-\p{Script_Extensions=Lepcha}
-\p{Script_Extensions=Limbu}
-\p{Script_Extensions=Linear_A}
-\p{Script_Extensions=Linear_B}
-\p{Script_Extensions=Lisu}
-\p{Script_Extensions=Lycian}
-\p{Script_Extensions=Lydian}
-\p{Script_Extensions=Mahajani}
-\p{Script_Extensions=Makasar}
-\p{Script_Extensions=Malayalam}
-\p{Script_Extensions=Mandaic}
-\p{Script_Extensions=Manichaean}
-\p{Script_Extensions=Marchen}
-\p{Script_Extensions=Masaram_Gondi}
-\p{Script_Extensions=Medefaidrin}
-\p{Script_Extensions=Meetei_Mayek}
-\p{Script_Extensions=Mende_Kikakui}
-\p{Script_Extensions=Meroitic_Cursive}
-\p{Script_Extensions=Meroitic_Hieroglyphs}
-\p{Script_Extensions=Miao}
-\p{Script_Extensions=Modi}
-\p{Script_Extensions=Mongolian}
-\p{Script_Extensions=Mro}
-\p{Script_Extensions=Multani}
-\p{Script_Extensions=Myanmar}
-\p{Script_Extensions=Nabataean}
-\p{Script_Extensions=Nandinagari}
-\p{Script_Extensions=New_Tai_Lue}
-\p{Script_Extensions=Newa}
-\p{Script_Extensions=Nko}
-\p{Script_Extensions=Nushu}
-\p{Script_Extensions=Nyiakeng_Puachue_Hmong}
-\p{Script_Extensions=Ogham}
-\p{Script_Extensions=Ol_Chiki}
-\p{Script_Extensions=Old_Hungarian}
-\p{Script_Extensions=Old_Italic}
-\p{Script_Extensions=Old_North_Arabian}
-\p{Script_Extensions=Old_Permic}
-\p{Script_Extensions=Old_Persian}
-\p{Script_Extensions=Old_Sogdian}
-\p{Script_Extensions=Old_South_Arabian}
-\p{Script_Extensions=Old_Turkic}
-\p{Script_Extensions=Old_Uyghur}
-\p{Script_Extensions=Oriya}
-\p{Script_Extensions=Osage}
-\p{Script_Extensions=Osmanya}
-\p{Script_Extensions=Pahawh_Hmong}
-\p{Script_Extensions=Palmyrene}
-\p{Script_Extensions=Pau_Cin_Hau}
-\p{Script_Extensions=Phags_Pa}
-\p{Script_Extensions=Phoenician}
-\p{Script_Extensions=Psalter_Pahlavi}
-\p{Script_Extensions=Rejang}
-\p{Script_Extensions=Runic}
-\p{Script_Extensions=Samaritan}
-\p{Script_Extensions=Saurashtra}
-\p{Script_Extensions=Sharada}
-\p{Script_Extensions=Shavian}
-\p{Script_Extensions=Siddham}
-\p{Script_Extensions=SignWriting}
-\p{Script_Extensions=Sinhala}
-\p{Script_Extensions=Sogdian}
-\p{Script_Extensions=Sora_Sompeng}
-\p{Script_Extensions=Soyombo}
-\p{Script_Extensions=Sundanese}
-\p{Script_Extensions=Syloti_Nagri}
-\p{Script_Extensions=Syriac}
-\p{Script_Extensions=Tagalog}
-\p{Script_Extensions=Tagbanwa}
-\p{Script_Extensions=Tai_Le}
-\p{Script_Extensions=Tai_Tham}
-\p{Script_Extensions=Tai_Viet}
-\p{Script_Extensions=Takri}
-\p{Script_Extensions=Tamil}
-\p{Script_Extensions=Tangsa}
-\p{Script_Extensions=Tangut}
-\p{Script_Extensions=Telugu}
-\p{Script_Extensions=Thaana}
-\p{Script_Extensions=Thai}
-\p{Script_Extensions=Tibetan}
-\p{Script_Extensions=Tifinagh}
-\p{Script_Extensions=Tirhuta}
-\p{Script_Extensions=Toto}
-\p{Script_Extensions=Ugaritic}
-\p{Script_Extensions=Vai}
-\p{Script_Extensions=Vithkuqi}
-\p{Script_Extensions=Wancho}
-\p{Script_Extensions=Warang_Citi}
-\p{Script_Extensions=Yezidi}
-\p{Script_Extensions=Yi}
-\p{Script_Extensions=Zanabazar_Square}
-```
-
-Note that script name aliases may be used as well, e.g. `\p{Script_Extensions=Aghb}`, although IMHO it’s more readable to stick to the canonical script names listed above.
-
-## Binary properties
-
-The following binary properties are supported:
-
-```sh
-$ node -e 'require("regenerate-unicode-properties").get("Binary_Property").forEach(p => { console.log(`\\p{${p}}`); })'
-\p{ASCII}
-\p{ASCII_Hex_Digit}
-\p{Alphabetic}
-\p{Any}
-\p{Assigned}
-\p{Bidi_Control}
-\p{Bidi_Mirrored}
-\p{Case_Ignorable}
-\p{Cased}
-\p{Changes_When_Casefolded}
-\p{Changes_When_Casemapped}
-\p{Changes_When_Lowercased}
-\p{Changes_When_NFKC_Casefolded}
-\p{Changes_When_Titlecased}
-\p{Changes_When_Uppercased}
-\p{Dash}
-\p{Default_Ignorable_Code_Point}
-\p{Deprecated}
-\p{Diacritic}
-\p{Emoji}
-\p{Emoji_Component}
-\p{Emoji_Modifier}
-\p{Emoji_Modifier_Base}
-\p{Emoji_Presentation}
-\p{Extended_Pictographic}
-\p{Extender}
-\p{Grapheme_Base}
-\p{Grapheme_Extend}
-\p{Hex_Digit}
-\p{IDS_Binary_Operator}
-\p{IDS_Trinary_Operator}
-\p{ID_Continue}
-\p{ID_Start}
-\p{Ideographic}
-\p{Join_Control}
-\p{Logical_Order_Exception}
-\p{Lowercase}
-\p{Math}
-\p{Noncharacter_Code_Point}
-\p{Pattern_Syntax}
-\p{Pattern_White_Space}
-\p{Quotation_Mark}
-\p{Radical}
-\p{Regional_Indicator}
-\p{Sentence_Terminal}
-\p{Soft_Dotted}
-\p{Terminal_Punctuation}
-\p{Unified_Ideograph}
-\p{Uppercase}
-\p{Variation_Selector}
-\p{White_Space}
-\p{XID_Continue}
-\p{XID_Start}
-```
-
-Note that property name aliases may be used as well, e.g. `\p{AHex}`, although IMHO it’s more readable to stick to the canonical property names listed above.
diff --git a/rewrite-pattern.js b/rewrite-pattern.js
index 2b95ea3..c6969ab 100644
--- a/rewrite-pattern.js
+++ b/rewrite-pattern.js
@@ -1,6 +1,6 @@
 'use strict';
 
-const generate = require('regjsgen').generate;
+const generate = require('@babel/regjsgen').generate;
 const parse = require('regjsparser').parse;
 const regenerate = require('regenerate');
 const unicodeMatchProperty = require('unicode-match-property-ecmascript');
@@ -27,16 +27,20 @@ const SPECIAL_CHARS = /([\\^$.*+?()[\]{}|])/g;
 // character classes (if any).
 const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
 
+const ASTRAL_SET = regenerate().addRange(0x10000, 0x10FFFF);
+
+const NEWLINE_SET = regenerate().add(
+	// `LineTerminator`s (https://mths.be/es6#sec-line-terminators):
+	0x000A, // Line Feed <LF>
+	0x000D, // Carriage Return <CR>
+	0x2028, // Line Separator <LS>
+	0x2029  // Paragraph Separator <PS>
+);
+
 // Prepare a Regenerate set containing all code points that are supposed to be
 // matched by `/./u`. https://mths.be/es6#sec-atom
 const DOT_SET_UNICODE = UNICODE_SET.clone() // all Unicode code points
-	.remove(
-		// minus `LineTerminator`s (https://mths.be/es6#sec-line-terminators):
-		0x000A, // Line Feed <LF>
-		0x000D, // Carriage Return <CR>
-		0x2028, // Line Separator <LS>
-		0x2029  // Paragraph Separator <PS>
-	);
+	.remove(NEWLINE_SET);
 
 const getCharacterClassEscapeSet = (character, unicode, ignoreCase) => {
 	if (unicode) {
@@ -126,12 +130,23 @@ const getUnicodePropertyEscapeCharacterClassData = (property, isNegative) => {
 	return data;
 };
 
+function configNeedCaseFoldAscii() {
+	return !!config.modifiersData.i;
+}
+
+function configNeedCaseFoldUnicode() {
+	// config.modifiersData.i : undefined | false
+	if (config.modifiersData.i === false) return false;
+	if (!config.transform.unicodeFlag) return false;
+	return Boolean(config.modifiersData.i || config.flags.ignoreCase);
+}
+
 // Given a range of code points, add any case-folded code points in that range
 // to a set.
 regenerate.prototype.iuAddRange = function(min, max) {
 	const $this = this;
 	do {
-		const folded = caseFold(min);
+		const folded = caseFold(min, configNeedCaseFoldAscii(), configNeedCaseFoldUnicode());
 		if (folded) {
 			$this.add(folded);
 		}
@@ -141,7 +156,7 @@ regenerate.prototype.iuAddRange = function(min, max) {
 regenerate.prototype.iuRemoveRange = function(min, max) {
 	const $this = this;
 	do {
-		const folded = caseFold(min);
+		const folded = caseFold(min, configNeedCaseFoldAscii(), configNeedCaseFoldUnicode());
 		if (folded) {
 			$this.remove(folded);
 		}
@@ -150,7 +165,13 @@ regenerate.prototype.iuRemoveRange = function(min, max) {
 };
 
 const update = (item, pattern) => {
-	let tree = parse(pattern, config.useUnicodeFlag ? 'u' : '');
+	let tree = parse(pattern, config.useUnicodeFlag ? 'u' : '', {
+		lookbehind: true,
+		namedGroups: true,
+		unicodePropertyEscape: true,
+		unicodeSet: true,
+		modifiers: true,
+	});
 	switch (tree.type) {
 		case 'characterClass':
 		case 'group':
@@ -174,8 +195,17 @@ const wrap = (tree, pattern) => {
 	};
 };
 
-const caseFold = (codePoint) => {
-	return iuMappings.get(codePoint) || false;
+const caseFold = (codePoint, includeAscii, includeUnicode) => {
+	let folded = (includeUnicode ? iuMappings.get(codePoint) : undefined) || [];
+	if (typeof folded === 'number') folded = [folded];
+	if (includeAscii) {
+		if (codePoint >= 0x41 && codePoint <= 0x5A) {
+			folded.push(codePoint + 0x20);
+		} else if (codePoint >= 0x61 && codePoint <= 0x7A) {
+			folded.push(codePoint - 0x20);
+		}
+	}
+	return folded.length == 0 ? false : folded;
 };
 
 const buildHandler = (action) => {
@@ -316,8 +346,11 @@ const getCharacterClassEmptyData = () => ({
 });
 
 const maybeFold = (codePoint) => {
-	if (config.flags.ignoreCase && config.transform.unicodeFlag) {
-		const folded = caseFold(codePoint);
+	const caseFoldAscii = configNeedCaseFoldAscii();
+	const caseFoldUnicode = configNeedCaseFoldUnicode();
+
+	if (caseFoldAscii || caseFoldUnicode) {
+		const folded = caseFold(codePoint, caseFoldAscii, caseFoldUnicode);
 		if (folded) {
 			return [codePoint, folded];
 		}
@@ -328,6 +361,9 @@ const maybeFold = (codePoint) => {
 const computeClassStrings = (classStrings, regenerateOptions) => {
 	let data = getCharacterClassEmptyData();
 
+	const caseFoldAscii = configNeedCaseFoldAscii();
+	const caseFoldUnicode = configNeedCaseFoldUnicode();
+
 	for (const string of classStrings.strings) {
 		if (string.characters.length === 1) {
 			maybeFold(string.characters[0].codePoint).forEach((cp) => {
@@ -335,11 +371,11 @@ const computeClassStrings = (classStrings, regenerateOptions) => {
 			});
 		} else {
 			let stringifiedString;
-			if (config.flags.ignoreCase && config.transform.unicodeFlag) {
+			if (caseFoldUnicode || caseFoldAscii) {
 				stringifiedString = '';
 				for (const ch of string.characters) {
 					let set = regenerate(ch.codePoint);
-					const folded = caseFold(ch.codePoint);
+					const folded = maybeFold(ch.codePoint);
 					if (folded) set.add(folded);
 					stringifiedString += set.toString(regenerateOptions);
 				}
@@ -381,6 +417,9 @@ const computeCharacterClass = (characterClassItem, regenerateOptions) => {
 			throw new Error(`Unknown character class kind: ${ characterClassItem.kind }`);
 	}
 
+	const caseFoldAscii = configNeedCaseFoldAscii();
+	const caseFoldUnicode = configNeedCaseFoldUnicode();
+
 	for (const item of characterClassItem.body) {
 		switch (item.type) {
 			case 'value':
@@ -392,8 +431,9 @@ const computeCharacterClass = (characterClassItem, regenerateOptions) => {
 				const min = item.min.codePoint;
 				const max = item.max.codePoint;
 				handlePositive.range(data, min, max);
-				if (config.flags.ignoreCase && config.transform.unicodeFlag) {
+				if (caseFoldAscii || caseFoldUnicode) {
 					handlePositive.iuRange(data, min, max);
+					data.transformed = true;
 				}
 				break;
 			case 'characterClassEscape':
@@ -452,7 +492,38 @@ const processCharacterClass = (
 			if (config.useUnicodeFlag) {
 				update(characterClassItem, `[^${setStr[0] === '[' ? setStr.slice(1, -1) : setStr}]`)
 			} else {
-				update(characterClassItem, `(?!${setStr})[\\s\\S]`)
+				if (config.flags.unicode) {
+					if (config.flags.ignoreCase) {
+						const astralCharsSet = singleChars.clone().intersection(ASTRAL_SET);
+						// Assumption: singleChars do not contain lone surrogates.
+						// Regex like /[^\ud800]/u is not supported
+						const surrogateOrBMPSetStr = singleChars
+							.clone()
+							.remove(astralCharsSet)
+							.addRange(0xd800, 0xdfff)
+							.toString({ bmpOnly: true });
+						// Don't generate negative lookahead for astral characters
+						// because the case folding is not working anyway as we break
+						// code points into surrogate pairs.
+						const astralNegativeSetStr = ASTRAL_SET
+							.clone()
+							.remove(astralCharsSet)
+							.toString(regenerateOptions);
+						// The transform here does not support lone surrogates.
+						update(
+							characterClassItem,
+							`(?!${surrogateOrBMPSetStr})[\\s\\S]|${astralNegativeSetStr}`
+						);
+					} else {
+						// Generate negative set directly when case folding is not involved.
+						update(
+							characterClassItem,
+							UNICODE_SET.clone().remove(singleChars).toString(regenerateOptions)
+						);
+					}
+				} else {
+					update(characterClassItem, `(?!${setStr})[\\s\\S]`);
+				}
 			}
 		} else {
 			const hasEmptyString = longStrings.has('');
@@ -475,15 +546,40 @@ const assertNoUnmatchedReferences = (groups) => {
 	}
 };
 
+const processModifiers = (item, regenerateOptions, groups) => {
+	const enabling = item.modifierFlags.enabling;
+	const disabling = item.modifierFlags.disabling;
+
+	delete item.modifierFlags;
+	item.behavior = 'ignore';
+
+	const oldData = Object.assign({}, config.modifiersData);
+
+	enabling.split('').forEach(flag => {
+		config.modifiersData[flag] = true;
+	});
+	disabling.split('').forEach(flag => {
+		config.modifiersData[flag] = false;
+	});
+
+	item.body = item.body.map(term => {
+		return processTerm(term, regenerateOptions, groups);
+	});
+
+	config.modifiersData = oldData;
+
+	return item;
+}
+
 const processTerm = (item, regenerateOptions, groups) => {
 	switch (item.type) {
 		case 'dot':
 			if (config.transform.unicodeFlag) {
 				update(
 					item,
-					getUnicodeDotSet(config.flags.dotAll).toString(regenerateOptions)
+					getUnicodeDotSet(config.flags.dotAll || config.modifiersData.s).toString(regenerateOptions)
 				);
-			} else if (config.transform.dotAllFlag) {
+			} else if (config.transform.dotAllFlag || config.modifiersData.s) {
 				// TODO: consider changing this at the regenerate level.
 				update(item, '[\\s\\S]');
 			}
@@ -554,6 +650,9 @@ const processTerm = (item, regenerateOptions, groups) => {
 					delete groups.unmatchedReferences[name];
 				}
 			}
+			if (item.modifierFlags && config.transform.modifiers) {
+				return processModifiers(item, regenerateOptions, groups);
+			}
 			/* falls through */
 		case 'quantifier':
 			item.body = item.body.map(term => {
@@ -577,12 +676,8 @@ const processTerm = (item, regenerateOptions, groups) => {
 		case 'value':
 			const codePoint = item.codePoint;
 			const set = regenerate(codePoint);
-			if (config.flags.ignoreCase && config.transform.unicodeFlag) {
-				const folded = caseFold(codePoint);
-				if (folded) {
-					set.add(folded);
-				}
-			}
+			const folded = maybeFold(codePoint);
+			set.add(folded);
 			update(item, set.toString(regenerateOptions));
 			break;
 		case 'reference':
@@ -622,8 +717,14 @@ const processTerm = (item, regenerateOptions, groups) => {
 			}
 			break;
 		case 'anchor':
+			if (config.modifiersData.m) {
+				if (item.kind == 'start') {
+					update(item, `(?:^|(?<=${NEWLINE_SET.toString()}))`);
+				} else if (item.kind == 'end') {
+					update(item, `(?:$|(?=${NEWLINE_SET.toString()}))`);
+				}
+			}
 		case 'empty':
-		case 'group':
 			// Nothing to do here.
 			break;
 		// The `default` clause is only here as a safeguard; it should never be
@@ -641,6 +742,7 @@ const config = {
 		'unicode': false,
 		'unicodeSets': false,
 		'dotAll': false,
+		'multiline': false,
 	},
 	'transform': {
 		'dotAllFlag': false,
@@ -648,6 +750,12 @@ const config = {
 		'unicodeSetsFlag': false,
 		'unicodePropertyEscapes': false,
 		'namedGroups': false,
+		'modifiers': false,
+	},
+	'modifiersData': {
+		'i': undefined,
+		's': undefined,
+		'm': undefined,
 	},
 	get useUnicodeFlag() {
 		return (this.flags.unicode || this.flags.unicodeSets) && !this.transform.unicodeFlag;
@@ -668,14 +776,16 @@ const validateOptions = (options) => {
 					throw new Error(`.${key} must be false (default) or 'transform'.`);
 				}
 				break;
+			case 'modifiers':
 			case 'unicodeSetsFlag':
 				if (value != null && value !== false && value !== 'parse' && value !== 'transform') {
 					throw new Error(`.${key} must be false (default), 'parse' or 'transform'.`);
 				}
 				break;
 			case 'onNamedGroup':
+			case 'onNewFlags':
 				if (value != null && typeof value !== 'function') {
-					throw new Error('.onNamedGroup must be a function.');
+					throw new Error(`.${key} must be a function.`);
 				}
 				break;
 			default:
@@ -694,6 +804,7 @@ const rewritePattern = (pattern, flags, options) => {
 	config.flags.unicodeSets = hasFlag(flags, 'v');
 	config.flags.ignoreCase = hasFlag(flags, 'i');
 	config.flags.dotAll = hasFlag(flags, 's');
+	config.flags.multiline = hasFlag(flags, 'm');
 
 	config.transform.dotAllFlag = config.flags.dotAll && transform(options, 'dotAllFlag');
 	config.transform.unicodeFlag = (config.flags.unicode || config.flags.unicodeSets) && transform(options, 'unicodeFlag');
@@ -704,9 +815,15 @@ const rewritePattern = (pattern, flags, options) => {
 		transform(options, 'unicodeFlag') || transform(options, 'unicodePropertyEscapes')
 	);
 	config.transform.namedGroups = transform(options, 'namedGroups');
+	config.transform.modifiers = transform(options, 'modifiers');
+
+	config.modifiersData.i = undefined;
+	config.modifiersData.s = undefined;
+	config.modifiersData.m = undefined;
 
 	const regjsparserFeatures = {
 		'unicodeSet': Boolean(options && options.unicodeSetsFlag),
+		'modifiers': Boolean(options && options.modifiers),
 
 		// Enable every stable RegExp feature by default
 		'unicodePropertyEscape': true,
@@ -728,9 +845,57 @@ const rewritePattern = (pattern, flags, options) => {
 	};
 
 	const tree = parse(pattern, flags, regjsparserFeatures);
+
+	if (config.transform.modifiers) {
+		if (/\(\?[a-z]*-[a-z]+:/.test(pattern)) {
+			// the pattern _likely_ contain inline disabled modifiers
+			// we need to traverse to make sure that they are actually modifiers and to collect them
+			const allDisabledModifiers = Object.create(null)
+			const itemStack = [tree];
+			let node;
+			while (node = itemStack.pop(), node != undefined) {
+				if (Array.isArray(node)) {
+					Array.prototype.push.apply(itemStack, node);
+				} else if (typeof node == 'object' && node != null) {
+					for (const key of Object.keys(node)) {
+						const value = node[key];
+						if (key == 'modifierFlags') {
+							if (value.disabling.length > 0){
+								value.disabling.split('').forEach((flag)=>{
+									allDisabledModifiers[flag] = true
+								});
+							}
+						} else if (typeof value == 'object' && value != null) {
+							itemStack.push(value);
+						}
+					}
+				}
+			}
+			for (const flag of Object.keys(allDisabledModifiers)) {
+				config.modifiersData[flag] = true;
+			}
+		}
+	}
+
 	// Note: `processTerm` mutates `tree` and `groups`.
 	processTerm(tree, regenerateOptions, groups);
 	assertNoUnmatchedReferences(groups);
+
+	const onNewFlags = options && options.onNewFlags;
+	if (onNewFlags) {
+		let newFlags = flags.split('').filter((flag) => !config.modifiersData[flag]).join('');
+		if (config.transform.unicodeSetsFlag) {
+			newFlags = newFlags.replace('v', 'u');
+		}
+		if (config.transform.unicodeFlag) {
+			newFlags = newFlags.replace('u', '');
+		}
+		if (config.transform.dotAllFlag === 'transform') {
+			newFlags = newFlags.replace('s', '');
+		}
+		onNewFlags(newFlags);
+	}
+
 	return generate(tree);
 };
 
diff --git a/scripts/character-class-escape-sets.js b/scripts/character-class-escape-sets.js
deleted file mode 100644
index 9e0f6a3..0000000
--- a/scripts/character-class-escape-sets.js
+++ /dev/null
@@ -1,135 +0,0 @@
-'use strict';
-
-const fs = require('fs');
-const jsesc = require('jsesc');
-const regenerate = require('regenerate');
-
-const Zs = require('@unicode/unicode-15.0.0/General_Category/Space_Separator/code-points.js');
-
-const iuMappings = require('../data/iu-mappings.js');
-
-const caseFold = (codePoint) => {
-	return iuMappings.get(codePoint) || false;
-};
-
-// Prepare a Regenerate set containing all code points, used for negative
-// character classes (if any).
-const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
-// Without the `u` flag, the range stops at 0xFFFF.
-// https://mths.be/es#sec-pattern-semantics
-const BMP_SET = regenerate().addRange(0x0, 0xFFFF);
-
-const ESCAPE_CHARS = {};
-const ESCAPE_CHARS_UNICODE = {};
-const ESCAPE_CHARS_UNICODE_IGNORE_CASE = {};
-const addCharacterClassEscape = (lower, set) => {
-	ESCAPE_CHARS[lower] = ESCAPE_CHARS_UNICODE[lower] = set;
-	const upper = lower.toUpperCase();
-	ESCAPE_CHARS[upper] = BMP_SET.clone().remove(set);
-	ESCAPE_CHARS_UNICODE[upper] = UNICODE_SET.clone().remove(set);
-	// Check if one or more symbols in this set fold to another one. If so,
-	// a copy of the set including the mapped symbols is created for use with
-	// regular expressions that have both the `u` and `i` flags set.
-	const codePoints = set.toArray();
-	const iuSet = regenerate();
-	let containsFoldingSymbols = false;
-	for (const codePoint of codePoints) {
-		let folded = caseFold(codePoint);
-		if (folded) {
-			containsFoldingSymbols = true;
-			iuSet.add(folded);
-			folded = caseFold(folded);
-			if (folded) {
-				iuSet.add(folded);
-			}
-		}
-	}
-	const iuLowerSet = containsFoldingSymbols ?
-		iuSet.clone().add(set) :
-		set;
-	const iuUpperSet = UNICODE_SET.clone().remove(iuLowerSet);
-	ESCAPE_CHARS_UNICODE_IGNORE_CASE[lower] = iuLowerSet;
-	ESCAPE_CHARS_UNICODE_IGNORE_CASE[upper] = iuUpperSet;
-}
-
-// Prepare a Regenerate set for every existing character class escape.
-// https://mths.be/es#sec-characterclassescape
-addCharacterClassEscape(
-	'd', // `\d` and `\D`
-	regenerate().addRange('0', '9')
-);
-addCharacterClassEscape(
-	's', // `\s` and `\S`
-	regenerate(
-		// https://mths.be/es#sec-white-space
-		0x0009,
-		0x000B,
-		0x000C,
-		0x0020,
-		0x00A0,
-		0xFEFF,
-		Zs,
-		// https://mths.be/es#sec-line-terminators
-		0x000A,
-		0x000D,
-		0x2028,
-		0x2029
-	)
-);
-addCharacterClassEscape(
-	'w', // `\w` and `\W`
-	regenerate('_').addRange('a', 'z').addRange('A', 'Z').addRange('0', '9')
-);
-
-/*----------------------------------------------------------------------------*/
-
-const codePointToString = (codePoint) => {
-	return '0x' + codePoint.toString(16).toUpperCase();
-};
-
-// Regenerate plugin that turns a set into some JavaScript source code that
-// generates that set.
-regenerate.prototype.toCode = function() {
-	const data = this.data;
-	// Iterate over the data per `(start, end)` pair.
-	let index = 0;
-	let start;
-	let end;
-	const length = data.length;
-	const loneCodePoints = [];
-	const ranges = [];
-	while (index < length) {
-		start = data[index];
-		end = data[index + 1] - 1; // Note: the `- 1` makes `end` inclusive.
-		if (start == end) {
-			loneCodePoints.push(codePointToString(start));
-		} else {
-			ranges.push(
-				'addRange(' + codePointToString(start) +
-				', ' + codePointToString(end) + ')'
-			);
-		}
-		index += 2;
-	}
-	return 'regenerate(' + loneCodePoints.join(', ') + ')' +
-		(ranges.length ? '\n\t\t.' + ranges.join('\n\t\t.') : '');
-};
-
-const stringify = (name, object) => {
-	const source = 'exports.' + name + ' = new Map([\n\t' + Object.keys(object).map((character) => {
-		const set = object[character];
-		return '[' + jsesc(character, { 'wrap': true }) + ', ' + set.toCode() + ']';
-	}).join(',\n\t') + '\n]);';
-	return source;
-};
-
-const source = [
-	'// Generated using `npm run build`. Do not edit.\n' +
-	`'use strict';\n\nconst regenerate = require('regenerate');`,
-	stringify('REGULAR', ESCAPE_CHARS),
-	stringify('UNICODE', ESCAPE_CHARS_UNICODE),
-	stringify('UNICODE_IGNORE_CASE', ESCAPE_CHARS_UNICODE_IGNORE_CASE)
-].join('\n\n');
-
-// Save the precompiled sets to a static file.
-fs.writeFileSync('data/character-class-escape-sets.js', source + '\n');
diff --git a/scripts/iu-mappings.js b/scripts/iu-mappings.js
deleted file mode 100644
index ce3f953..0000000
--- a/scripts/iu-mappings.js
+++ /dev/null
@@ -1,179 +0,0 @@
-'use strict';
-
-const fs = require('fs');
-const _ = require('lodash');
-const jsesc = require('jsesc');
-
-const hex = (number) => {
-	return `0x${ number.toString(16).toUpperCase() }`;
-};
-
-const writeMap = (fileName, map) => {
-	// Sort map by key.
-	const sortedMap = new Map([...map].sort((a, b) => a[0] - b[0]));
-	fs.writeFileSync(
-		fileName,
-		`module.exports = ${ jsesc(sortedMap, {
-			'compact': false,
-			'numbers': 'hexadecimal'
-		}) };\n`
-	);
-}
-
-// Given two code points, check if both are in the ASCII range and if one is
-// the uppercased version of the other. In that case, ES5 engines know about
-// this mapping, so it’s only needed to include one of the two in a
-// case-insensitive regular expression.
-const isES5CasedVariant = (a, b) => {
-	return (a < 0x80 && b < 0x80) &&
-		(oneWayMappings.get(a) == b || oneWayMappings.get(b) == a);
-};
-
-const extend = (map, key, value, callback) => {
-	if (map.has(key)) {
-		const currentValue = map.get(key);
-		if (Array.isArray(currentValue)) {
-			if (currentValue.indexOf(value) > -1) {
-				return;
-			}
-			if (callback) {
-				const skip = currentValue.some((codePoint) => {
-					return callback(codePoint, value);
-				});
-				if (skip) {
-					return;
-				}
-			}
-			currentValue.push(value);
-		} else {
-			if (currentValue == value) {
-				return;
-			}
-			if (callback) {
-				if (callback(currentValue, value)) {
-					return;
-				}
-			}
-			map.set(key, [currentValue, value]);
-		}
-	} else {
-		map.set(key, value);
-	}
-};
-
-// From <http://unicode.org/Public/UCD/latest/ucd/CaseFolding.txt>:
-//
-// The status field is:
-// C: common case folding, common mappings shared by both simple and full
-//    mappings.
-// F: full case folding, mappings that cause strings to grow in length. Multiple
-//    characters are separated by spaces.
-// S: simple case folding, mappings to single characters where different from F.
-// T: special case for uppercase I and dotted uppercase I
-//    - For non-Turkic languages, this mapping is normally not used.
-//    - For Turkic languages (tr, az), this mapping can be used instead of the
-//      normal mapping for these characters. Note that the Turkic mappings do
-//      not maintain canonical equivalence without additional processing.
-//      See the discussions of case mapping in the Unicode Standard for more
-//      information.
-//
-// Usage:
-//  A. To do a simple case folding, use the mappings with status C + S.
-//  B. To do a full case folding, use the mappings with status C + F.
-
-const commonMappings = require('@unicode/unicode-15.0.0/Case_Folding/C/code-points.js');
-const simpleMappings = require('@unicode/unicode-15.0.0/Case_Folding/S/code-points.js');
-
-// We want the `C` mappings in both directions (i.e. `A` should fold to `a`
-// and `a` to `A`), and the `S` mappings in both directions (i.e. `ẞ` should
-// fold to `ß` and `ß` to `ẞ`). Let’s start with the simple case folding (in
-// one direction) first, then filter the set, and then deal with the inverse.
-const oneWayMappings = new Map();
-for (const [from, to] of commonMappings) {
-	oneWayMappings.set(from, to);
-}
-for (const [from, to] of simpleMappings) {
-	oneWayMappings.set(from, to);
-}
-// Note: various code points can fold into the same code point, so it’s not
-// possible to simply invert `oneWayMappings` — some entries would be lost in
-// the process.
-
-// In case-insignificant matches when `Unicode` is `true` (i.e. when the `u`
-// flag is enabled), all characters are implicitly case-folded using the
-// simple mapping provided by the Unicode standard immediately before they
-// are compared. The simple mapping always maps to a single code point, so it
-// does not map, for example, `ß` (U+00DF) to `SS`. It may however map a code
-// point outside the Basic Latin range to a character within, for example, `ſ`
-// (U+017F) to `s`. Such characters are not mapped if `Unicode` is `false`.
-// This prevents Unicode code points such as U+017F and U+212A from matching
-// regular expressions such as `/[a‑z]/i`, but they will match `/[a‑z]/ui`.
-// https://mths.be/es6#sec-runtime-semantics-canonicalize-abstract-operation
-// Get the mappings that are unique to regular expressions that have both the
-// `i` and `u` flags set. In addition to the above, this includes all mappings
-// for astral code points.
-const filteredMappings = new Map();
-for (const [from, to] of oneWayMappings) {
-	// Case folding is applied to both the pattern and the string being matched.
-	// Because of that e.g. `/[A-Z]/iu` matches U+017F and U+212A, just like
-	// `/[a-z]/iu` would, even though no symbol in the range from `A` to `Z`
-	// folds to U+017F or U+212A directly. Since we’re only transpiling regular
-	// expressions and not strings, we have to account for this in regular
-	// expressions only. This can be done as per this example:
-	// 1. `oneWayMappings` already maps `S` to `s`. (83 → 115)
-	// 2. `oneWayMappings` already maps `ſ` to `s`. (383 → 115)
-	// 3. So, in the generated mappings, make sure `S` maps to `ſ`. (83 → 383)
-	// Check if there are any other code points that map to the same `to` value.
-	for (const [otherFrom, otherTo] of oneWayMappings) {
-		if (otherFrom != from && otherTo == to) {
-			// Note: we could use `extend` here, but it’s not necessary as there can
-			// only be a single value for the key `from` at this point.
-			filteredMappings.set(from, otherFrom);
-		}
-	}
-	if (
-		// Include astral code points.
-		(from > 0xFFFF || to > 0xFFFF) ||
-		// Exclude ES5 mappings as per the above comment.
-		// https://mths.be/es6#sec-runtime-semantics-canonicalize-abstract-operation
-		(
-			// TODO: Make this not depend on the engine in which this build script
-			// runs. (If V8 has a bug, then the generated data has the same bug.)
-			!RegExp(String.fromCodePoint(from), 'i').test(String.fromCodePoint(to))
-		)
-	) {
-		extend(filteredMappings, from, to);
-	} else {
-		const stringFrom = String.fromCodePoint(from);
-		const stringTo = String.fromCodePoint(to);
-		const code = `/${
-			jsesc(stringFrom)
-		}/i.test(${
-			jsesc(stringTo, { 'wrap': true })
-		})`;
-		console.log(
-			`Skipping ${ hex(from) } → ${ hex(to) } since ${ code } is already \`true\`.`
-		);
-		// The following snippet was used to create https://mths.be/demo/regex-i.
-		// https://github.com/mathiasbynens/regexpu-core/issues/7#issuecomment-225894534
-		// console.log(
-		// 	`console.assert(${ code }, ${ JSON.stringify(code) });`
-		// );
-	}
-}
-
-// Create a new object containing all `filteredMappings` and their inverse.
-const iuMappings = new Map();
-for (const [from, to] of filteredMappings) {
-	if (Array.isArray(to)) {
-		for (const codePoint of to) {
-			extend(iuMappings, from, codePoint, isES5CasedVariant);
-			extend(iuMappings, codePoint, from, isES5CasedVariant);
-		}
-	} else {
-		extend(iuMappings, from, to, isES5CasedVariant);
-		extend(iuMappings, to, from, isES5CasedVariant);
-	}
-}
-
-writeMap('data/iu-mappings.js', iuMappings);
diff --git a/tests/tests.js b/tests/tests.js
deleted file mode 100644
index 9812394..0000000
--- a/tests/tests.js
+++ /dev/null
@@ -1,1445 +0,0 @@
-'use strict';
-
-const assert = require('assert');
-const regenerate = require('regenerate');
-const rewritePattern = require('../rewrite-pattern.js');
-const fixtures = require('regexpu-fixtures');
-
-const BMP_SET = regenerate().addRange(0x0, 0xFFFF);
-const BMP_PATTERN = BMP_SET.toString({ 'bmpOnly': true });
-const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
-const UNICODE_PATTERN = UNICODE_SET.toString();
-
-describe('rewritePattern { unicodeFlag }', () => {
-	const options = {
-		'unicodeFlag': 'transform'
-	};
-	for (const fixture of fixtures) {
-		const pattern = fixture.pattern;
-		for (const flag of fixture.flags) {
-			if (flag.includes('u')) {
-				it('rewrites `/' + pattern + '/' + flag + '` correctly', () => {
-					assert.equal(rewritePattern(pattern, flag, options), fixture.transpiled);
-				});
-			} else {
-				it('leaves `/' + pattern + '/' + flag + '` as-is', () => {
-					// TODO: Update regexpu-fixtures
-					const expected = pattern.replace(/^\uD834\uDF06/g, '\\uD834\\uDF06');
-					assert.equal(rewritePattern(pattern, flag, options), expected);
-				});
-			}
-		}
-	}
-});
-
-const unicodePropertyEscapeFixtures = [
-	// https://unicode.org/reports/tr18/#RL1.2 item 1
-	{
-		'path': 'General_Category/Uppercase_Letter',
-		'expressions': [
-			'gc=Lu',
-			'gc=Uppercase_Letter',
-			'General_Category=Lu',
-			'General_Category=Uppercase_Letter',
-			'Lu',
-			'Uppercase_Letter'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 2a
-	{
-		'path': 'Script/Greek',
-		'expressions': [
-			'sc=Grek',
-			'sc=Greek',
-			'Script=Grek',
-			'Script=Greek'
-		]
-	},
-	{
-		'path': 'Script/Hiragana',
-		'expressions': [
-			'sc=Hira',
-			'sc=Hiragana',
-			'Script=Hira',
-			'Script=Hiragana'
-		]
-	},
-	{
-		'path': 'Script/Kawi',
-		'expressions': [
-			'sc=Kawi',
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 2b
-	{
-		'path': 'Script_Extensions/Greek',
-		'expressions': [
-			'scx=Grek',
-			'scx=Greek',
-			'Script_Extensions=Grek',
-			'Script_Extensions=Greek'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 3
-	{
-		'path': 'Binary_Property/Alphabetic',
-		'expressions': [
-			'Alpha',
-			'Alphabetic'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 4
-	{
-		'path': 'Binary_Property/Uppercase',
-		'expressions': [
-			'Upper',
-			'Uppercase'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 5
-	{
-		'path': 'Binary_Property/Lowercase',
-		'expressions': [
-			'Lower',
-			'Lowercase'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 6
-	{
-		'path': 'Binary_Property/White_Space',
-		'expressions': [
-			'WSpace',
-			'White_Space'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 7
-	{
-		'path': 'Binary_Property/Noncharacter_Code_Point',
-		'expressions': [
-			'NChar',
-			'Noncharacter_Code_Point'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 8
-	{
-		'path': 'Binary_Property/Default_Ignorable_Code_Point',
-		'expressions': [
-			'DI',
-			'Default_Ignorable_Code_Point'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 9a
-	{
-		'path': 'Binary_Property/Any',
-		'expressions': [
-			'Any'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 9b
-	{
-		'path': 'Binary_Property/ASCII',
-		'expressions': [
-			'ASCII'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL1.2 item 9c
-	{
-		'path': 'Binary_Property/Assigned',
-		'expressions': [
-			'Assigned'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/ASCII_Hex_Digit',
-		'expressions': [
-			'ASCII_Hex_Digit',
-			'AHex'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	// {
-	// 	'path': 'Bidi_Class/Arabic_Letter',
-	// 	'expressions': [
-	// 		'bc=AL',
-	// 		'bc=Arabic_Letter',
-	// 		'Bidi_Class=AL',
-	// 		'Bidi_Class=Arabic_Letter'
-	// 	]
-	// },
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Bidi_Control',
-		'expressions': [
-			'Bidi_C',
-			'Bidi_Control'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Bidi_Mirrored',
-		'expressions': [
-			'Bidi_M',
-			'Bidi_Mirrored'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Case_Ignorable',
-		'expressions': [
-			'CI',
-			'Case_Ignorable',
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Cased',
-		'expressions': [
-			'Cased'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Changes_When_NFKC_Casefolded',
-		'expressions': [
-			'CWKCF',
-			'Changes_When_NFKC_Casefolded'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Changes_When_Casefolded',
-		'expressions': [
-			'CWCF',
-			'Changes_When_Casefolded'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Changes_When_Casemapped',
-		'expressions': [
-			'CWCM',
-			'Changes_When_Casemapped'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Changes_When_Lowercased',
-		'expressions': [
-			'CWL',
-			'Changes_When_Lowercased'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Changes_When_Titlecased',
-		'expressions': [
-			'CWT',
-			'Changes_When_Titlecased'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Changes_When_Uppercased',
-		'expressions': [
-			'CWU',
-			'Changes_When_Uppercased'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Dash',
-		'expressions': [
-			'Dash'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Deprecated',
-		'expressions': [
-			'Dep',
-			'Deprecated'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Diacritic',
-		'expressions': [
-			'Dia',
-			'Diacritic'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Extender',
-		'expressions': [
-			'Ext',
-			'Extender'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Grapheme_Base',
-		'expressions': [
-			'Gr_Base',
-			'Grapheme_Base'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Grapheme_Extend',
-		'expressions': [
-			'Gr_Ext',
-			'Grapheme_Extend'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Hex_Digit',
-		'expressions': [
-			'Hex',
-			'Hex_Digit'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/ID_Continue',
-		'expressions': [
-			'IDC',
-			'ID_Continue'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/ID_Start',
-		'expressions': [
-			'IDS',
-			'ID_Start'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Ideographic',
-		'expressions': [
-			'Ideo',
-			'Ideographic'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/IDS_Binary_Operator',
-		'expressions': [
-			'IDSB',
-			'IDS_Binary_Operator'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/IDS_Trinary_Operator',
-		'expressions': [
-			'IDST',
-			'IDS_Trinary_Operator'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Join_Control',
-		'expressions': [
-			'Join_C',
-			'Join_Control'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Logical_Order_Exception',
-		'expressions': [
-			'LOE',
-			'Logical_Order_Exception'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Math',
-		'expressions': [
-			'Math'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Pattern_Syntax',
-		'expressions': [
-			'Pat_Syn',
-			'Pattern_Syntax'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Pattern_White_Space',
-		'expressions': [
-			'Pat_WS',
-			'Pattern_White_Space'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Quotation_Mark',
-		'expressions': [
-			'QMark',
-			'Quotation_Mark'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Radical',
-		'expressions': [
-			'Radical'
-		]
-	},
-	{
-		'path': 'Binary_Property/Regional_Indicator',
-		'expressions': [
-			'RI',
-			'Regional_Indicator'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Soft_Dotted',
-		'expressions': [
-			'SD',
-			'Soft_Dotted'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Sentence_Terminal',
-		'expressions': [
-			'STerm',
-			'Sentence_Terminal'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Terminal_Punctuation',
-		'expressions': [
-			'Term',
-			'Terminal_Punctuation'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Unified_Ideograph',
-		'expressions': [
-			'UIdeo',
-			'Unified_Ideograph'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/Variation_Selector',
-		'expressions': [
-			'VS',
-			'Variation_Selector'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/XID_Continue',
-		'expressions': [
-			'XIDC',
-			'XID_Continue'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	{
-		'path': 'Binary_Property/XID_Start',
-		'expressions': [
-			'XIDS',
-			'XID_Start'
-		]
-	},
-	// https://unicode.org/reports/tr18/#RL2.7
-	// {
-	// 	'path': 'Bidi_Paired_Bracket_Type/Open',
-	// 	'expressions': [
-	// 		'bpt=o',
-	// 		'bpt=Open',
-	// 		'Bidi_Paired_Bracket_Type=o',
-	// 		'Bidi_Paired_Bracket_Type=Open'
-	// 	]
-	// },
-	// https://unicode.org/reports/tr51/
-	{
-		'path': 'Binary_Property/Emoji',
-		'expressions': [
-			'Emoji'
-		]
-	},
-	// https://unicode.org/reports/tr51/
-	{
-		'path': 'Binary_Property/Emoji_Component',
-		'expressions': [
-			'Emoji_Component'
-		]
-	},
-	// https://unicode.org/reports/tr51/
-	{
-		'path': 'Binary_Property/Emoji_Modifier',
-		'expressions': [
-			'Emoji_Modifier'
-		]
-	},
-	// https://unicode.org/reports/tr51/
-	{
-		'path': 'Binary_Property/Emoji_Modifier_Base',
-		'expressions': [
-			'Emoji_Modifier_Base'
-		]
-	},
-	// https://unicode.org/reports/tr51/
-	{
-		'path': 'Binary_Property/Emoji_Presentation',
-		'expressions': [
-			'Emoji_Presentation'
-		]
-	},
-	// https://unicode.org/reports/tr51/proposed.html
-	{
-		'path': 'Binary_Property/Extended_Pictographic',
-		'expressions': [
-			'Extended_Pictographic'
-		]
-	},
-	{
-		'path': 'Script_Extensions/Yezidi',
-		'expressions': [
-			'scx=Yezi',
-			'scx=Yezidi',
-			'Script_Extensions=Yezi',
-			'Script_Extensions=Yezidi',
-		]
-	},
-	{
-		'path': 'Script_Extensions/Toto',
-		'expressions': [
-			'scx=Toto',
-			'Script_Extensions=Toto',
-		]
-	},
-];
-
-const getPropertyValuePattern = (path) => {
-	const codePoints = require(`@unicode/unicode-15.0.0/${
-		path }/code-points.js`);
-	return {
-		'p': regenerate(codePoints).toString(),
-		'P': UNICODE_SET.clone().remove(codePoints).toString()
-	};
-};
-
-describe('unicodePropertyEscapes', () => {
-	const features = {
-		'unicodePropertyEscapes': 'transform',
-		'unicodeFlag': 'transform'
-	};
-	for (const fixture of unicodePropertyEscapeFixtures) {
-		const expected = getPropertyValuePattern(fixture.path);
-		for (const pattern of fixture.expressions) {
-			const p = `\\p{${ pattern }}`;
-			it('rewrites `/' + p + '/u` correctly', () => {
-				const transpiled = rewritePattern(p, 'u', features);
-				if (transpiled != '(?:' + expected.p + ')') {
-					assert.equal(transpiled, expected.p);
-				}
-			});
-			const P = `\\P{${ pattern }}`;
-			it('rewrites `/' + P + '/u` correctly', () => {
-				const transpiled = rewritePattern(P, 'u', features);
-				if (transpiled != '(?:' + expected.P + ')') {
-					assert.equal(transpiled, expected.P);
-				}
-			});
-		}
-	}
-	it('transpiles Unicode property escapes within various constructions', () => {
-		assert.equal(
-			rewritePattern('\\p{ASCII_Hex_Digit}', 'u', features),
-			'[0-9A-Fa-f]'
-		);
-		assert.equal(
-			rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', features),
-			'(?:\\uD811[\\uDC00-\\uDE46])'
-		);
-		assert.equal(
-			rewritePattern('\\p{ASCII_Hex_Digit}+', 'u', features),
-			'[0-9A-Fa-f]+'
-		);
-		assert.equal(
-			rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}+', 'u', features),
-			'(?:\\uD811[\\uDC00-\\uDE46])+'
-		);
-		assert.equal(
-			rewritePattern('[\\p{ASCII_Hex_Digit}_]', 'u', features),
-			'[0-9A-F_a-f]'
-		);
-		assert.equal(
-			rewritePattern('[^\\p{ASCII_Hex_Digit}_]', 'u', features),
-			'(?:(?![0-9A-F_a-f])[\\s\\S])'
-		);
-		assert.equal(
-			rewritePattern('[\\P{Script_Extensions=Anatolian_Hieroglyphs}]', 'u', features),
-			'(?:[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uD810\\uD812-\\uDBFF][\\uDC00-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])'
-		);
-		assert.equal(
-			rewritePattern('[\\p{Script_Extensions=Anatolian_Hieroglyphs}_]', 'u', features),
-			'(?:_|\\uD811[\\uDC00-\\uDE46])'
-		);
-		assert.equal(
-			rewritePattern('[\\P{Script_Extensions=Anatolian_Hieroglyphs}_]', 'u', features),
-			'(?:[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uD810\\uD812-\\uDBFF][\\uDC00-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])'
-		);
-		assert.equal(
-			rewritePattern('(?:\\p{ASCII_Hex_Digit})', 'u', features),
-			'(?:[0-9A-Fa-f])'
-		);
-		assert.equal(
-			rewritePattern('(?:\\p{Script_Extensions=Anatolian_Hieroglyphs})', 'u', features),
-			'(?:(?:\\uD811[\\uDC00-\\uDE46]))'
-		);
-		assert.equal(
-			rewritePattern('(?:\\p{Script_Extensions=Wancho})', 'u', features),
-			'(?:(?:\\uD838[\\uDEC0-\\uDEF9\\uDEFF]))'
-		);
-	});
-	it('throws on unknown binary properties', () => {
-		assert.throws(() => {
-			rewritePattern('\\p{UnknownBinaryProperty}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{UnknownBinaryProperty}', 'u', features);
-		}, Error);
-	});
-	it('throws on explicitly unsupported properties', () => {
-		// https://github.com/tc39/proposal-regexp-unicode-property-escapes/issues/27
-		assert.throws(() => {
-			rewritePattern('\\P{Composition_Exclusion}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\p{Expands_On_NFC}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\p{Expands_On_NFD}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\p{Expands_On_NFKC}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\p{Expands_On_NFKD}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\p{FC_NFKC_Closure}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\p{Full_Composition_Exclusion}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Grapheme_Link}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Hyphen}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_Alphabetic}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_Default_Ignorable_Code_Point}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_Grapheme_Extend}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_ID_Continue}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_ID_Start}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_Lowercase}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_Math}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Other_Uppercase}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{Prepended_Concatenation_Mark}', 'u', features);
-		}, Error);
-	});
-	it('throws on non-binary properties without a value', () => {
-		assert.throws(() => {
-			rewritePattern('\\p{General_Category}', 'u', features);
-		}, Error);
-	});
-	it('throws on unknown property values', () => {
-		assert.throws(() => {
-			rewritePattern('\\p{General_Category=UnknownCategory}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{General_Category=UnknownCategory}', 'u', features);
-		}, Error);
-	});
-	it('throws when loose matching is attempted', () => {
-		assert.throws(() => {
-			rewritePattern('\\p{gc=uppercaseletter}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\p{Block=Superscripts and Subscripts}', 'u', features);
-		}, Error);
-		assert.throws(() => {
-			rewritePattern('\\P{_-_lOwEr_C-A_S-E_-_}', 'u', features);
-		}, Error);
-	});
-	it('simplifies the output using Unicode code point escapes when not transforming the u flag', () => {
-		assert.equal(
-			rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', {
-				'unicodePropertyEscapes': 'transform',
-			}),
-			'[\\u{14400}-\\u{14646}]'
-		);
-		assert.equal(
-			rewritePattern('[\\p{Script_Extensions=Anatolian_Hieroglyphs}]', 'u', {
-				'unicodePropertyEscapes': 'transform',
-			}),
-			'[\\u{14400}-\\u{14646}]'
-		);
-	});
-	it('should not transpile unicode property when unicodePropertyEscapes is not enabled', () => {
-		assert.equal(
-			rewritePattern('\\p{ASCII_Hex_Digit}\\P{ASCII_Hex_Digit}', 'u'),
-			'\\p{ASCII_Hex_Digit}\\P{ASCII_Hex_Digit}'
-		);
-	});
-	it('should transpile to minimal case-insensitive set', () => {
-		assert.equal(
-			rewritePattern('\u03B8', 'iu', {
-				'unicodeFlag': 'transform'
-			}),
-			'[\\u03B8\\u03F4]'
-		);
-		assert.equal(
-			rewritePattern('\u03B8', 'iu'),
-			'\\u03B8'
-		);
-	});
-});
-
-const dotAllFlagFixtures = [
-	{
-		'pattern': '.',
-		'flags': 's',
-		'expected': '[\\s\\S]'
-	},
-	{
-		'pattern': '.',
-		'flags': 'gimsy',
-		'expected': '[\\s\\S]'
-	},
-	{
-		'pattern': '.',
-		'flags': 's',
-		'expected': '[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		'pattern': '.',
-		'flags': 'gimsy',
-		'expected': '[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		'pattern': '.',
-		'flags': 'su',
-		'expected': UNICODE_PATTERN,
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		'pattern': '.',
-		'flags': 'gimsuy',
-		'expected': UNICODE_PATTERN,
-		'options': { unicodeFlag: 'transform' }
-	}
-];
-
-describe('dotAllFlag', () => {
-	for (const fixture of dotAllFlagFixtures) {
-		const pattern = fixture.pattern;
-		const flags = fixture.flags;
-		const options = Object.assign({
-			'dotAllFlag': 'transform'
-		}, fixture.options);
-		it('rewrites `/' + pattern + '/' + flags + '` correctly', () => {
-			const transpiled = rewritePattern(pattern, flags, options);
-			const expected = fixture.expected;
-			if (transpiled != '(?:' + expected + ')') {
-				assert.strictEqual(transpiled, expected);
-			}
-		});
-	}
-
-	it('not transformed', () => {
-		it('leaves `/./su` as-is', () => {
-			assert.equal(rewritePattern('.', 'su'), '.');
-		});
-	});
-});
-
-const namedGroupFixtures = [
-	{
-		'pattern': '(?<name>)\\k<name>',
-		'flags': '',
-		'expected': '()\\1',
-		'expectedGroups': [
-			['name', 1]
-		]
-	},
-	{
-		'pattern': '(?<name1>)(?<name2>)\\k<name1>\\k<name2>',
-		'flags': '',
-		'expected': '()()\\1\\2',
-		'expectedGroups': [
-			['name1', 1],
-			['name2', 2]
-		]
-	},
-	{
-		'pattern': '()(?<name>)\\k<name>',
-		'flags': '',
-		'expected': '()()\\2',
-		'expectedGroups': [
-			['name', 2]
-		]
-	},
-	{
-		'pattern': '(?<name>)()\\1',
-		'flags': '',
-		'expected': '()()\\1'
-	},
-	{
-		'pattern': '\\k<name>\\k<name>(?<name>)\\k<name>',
-		'flags': '',
-		'expected': '(?:)(?:)()\\1'
-	},
-	{
-		'pattern': '(?<name>\\k<name>)',
-		'flags': '',
-		'expected': '(\\1)'
-	},
-	{
-		'pattern': '(?<$𐒤>a)b\\k<$𐒤>',
-		'flags': '',
-		'expected': '(a)b\\1'
-	},
-	{
-		'pattern': '(?<=a)(?<!b)(?=c)(?!d)(?:e)(?<name>f)\\k<name>',
-		'flags': '',
-		'expected': '(?<=a)(?<!b)(?=c)(?!d)(?:e)(f)\\1',
-		'expectedGroups': [
-			['name', 1]
-		]
-	},
-	{
-		'pattern': '(?:(?<a>x)|(?<a>y))\\k<a>',
-		'flags': '',
-		'expected': '(?:(x)|(y))\\1\\2',
-		'expectedGroups': [
-			['a', 1],
-			['a', 2]
-		]
-	},
-	{
-		'pattern': '(?:(?<a>x)\\k<a>|(?<a>y)\\k<a>)',
-		'flags': '',
-		'expected': '(?:(x)\\1|(y)\\1\\2)',
-		'expectedGroups': [
-			['a', 1],
-			['a', 2]
-		]
-	}
-];
-
-describe('namedGroups', () => {
-	for (const fixture of namedGroupFixtures) {
-		const {
-			pattern,
-			flags,
-			expected,
-			expectedGroups,
-			options = {}
-		} = fixture;
-		const groups = [];
-
-		Object.assign(options, {
-			namedGroups: 'transform',
-			'onNamedGroup': (name, index) => {
-				groups.push([ name, index ]);
-			}
-		});
-
-		it('rewrites `/' + pattern + '/' + flags + '` correctly', () => {
-			const transpiled = rewritePattern(pattern, flags, options);
-			assert.strictEqual(transpiled, expected);
-			if (expectedGroups) {
-				assert.deepStrictEqual(groups, expectedGroups);
-			}
-		});
-	}
-
-	it('onNamedGroup is optional', () => {
-		let transpiled;
-		const expected = '()';
-		assert.doesNotThrow(() => {
-			transpiled = rewritePattern('(?<name>)', '', {
-				namedGroups: 'transform'
-			});
-		});
-		assert.strictEqual(transpiled, expected);
-	});
-
-	it('multiple groups with the same name in the same disjunction are disallowed', () => {
-		assert.throws(() => {
-			rewritePattern('(?<name>)(?<name>)', '', {
-				namedGroups: 'transform'
-			});
-		});
-
-		assert.throws(() => {
-			rewritePattern('(?<name>)(?:a|(?<name>))', '', {
-				namedGroups: 'transform'
-			});
-		});
-
-		assert.throws(() => {
-			rewritePattern('(?:b|(?<name>))(?:a|(?<name>))', '', {
-				namedGroups: 'transform'
-			});
-		});
-	});
-
-	it('multiple groups with the same name in the different disjunctions are allowed', () => {
-		assert.doesNotThrow(() => {
-			rewritePattern('(?<name>)|(?<name>)', '', {
-				namedGroups: 'transform'
-			});
-		});
-
-		assert.doesNotThrow(() => {
-			rewritePattern('(?:b|(?<name>))|(?:a|(?<name>))', '', {
-				namedGroups: 'transform'
-			});
-		});
-	});
-
-	it('named references must reference a group', () => {
-		assert.throws(() => {
-			rewritePattern('\\k<name>', '', {
-				namedGroups: 'transform'
-			});
-		});
-	});
-
-	it('should not transpile when namedGroups is not enabled', () => {
-		const pattern = '(?<name>)';
-		let transpiled;
-		assert.doesNotThrow(() => {
-			transpiled = rewritePattern(pattern, '');
-		});
-		assert.strictEqual(pattern, transpiled);
-	});
-
-	it('should support named group references when namedGroups is not enabled', () => {
-		const pattern = '(?<name>)\\k<name>';
-		let transpiled;
-		assert.doesNotThrow(() => {
-			transpiled = rewritePattern(pattern, '');
-		});
-		assert.strictEqual(pattern, transpiled);
-	});
-
-	it('should validate named group references when namedGroups is not enabled', () => {
-		assert.throws(() => rewritePattern('\\k<foo>', ''), /Unknown group names: foo/);
-	});
-
-	it('shold call onNamedGroup even if namedGroups is not enabled', () => {
-		let called = false;
-		rewritePattern('(?<name>)', '', {
-			onNamedGroup() {
-				called = true;
-			},
-		});
-		assert.strictEqual(called, true);
-	})
-});
-
-const characterClassFixtures = [
-	{
-		pattern: '[^K]', // LATIN CAPITAL LETTER K
-		flags: 'iu',
-		expected: '(?![K\\u212A])[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		pattern: '[^k]', // LATIN SMALL LETTER K
-		flags: 'iu',
-		expected: '(?![k\\u212A])[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		pattern: '[^\u212a]', // KELVIN SIGN
-		flags: 'iu',
-		expected: '(?![K\\u212A])[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		pattern: '[^K]', // LATIN CAPITAL LETTER K
-		flags: 'iu',
-		expected: '[^K]',
-		'options': {}
-	},
-	{
-		pattern: '[^k]', // LATIN SMALL LETTER K
-		flags: 'iu',
-		expected: '[^k]',
-		'options': {}
-	},
-	{
-		pattern: '[^\u212a]', // KELVIN SIGN
-		flags: 'iu',
-		expected: '[^\u212a]',
-		'options': {}
-	},
-	{
-		pattern: '[^K]', // LATIN CAPITAL LETTER K
-		flags: 'u',
-		expected: '(?!K)[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		pattern: '[^k]', // LATIN SMALL LETTER K
-		flags: 'u',
-		expected: '(?!k)[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		pattern: '[^\u212a]', // KELVIN SIGN
-		flags: 'u',
-		expected: '(?!\\u212A)[\\s\\S]',
-		'options': { unicodeFlag: 'transform' }
-	},
-	{
-		pattern: '[^K]', // LATIN CAPITAL LETTER K
-		flags: 'u',
-		expected: '[^K]',
-		'options': {}
-	},
-	{
-		pattern: '[^k]', // LATIN SMALL LETTER K
-		flags: 'u',
-		expected: '[^k]',
-		'options': {}
-	},
-	{
-		pattern: '[^\u212a]', // KELVIN SIGN
-		flags: 'u',
-		expected: '[^\u212a]',
-		'options': {}
-	}
-];
-
-describe('character classes', () => {
-	for (const fixture of characterClassFixtures) {
-		const pattern = fixture.pattern;
-		const flags = fixture.flags;
-		const options = fixture.options;
-		const transformUnicodeFlag = options.unicodeFlag === 'transform';
-		it('rewrites `/' + pattern + '/' + flags + '` with' + (transformUnicodeFlag ? 'out' : '') + ' unicode correctly', () => {
-			const transpiled = rewritePattern(pattern, flags, options);
-			const expected = fixture.expected;
-			if (transpiled != '(?:' + expected + ')') {
-				assert.strictEqual(transpiled, expected);
-			}
-		});
-	}
-});
-
-const TRANSFORM_U = { unicodeFlag: 'transform', unicodeSetsFlag: 'transform' };
-
-const Basic_Emoji = {
-	get all() { return `${this.strings}|[${this.chars}]` },
-	strings: "🅰️|🅱️|🅾️|🅿️|🈂️|🈷️|🌡️|🌤️|🌥️|🌦️|🌧️|🌨️|🌩️|🌪️|🌫️|🌬️|🌶️|🍽️|🎖️|🎗️|🎙️|🎚️|🎛️|🎞️|🎟️|🏋️|🏌️|🏍️|🏎️|🏔️|🏕️|🏖️|🏗️|🏘️|🏙️|🏚️|🏛️|🏜️|🏝️|🏞️|🏟️|🏳️|🏵️|🏷️|🐿️|👁️|📽️|🕉️|🕊️|🕯️|🕰️|🕳️|🕴️|🕵️|🕶️|🕷️|🕸️|🕹️|🖇️|🖊️|🖋️|🖌️|🖍️|🖐️|🖥️|🖨️|🖱️|🖲️|🖼️|🗂️|🗃️|🗄️|🗑️|🗒️|🗓️|🗜️|🗝️|🗞️|🗡️|🗣️|🗨️|🗯️|🗳️|🗺️|🛋️|🛍️|🛎️|🛏️|🛠️|🛡️|🛢️|🛣️|🛤️|🛥️|🛩️|🛰️|🛳️|©️|®️|‼️|⁉️|™️|ℹ️|↔️|↕️|↖️|↗️|↘️|↙️|↩️|↪️|⌨️|⏏️|⏭️|⏮️|⏯️|⏱️|⏲️|⏸️|⏹️|⏺️|Ⓜ️|▪️|▫️|▶️|◀️|◻️|◼️|☀️|☁️|☂️|☃️|☄️|☎️|☑️|☘️|☝️|☠️|☢️|☣️|☦️|☪️|☮️|☯️|☸️|☹️|☺️|♀️|♂️|♟️|♠️|♣️|♥️|♦️|♨️|♻️|♾️|⚒️|⚔️|⚕️|⚖️|⚗️|⚙️|⚛️|⚜️|⚠️|⚧️|⚰️|⚱️|⛈️|⛏️|⛑️|⛓️|⛩️|⛰️|⛱️|⛴️|⛷️|⛸️|⛹️|✂️|✈️|✉️|✌️|✍️|✏️|✒️|✔️|✖️|✝️|✡️|✳️|✴️|❄️|❇️|❣️|❤️|➡️|⤴️|⤵️|⬅️|⬆️|⬇️|〰️|〽️|㊗️|㊙️",
-	chars: "\\u231A\\u231B\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u25FE\\u2614\\u2615\\u2648-\\u2653\\u267F\\u2693\\u26A1\\u26AA\\u26AB\\u26BD\\u26BE\\u26C4\\u26C5\\u26CE\\u26D4\\u26EA\\u26F2\\u26F3\\u26F5\\u26FA\\u26FD\\u2705\\u270A\\u270B\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2795-\\u2797\\u27B0\\u27BF\\u2B1B\\u2B1C\\u2B50\\u2B55\\u{1F004}\\u{1F0CF}\\u{1F18E}\\u{1F191}-\\u{1F19A}\\u{1F201}\\u{1F21A}\\u{1F22F}\\u{1F232}-\\u{1F236}\\u{1F238}-\\u{1F23A}\\u{1F250}\\u{1F251}\\u{1F300}-\\u{1F320}\\u{1F32D}-\\u{1F335}\\u{1F337}-\\u{1F37C}\\u{1F37E}-\\u{1F393}\\u{1F3A0}-\\u{1F3CA}\\u{1F3CF}-\\u{1F3D3}\\u{1F3E0}-\\u{1F3F0}\\u{1F3F4}\\u{1F3F8}-\\u{1F43E}\\u{1F440}\\u{1F442}-\\u{1F4FC}\\u{1F4FF}-\\u{1F53D}\\u{1F54B}-\\u{1F54E}\\u{1F550}-\\u{1F567}\\u{1F57A}\\u{1F595}\\u{1F596}\\u{1F5A4}\\u{1F5FB}-\\u{1F64F}\\u{1F680}-\\u{1F6C5}\\u{1F6CC}\\u{1F6D0}-\\u{1F6D2}\\u{1F6D5}-\\u{1F6D7}\\u{1F6DC}-\\u{1F6DF}\\u{1F6EB}\\u{1F6EC}\\u{1F6F4}-\\u{1F6FC}\\u{1F7E0}-\\u{1F7EB}\\u{1F7F0}\\u{1F90C}-\\u{1F93A}\\u{1F93C}-\\u{1F945}\\u{1F947}-\\u{1F9FF}\\u{1FA70}-\\u{1FA7C}\\u{1FA80}-\\u{1FA88}\\u{1FA90}-\\u{1FABD}\\u{1FABF}-\\u{1FAC5}\\u{1FACE}-\\u{1FADB}\\u{1FAE0}-\\u{1FAE8}\\u{1FAF0}-\\u{1FAF8}"
-};
-
-const unicodeSetFixtures = [
-	{
-		pattern: '[[a-h]&&[f-z]]',
-		expected: '[f-h]'
-	},
-	{
-		pattern: '[[a-h]&&[f-z]&&[p-z]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[a-h]&&[b]]',
-		expected: 'b'
-	},
-	{
-		pattern: '[[a-h]&&b]',
-		expected: 'b'
-	},
-	{
-		pattern: '[[g-z]&&b]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[a-h]&&[^f-z]]',
-		expected: '[a-e]'
-	},
-	{
-		pattern: '[[a-h]&&[^f-z]&&[p-z]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[a-h]&&[^f-z]&&[^p-z]]',
-		expected: '[a-e]'
-	},
-	{
-		pattern: '[[a-h]&&[^b]]',
-		expected: '[ac-h]'
-	},
-	{
-		pattern: '[[a-h]--[f-z]]',
-		expected: '[a-e]'
-	},
-	{
-		pattern: '[[a-h]--[f-z]--[p-z]]',
-		expected: '[a-e]'
-	},
-	{
-		pattern: '[[a-z]--[d-k]--[s-w]]',
-		expected: '[a-cl-rx-z]'
-	},
-	{
-		pattern: '[[a-h]--[b]]',
-		expected: '[ac-h]'
-	},
-	{
-		pattern: '[[b]--[a-h]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[a-h]--b]',
-		expected: '[ac-h]'
-	},
-	{
-		pattern: '[b--[a-h]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[g-z]--b]',
-		expected: '[g-z]'
-	},
-	{
-		pattern: '[b--[g-z]]',
-		expected: 'b'
-	},
-	{
-		pattern: '[[a-h]--[^f-z]]',
-		expected: '[f-h]'
-	},
-	{
-		pattern: '[[a-h]--[^f-z]--[p-z]]',
-		expected: '[f-h]'
-	},
-	{
-		pattern: '[[a-h]--[^f-z]--[^p-z]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[a-h]--[^b]]',
-		expected: 'b'
-	},
-	{
-		pattern: '[[a-z][f-h]]',
-		expected: '[a-z]'
-	},
-	{
-		pattern: '[^[a-z][f-h]]',
-		expected: '[^a-z]'
-	},
-	{
-		pattern: '[^[a-z][f-h]]',
-		expected: '(?:(?![a-z])[\\s\\S])',
-		options: TRANSFORM_U
-	},
-	{
-		pattern: '[[^a-z][f-h]]',
-		expected: '[\\0-`f-h\\{-\\u{10FFFF}]'
-	},
-	{
-		pattern: '[[^a-z][f-h]]',
-		expected: '(?:[\\0-`f-h\\{-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])',
-		options: TRANSFORM_U
-	},
-	{
-		pattern: '[\\q{A|AB|B|ABC|BC}ab]',
-		expected: '(?:ABC|AB|BC|[ABab])'
-	},
-	{
-		pattern: '[\\q{A|AB}a\\q{B|ABC|BC}b]',
-		expected: '(?:ABC|AB|BC|[ABab])'
-	},
-	{
-		pattern: '[\\q{A|AB}ab\\q{B|ABC|BC}]',
-		expected: '(?:ABC|AB|BC|[ABab])'
-	},
-	{
-		pattern: '[[\\q{A|AB}a]b\\q{B|ABC|BC}]',
-		expected: '(?:ABC|AB|BC|[ABab])'
-	},
-	{
-		pattern: '[\\q{👩🏿‍✈️|🚲|🇧🇪}]',
-		expected: '(?:👩🏿‍✈️|🇧🇪|\\u{1F6B2})'
-	},
-	{
-		pattern: '[ab\\q{}]',
-		expected: '(?:[ab]|)'
-	},
-	{
-		pattern: '[ab\\q{|}]',
-		expected: '(?:[ab]|)'
-	},
-	{
-		pattern: '[ab\\q{|A|AB}]',
-		expected: '(?:AB|[Aab]|)'
-	},
-	{
-		pattern: '[\\q{sA}asb]',
-		flags: 'iv',
-		expected: '(?:sA|[abs])'
-	},
-	{
-		pattern: '[\\q{sA}asb]',
-		flags: 'iv',
-		options: TRANSFORM_U,
-		expected: '(?:[s\\u017F]A|[abs\\u017F])'
-	},
-	{
-		pattern: '[[ab\\q{cd}]--a]',
-		expected: '(?:cd|b)'
-	},
-	{
-		pattern: '[[ab\\q{cd}]--[ab]]',
-		expected: '(?:cd)'
-	},
-	{
-		pattern: '[[ab\\q{cd}]--[cd]]',
-		expected: '(?:cd|[ab])'
-	},
-	{
-		pattern: '[[ab\\q{cd}]--\\q{cd}]',
-		expected: '[ab]'
-	},
-	{
-		pattern: '[[ab\\q{cd}]--[a\\q{cd}]]',
-		expected: 'b'
-	},
-	{
-		pattern: '[[ab\\q{cd}]--[ab\\q{cd}]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[[ab]--[ab\\q{cd}]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[\\q{cd}--[ab\\q{cd}]]',
-		expected: '[]'
-	},
-	{
-		pattern: '[\\q{cd}--[ab\\q{dc}]]',
-		expected: '(?:cd)'
-	},
-	{
-		pattern: '[\\q{ab|cd|abc}--\\q{abc|cd}]',
-		expected: '(?:ab)'
-	},
-	{
-		pattern: '[\\q{ab|cd|abc}--\\q{abc}--\\q{cd}]',
-		expected: '(?:ab)'
-	},
-	{
-		pattern: '[a&&\\q{a}]',
-		expected: 'a'
-	},
-	{
-		pattern: '[a&&\\q{ab}]',
-		expected: '[]'
-	},
-	{
-		pattern: '[\\q{ab}&&\\q{ab}]',
-		expected: '(?:ab)'
-	},
-	{
-		pattern: '[\\q{ab|cd|abc}&&\\q{ab|bc|abc}]',
-		expected: '(?:abc|ab)'
-	},
-	{
-		pattern: '[[a\\q{ab}]&&\\q{ab}]',
-		expected: '(?:ab)'
-	},
-	{
-		pattern: '[[a\\q{ab}]&&a]',
-		expected: 'a'
-	},
-	{
-		pattern: '[^\\q{a}]',
-		expected: '[^a]'
-	},
-	{
-		pattern: '[^\\q{abc}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{a|}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{}--\\q{}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{ab}--\\q{ab}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{a}--\\q{ab}]',
-		expected: '[^a]'
-	},
-	{
-		pattern: '[^[\\q{ab}--\\q{ab}]]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{}&&a]',
-		expected: '[^]'
-	},
-	{
-		pattern: '[^\\q{ab}&&a]',
-		expected: '[^]'
-	},
-	{
-		pattern: '[^\\q{}&&\\q{}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{ab}&&\\q{ab}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '[^\\q{}&&\\q{ab}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '\\p{Basic_Emoji}',
-		expected: `(?:${Basic_Emoji.all})`
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}]',
-		expected: `(?:${Basic_Emoji.all})`
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}&&\\p{Basic_Emoji}]',
-		expected: `(?:${Basic_Emoji.all})`
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}&&[\\u{0}-\\u{10ffff}]]',
-		expected: `[${Basic_Emoji.chars}]`
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}\\p{Emoji}]',
-		expected: `(?:${Basic_Emoji.strings}|[#\\*0-9\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23E9-\\u23F3\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB-\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u261D\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A1\\u26A7\\u26AA\\u26AB\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C5\\u26C8\\u26CE\\u26CF\\u26D1\\u26D3\\u26D4\\u26E9\\u26EA\\u26F0-\\u26F5\\u26F7-\\u26FA\\u26FD\\u2702\\u2705\\u2708-\\u270D\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2728\\u2733\\u2734\\u2744\\u2747\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2763\\u2764\\u2795-\\u2797\\u27A1\\u27B0\\u27BF\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B50\\u2B55\\u3030\\u303D\\u3297\\u3299\\u{1F004}\\u{1F0CF}\\u{1F170}\\u{1F171}\\u{1F17E}\\u{1F17F}\\u{1F18E}\\u{1F191}-\\u{1F19A}\\u{1F1E6}-\\u{1F1FF}\\u{1F201}\\u{1F202}\\u{1F21A}\\u{1F22F}\\u{1F232}-\\u{1F23A}\\u{1F250}\\u{1F251}\\u{1F300}-\\u{1F321}\\u{1F324}-\\u{1F393}\\u{1F396}\\u{1F397}\\u{1F399}-\\u{1F39B}\\u{1F39E}-\\u{1F3F0}\\u{1F3F3}-\\u{1F3F5}\\u{1F3F7}-\\u{1F4FD}\\u{1F4FF}-\\u{1F53D}\\u{1F549}-\\u{1F54E}\\u{1F550}-\\u{1F567}\\u{1F56F}\\u{1F570}\\u{1F573}-\\u{1F57A}\\u{1F587}\\u{1F58A}-\\u{1F58D}\\u{1F590}\\u{1F595}\\u{1F596}\\u{1F5A4}\\u{1F5A5}\\u{1F5A8}\\u{1F5B1}\\u{1F5B2}\\u{1F5BC}\\u{1F5C2}-\\u{1F5C4}\\u{1F5D1}-\\u{1F5D3}\\u{1F5DC}-\\u{1F5DE}\\u{1F5E1}\\u{1F5E3}\\u{1F5E8}\\u{1F5EF}\\u{1F5F3}\\u{1F5FA}-\\u{1F64F}\\u{1F680}-\\u{1F6C5}\\u{1F6CB}-\\u{1F6D2}\\u{1F6D5}-\\u{1F6D7}\\u{1F6DC}-\\u{1F6E5}\\u{1F6E9}\\u{1F6EB}\\u{1F6EC}\\u{1F6F0}\\u{1F6F3}-\\u{1F6FC}\\u{1F7E0}-\\u{1F7EB}\\u{1F7F0}\\u{1F90C}-\\u{1F93A}\\u{1F93C}-\\u{1F945}\\u{1F947}-\\u{1F9FF}\\u{1FA70}-\\u{1FA7C}\\u{1FA80}-\\u{1FA88}\\u{1FA90}-\\u{1FABD}\\u{1FABF}-\\u{1FAC5}\\u{1FACE}-\\u{1FADB}\\u{1FAE0}-\\u{1FAE8}\\u{1FAF0}-\\u{1FAF8}])`
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}&&\\q{🇮🇴|dog}]',
-		expected: '[]'
-	},
-	{
-		pattern: '[\\p{RGI_Emoji_Flag_Sequence}&&\\q{🇮🇴|dog}]',
-		expected: '🇮🇴'
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}\\q{JavaScript|ECMAScript}]',
-		expected: `(?:JavaScript|ECMAScript|${Basic_Emoji.all})`
-	},
-	{
-		pattern: '[\\p{Basic_Emoji}&&\\q{😷|©️|dog}]',
-		expected: '(?:©️|\\u{1F637})'
-	},
-	{
-		pattern: '\\P{Basic_Emoji}',
-		throws: /Cannot negate Unicode property of strings/
-	},
-	{
-		pattern: '[^\\p{Basic_Emoji}]',
-		throws: /Cannot negate set containing strings/
-	},
-	{
-		pattern: '\\p{RGI_Emoji}',
-		// keycaps like *️⃣ give problems
-		expected: '(?:👨🏻‍❤️‍💋‍👨🏻|👨🏻‍❤️‍💋‍👨🏼|👨🏻‍❤️‍💋‍👨🏽|👨🏻‍❤️‍💋‍👨🏾|👨🏻‍❤️‍💋‍👨🏿|👨🏼‍❤️‍💋‍👨🏻|👨🏼‍❤️‍💋‍👨🏼|👨🏼‍❤️‍💋‍👨🏽|👨🏼‍❤️‍💋‍👨🏾|👨🏼‍❤️‍💋‍👨🏿|👨🏽‍❤️‍💋‍👨🏻|👨🏽‍❤️‍💋‍👨🏼|👨🏽‍❤️‍💋‍👨🏽|👨🏽‍❤️‍💋‍👨🏾|👨🏽‍❤️‍💋‍👨🏿|👨🏾‍❤️‍💋‍👨🏻|👨🏾‍❤️‍💋‍👨🏼|👨🏾‍❤️‍💋‍👨🏽|👨🏾‍❤️‍💋‍👨🏾|👨🏾‍❤️‍💋‍👨🏿|👨🏿‍❤️‍💋‍👨🏻|👨🏿‍❤️‍💋‍👨🏼|👨🏿‍❤️‍💋‍👨🏽|👨🏿‍❤️‍💋‍👨🏾|👨🏿‍❤️‍💋‍👨🏿|👩🏻‍❤️‍💋‍👨🏻|👩🏻‍❤️‍💋‍👨🏼|👩🏻‍❤️‍💋‍👨🏽|👩🏻‍❤️‍💋‍👨🏾|👩🏻‍❤️‍💋‍👨🏿|👩🏻‍❤️‍💋‍👩🏻|👩🏻‍❤️‍💋‍👩🏼|👩🏻‍❤️‍💋‍👩🏽|👩🏻‍❤️‍💋‍👩🏾|👩🏻‍❤️‍💋‍👩🏿|👩🏼‍❤️‍💋‍👨🏻|👩🏼‍❤️‍💋‍👨🏼|👩🏼‍❤️‍💋‍👨🏽|👩🏼‍❤️‍💋‍👨🏾|👩🏼‍❤️‍💋‍👨🏿|👩🏼‍❤️‍💋‍👩🏻|👩🏼‍❤️‍💋‍👩🏼|👩🏼‍❤️‍💋‍👩🏽|👩🏼‍❤️‍💋‍👩🏾|👩🏼‍❤️‍💋‍👩🏿|👩🏽‍❤️‍💋‍👨🏻|👩🏽‍❤️‍💋‍👨🏼|👩🏽‍❤️‍💋‍👨🏽|👩🏽‍❤️‍💋‍👨🏾|👩🏽‍❤️‍💋‍👨🏿|👩🏽‍❤️‍💋‍👩🏻|👩🏽‍❤️‍💋‍👩🏼|👩🏽‍❤️‍💋‍👩🏽|👩🏽‍❤️‍💋‍👩🏾|👩🏽‍❤️‍💋‍👩🏿|👩🏾‍❤️‍💋‍👨🏻|👩🏾‍❤️‍💋‍👨🏼|👩🏾‍❤️‍💋‍👨🏽|👩🏾‍❤️‍💋‍👨🏾|👩🏾‍❤️‍💋‍👨🏿|👩🏾‍❤️‍💋‍👩🏻|👩🏾‍❤️‍💋‍👩🏼|👩🏾‍❤️‍💋‍👩🏽|👩🏾‍❤️‍💋‍👩🏾|👩🏾‍❤️‍💋‍👩🏿|👩🏿‍❤️‍💋‍👨🏻|👩🏿‍❤️‍💋‍👨🏼|👩🏿‍❤️‍💋‍👨🏽|👩🏿‍❤️‍💋‍👨🏾|👩🏿‍❤️‍💋‍👨🏿|👩🏿‍❤️‍💋‍👩🏻|👩🏿‍❤️‍💋‍👩🏼|👩🏿‍❤️‍💋‍👩🏽|👩🏿‍❤️‍💋‍👩🏾|👩🏿‍❤️‍💋‍👩🏿|🧑🏻‍❤️‍💋‍🧑🏼|🧑🏻‍❤️‍💋‍🧑🏽|🧑🏻‍❤️‍💋‍🧑🏾|🧑🏻‍❤️‍💋‍🧑🏿|🧑🏼‍❤️‍💋‍🧑🏻|🧑🏼‍❤️‍💋‍🧑🏽|🧑🏼‍❤️‍💋‍🧑🏾|🧑🏼‍❤️‍💋‍🧑🏿|🧑🏽‍❤️‍💋‍🧑🏻|🧑🏽‍❤️‍💋‍🧑🏼|🧑🏽‍❤️‍💋‍🧑🏾|🧑🏽‍❤️‍💋‍🧑🏿|🧑🏾‍❤️‍💋‍🧑🏻|🧑🏾‍❤️‍💋‍🧑🏼|🧑🏾‍❤️‍💋‍🧑🏽|🧑🏾‍❤️‍💋‍🧑🏿|🧑🏿‍❤️‍💋‍🧑🏻|🧑🏿‍❤️‍💋‍🧑🏼|🧑🏿‍❤️‍💋‍🧑🏽|🧑🏿‍❤️‍💋‍🧑🏾|🏴󠁧󠁢󠁥󠁮󠁧󠁿|🏴󠁧󠁢󠁳󠁣󠁴󠁿|🏴󠁧󠁢󠁷󠁬󠁳󠁿|👨🏻‍❤️‍👨🏻|👨🏻‍❤️‍👨🏼|👨🏻‍❤️‍👨🏽|👨🏻‍❤️‍👨🏾|👨🏻‍❤️‍👨🏿|👨🏻‍🤝‍👨🏼|👨🏻‍🤝‍👨🏽|👨🏻‍🤝‍👨🏾|👨🏻‍🤝‍👨🏿|👨🏼‍❤️‍👨🏻|👨🏼‍❤️‍👨🏼|👨🏼‍❤️‍👨🏽|👨🏼‍❤️‍👨🏾|👨🏼‍❤️‍👨🏿|👨🏼‍🤝‍👨🏻|👨🏼‍🤝‍👨🏽|👨🏼‍🤝‍👨🏾|👨🏼‍🤝‍👨🏿|👨🏽‍❤️‍👨🏻|👨🏽‍❤️‍👨🏼|👨🏽‍❤️‍👨🏽|👨🏽‍❤️‍👨🏾|👨🏽‍❤️‍👨🏿|👨🏽‍🤝‍👨🏻|👨🏽‍🤝‍👨🏼|👨🏽‍🤝‍👨🏾|👨🏽‍🤝‍👨🏿|👨🏾‍❤️‍👨🏻|👨🏾‍❤️‍👨🏼|👨🏾‍❤️‍👨🏽|👨🏾‍❤️‍👨🏾|👨🏾‍❤️‍👨🏿|👨🏾‍🤝‍👨🏻|👨🏾‍🤝‍👨🏼|👨🏾‍🤝‍👨🏽|👨🏾‍🤝‍👨🏿|👨🏿‍❤️‍👨🏻|👨🏿‍❤️‍👨🏼|👨🏿‍❤️‍👨🏽|👨🏿‍❤️‍👨🏾|👨🏿‍❤️‍👨🏿|👨🏿‍🤝‍👨🏻|👨🏿‍🤝‍👨🏼|👨🏿‍🤝‍👨🏽|👨🏿‍🤝‍👨🏾|👩🏻‍❤️‍👨🏻|👩🏻‍❤️‍👨🏼|👩🏻‍❤️‍👨🏽|👩🏻‍❤️‍👨🏾|👩🏻‍❤️‍👨🏿|👩🏻‍❤️‍👩🏻|👩🏻‍❤️‍👩🏼|👩🏻‍❤️‍👩🏽|👩🏻‍❤️‍👩🏾|👩🏻‍❤️‍👩🏿|👩🏻‍🤝‍👨🏼|👩🏻‍🤝‍👨🏽|👩🏻‍🤝‍👨🏾|👩🏻‍🤝‍👨🏿|👩🏻‍🤝‍👩🏼|👩🏻‍🤝‍👩🏽|👩🏻‍🤝‍👩🏾|👩🏻‍🤝‍👩🏿|👩🏼‍❤️‍👨🏻|👩🏼‍❤️‍👨🏼|👩🏼‍❤️‍👨🏽|👩🏼‍❤️‍👨🏾|👩🏼‍❤️‍👨🏿|👩🏼‍❤️‍👩🏻|👩🏼‍❤️‍👩🏼|👩🏼‍❤️‍👩🏽|👩🏼‍❤️‍👩🏾|👩🏼‍❤️‍👩🏿|👩🏼‍🤝‍👨🏻|👩🏼‍🤝‍👨🏽|👩🏼‍🤝‍👨🏾|👩🏼‍🤝‍👨🏿|👩🏼‍🤝‍👩🏻|👩🏼‍🤝‍👩🏽|👩🏼‍🤝‍👩🏾|👩🏼‍🤝‍👩🏿|👩🏽‍❤️‍👨🏻|👩🏽‍❤️‍👨🏼|👩🏽‍❤️‍👨🏽|👩🏽‍❤️‍👨🏾|👩🏽‍❤️‍👨🏿|👩🏽‍❤️‍👩🏻|👩🏽‍❤️‍👩🏼|👩🏽‍❤️‍👩🏽|👩🏽‍❤️‍👩🏾|👩🏽‍❤️‍👩🏿|👩🏽‍🤝‍👨🏻|👩🏽‍🤝‍👨🏼|👩🏽‍🤝‍👨🏾|👩🏽‍🤝‍👨🏿|👩🏽‍🤝‍👩🏻|👩🏽‍🤝‍👩🏼|👩🏽‍🤝‍👩🏾|👩🏽‍🤝‍👩🏿|👩🏾‍❤️‍👨🏻|👩🏾‍❤️‍👨🏼|👩🏾‍❤️‍👨🏽|👩🏾‍❤️‍👨🏾|👩🏾‍❤️‍👨🏿|👩🏾‍❤️‍👩🏻|👩🏾‍❤️‍👩🏼|👩🏾‍❤️‍👩🏽|👩🏾‍❤️‍👩🏾|👩🏾‍❤️‍👩🏿|👩🏾‍🤝‍👨🏻|👩🏾‍🤝‍👨🏼|👩🏾‍🤝‍👨🏽|👩🏾‍🤝‍👨🏿|👩🏾‍🤝‍👩🏻|👩🏾‍🤝‍👩🏼|👩🏾‍🤝‍👩🏽|👩🏾‍🤝‍👩🏿|👩🏿‍❤️‍👨🏻|👩🏿‍❤️‍👨🏼|👩🏿‍❤️‍👨🏽|👩🏿‍❤️‍👨🏾|👩🏿‍❤️‍👨🏿|👩🏿‍❤️‍👩🏻|👩🏿‍❤️‍👩🏼|👩🏿‍❤️‍👩🏽|👩🏿‍❤️‍👩🏾|👩🏿‍❤️‍👩🏿|👩🏿‍🤝‍👨🏻|👩🏿‍🤝‍👨🏼|👩🏿‍🤝‍👨🏽|👩🏿‍🤝‍👨🏾|👩🏿‍🤝‍👩🏻|👩🏿‍🤝‍👩🏼|👩🏿‍🤝‍👩🏽|👩🏿‍🤝‍👩🏾|🧑🏻‍❤️‍🧑🏼|🧑🏻‍❤️‍🧑🏽|🧑🏻‍❤️‍🧑🏾|🧑🏻‍❤️‍🧑🏿|🧑🏻‍🤝‍🧑🏻|🧑🏻‍🤝‍🧑🏼|🧑🏻‍🤝‍🧑🏽|🧑🏻‍🤝‍🧑🏾|🧑🏻‍🤝‍🧑🏿|🧑🏼‍❤️‍🧑🏻|🧑🏼‍❤️‍🧑🏽|🧑🏼‍❤️‍🧑🏾|🧑🏼‍❤️‍🧑🏿|🧑🏼‍🤝‍🧑🏻|🧑🏼‍🤝‍🧑🏼|🧑🏼‍🤝‍🧑🏽|🧑🏼‍🤝‍🧑🏾|🧑🏼‍🤝‍🧑🏿|🧑🏽‍❤️‍🧑🏻|🧑🏽‍❤️‍🧑🏼|🧑🏽‍❤️‍🧑🏾|🧑🏽‍❤️‍🧑🏿|🧑🏽‍🤝‍🧑🏻|🧑🏽‍🤝‍🧑🏼|🧑🏽‍🤝‍🧑🏽|🧑🏽‍🤝‍🧑🏾|🧑🏽‍🤝‍🧑🏿|🧑🏾‍❤️‍🧑🏻|🧑🏾‍❤️‍🧑🏼|🧑🏾‍❤️‍🧑🏽|🧑🏾‍❤️‍🧑🏿|🧑🏾‍🤝‍🧑🏻|🧑🏾‍🤝‍🧑🏼|🧑🏾‍🤝‍🧑🏽|🧑🏾‍🤝‍🧑🏾|🧑🏾‍🤝‍🧑🏿|🧑🏿‍❤️‍🧑🏻|🧑🏿‍❤️‍🧑🏼|🧑🏿‍❤️‍🧑🏽|🧑🏿‍❤️‍🧑🏾|🧑🏿‍🤝‍🧑🏻|🧑🏿‍🤝‍🧑🏼|🧑🏿‍🤝‍🧑🏽|🧑🏿‍🤝‍🧑🏾|🧑🏿‍🤝‍🧑🏿|👨‍❤️‍💋‍👨|👨‍👨‍👦‍👦|👨‍👨‍👧‍👦|👨‍👨‍👧‍👧|👨‍👩‍👦‍👦|👨‍👩‍👧‍👦|👨‍👩‍👧‍👧|👩‍❤️‍💋‍👨|👩‍❤️‍💋‍👩|👩‍👩‍👦‍👦|👩‍👩‍👧‍👦|👩‍👩‍👧‍👧|🫱🏻‍🫲🏼|🫱🏻‍🫲🏽|🫱🏻‍🫲🏾|🫱🏻‍🫲🏿|🫱🏼‍🫲🏻|🫱🏼‍🫲🏽|🫱🏼‍🫲🏾|🫱🏼‍🫲🏿|🫱🏽‍🫲🏻|🫱🏽‍🫲🏼|🫱🏽‍🫲🏾|🫱🏽‍🫲🏿|🫱🏾‍🫲🏻|🫱🏾‍🫲🏼|🫱🏾‍🫲🏽|🫱🏾‍🫲🏿|🫱🏿‍🫲🏻|🫱🏿‍🫲🏼|🫱🏿‍🫲🏽|🫱🏿‍🫲🏾|👨‍❤️‍👨|👨‍👦‍👦|👨‍👧‍👦|👨‍👧‍👧|👨‍👨‍👦|👨‍👨‍👧|👨‍👩‍👦|👨‍👩‍👧|👩‍❤️‍👨|👩‍❤️‍👩|👩‍👦‍👦|👩‍👧‍👦|👩‍👧‍👧|👩‍👩‍👦|👩‍👩‍👧|🧑‍🤝‍🧑|🏃🏻‍♀️|🏃🏻‍♂️|🏃🏼‍♀️|🏃🏼‍♂️|🏃🏽‍♀️|🏃🏽‍♂️|🏃🏾‍♀️|🏃🏾‍♂️|🏃🏿‍♀️|🏃🏿‍♂️|🏄🏻‍♀️|🏄🏻‍♂️|🏄🏼‍♀️|🏄🏼‍♂️|🏄🏽‍♀️|🏄🏽‍♂️|🏄🏾‍♀️|🏄🏾‍♂️|🏄🏿‍♀️|🏄🏿‍♂️|🏊🏻‍♀️|🏊🏻‍♂️|🏊🏼‍♀️|🏊🏼‍♂️|🏊🏽‍♀️|🏊🏽‍♂️|🏊🏾‍♀️|🏊🏾‍♂️|🏊🏿‍♀️|🏊🏿‍♂️|🏋🏻‍♀️|🏋🏻‍♂️|🏋🏼‍♀️|🏋🏼‍♂️|🏋🏽‍♀️|🏋🏽‍♂️|🏋🏾‍♀️|🏋🏾‍♂️|🏋🏿‍♀️|🏋🏿‍♂️|🏌🏻‍♀️|🏌🏻‍♂️|🏌🏼‍♀️|🏌🏼‍♂️|🏌🏽‍♀️|🏌🏽‍♂️|🏌🏾‍♀️|🏌🏾‍♂️|🏌🏿‍♀️|🏌🏿‍♂️|👁️‍🗨️|👨🏻‍⚕️|👨🏻‍⚖️|👨🏻‍✈️|👨🏻‍🌾|👨🏻‍🍳|👨🏻‍🍼|👨🏻‍🎓|👨🏻‍🎤|👨🏻‍🎨|👨🏻‍🏫|👨🏻‍🏭|👨🏻‍💻|👨🏻‍💼|👨🏻‍🔧|👨🏻‍🔬|👨🏻‍🚀|👨🏻‍🚒|👨🏻‍🦯|👨🏻‍🦰|👨🏻‍🦱|👨🏻‍🦲|👨🏻‍🦳|👨🏻‍🦼|👨🏻‍🦽|👨🏼‍⚕️|👨🏼‍⚖️|👨🏼‍✈️|👨🏼‍🌾|👨🏼‍🍳|👨🏼‍🍼|👨🏼‍🎓|👨🏼‍🎤|👨🏼‍🎨|👨🏼‍🏫|👨🏼‍🏭|👨🏼‍💻|👨🏼‍💼|👨🏼‍🔧|👨🏼‍🔬|👨🏼‍🚀|👨🏼‍🚒|👨🏼‍🦯|👨🏼‍🦰|👨🏼‍🦱|👨🏼‍🦲|👨🏼‍🦳|👨🏼‍🦼|👨🏼‍🦽|👨🏽‍⚕️|👨🏽‍⚖️|👨🏽‍✈️|👨🏽‍🌾|👨🏽‍🍳|👨🏽‍🍼|👨🏽‍🎓|👨🏽‍🎤|👨🏽‍🎨|👨🏽‍🏫|👨🏽‍🏭|👨🏽‍💻|👨🏽‍💼|👨🏽‍🔧|👨🏽‍🔬|👨🏽‍🚀|👨🏽‍🚒|👨🏽‍🦯|👨🏽‍🦰|👨🏽‍🦱|👨🏽‍🦲|👨🏽‍🦳|👨🏽‍🦼|👨🏽‍🦽|👨🏾‍⚕️|👨🏾‍⚖️|👨🏾‍✈️|👨🏾‍🌾|👨🏾‍🍳|👨🏾‍🍼|👨🏾‍🎓|👨🏾‍🎤|👨🏾‍🎨|👨🏾‍🏫|👨🏾‍🏭|👨🏾‍💻|👨🏾‍💼|👨🏾‍🔧|👨🏾‍🔬|👨🏾‍🚀|👨🏾‍🚒|👨🏾‍🦯|👨🏾‍🦰|👨🏾‍🦱|👨🏾‍🦲|👨🏾‍🦳|👨🏾‍🦼|👨🏾‍🦽|👨🏿‍⚕️|👨🏿‍⚖️|👨🏿‍✈️|👨🏿‍🌾|👨🏿‍🍳|👨🏿‍🍼|👨🏿‍🎓|👨🏿‍🎤|👨🏿‍🎨|👨🏿‍🏫|👨🏿‍🏭|👨🏿‍💻|👨🏿‍💼|👨🏿‍🔧|👨🏿‍🔬|👨🏿‍🚀|👨🏿‍🚒|👨🏿‍🦯|👨🏿‍🦰|👨🏿‍🦱|👨🏿‍🦲|👨🏿‍🦳|👨🏿‍🦼|👨🏿‍🦽|👩🏻‍⚕️|👩🏻‍⚖️|👩🏻‍✈️|👩🏻‍🌾|👩🏻‍🍳|👩🏻‍🍼|👩🏻‍🎓|👩🏻‍🎤|👩🏻‍🎨|👩🏻‍🏫|👩🏻‍🏭|👩🏻‍💻|👩🏻‍💼|👩🏻‍🔧|👩🏻‍🔬|👩🏻‍🚀|👩🏻‍🚒|👩🏻‍🦯|👩🏻‍🦰|👩🏻‍🦱|👩🏻‍🦲|👩🏻‍🦳|👩🏻‍🦼|👩🏻‍🦽|👩🏼‍⚕️|👩🏼‍⚖️|👩🏼‍✈️|👩🏼‍🌾|👩🏼‍🍳|👩🏼‍🍼|👩🏼‍🎓|👩🏼‍🎤|👩🏼‍🎨|👩🏼‍🏫|👩🏼‍🏭|👩🏼‍💻|👩🏼‍💼|👩🏼‍🔧|👩🏼‍🔬|👩🏼‍🚀|👩🏼‍🚒|👩🏼‍🦯|👩🏼‍🦰|👩🏼‍🦱|👩🏼‍🦲|👩🏼‍🦳|👩🏼‍🦼|👩🏼‍🦽|👩🏽‍⚕️|👩🏽‍⚖️|👩🏽‍✈️|👩🏽‍🌾|👩🏽‍🍳|👩🏽‍🍼|👩🏽‍🎓|👩🏽‍🎤|👩🏽‍🎨|👩🏽‍🏫|👩🏽‍🏭|👩🏽‍💻|👩🏽‍💼|👩🏽‍🔧|👩🏽‍🔬|👩🏽‍🚀|👩🏽‍🚒|👩🏽‍🦯|👩🏽‍🦰|👩🏽‍🦱|👩🏽‍🦲|👩🏽‍🦳|👩🏽‍🦼|👩🏽‍🦽|👩🏾‍⚕️|👩🏾‍⚖️|👩🏾‍✈️|👩🏾‍🌾|👩🏾‍🍳|👩🏾‍🍼|👩🏾‍🎓|👩🏾‍🎤|👩🏾‍🎨|👩🏾‍🏫|👩🏾‍🏭|👩🏾‍💻|👩🏾‍💼|👩🏾‍🔧|👩🏾‍🔬|👩🏾‍🚀|👩🏾‍🚒|👩🏾‍🦯|👩🏾‍🦰|👩🏾‍🦱|👩🏾‍🦲|👩🏾‍🦳|👩🏾‍🦼|👩🏾‍🦽|👩🏿‍⚕️|👩🏿‍⚖️|👩🏿‍✈️|👩🏿‍🌾|👩🏿‍🍳|👩🏿‍🍼|👩🏿‍🎓|👩🏿‍🎤|👩🏿‍🎨|👩🏿‍🏫|👩🏿‍🏭|👩🏿‍💻|👩🏿‍💼|👩🏿‍🔧|👩🏿‍🔬|👩🏿‍🚀|👩🏿‍🚒|👩🏿‍🦯|👩🏿‍🦰|👩🏿‍🦱|👩🏿‍🦲|👩🏿‍🦳|👩🏿‍🦼|👩🏿‍🦽|👮🏻‍♀️|👮🏻‍♂️|👮🏼‍♀️|👮🏼‍♂️|👮🏽‍♀️|👮🏽‍♂️|👮🏾‍♀️|👮🏾‍♂️|👮🏿‍♀️|👮🏿‍♂️|👰🏻‍♀️|👰🏻‍♂️|👰🏼‍♀️|👰🏼‍♂️|👰🏽‍♀️|👰🏽‍♂️|👰🏾‍♀️|👰🏾‍♂️|👰🏿‍♀️|👰🏿‍♂️|👱🏻‍♀️|👱🏻‍♂️|👱🏼‍♀️|👱🏼‍♂️|👱🏽‍♀️|👱🏽‍♂️|👱🏾‍♀️|👱🏾‍♂️|👱🏿‍♀️|👱🏿‍♂️|👳🏻‍♀️|👳🏻‍♂️|👳🏼‍♀️|👳🏼‍♂️|👳🏽‍♀️|👳🏽‍♂️|👳🏾‍♀️|👳🏾‍♂️|👳🏿‍♀️|👳🏿‍♂️|👷🏻‍♀️|👷🏻‍♂️|👷🏼‍♀️|👷🏼‍♂️|👷🏽‍♀️|👷🏽‍♂️|👷🏾‍♀️|👷🏾‍♂️|👷🏿‍♀️|👷🏿‍♂️|💁🏻‍♀️|💁🏻‍♂️|💁🏼‍♀️|💁🏼‍♂️|💁🏽‍♀️|💁🏽‍♂️|💁🏾‍♀️|💁🏾‍♂️|💁🏿‍♀️|💁🏿‍♂️|💂🏻‍♀️|💂🏻‍♂️|💂🏼‍♀️|💂🏼‍♂️|💂🏽‍♀️|💂🏽‍♂️|💂🏾‍♀️|💂🏾‍♂️|💂🏿‍♀️|💂🏿‍♂️|💆🏻‍♀️|💆🏻‍♂️|💆🏼‍♀️|💆🏼‍♂️|💆🏽‍♀️|💆🏽‍♂️|💆🏾‍♀️|💆🏾‍♂️|💆🏿‍♀️|💆🏿‍♂️|💇🏻‍♀️|💇🏻‍♂️|💇🏼‍♀️|💇🏼‍♂️|💇🏽‍♀️|💇🏽‍♂️|💇🏾‍♀️|💇🏾‍♂️|💇🏿‍♀️|💇🏿‍♂️|🕵🏻‍♀️|🕵🏻‍♂️|🕵🏼‍♀️|🕵🏼‍♂️|🕵🏽‍♀️|🕵🏽‍♂️|🕵🏾‍♀️|🕵🏾‍♂️|🕵🏿‍♀️|🕵🏿‍♂️|🙅🏻‍♀️|🙅🏻‍♂️|🙅🏼‍♀️|🙅🏼‍♂️|🙅🏽‍♀️|🙅🏽‍♂️|🙅🏾‍♀️|🙅🏾‍♂️|🙅🏿‍♀️|🙅🏿‍♂️|🙆🏻‍♀️|🙆🏻‍♂️|🙆🏼‍♀️|🙆🏼‍♂️|🙆🏽‍♀️|🙆🏽‍♂️|🙆🏾‍♀️|🙆🏾‍♂️|🙆🏿‍♀️|🙆🏿‍♂️|🙇🏻‍♀️|🙇🏻‍♂️|🙇🏼‍♀️|🙇🏼‍♂️|🙇🏽‍♀️|🙇🏽‍♂️|🙇🏾‍♀️|🙇🏾‍♂️|🙇🏿‍♀️|🙇🏿‍♂️|🙋🏻‍♀️|🙋🏻‍♂️|🙋🏼‍♀️|🙋🏼‍♂️|🙋🏽‍♀️|🙋🏽‍♂️|🙋🏾‍♀️|🙋🏾‍♂️|🙋🏿‍♀️|🙋🏿‍♂️|🙍🏻‍♀️|🙍🏻‍♂️|🙍🏼‍♀️|🙍🏼‍♂️|🙍🏽‍♀️|🙍🏽‍♂️|🙍🏾‍♀️|🙍🏾‍♂️|🙍🏿‍♀️|🙍🏿‍♂️|🙎🏻‍♀️|🙎🏻‍♂️|🙎🏼‍♀️|🙎🏼‍♂️|🙎🏽‍♀️|🙎🏽‍♂️|🙎🏾‍♀️|🙎🏾‍♂️|🙎🏿‍♀️|🙎🏿‍♂️|🚣🏻‍♀️|🚣🏻‍♂️|🚣🏼‍♀️|🚣🏼‍♂️|🚣🏽‍♀️|🚣🏽‍♂️|🚣🏾‍♀️|🚣🏾‍♂️|🚣🏿‍♀️|🚣🏿‍♂️|🚴🏻‍♀️|🚴🏻‍♂️|🚴🏼‍♀️|🚴🏼‍♂️|🚴🏽‍♀️|🚴🏽‍♂️|🚴🏾‍♀️|🚴🏾‍♂️|🚴🏿‍♀️|🚴🏿‍♂️|🚵🏻‍♀️|🚵🏻‍♂️|🚵🏼‍♀️|🚵🏼‍♂️|🚵🏽‍♀️|🚵🏽‍♂️|🚵🏾‍♀️|🚵🏾‍♂️|🚵🏿‍♀️|🚵🏿‍♂️|🚶🏻‍♀️|🚶🏻‍♂️|🚶🏼‍♀️|🚶🏼‍♂️|🚶🏽‍♀️|🚶🏽‍♂️|🚶🏾‍♀️|🚶🏾‍♂️|🚶🏿‍♀️|🚶🏿‍♂️|🤦🏻‍♀️|🤦🏻‍♂️|🤦🏼‍♀️|🤦🏼‍♂️|🤦🏽‍♀️|🤦🏽‍♂️|🤦🏾‍♀️|🤦🏾‍♂️|🤦🏿‍♀️|🤦🏿‍♂️|🤵🏻‍♀️|🤵🏻‍♂️|🤵🏼‍♀️|🤵🏼‍♂️|🤵🏽‍♀️|🤵🏽‍♂️|🤵🏾‍♀️|🤵🏾‍♂️|🤵🏿‍♀️|🤵🏿‍♂️|🤷🏻‍♀️|🤷🏻‍♂️|🤷🏼‍♀️|🤷🏼‍♂️|🤷🏽‍♀️|🤷🏽‍♂️|🤷🏾‍♀️|🤷🏾‍♂️|🤷🏿‍♀️|🤷🏿‍♂️|🤸🏻‍♀️|🤸🏻‍♂️|🤸🏼‍♀️|🤸🏼‍♂️|🤸🏽‍♀️|🤸🏽‍♂️|🤸🏾‍♀️|🤸🏾‍♂️|🤸🏿‍♀️|🤸🏿‍♂️|🤹🏻‍♀️|🤹🏻‍♂️|🤹🏼‍♀️|🤹🏼‍♂️|🤹🏽‍♀️|🤹🏽‍♂️|🤹🏾‍♀️|🤹🏾‍♂️|🤹🏿‍♀️|🤹🏿‍♂️|🤽🏻‍♀️|🤽🏻‍♂️|🤽🏼‍♀️|🤽🏼‍♂️|🤽🏽‍♀️|🤽🏽‍♂️|🤽🏾‍♀️|🤽🏾‍♂️|🤽🏿‍♀️|🤽🏿‍♂️|🤾🏻‍♀️|🤾🏻‍♂️|🤾🏼‍♀️|🤾🏼‍♂️|🤾🏽‍♀️|🤾🏽‍♂️|🤾🏾‍♀️|🤾🏾‍♂️|🤾🏿‍♀️|🤾🏿‍♂️|🦸🏻‍♀️|🦸🏻‍♂️|🦸🏼‍♀️|🦸🏼‍♂️|🦸🏽‍♀️|🦸🏽‍♂️|🦸🏾‍♀️|🦸🏾‍♂️|🦸🏿‍♀️|🦸🏿‍♂️|🦹🏻‍♀️|🦹🏻‍♂️|🦹🏼‍♀️|🦹🏼‍♂️|🦹🏽‍♀️|🦹🏽‍♂️|🦹🏾‍♀️|🦹🏾‍♂️|🦹🏿‍♀️|🦹🏿‍♂️|🧍🏻‍♀️|🧍🏻‍♂️|🧍🏼‍♀️|🧍🏼‍♂️|🧍🏽‍♀️|🧍🏽‍♂️|🧍🏾‍♀️|🧍🏾‍♂️|🧍🏿‍♀️|🧍🏿‍♂️|🧎🏻‍♀️|🧎🏻‍♂️|🧎🏼‍♀️|🧎🏼‍♂️|🧎🏽‍♀️|🧎🏽‍♂️|🧎🏾‍♀️|🧎🏾‍♂️|🧎🏿‍♀️|🧎🏿‍♂️|🧏🏻‍♀️|🧏🏻‍♂️|🧏🏼‍♀️|🧏🏼‍♂️|🧏🏽‍♀️|🧏🏽‍♂️|🧏🏾‍♀️|🧏🏾‍♂️|🧏🏿‍♀️|🧏🏿‍♂️|🧑🏻‍⚕️|🧑🏻‍⚖️|🧑🏻‍✈️|🧑🏻‍🌾|🧑🏻‍🍳|🧑🏻‍🍼|🧑🏻‍🎄|🧑🏻‍🎓|🧑🏻‍🎤|🧑🏻‍🎨|🧑🏻‍🏫|🧑🏻‍🏭|🧑🏻‍💻|🧑🏻‍💼|🧑🏻‍🔧|🧑🏻‍🔬|🧑🏻‍🚀|🧑🏻‍🚒|🧑🏻‍🦯|🧑🏻‍🦰|🧑🏻‍🦱|🧑🏻‍🦲|🧑🏻‍🦳|🧑🏻‍🦼|🧑🏻‍🦽|🧑🏼‍⚕️|🧑🏼‍⚖️|🧑🏼‍✈️|🧑🏼‍🌾|🧑🏼‍🍳|🧑🏼‍🍼|🧑🏼‍🎄|🧑🏼‍🎓|🧑🏼‍🎤|🧑🏼‍🎨|🧑🏼‍🏫|🧑🏼‍🏭|🧑🏼‍💻|🧑🏼‍💼|🧑🏼‍🔧|🧑🏼‍🔬|🧑🏼‍🚀|🧑🏼‍🚒|🧑🏼‍🦯|🧑🏼‍🦰|🧑🏼‍🦱|🧑🏼‍🦲|🧑🏼‍🦳|🧑🏼‍🦼|🧑🏼‍🦽|🧑🏽‍⚕️|🧑🏽‍⚖️|🧑🏽‍✈️|🧑🏽‍🌾|🧑🏽‍🍳|🧑🏽‍🍼|🧑🏽‍🎄|🧑🏽‍🎓|🧑🏽‍🎤|🧑🏽‍🎨|🧑🏽‍🏫|🧑🏽‍🏭|🧑🏽‍💻|🧑🏽‍💼|🧑🏽‍🔧|🧑🏽‍🔬|🧑🏽‍🚀|🧑🏽‍🚒|🧑🏽‍🦯|🧑🏽‍🦰|🧑🏽‍🦱|🧑🏽‍🦲|🧑🏽‍🦳|🧑🏽‍🦼|🧑🏽‍🦽|🧑🏾‍⚕️|🧑🏾‍⚖️|🧑🏾‍✈️|🧑🏾‍🌾|🧑🏾‍🍳|🧑🏾‍🍼|🧑🏾‍🎄|🧑🏾‍🎓|🧑🏾‍🎤|🧑🏾‍🎨|🧑🏾‍🏫|🧑🏾‍🏭|🧑🏾‍💻|🧑🏾‍💼|🧑🏾‍🔧|🧑🏾‍🔬|🧑🏾‍🚀|🧑🏾‍🚒|🧑🏾‍🦯|🧑🏾‍🦰|🧑🏾‍🦱|🧑🏾‍🦲|🧑🏾‍🦳|🧑🏾‍🦼|🧑🏾‍🦽|🧑🏿‍⚕️|🧑🏿‍⚖️|🧑🏿‍✈️|🧑🏿‍🌾|🧑🏿‍🍳|🧑🏿‍🍼|🧑🏿‍🎄|🧑🏿‍🎓|🧑🏿‍🎤|🧑🏿‍🎨|🧑🏿‍🏫|🧑🏿‍🏭|🧑🏿‍💻|🧑🏿‍💼|🧑🏿‍🔧|🧑🏿‍🔬|🧑🏿‍🚀|🧑🏿‍🚒|🧑🏿‍🦯|🧑🏿‍🦰|🧑🏿‍🦱|🧑🏿‍🦲|🧑🏿‍🦳|🧑🏿‍🦼|🧑🏿‍🦽|🧔🏻‍♀️|🧔🏻‍♂️|🧔🏼‍♀️|🧔🏼‍♂️|🧔🏽‍♀️|🧔🏽‍♂️|🧔🏾‍♀️|🧔🏾‍♂️|🧔🏿‍♀️|🧔🏿‍♂️|🧖🏻‍♀️|🧖🏻‍♂️|🧖🏼‍♀️|🧖🏼‍♂️|🧖🏽‍♀️|🧖🏽‍♂️|🧖🏾‍♀️|🧖🏾‍♂️|🧖🏿‍♀️|🧖🏿‍♂️|🧗🏻‍♀️|🧗🏻‍♂️|🧗🏼‍♀️|🧗🏼‍♂️|🧗🏽‍♀️|🧗🏽‍♂️|🧗🏾‍♀️|🧗🏾‍♂️|🧗🏿‍♀️|🧗🏿‍♂️|🧘🏻‍♀️|🧘🏻‍♂️|🧘🏼‍♀️|🧘🏼‍♂️|🧘🏽‍♀️|🧘🏽‍♂️|🧘🏾‍♀️|🧘🏾‍♂️|🧘🏿‍♀️|🧘🏿‍♂️|🧙🏻‍♀️|🧙🏻‍♂️|🧙🏼‍♀️|🧙🏼‍♂️|🧙🏽‍♀️|🧙🏽‍♂️|🧙🏾‍♀️|🧙🏾‍♂️|🧙🏿‍♀️|🧙🏿‍♂️|🧚🏻‍♀️|🧚🏻‍♂️|🧚🏼‍♀️|🧚🏼‍♂️|🧚🏽‍♀️|🧚🏽‍♂️|🧚🏾‍♀️|🧚🏾‍♂️|🧚🏿‍♀️|🧚🏿‍♂️|🧛🏻‍♀️|🧛🏻‍♂️|🧛🏼‍♀️|🧛🏼‍♂️|🧛🏽‍♀️|🧛🏽‍♂️|🧛🏾‍♀️|🧛🏾‍♂️|🧛🏿‍♀️|🧛🏿‍♂️|🧜🏻‍♀️|🧜🏻‍♂️|🧜🏼‍♀️|🧜🏼‍♂️|🧜🏽‍♀️|🧜🏽‍♂️|🧜🏾‍♀️|🧜🏾‍♂️|🧜🏿‍♀️|🧜🏿‍♂️|🧝🏻‍♀️|🧝🏻‍♂️|🧝🏼‍♀️|🧝🏼‍♂️|🧝🏽‍♀️|🧝🏽‍♂️|🧝🏾‍♀️|🧝🏾‍♂️|🧝🏿‍♀️|🧝🏿‍♂️|⛹🏻‍♀️|⛹🏻‍♂️|⛹🏼‍♀️|⛹🏼‍♂️|⛹🏽‍♀️|⛹🏽‍♂️|⛹🏾‍♀️|⛹🏾‍♂️|⛹🏿‍♀️|⛹🏿‍♂️|🏋️‍♀️|🏋️‍♂️|🏌️‍♀️|🏌️‍♂️|🏳️‍⚧️|🏳️‍🌈|🕵️‍♀️|🕵️‍♂️|😶‍🌫️|⛹️‍♀️|⛹️‍♂️|❤️‍🔥|❤️‍🩹|🏃‍♀️|🏃‍♂️|🏄‍♀️|🏄‍♂️|🏊‍♀️|🏊‍♂️|🏴‍☠️|🐕‍🦺|🐻‍❄️|👨‍⚕️|👨‍⚖️|👨‍✈️|👨‍🌾|👨‍🍳|👨‍🍼|👨‍🎓|👨‍🎤|👨‍🎨|👨‍🏫|👨‍🏭|👨‍👦|👨‍👧|👨‍💻|👨‍💼|👨‍🔧|👨‍🔬|👨‍🚀|👨‍🚒|👨‍🦯|👨‍🦰|👨‍🦱|👨‍🦲|👨‍🦳|👨‍🦼|👨‍🦽|👩‍⚕️|👩‍⚖️|👩‍✈️|👩‍🌾|👩‍🍳|👩‍🍼|👩‍🎓|👩‍🎤|👩‍🎨|👩‍🏫|👩‍🏭|👩‍👦|👩‍👧|👩‍💻|👩‍💼|👩‍🔧|👩‍🔬|👩‍🚀|👩‍🚒|👩‍🦯|👩‍🦰|👩‍🦱|👩‍🦲|👩‍🦳|👩‍🦼|👩‍🦽|👮‍♀️|👮‍♂️|👯‍♀️|👯‍♂️|👰‍♀️|👰‍♂️|👱‍♀️|👱‍♂️|👳‍♀️|👳‍♂️|👷‍♀️|👷‍♂️|💁‍♀️|💁‍♂️|💂‍♀️|💂‍♂️|💆‍♀️|💆‍♂️|💇‍♀️|💇‍♂️|😮‍💨|😵‍💫|🙅‍♀️|🙅‍♂️|🙆‍♀️|🙆‍♂️|🙇‍♀️|🙇‍♂️|🙋‍♀️|🙋‍♂️|🙍‍♀️|🙍‍♂️|🙎‍♀️|🙎‍♂️|🚣‍♀️|🚣‍♂️|🚴‍♀️|🚴‍♂️|🚵‍♀️|🚵‍♂️|🚶‍♀️|🚶‍♂️|🤦‍♀️|🤦‍♂️|🤵‍♀️|🤵‍♂️|🤷‍♀️|🤷‍♂️|🤸‍♀️|🤸‍♂️|🤹‍♀️|🤹‍♂️|🤼‍♀️|🤼‍♂️|🤽‍♀️|🤽‍♂️|🤾‍♀️|🤾‍♂️|🦸‍♀️|🦸‍♂️|🦹‍♀️|🦹‍♂️|🧍‍♀️|🧍‍♂️|🧎‍♀️|🧎‍♂️|🧏‍♀️|🧏‍♂️|🧑‍⚕️|🧑‍⚖️|🧑‍✈️|🧑‍🌾|🧑‍🍳|🧑‍🍼|🧑‍🎄|🧑‍🎓|🧑‍🎤|🧑‍🎨|🧑‍🏫|🧑‍🏭|🧑‍💻|🧑‍💼|🧑‍🔧|🧑‍🔬|🧑‍🚀|🧑‍🚒|🧑‍🦯|🧑‍🦰|🧑‍🦱|🧑‍🦲|🧑‍🦳|🧑‍🦼|🧑‍🦽|🧔‍♀️|🧔‍♂️|🧖‍♀️|🧖‍♂️|🧗‍♀️|🧗‍♂️|🧘‍♀️|🧘‍♂️|🧙‍♀️|🧙‍♂️|🧚‍♀️|🧚‍♂️|🧛‍♀️|🧛‍♂️|🧜‍♀️|🧜‍♂️|🧝‍♀️|🧝‍♂️|🧞‍♀️|🧞‍♂️|🧟‍♀️|🧟‍♂️|\\*️⃣|🇦🇨|🇦🇩|🇦🇪|🇦🇫|🇦🇬|🇦🇮|🇦🇱|🇦🇲|🇦🇴|🇦🇶|🇦🇷|🇦🇸|🇦🇹|🇦🇺|🇦🇼|🇦🇽|🇦🇿|🇧🇦|🇧🇧|🇧🇩|🇧🇪|🇧🇫|🇧🇬|🇧🇭|🇧🇮|🇧🇯|🇧🇱|🇧🇲|🇧🇳|🇧🇴|🇧🇶|🇧🇷|🇧🇸|🇧🇹|🇧🇻|🇧🇼|🇧🇾|🇧🇿|🇨🇦|🇨🇨|🇨🇩|🇨🇫|🇨🇬|🇨🇭|🇨🇮|🇨🇰|🇨🇱|🇨🇲|🇨🇳|🇨🇴|🇨🇵|🇨🇷|🇨🇺|🇨🇻|🇨🇼|🇨🇽|🇨🇾|🇨🇿|🇩🇪|🇩🇬|🇩🇯|🇩🇰|🇩🇲|🇩🇴|🇩🇿|🇪🇦|🇪🇨|🇪🇪|🇪🇬|🇪🇭|🇪🇷|🇪🇸|🇪🇹|🇪🇺|🇫🇮|🇫🇯|🇫🇰|🇫🇲|🇫🇴|🇫🇷|🇬🇦|🇬🇧|🇬🇩|🇬🇪|🇬🇫|🇬🇬|🇬🇭|🇬🇮|🇬🇱|🇬🇲|🇬🇳|🇬🇵|🇬🇶|🇬🇷|🇬🇸|🇬🇹|🇬🇺|🇬🇼|🇬🇾|🇭🇰|🇭🇲|🇭🇳|🇭🇷|🇭🇹|🇭🇺|🇮🇨|🇮🇩|🇮🇪|🇮🇱|🇮🇲|🇮🇳|🇮🇴|🇮🇶|🇮🇷|🇮🇸|🇮🇹|🇯🇪|🇯🇲|🇯🇴|🇯🇵|🇰🇪|🇰🇬|🇰🇭|🇰🇮|🇰🇲|🇰🇳|🇰🇵|🇰🇷|🇰🇼|🇰🇾|🇰🇿|🇱🇦|🇱🇧|🇱🇨|🇱🇮|🇱🇰|🇱🇷|🇱🇸|🇱🇹|🇱🇺|🇱🇻|🇱🇾|🇲🇦|🇲🇨|🇲🇩|🇲🇪|🇲🇫|🇲🇬|🇲🇭|🇲🇰|🇲🇱|🇲🇲|🇲🇳|🇲🇴|🇲🇵|🇲🇶|🇲🇷|🇲🇸|🇲🇹|🇲🇺|🇲🇻|🇲🇼|🇲🇽|🇲🇾|🇲🇿|🇳🇦|🇳🇨|🇳🇪|🇳🇫|🇳🇬|🇳🇮|🇳🇱|🇳🇴|🇳🇵|🇳🇷|🇳🇺|🇳🇿|🇴🇲|🇵🇦|🇵🇪|🇵🇫|🇵🇬|🇵🇭|🇵🇰|🇵🇱|🇵🇲|🇵🇳|🇵🇷|🇵🇸|🇵🇹|🇵🇼|🇵🇾|🇶🇦|🇷🇪|🇷🇴|🇷🇸|🇷🇺|🇷🇼|🇸🇦|🇸🇧|🇸🇨|🇸🇩|🇸🇪|🇸🇬|🇸🇭|🇸🇮|🇸🇯|🇸🇰|🇸🇱|🇸🇲|🇸🇳|🇸🇴|🇸🇷|🇸🇸|🇸🇹|🇸🇻|🇸🇽|🇸🇾|🇸🇿|🇹🇦|🇹🇨|🇹🇩|🇹🇫|🇹🇬|🇹🇭|🇹🇯|🇹🇰|🇹🇱|🇹🇲|🇹🇳|🇹🇴|🇹🇷|🇹🇹|🇹🇻|🇹🇼|🇹🇿|🇺🇦|🇺🇬|🇺🇲|🇺🇳|🇺🇸|🇺🇾|🇺🇿|🇻🇦|🇻🇨|🇻🇪|🇻🇬|🇻🇮|🇻🇳|🇻🇺|🇼🇫|🇼🇸|🇽🇰|🇾🇪|🇾🇹|🇿🇦|🇿🇲|🇿🇼|🎅🏻|🎅🏼|🎅🏽|🎅🏾|🎅🏿|🏂🏻|🏂🏼|🏂🏽|🏂🏾|🏂🏿|🏃🏻|🏃🏼|🏃🏽|🏃🏾|🏃🏿|🏄🏻|🏄🏼|🏄🏽|🏄🏾|🏄🏿|🏇🏻|🏇🏼|🏇🏽|🏇🏾|🏇🏿|🏊🏻|🏊🏼|🏊🏽|🏊🏾|🏊🏿|🏋🏻|🏋🏼|🏋🏽|🏋🏾|🏋🏿|🏌🏻|🏌🏼|🏌🏽|🏌🏾|🏌🏿|🐈‍⬛|🐦‍⬛|👂🏻|👂🏼|👂🏽|👂🏾|👂🏿|👃🏻|👃🏼|👃🏽|👃🏾|👃🏿|👆🏻|👆🏼|👆🏽|👆🏾|👆🏿|👇🏻|👇🏼|👇🏽|👇🏾|👇🏿|👈🏻|👈🏼|👈🏽|👈🏾|👈🏿|👉🏻|👉🏼|👉🏽|👉🏾|👉🏿|👊🏻|👊🏼|👊🏽|👊🏾|👊🏿|👋🏻|👋🏼|👋🏽|👋🏾|👋🏿|👌🏻|👌🏼|👌🏽|👌🏾|👌🏿|👍🏻|👍🏼|👍🏽|👍🏾|👍🏿|👎🏻|👎🏼|👎🏽|👎🏾|👎🏿|👏🏻|👏🏼|👏🏽|👏🏾|👏🏿|👐🏻|👐🏼|👐🏽|👐🏾|👐🏿|👦🏻|👦🏼|👦🏽|👦🏾|👦🏿|👧🏻|👧🏼|👧🏽|👧🏾|👧🏿|👨🏻|👨🏼|👨🏽|👨🏾|👨🏿|👩🏻|👩🏼|👩🏽|👩🏾|👩🏿|👫🏻|👫🏼|👫🏽|👫🏾|👫🏿|👬🏻|👬🏼|👬🏽|👬🏾|👬🏿|👭🏻|👭🏼|👭🏽|👭🏾|👭🏿|👮🏻|👮🏼|👮🏽|👮🏾|👮🏿|👰🏻|👰🏼|👰🏽|👰🏾|👰🏿|👱🏻|👱🏼|👱🏽|👱🏾|👱🏿|👲🏻|👲🏼|👲🏽|👲🏾|👲🏿|👳🏻|👳🏼|👳🏽|👳🏾|👳🏿|👴🏻|👴🏼|👴🏽|👴🏾|👴🏿|👵🏻|👵🏼|👵🏽|👵🏾|👵🏿|👶🏻|👶🏼|👶🏽|👶🏾|👶🏿|👷🏻|👷🏼|👷🏽|👷🏾|👷🏿|👸🏻|👸🏼|👸🏽|👸🏾|👸🏿|👼🏻|👼🏼|👼🏽|👼🏾|👼🏿|💁🏻|💁🏼|💁🏽|💁🏾|💁🏿|💂🏻|💂🏼|💂🏽|💂🏾|💂🏿|💃🏻|💃🏼|💃🏽|💃🏾|💃🏿|💅🏻|💅🏼|💅🏽|💅🏾|💅🏿|💆🏻|💆🏼|💆🏽|💆🏾|💆🏿|💇🏻|💇🏼|💇🏽|💇🏾|💇🏿|💏🏻|💏🏼|💏🏽|💏🏾|💏🏿|💑🏻|💑🏼|💑🏽|💑🏾|💑🏿|💪🏻|💪🏼|💪🏽|💪🏾|💪🏿|🕴🏻|🕴🏼|🕴🏽|🕴🏾|🕴🏿|🕵🏻|🕵🏼|🕵🏽|🕵🏾|🕵🏿|🕺🏻|🕺🏼|🕺🏽|🕺🏾|🕺🏿|🖐🏻|🖐🏼|🖐🏽|🖐🏾|🖐🏿|🖕🏻|🖕🏼|🖕🏽|🖕🏾|🖕🏿|🖖🏻|🖖🏼|🖖🏽|🖖🏾|🖖🏿|🙅🏻|🙅🏼|🙅🏽|🙅🏾|🙅🏿|🙆🏻|🙆🏼|🙆🏽|🙆🏾|🙆🏿|🙇🏻|🙇🏼|🙇🏽|🙇🏾|🙇🏿|🙋🏻|🙋🏼|🙋🏽|🙋🏾|🙋🏿|🙌🏻|🙌🏼|🙌🏽|🙌🏾|🙌🏿|🙍🏻|🙍🏼|🙍🏽|🙍🏾|🙍🏿|🙎🏻|🙎🏼|🙎🏽|🙎🏾|🙎🏿|🙏🏻|🙏🏼|🙏🏽|🙏🏾|🙏🏿|🚣🏻|🚣🏼|🚣🏽|🚣🏾|🚣🏿|🚴🏻|🚴🏼|🚴🏽|🚴🏾|🚴🏿|🚵🏻|🚵🏼|🚵🏽|🚵🏾|🚵🏿|🚶🏻|🚶🏼|🚶🏽|🚶🏾|🚶🏿|🛀🏻|🛀🏼|🛀🏽|🛀🏾|🛀🏿|🛌🏻|🛌🏼|🛌🏽|🛌🏾|🛌🏿|🤌🏻|🤌🏼|🤌🏽|🤌🏾|🤌🏿|🤏🏻|🤏🏼|🤏🏽|🤏🏾|🤏🏿|🤘🏻|🤘🏼|🤘🏽|🤘🏾|🤘🏿|🤙🏻|🤙🏼|🤙🏽|🤙🏾|🤙🏿|🤚🏻|🤚🏼|🤚🏽|🤚🏾|🤚🏿|🤛🏻|🤛🏼|🤛🏽|🤛🏾|🤛🏿|🤜🏻|🤜🏼|🤜🏽|🤜🏾|🤜🏿|🤝🏻|🤝🏼|🤝🏽|🤝🏾|🤝🏿|🤞🏻|🤞🏼|🤞🏽|🤞🏾|🤞🏿|🤟🏻|🤟🏼|🤟🏽|🤟🏾|🤟🏿|🤦🏻|🤦🏼|🤦🏽|🤦🏾|🤦🏿|🤰🏻|🤰🏼|🤰🏽|🤰🏾|🤰🏿|🤱🏻|🤱🏼|🤱🏽|🤱🏾|🤱🏿|🤲🏻|🤲🏼|🤲🏽|🤲🏾|🤲🏿|🤳🏻|🤳🏼|🤳🏽|🤳🏾|🤳🏿|🤴🏻|🤴🏼|🤴🏽|🤴🏾|🤴🏿|🤵🏻|🤵🏼|🤵🏽|🤵🏾|🤵🏿|🤶🏻|🤶🏼|🤶🏽|🤶🏾|🤶🏿|🤷🏻|🤷🏼|🤷🏽|🤷🏾|🤷🏿|🤸🏻|🤸🏼|🤸🏽|🤸🏾|🤸🏿|🤹🏻|🤹🏼|🤹🏽|🤹🏾|🤹🏿|🤽🏻|🤽🏼|🤽🏽|🤽🏾|🤽🏿|🤾🏻|🤾🏼|🤾🏽|🤾🏾|🤾🏿|🥷🏻|🥷🏼|🥷🏽|🥷🏾|🥷🏿|🦵🏻|🦵🏼|🦵🏽|🦵🏾|🦵🏿|🦶🏻|🦶🏼|🦶🏽|🦶🏾|🦶🏿|🦸🏻|🦸🏼|🦸🏽|🦸🏾|🦸🏿|🦹🏻|🦹🏼|🦹🏽|🦹🏾|🦹🏿|🦻🏻|🦻🏼|🦻🏽|🦻🏾|🦻🏿|🧍🏻|🧍🏼|🧍🏽|🧍🏾|🧍🏿|🧎🏻|🧎🏼|🧎🏽|🧎🏾|🧎🏿|🧏🏻|🧏🏼|🧏🏽|🧏🏾|🧏🏿|🧑🏻|🧑🏼|🧑🏽|🧑🏾|🧑🏿|🧒🏻|🧒🏼|🧒🏽|🧒🏾|🧒🏿|🧓🏻|🧓🏼|🧓🏽|🧓🏾|🧓🏿|🧔🏻|🧔🏼|🧔🏽|🧔🏾|🧔🏿|🧕🏻|🧕🏼|🧕🏽|🧕🏾|🧕🏿|🧖🏻|🧖🏼|🧖🏽|🧖🏾|🧖🏿|🧗🏻|🧗🏼|🧗🏽|🧗🏾|🧗🏿|🧘🏻|🧘🏼|🧘🏽|🧘🏾|🧘🏿|🧙🏻|🧙🏼|🧙🏽|🧙🏾|🧙🏿|🧚🏻|🧚🏼|🧚🏽|🧚🏾|🧚🏿|🧛🏻|🧛🏼|🧛🏽|🧛🏾|🧛🏿|🧜🏻|🧜🏼|🧜🏽|🧜🏾|🧜🏿|🧝🏻|🧝🏼|🧝🏽|🧝🏾|🧝🏿|🫃🏻|🫃🏼|🫃🏽|🫃🏾|🫃🏿|🫄🏻|🫄🏼|🫄🏽|🫄🏾|🫄🏿|🫅🏻|🫅🏼|🫅🏽|🫅🏾|🫅🏿|🫰🏻|🫰🏼|🫰🏽|🫰🏾|🫰🏿|🫱🏻|🫱🏼|🫱🏽|🫱🏾|🫱🏿|🫲🏻|🫲🏼|🫲🏽|🫲🏾|🫲🏿|🫳🏻|🫳🏼|🫳🏽|🫳🏾|🫳🏿|🫴🏻|🫴🏼|🫴🏽|🫴🏾|🫴🏿|🫵🏻|🫵🏼|🫵🏽|🫵🏾|🫵🏿|🫶🏻|🫶🏼|🫶🏽|🫶🏾|🫶🏿|🫷🏻|🫷🏼|🫷🏽|🫷🏾|🫷🏿|🫸🏻|🫸🏼|🫸🏽|🫸🏾|🫸🏿|#️⃣|0️⃣|1️⃣|2️⃣|3️⃣|4️⃣|5️⃣|6️⃣|7️⃣|8️⃣|9️⃣|☝🏻|☝🏼|☝🏽|☝🏾|☝🏿|⛹🏻|⛹🏼|⛹🏽|⛹🏾|⛹🏿|✊🏻|✊🏼|✊🏽|✊🏾|✊🏿|✋🏻|✋🏼|✋🏽|✋🏾|✋🏿|✌🏻|✌🏼|✌🏽|✌🏾|✌🏿|✍🏻|✍🏼|✍🏽|✍🏾|✍🏿|🅰️|🅱️|🅾️|🅿️|🈂️|🈷️|🌡️|🌤️|🌥️|🌦️|🌧️|🌨️|🌩️|🌪️|🌫️|🌬️|🌶️|🍽️|🎖️|🎗️|🎙️|🎚️|🎛️|🎞️|🎟️|🏋️|🏌️|🏍️|🏎️|🏔️|🏕️|🏖️|🏗️|🏘️|🏙️|🏚️|🏛️|🏜️|🏝️|🏞️|🏟️|🏳️|🏵️|🏷️|🐿️|👁️|📽️|🕉️|🕊️|🕯️|🕰️|🕳️|🕴️|🕵️|🕶️|🕷️|🕸️|🕹️|🖇️|🖊️|🖋️|🖌️|🖍️|🖐️|🖥️|🖨️|🖱️|🖲️|🖼️|🗂️|🗃️|🗄️|🗑️|🗒️|🗓️|🗜️|🗝️|🗞️|🗡️|🗣️|🗨️|🗯️|🗳️|🗺️|🛋️|🛍️|🛎️|🛏️|🛠️|🛡️|🛢️|🛣️|🛤️|🛥️|🛩️|🛰️|🛳️|©️|®️|‼️|⁉️|™️|ℹ️|↔️|↕️|↖️|↗️|↘️|↙️|↩️|↪️|⌨️|⏏️|⏭️|⏮️|⏯️|⏱️|⏲️|⏸️|⏹️|⏺️|Ⓜ️|▪️|▫️|▶️|◀️|◻️|◼️|☀️|☁️|☂️|☃️|☄️|☎️|☑️|☘️|☝️|☠️|☢️|☣️|☦️|☪️|☮️|☯️|☸️|☹️|☺️|♀️|♂️|♟️|♠️|♣️|♥️|♦️|♨️|♻️|♾️|⚒️|⚔️|⚕️|⚖️|⚗️|⚙️|⚛️|⚜️|⚠️|⚧️|⚰️|⚱️|⛈️|⛏️|⛑️|⛓️|⛩️|⛰️|⛱️|⛴️|⛷️|⛸️|⛹️|✂️|✈️|✉️|✌️|✍️|✏️|✒️|✔️|✖️|✝️|✡️|✳️|✴️|❄️|❇️|❣️|❤️|➡️|⤴️|⤵️|⬅️|⬆️|⬇️|〰️|〽️|㊗️|㊙️|[\\u231A\\u231B\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u25FE\\u2614\\u2615\\u2648-\\u2653\\u267F\\u2693\\u26A1\\u26AA\\u26AB\\u26BD\\u26BE\\u26C4\\u26C5\\u26CE\\u26D4\\u26EA\\u26F2\\u26F3\\u26F5\\u26FA\\u26FD\\u2705\\u270A\\u270B\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2795-\\u2797\\u27B0\\u27BF\\u2B1B\\u2B1C\\u2B50\\u2B55\\u{1F004}\\u{1F0CF}\\u{1F18E}\\u{1F191}-\\u{1F19A}\\u{1F201}\\u{1F21A}\\u{1F22F}\\u{1F232}-\\u{1F236}\\u{1F238}-\\u{1F23A}\\u{1F250}\\u{1F251}\\u{1F300}-\\u{1F320}\\u{1F32D}-\\u{1F335}\\u{1F337}-\\u{1F37C}\\u{1F37E}-\\u{1F393}\\u{1F3A0}-\\u{1F3CA}\\u{1F3CF}-\\u{1F3D3}\\u{1F3E0}-\\u{1F3F0}\\u{1F3F4}\\u{1F3F8}-\\u{1F43E}\\u{1F440}\\u{1F442}-\\u{1F4FC}\\u{1F4FF}-\\u{1F53D}\\u{1F54B}-\\u{1F54E}\\u{1F550}-\\u{1F567}\\u{1F57A}\\u{1F595}\\u{1F596}\\u{1F5A4}\\u{1F5FB}-\\u{1F64F}\\u{1F680}-\\u{1F6C5}\\u{1F6CC}\\u{1F6D0}-\\u{1F6D2}\\u{1F6D5}-\\u{1F6D7}\\u{1F6DC}-\\u{1F6DF}\\u{1F6EB}\\u{1F6EC}\\u{1F6F4}-\\u{1F6FC}\\u{1F7E0}-\\u{1F7EB}\\u{1F7F0}\\u{1F90C}-\\u{1F93A}\\u{1F93C}-\\u{1F945}\\u{1F947}-\\u{1F9FF}\\u{1FA70}-\\u{1FA7C}\\u{1FA80}-\\u{1FA88}\\u{1FA90}-\\u{1FABD}\\u{1FABF}-\\u{1FAC5}\\u{1FACE}-\\u{1FADB}\\u{1FAE0}-\\u{1FAE8}\\u{1FAF0}-\\u{1FAF8}])'
-	}
-];
-
-describe('unicodeSets (v) flag', () => {
-	for (const fixture of unicodeSetFixtures) {
-		const pattern = fixture.pattern;
-		const flags = fixture.flags || 'v';
-		const options = fixture.options || { unicodeSetsFlag: 'transform' };
-		const transformUnicodeFlag = options.unicodeFlag === 'transform';
-
-		const inputRE = `/${pattern}/${flags}`;
-
-		const expected = fixture.expected;
-		const throws = fixture.throws;
-
-		if (throws) {
-			if (expected) {
-				throw new Error(`TEST ERROR: ${inputRE} cannot both throw and have an expected output.`);
-			}
-			it(`throws for \`${inputRE}\` ${transformUnicodeFlag ? 'without ' : ''}using the u flag`, () => {
-				assert.throws(() => {
-					rewritePattern(pattern, flags, options);
-				}, throws);
-			});
-		} else {
-			it(`rewrites \`${inputRE}\` correctly ${transformUnicodeFlag ? 'without ' : ''}using the u flag`, () => {
-				const transpiled = rewritePattern(pattern, flags, options);
-				if (transpiled != '(?:' + expected + ')') {
-					assert.strictEqual(transpiled, expected);
-				}
-			});
-		}
-	}
-
-	it('Property of strings used without the v flag', () => {
-		assert.throws(() => {
-			rewritePattern('\\p{Basic_Emoji}', 'u')
-		}, /Properties of strings are only supported when using the unicodeSets \(v\) flag/);
-	})
-});
-

More details

Full run details

Historical runs