oniguruma-to-es
Version:
Convert Oniguruma patterns to native JavaScript RegExp
1,301 lines (1,291 loc) • 110 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.js
var index_exports = {};
__export(index_exports, {
EmulatedRegExp: () => EmulatedRegExp,
toRegExp: () => toRegExp,
toRegExpDetails: () => toRegExpDetails
});
module.exports = __toCommonJS(index_exports);
// src/utils.js
var cp = String.fromCodePoint;
var r = String.raw;
var envFlags = {};
var globalRegExp = globalThis.RegExp;
envFlags.flagGroups = (() => {
try {
new globalRegExp("(?i:)");
} catch {
return false;
}
return true;
})();
envFlags.unicodeSets = (() => {
try {
new globalRegExp("[[]]", "v");
} catch {
return false;
}
return true;
})();
envFlags.bugFlagVLiteralHyphenIsRange = envFlags.unicodeSets ? (() => {
try {
new globalRegExp(r`[\d\-a]`, "v");
} catch {
return true;
}
return false;
})() : false;
envFlags.bugNestedClassIgnoresNegation = envFlags.unicodeSets && new globalRegExp("[[^a]]", "v").test("a");
function getNewCurrentFlags(current, { enable, disable }) {
return {
dotAll: !disable?.dotAll && !!(enable?.dotAll || current.dotAll),
ignoreCase: !disable?.ignoreCase && !!(enable?.ignoreCase || current.ignoreCase)
};
}
function getOrInsert(map, key, defaultValue) {
if (!map.has(key)) {
map.set(key, defaultValue);
}
return map.get(key);
}
function isMinTarget(target, min) {
return EsVersion[target] >= EsVersion[min];
}
function throwIfNullish(value, msg) {
if (value == null) {
throw new Error(msg ?? "Value expected");
}
return value;
}
// src/options.js
var EsVersion = {
ES2025: 2025,
ES2024: 2024,
ES2018: 2018
};
var Target = (
/** @type {const} */
{
auto: "auto",
ES2025: "ES2025",
ES2024: "ES2024",
ES2018: "ES2018"
}
);
function getOptions(options = {}) {
if ({}.toString.call(options) !== "[object Object]") {
throw new Error("Unexpected options");
}
if (options.target !== void 0 && !Target[options.target]) {
throw new Error(`Unexpected target "${options.target}"`);
}
const opts = {
// Sets the level of emulation rigor/strictness.
accuracy: "default",
// Disables advanced emulation that relies on returning a `RegExp` subclass, resulting in
// certain patterns not being emulatable.
avoidSubclass: false,
// Oniguruma flags; a string with `i`, `m`, `x`, `D`, `S`, `W`, `y{g}` in any order (all
// optional). Oniguruma's `m` is equivalent to JavaScript's `s` (`dotAll`).
flags: "",
// Include JavaScript flag `g` (`global`) in the result.
global: false,
// Include JavaScript flag `d` (`hasIndices`) in the result.
hasIndices: false,
// Delay regex construction until first use if the transpiled pattern is at least this length.
lazyCompileLength: Infinity,
// JavaScript version used for generated regexes. Using `auto` detects the best value based on
// your environment. Later targets allow faster processing, simpler generated source, and
// support for additional features.
target: "auto",
// Disables minifications that simplify the pattern without changing the meaning.
verbose: false,
...options,
// Advanced options that override standard behavior, error checking, and flags when enabled.
rules: {
// Useful with TextMate grammars that merge backreferences across patterns.
allowOrphanBackrefs: false,
// Use ASCII `\b` and `\B`, which increases search performance of generated regexes.
asciiWordBoundaries: false,
// Allow unnamed captures and numbered calls (backreferences and subroutines) when using
// named capture. This is Oniguruma option `ONIG_OPTION_CAPTURE_GROUP`; on by default in
// `vscode-oniguruma`.
captureGroup: false,
// Change the recursion depth limit from Oniguruma's `20` to an integer `2`–`20`.
recursionLimit: 20,
// `^` as `\A`; `$` as`\Z`. Improves search performance of generated regexes without changing
// the meaning if searching line by line. This is Oniguruma option `ONIG_OPTION_SINGLELINE`.
singleline: false,
...options.rules
}
};
if (opts.target === "auto") {
opts.target = envFlags.flagGroups ? "ES2025" : envFlags.unicodeSets ? "ES2024" : "ES2018";
}
return opts;
}
// node_modules/.pnpm/oniguruma-parser@0.12.2/node_modules/oniguruma-parser/dist/utils.js
function r2(e) {
if ([...e].length !== 1) throw new Error(`Expected "${e}" to be a single code point`);
return e.codePointAt(0);
}
function l(e, t, n) {
return e.has(t) || e.set(t, n), e.get(t);
}
var i = /* @__PURE__ */ new Set(["alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph", "lower", "print", "punct", "space", "upper", "word", "xdigit"]);
var o = String.raw;
function u(e, t) {
if (e == null) throw new Error(t ?? "Value expected");
return e;
}
// node_modules/.pnpm/oniguruma-parser@0.12.2/node_modules/oniguruma-parser/dist/tokenizer/tokenize.js
var m = o`\[\^?`;
var b = `c.? | C(?:-.?)?|${o`[pP]\{(?:\^?[-\x20_]*[A-Za-z][-\x20\w]*\})?`}|${o`x[89A-Fa-f]\p{AHex}(?:\\x[89A-Fa-f]\p{AHex})*`}|${o`u(?:\p{AHex}{4})? | x\{[^\}]*\}? | x\p{AHex}{0,2}`}|${o`o\{[^\}]*\}?`}|${o`\d{1,3}`}`;
var y = /[?*+][?+]?|\{(?:\d+(?:,\d*)?|,\d+)\}\??/;
var C = new RegExp(o`
\\ (?:
${b}
| [gk]<[^>]*>?
| [gk]'[^']*'?
| .
)
| \( (?:
\? (?:
[:=!>({]
| <[=!]
| <[^>]*>
| '[^']*'
| ~\|?
| #(?:[^)\\]|\\.?)*
| [^:)]*[:)]
)?
| \*[^\)]*\)?
)?
| (?:${y.source})+
| ${m}
| .
`.replace(/\s+/g, ""), "gsu");
var T = new RegExp(o`
\\ (?:
${b}
| .
)
| \[:(?:\^?\p{Alpha}+|\^):\]
| ${m}
| &&
| .
`.replace(/\s+/g, ""), "gsu");
function M(e, n = {}) {
const t = { flags: "", ...n, rules: { captureGroup: false, singleline: false, ...n.rules } };
if (typeof e != "string") throw new Error("String expected as pattern");
const o3 = Y(t.flags), s2 = [o3.extended], a2 = { captureGroup: t.rules.captureGroup, getCurrentModX() {
return s2.at(-1);
}, numOpenGroups: 0, popModX() {
s2.pop();
}, pushModX(u2) {
s2.push(u2);
}, replaceCurrentModX(u2) {
s2[s2.length - 1] = u2;
}, singleline: t.rules.singleline };
let r4 = [], i2;
for (C.lastIndex = 0; i2 = C.exec(e); ) {
const u2 = F(a2, e, i2[0], C.lastIndex);
u2.tokens ? r4.push(...u2.tokens) : u2.token && r4.push(u2.token), u2.lastIndex !== void 0 && (C.lastIndex = u2.lastIndex);
}
const l3 = [];
let c = 0;
r4.filter((u2) => u2.type === "GroupOpen").forEach((u2) => {
u2.kind === "capturing" ? u2.number = ++c : u2.raw === "(" && l3.push(u2);
}), c || l3.forEach((u2, S2) => {
u2.kind = "capturing", u2.number = S2 + 1;
});
const g = c || l3.length;
return { tokens: r4.map((u2) => u2.type === "EscapedNumber" ? ee(u2, g) : u2).flat(), flags: o3 };
}
function F(e, n, t, o3) {
const [s2, a2] = t;
if (t === "[" || t === "[^") {
const r4 = K(n, t, o3);
return { tokens: r4.tokens, lastIndex: r4.lastIndex };
}
if (s2 === "\\") {
if ("AbBGyYzZ".includes(a2)) return { token: w(t, t) };
if (/^\\g[<']/.test(t)) {
if (!/^\\g(?:<[^>]+>|'[^']+')$/.test(t)) throw new Error(`Invalid group name "${t}"`);
return { token: R(t) };
}
if (/^\\k[<']/.test(t)) {
if (!/^\\k(?:<[^>]+>|'[^']+')$/.test(t)) throw new Error(`Invalid group name "${t}"`);
return { token: A(t) };
}
if (a2 === "K") return { token: I("keep", t) };
if (a2 === "N" || a2 === "R") return { token: k("newline", t, { negate: a2 === "N" }) };
if (a2 === "O") return { token: k("any", t) };
if (a2 === "X") return { token: k("text_segment", t) };
const r4 = x(t, { inCharClass: false });
return Array.isArray(r4) ? { tokens: r4 } : { token: r4 };
}
if (s2 === "(") {
if (a2 === "*") return { token: j(t) };
if (t === "(?{") throw new Error(`Unsupported callout "${t}"`);
if (t.startsWith("(?#")) {
if (n[o3] !== ")") throw new Error('Unclosed comment group "(?#"');
return { lastIndex: o3 + 1 };
}
if (/^\(\?[-imx]+[:)]$/.test(t)) return { token: L(t, e) };
if (e.pushModX(e.getCurrentModX()), e.numOpenGroups++, t === "(" && !e.captureGroup || t === "(?:") return { token: f("group", t) };
if (t === "(?>") return { token: f("atomic", t) };
if (t === "(?=" || t === "(?!" || t === "(?<=" || t === "(?<!") return { token: f(t[2] === "<" ? "lookbehind" : "lookahead", t, { negate: t.endsWith("!") }) };
if (t === "(" && e.captureGroup || t.startsWith("(?<") && t.endsWith(">") || t.startsWith("(?'") && t.endsWith("'")) return { token: f("capturing", t, { ...t !== "(" && { name: t.slice(3, -1) } }) };
if (t.startsWith("(?~")) {
if (t === "(?~|") throw new Error(`Unsupported absence function kind "${t}"`);
return { token: f("absence_repeater", t) };
}
throw t === "(?(" ? new Error(`Unsupported conditional "${t}"`) : new Error(`Invalid or unsupported group option "${t}"`);
}
if (t === ")") {
if (e.popModX(), e.numOpenGroups--, e.numOpenGroups < 0) throw new Error('Unmatched ")"');
return { token: Q(t) };
}
if (e.getCurrentModX()) {
if (t === "#") {
const r4 = n.indexOf(`
`, o3);
return { lastIndex: r4 === -1 ? n.length : r4 };
}
if (/^\s$/.test(t)) {
const r4 = /\s+/y;
return r4.lastIndex = o3, { lastIndex: r4.exec(n) ? r4.lastIndex : o3 };
}
}
if (t === ".") return { token: k("dot", t) };
if (t === "^" || t === "$") {
const r4 = e.singleline ? { "^": o`\A`, $: o`\Z` }[t] : t;
return { token: w(r4, t) };
}
return t === "|" ? { token: P(t) } : y.test(t) ? { tokens: te(t) } : { token: d(r2(t), t) };
}
function K(e, n, t) {
const o3 = [E(n[1] === "^", n)];
let s2 = 1, a2;
for (T.lastIndex = t; a2 = T.exec(e); ) {
const r4 = a2[0];
if (r4[0] === "[" && r4[1] !== ":") s2++, o3.push(E(r4[1] === "^", r4));
else if (r4 === "]") {
if (o3.at(-1).type === "CharacterClassOpen") o3.push(d(93, r4));
else if (s2--, o3.push(z(r4)), !s2) break;
} else {
const i2 = X(r4);
Array.isArray(i2) ? o3.push(...i2) : o3.push(i2);
}
}
return { tokens: o3, lastIndex: T.lastIndex || e.length };
}
function X(e) {
if (e[0] === "\\") return x(e, { inCharClass: true });
if (e[0] === "[") {
const n = /\[:(?<negate>\^?)(?<name>[a-z]+):\]/.exec(e);
if (!n || !i.has(n.groups.name)) throw new Error(`Invalid POSIX class "${e}"`);
return k("posix", e, { value: n.groups.name, negate: !!n.groups.negate });
}
return e === "-" ? U(e) : e === "&&" ? H(e) : d(r2(e), e);
}
function x(e, { inCharClass: n }) {
const t = e[1];
if (t === "c" || t === "C") return Z(e);
if ("dDhHsSwW".includes(t)) return q(e);
if (e.startsWith(o`\o{`)) throw new Error(`Incomplete, invalid, or unsupported octal code point "${e}"`);
if (/^\\[pP]\{/.test(e)) {
if (e.length === 3) throw new Error(`Incomplete or invalid Unicode property "${e}"`);
return V(e);
}
if (/^\\x[89A-Fa-f]\p{AHex}/u.test(e)) try {
const o3 = e.split(/\\x/).slice(1).map((i2) => parseInt(i2, 16)), s2 = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }).decode(new Uint8Array(o3)), a2 = new TextEncoder();
return [...s2].map((i2) => {
const l3 = [...a2.encode(i2)].map((c) => `\\x${c.toString(16)}`).join("");
return d(r2(i2), l3);
});
} catch {
throw new Error(`Multibyte code "${e}" incomplete or invalid in Oniguruma`);
}
if (t === "u" || t === "x") return d(J(e), e);
if ($.has(t)) return d($.get(t), e);
if (/\d/.test(t)) return W(n, e);
if (e === "\\") throw new Error(o`Incomplete escape "\"`);
if (t === "M") throw new Error(`Unsupported meta "${e}"`);
if ([...e].length === 2) return d(e.codePointAt(1), e);
throw new Error(`Unexpected escape "${e}"`);
}
function P(e) {
return { type: "Alternator", raw: e };
}
function w(e, n) {
return { type: "Assertion", kind: e, raw: n };
}
function A(e) {
return { type: "Backreference", raw: e };
}
function d(e, n) {
return { type: "Character", value: e, raw: n };
}
function z(e) {
return { type: "CharacterClassClose", raw: e };
}
function U(e) {
return { type: "CharacterClassHyphen", raw: e };
}
function H(e) {
return { type: "CharacterClassIntersector", raw: e };
}
function E(e, n) {
return { type: "CharacterClassOpen", negate: e, raw: n };
}
function k(e, n, t = {}) {
return { type: "CharacterSet", kind: e, ...t, raw: n };
}
function I(e, n, t = {}) {
return e === "keep" ? { type: "Directive", kind: e, raw: n } : { type: "Directive", kind: e, flags: u(t.flags), raw: n };
}
function W(e, n) {
return { type: "EscapedNumber", inCharClass: e, raw: n };
}
function Q(e) {
return { type: "GroupClose", raw: e };
}
function f(e, n, t = {}) {
return { type: "GroupOpen", kind: e, ...t, raw: n };
}
function D(e, n, t, o3) {
return { type: "NamedCallout", kind: e, tag: n, arguments: t, raw: o3 };
}
function _(e, n, t, o3) {
return { type: "Quantifier", kind: e, min: n, max: t, raw: o3 };
}
function R(e) {
return { type: "Subroutine", raw: e };
}
var B = /* @__PURE__ */ new Set(["COUNT", "CMP", "ERROR", "FAIL", "MAX", "MISMATCH", "SKIP", "TOTAL_COUNT"]);
var $ = /* @__PURE__ */ new Map([["a", 7], ["b", 8], ["e", 27], ["f", 12], ["n", 10], ["r", 13], ["t", 9], ["v", 11]]);
function Z(e) {
const n = e[1] === "c" ? e[2] : e[3];
if (!n || !/[A-Za-z]/.test(n)) throw new Error(`Unsupported control character "${e}"`);
return d(r2(n.toUpperCase()) - 64, e);
}
function L(e, n) {
let { on: t, off: o3 } = /^\(\?(?<on>[imx]*)(?:-(?<off>[-imx]*))?/.exec(e).groups;
o3 ??= "";
const s2 = (n.getCurrentModX() || t.includes("x")) && !o3.includes("x"), a2 = v(t), r4 = v(o3), i2 = {};
if (a2 && (i2.enable = a2), r4 && (i2.disable = r4), e.endsWith(")")) return n.replaceCurrentModX(s2), I("flags", e, { flags: i2 });
if (e.endsWith(":")) return n.pushModX(s2), n.numOpenGroups++, f("group", e, { ...(a2 || r4) && { flags: i2 } });
throw new Error(`Unexpected flag modifier "${e}"`);
}
function j(e) {
const n = /\(\*(?<name>[A-Za-z_]\w*)?(?:\[(?<tag>(?:[A-Za-z_]\w*)?)\])?(?:\{(?<args>[^}]*)\})?\)/.exec(e);
if (!n) throw new Error(`Incomplete or invalid named callout "${e}"`);
const { name: t, tag: o3, args: s2 } = n.groups;
if (!t) throw new Error(`Invalid named callout "${e}"`);
if (o3 === "") throw new Error(`Named callout tag with empty value not allowed "${e}"`);
const a2 = s2 ? s2.split(",").filter((g) => g !== "").map((g) => /^[+-]?\d+$/.test(g) ? +g : g) : [], [r4, i2, l3] = a2, c = B.has(t) ? t.toLowerCase() : "custom";
switch (c) {
case "fail":
case "mismatch":
case "skip":
if (a2.length > 0) throw new Error(`Named callout arguments not allowed "${a2}"`);
break;
case "error":
if (a2.length > 1) throw new Error(`Named callout allows only one argument "${a2}"`);
if (typeof r4 == "string") throw new Error(`Named callout argument must be a number "${r4}"`);
break;
case "max":
if (!a2.length || a2.length > 2) throw new Error(`Named callout must have one or two arguments "${a2}"`);
if (typeof r4 == "string" && !/^[A-Za-z_]\w*$/.test(r4)) throw new Error(`Named callout argument one must be a tag or number "${r4}"`);
if (a2.length === 2 && (typeof i2 == "number" || !/^[<>X]$/.test(i2))) throw new Error(`Named callout optional argument two must be '<', '>', or 'X' "${i2}"`);
break;
case "count":
case "total_count":
if (a2.length > 1) throw new Error(`Named callout allows only one argument "${a2}"`);
if (a2.length === 1 && (typeof r4 == "number" || !/^[<>X]$/.test(r4))) throw new Error(`Named callout optional argument must be '<', '>', or 'X' "${r4}"`);
break;
case "cmp":
if (a2.length !== 3) throw new Error(`Named callout must have three arguments "${a2}"`);
if (typeof r4 == "string" && !/^[A-Za-z_]\w*$/.test(r4)) throw new Error(`Named callout argument one must be a tag or number "${r4}"`);
if (typeof i2 == "number" || !/^(?:[<>!=]=|[<>])$/.test(i2)) throw new Error(`Named callout argument two must be '==', '!=', '>', '<', '>=', or '<=' "${i2}"`);
if (typeof l3 == "string" && !/^[A-Za-z_]\w*$/.test(l3)) throw new Error(`Named callout argument three must be a tag or number "${l3}"`);
break;
case "custom":
throw new Error(`Undefined callout name "${t}"`);
default:
throw new Error(`Unexpected named callout kind "${c}"`);
}
return D(c, o3 ?? null, s2?.split(",") ?? null, e);
}
function O(e) {
let n = null, t, o3;
if (e[0] === "{") {
const { minStr: s2, maxStr: a2 } = /^\{(?<minStr>\d*)(?:,(?<maxStr>\d*))?/.exec(e).groups, r4 = 1e5;
if (+s2 > r4 || a2 && +a2 > r4) throw new Error("Quantifier value unsupported in Oniguruma");
if (t = +s2, o3 = a2 === void 0 ? +s2 : a2 === "" ? 1 / 0 : +a2, t > o3 && (n = "possessive", [t, o3] = [o3, t]), e.endsWith("?")) {
if (n === "possessive") throw new Error('Unsupported possessive interval quantifier chain with "?"');
n = "lazy";
} else n || (n = "greedy");
} else t = e[0] === "+" ? 1 : 0, o3 = e[0] === "?" ? 1 : 1 / 0, n = e[1] === "+" ? "possessive" : e[1] === "?" ? "lazy" : "greedy";
return _(n, t, o3, e);
}
function q(e) {
const n = e[1].toLowerCase();
return k({ d: "digit", h: "hex", s: "space", w: "word" }[n], e, { negate: e[1] !== n });
}
function V(e) {
const { p: n, neg: t, value: o3 } = /^\\(?<p>[pP])\{(?<neg>\^?)(?<value>[^}]+)/.exec(e).groups;
return k("property", e, { value: o3, negate: n === "P" && !t || n === "p" && !!t });
}
function v(e) {
const n = {};
return e.includes("i") && (n.ignoreCase = true), e.includes("m") && (n.dotAll = true), e.includes("x") && (n.extended = true), Object.keys(n).length ? n : null;
}
function Y(e) {
const n = { ignoreCase: false, dotAll: false, extended: false, digitIsAscii: false, posixIsAscii: false, spaceIsAscii: false, wordIsAscii: false, textSegmentMode: null };
for (let t = 0; t < e.length; t++) {
const o3 = e[t];
if (!"imxDPSWy".includes(o3)) throw new Error(`Invalid flag "${o3}"`);
if (o3 === "y") {
if (!/^y{[gw]}/.test(e.slice(t))) throw new Error('Invalid or unspecified flag "y" mode');
n.textSegmentMode = e[t + 2] === "g" ? "grapheme" : "word", t += 3;
continue;
}
n[{ i: "ignoreCase", m: "dotAll", x: "extended", D: "digitIsAscii", P: "posixIsAscii", S: "spaceIsAscii", W: "wordIsAscii" }[o3]] = true;
}
return n;
}
function J(e) {
if (/^(?:\\u(?!\p{AHex}{4})|\\x(?!\p{AHex}{1,2}|\{\p{AHex}{1,8}\}))/u.test(e)) throw new Error(`Incomplete or invalid escape "${e}"`);
const n = e[2] === "{" ? /^\\x\{\s*(?<hex>\p{AHex}+)/u.exec(e).groups.hex : e.slice(2);
return parseInt(n, 16);
}
function ee(e, n) {
const { raw: t, inCharClass: o3 } = e, s2 = t.slice(1);
if (!o3 && (s2 !== "0" && s2.length === 1 || s2[0] !== "0" && +s2 <= n)) return [A(t)];
const a2 = [], r4 = s2.match(/^[0-7]+|\d/g);
for (let i2 = 0; i2 < r4.length; i2++) {
const l3 = r4[i2];
let c;
if (i2 === 0 && l3 !== "8" && l3 !== "9") {
if (c = parseInt(l3, 8), c > 127) throw new Error(o`Octal encoded byte above 177 unsupported "${t}"`);
} else c = r2(l3);
a2.push(d(c, (i2 === 0 ? "\\" : "") + l3));
}
return a2;
}
function te(e) {
const n = [], t = new RegExp(y, "gy");
let o3;
for (; o3 = t.exec(e); ) {
const s2 = o3[0];
if (s2[0] === "{") {
const a2 = /^\{(?<min>\d+),(?<max>\d+)\}\??$/.exec(s2);
if (a2) {
const { min: r4, max: i2 } = a2.groups;
if (+r4 > +i2 && s2.endsWith("?")) {
t.lastIndex--, n.push(O(s2.slice(0, -1)));
continue;
}
}
}
n.push(O(s2));
}
return n;
}
// node_modules/.pnpm/oniguruma-parser@0.12.2/node_modules/oniguruma-parser/dist/parser/node-utils.js
function o2(e, t) {
if (!Array.isArray(e.body)) throw new Error("Expected node with body array");
if (e.body.length !== 1) return false;
const r4 = e.body[0];
return !t || Object.keys(t).every((n) => t[n] === r4[n]);
}
function s(e) {
return y2.has(e.type);
}
var y2 = /* @__PURE__ */ new Set(["AbsenceFunction", "Backreference", "CapturingGroup", "Character", "CharacterClass", "CharacterSet", "Group", "Quantifier", "Subroutine"]);
// node_modules/.pnpm/oniguruma-parser@0.12.2/node_modules/oniguruma-parser/dist/parser/parse.js
function J2(e, r4 = {}) {
const n = { flags: "", normalizeUnknownPropertyNames: false, skipBackrefValidation: false, skipLookbehindValidation: false, skipPropertyNameValidation: false, unicodePropertyMap: null, ...r4, rules: { captureGroup: false, singleline: false, ...r4.rules } }, o3 = M(e, { flags: n.flags, rules: { captureGroup: n.rules.captureGroup, singleline: n.rules.singleline } }), i2 = (p, N) => {
const u2 = o3.tokens[t.nextIndex];
switch (t.parent = p, t.nextIndex++, u2.type) {
case "Alternator":
return b2();
case "Assertion":
return W2(u2);
case "Backreference":
return X2(u2, t);
case "Character":
return m2(u2.value, { useLastValid: !!N.isCheckingRangeEnd });
case "CharacterClassHyphen":
return ee2(u2, t, N);
case "CharacterClassOpen":
return re(u2, t, N);
case "CharacterSet":
return ne(u2, t);
case "Directive":
return I2(u2.kind, { flags: u2.flags });
case "GroupOpen":
return te2(u2, t, N);
case "NamedCallout":
return U2(u2.kind, u2.tag, u2.arguments);
case "Quantifier":
return oe(u2, t);
case "Subroutine":
return ae(u2, t);
default:
throw new Error(`Unexpected token type "${u2.type}"`);
}
}, t = { capturingGroups: [], hasNumberedRef: false, namedGroupsByName: /* @__PURE__ */ new Map(), nextIndex: 0, normalizeUnknownPropertyNames: n.normalizeUnknownPropertyNames, parent: null, skipBackrefValidation: n.skipBackrefValidation, skipLookbehindValidation: n.skipLookbehindValidation, skipPropertyNameValidation: n.skipPropertyNameValidation, subroutines: [], tokens: o3.tokens, unicodePropertyMap: n.unicodePropertyMap, walk: i2 }, d2 = B2(T2(o3.flags));
let s2 = d2.body[0];
for (; t.nextIndex < o3.tokens.length; ) {
const p = i2(s2, {});
p.type === "Alternative" ? (d2.body.push(p), s2 = p) : s2.body.push(p);
}
const { capturingGroups: a2, hasNumberedRef: l3, namedGroupsByName: c, subroutines: f2 } = t;
if (l3 && c.size && !n.rules.captureGroup) throw new Error("Numbered backref/subroutine not allowed when using named capture");
for (const { ref: p } of f2) if (typeof p == "number") {
if (p > a2.length) throw new Error("Subroutine uses a group number that's not defined");
p && (a2[p - 1].isSubroutined = true);
} else if (c.has(p)) {
if (c.get(p).length > 1) throw new Error(o`Subroutine uses a duplicate group name "\g<${p}>"`);
c.get(p)[0].isSubroutined = true;
} else throw new Error(o`Subroutine uses a group name that's not defined "\g<${p}>"`);
return d2;
}
function W2({ kind: e }) {
return F2(u({ "^": "line_start", $: "line_end", "\\A": "string_start", "\\b": "word_boundary", "\\B": "word_boundary", "\\G": "search_start", "\\y": "text_segment_boundary", "\\Y": "text_segment_boundary", "\\z": "string_end", "\\Z": "string_end_newline" }[e], `Unexpected assertion kind "${e}"`), { negate: e === o`\B` || e === o`\Y` });
}
function X2({ raw: e }, r4) {
const n = /^\\k[<']/.test(e), o3 = n ? e.slice(3, -1) : e.slice(1), i2 = (t, d2 = false) => {
const s2 = r4.capturingGroups.length;
let a2 = false;
if (t > s2) if (r4.skipBackrefValidation) a2 = true;
else throw new Error(`Not enough capturing groups defined to the left "${e}"`);
return r4.hasNumberedRef = true, k2(d2 ? s2 + 1 - t : t, { orphan: a2 });
};
if (n) {
const t = /^(?<sign>-?)0*(?<num>[1-9]\d*)$/.exec(o3);
if (t) return i2(+t.groups.num, !!t.groups.sign);
if (/[-+]/.test(o3)) throw new Error(`Invalid backref name "${e}"`);
if (!r4.namedGroupsByName.has(o3)) throw new Error(`Group name not defined to the left "${e}"`);
return k2(o3);
}
return i2(+o3);
}
function ee2(e, r4, n) {
const { tokens: o3, walk: i2 } = r4, t = r4.parent, d2 = t.body.at(-1), s2 = o3[r4.nextIndex];
if (!n.isCheckingRangeEnd && d2 && d2.type !== "CharacterClass" && d2.type !== "CharacterClassRange" && s2 && s2.type !== "CharacterClassOpen" && s2.type !== "CharacterClassClose" && s2.type !== "CharacterClassIntersector") {
const a2 = i2(t, { ...n, isCheckingRangeEnd: true });
if (d2.type === "Character" && a2.type === "Character") return t.body.pop(), L2(d2, a2);
throw new Error("Invalid character class range");
}
return m2(r2("-"));
}
function re({ negate: e }, r4, n) {
const { tokens: o3, walk: i2 } = r4, t = [C2()], d2 = o3[r4.nextIndex];
let s2 = z2(d2);
for (; s2.type !== "CharacterClassClose"; ) {
if (s2.type === "CharacterClassIntersector") t.push(C2()), r4.nextIndex++;
else {
const l3 = t.at(-1);
l3.body.push(i2(l3, n));
}
s2 = z2(o3[r4.nextIndex], d2);
}
const a2 = C2({ negate: e });
return t.length === 1 ? a2.body = t[0].body : (a2.kind = "intersection", a2.body = t.map((l3) => l3.body.length === 1 ? l3.body[0] : l3)), r4.nextIndex++, a2;
}
function ne({ kind: e, negate: r4, value: n }, o3) {
const { normalizeUnknownPropertyNames: i2, skipPropertyNameValidation: t, unicodePropertyMap: d2 } = o3;
if (e === "property") {
const s2 = w2(n);
if (i.has(s2) && !d2?.has(s2)) e = "posix", n = s2;
else return Q2(n, { negate: r4, normalizeUnknownPropertyNames: i2, skipPropertyNameValidation: t, unicodePropertyMap: d2 });
}
return e === "posix" ? R2(n, { negate: r4 }) : E2(e, { negate: r4 });
}
function te2(e, r4, n) {
const { tokens: o3, capturingGroups: i2, namedGroupsByName: t, skipLookbehindValidation: d2, walk: s2 } = r4, a2 = ie(e), l3 = a2.type === "AbsenceFunction", c = $2(a2), f2 = c && a2.negate;
if (a2.type === "CapturingGroup" && (i2.push(a2), a2.name && l(t, a2.name, []).push(a2)), l3 && n.isInAbsenceFunction) throw new Error("Nested absence function not supported by Oniguruma");
let p = D2(o3[r4.nextIndex]);
for (; p.type !== "GroupClose"; ) {
if (p.type === "Alternator") a2.body.push(b2()), r4.nextIndex++;
else {
const N = a2.body.at(-1), u2 = s2(N, { ...n, isInAbsenceFunction: n.isInAbsenceFunction || l3, isInLookbehind: n.isInLookbehind || c, isInNegLookbehind: n.isInNegLookbehind || f2 });
if (N.body.push(u2), (c || n.isInLookbehind) && !d2) {
const v2 = "Lookbehind includes a pattern not allowed by Oniguruma";
if (f2 || n.isInNegLookbehind) {
if (M2(u2) || u2.type === "CapturingGroup") throw new Error(v2);
} else if (M2(u2) || $2(u2) && u2.negate) throw new Error(v2);
}
}
p = D2(o3[r4.nextIndex]);
}
return r4.nextIndex++, a2;
}
function oe({ kind: e, min: r4, max: n }, o3) {
const i2 = o3.parent, t = i2.body.at(-1);
if (!t || !s(t)) throw new Error("Quantifier requires a repeatable token");
const d2 = _2(e, r4, n, t);
return i2.body.pop(), d2;
}
function ae({ raw: e }, r4) {
const { capturingGroups: n, subroutines: o3 } = r4;
let i2 = e.slice(3, -1);
const t = /^(?<sign>[-+]?)0*(?<num>[1-9]\d*)$/.exec(i2);
if (t) {
const s2 = +t.groups.num, a2 = n.length;
if (r4.hasNumberedRef = true, i2 = { "": s2, "+": a2 + s2, "-": a2 + 1 - s2 }[t.groups.sign], i2 < 1) throw new Error("Invalid subroutine number");
} else i2 === "0" && (i2 = 0);
const d2 = O2(i2);
return o3.push(d2), d2;
}
function G(e, r4) {
if (e !== "repeater") throw new Error(`Unexpected absence function kind "${e}"`);
return { type: "AbsenceFunction", kind: e, body: h(r4?.body) };
}
function b2(e) {
return { type: "Alternative", body: V2(e?.body) };
}
function F2(e, r4) {
const n = { type: "Assertion", kind: e };
return (e === "word_boundary" || e === "text_segment_boundary") && (n.negate = !!r4?.negate), n;
}
function k2(e, r4) {
const n = !!r4?.orphan;
return { type: "Backreference", ref: e, ...n && { orphan: n } };
}
function P2(e, r4) {
const n = { name: void 0, isSubroutined: false, ...r4 };
if (n.name !== void 0 && !se(n.name)) throw new Error(`Group name "${n.name}" invalid in Oniguruma`);
return { type: "CapturingGroup", number: e, ...n.name && { name: n.name }, ...n.isSubroutined && { isSubroutined: n.isSubroutined }, body: h(r4?.body) };
}
function m2(e, r4) {
const n = { useLastValid: false, ...r4 };
if (e > 1114111) {
const o3 = e.toString(16);
if (n.useLastValid) e = 1114111;
else throw e > 1310719 ? new Error(`Invalid code point out of range "\\x{${o3}}"`) : new Error(`Invalid code point out of range in JS "\\x{${o3}}"`);
}
return { type: "Character", value: e };
}
function C2(e) {
const r4 = { kind: "union", negate: false, ...e };
return { type: "CharacterClass", kind: r4.kind, negate: r4.negate, body: V2(e?.body) };
}
function L2(e, r4) {
if (r4.value < e.value) throw new Error("Character class range out of order");
return { type: "CharacterClassRange", min: e, max: r4 };
}
function E2(e, r4) {
const n = !!r4?.negate, o3 = { type: "CharacterSet", kind: e };
return (e === "digit" || e === "hex" || e === "newline" || e === "space" || e === "word") && (o3.negate = n), (e === "text_segment" || e === "newline" && !n) && (o3.variableLength = true), o3;
}
function I2(e, r4 = {}) {
if (e === "keep") return { type: "Directive", kind: e };
if (e === "flags") return { type: "Directive", kind: e, flags: u(r4.flags) };
throw new Error(`Unexpected directive kind "${e}"`);
}
function T2(e) {
return { type: "Flags", ...e };
}
function A2(e) {
const r4 = e?.atomic, n = e?.flags;
if (r4 && n) throw new Error("Atomic group cannot have flags");
return { type: "Group", ...r4 && { atomic: r4 }, ...n && { flags: n }, body: h(e?.body) };
}
function K2(e) {
const r4 = { behind: false, negate: false, ...e };
return { type: "LookaroundAssertion", kind: r4.behind ? "lookbehind" : "lookahead", negate: r4.negate, body: h(e?.body) };
}
function U2(e, r4, n) {
return { type: "NamedCallout", kind: e, tag: r4, arguments: n };
}
function R2(e, r4) {
const n = !!r4?.negate;
if (!i.has(e)) throw new Error(`Invalid POSIX class "${e}"`);
return { type: "CharacterSet", kind: "posix", value: e, negate: n };
}
function _2(e, r4, n, o3) {
if (r4 > n) throw new Error("Invalid reversed quantifier range");
return { type: "Quantifier", kind: e, min: r4, max: n, body: o3 };
}
function B2(e, r4) {
return { type: "Regex", body: h(r4?.body), flags: e };
}
function O2(e) {
return { type: "Subroutine", ref: e };
}
function Q2(e, r4) {
const n = { negate: false, normalizeUnknownPropertyNames: false, skipPropertyNameValidation: false, unicodePropertyMap: null, ...r4 };
let o3 = n.unicodePropertyMap?.get(w2(e));
if (!o3) {
if (n.normalizeUnknownPropertyNames) o3 = de(e);
else if (n.unicodePropertyMap && !n.skipPropertyNameValidation) throw new Error(o`Invalid Unicode property "\p{${e}}"`);
}
return { type: "CharacterSet", kind: "property", value: o3 ?? e, negate: n.negate };
}
function ie({ flags: e, kind: r4, name: n, negate: o3, number: i2 }) {
switch (r4) {
case "absence_repeater":
return G("repeater");
case "atomic":
return A2({ atomic: true });
case "capturing":
return P2(i2, { name: n });
case "group":
return A2({ flags: e });
case "lookahead":
case "lookbehind":
return K2({ behind: r4 === "lookbehind", negate: o3 });
default:
throw new Error(`Unexpected group kind "${r4}"`);
}
}
function h(e) {
if (e === void 0) e = [b2()];
else if (!Array.isArray(e) || !e.length || !e.every((r4) => r4.type === "Alternative")) throw new Error("Invalid body; expected array of one or more Alternative nodes");
return e;
}
function V2(e) {
if (e === void 0) e = [];
else if (!Array.isArray(e) || !e.every((r4) => !!r4.type)) throw new Error("Invalid body; expected array of nodes");
return e;
}
function M2(e) {
return e.type === "LookaroundAssertion" && e.kind === "lookahead";
}
function $2(e) {
return e.type === "LookaroundAssertion" && e.kind === "lookbehind";
}
function se(e) {
return /^[\p{Alpha}\p{Pc}][^)]*$/u.test(e);
}
function de(e) {
return e.trim().replace(/[- _]+/g, "_").replace(/[A-Z][a-z]+(?=[A-Z])/g, "$&_").replace(/[A-Za-z]+/g, (r4) => r4[0].toUpperCase() + r4.slice(1).toLowerCase());
}
function w2(e) {
return e.replace(/[- _]+/g, "").toLowerCase();
}
function z2(e, r4) {
const n = r4;
return u(e, `Unclosed character class${n?.type === "Character" && n.value === 93 && n.raw === "]" ? ' (started with "]")' : ""}`);
}
function D2(e) {
return u(e, "Unclosed group");
}
// src/unicode.js
var asciiSpaceChar = "[ -\r ]";
var CharsWithoutIgnoreCaseExpansion = /* @__PURE__ */ new Set([
cp(304),
// İ
cp(305)
// ı
]);
var defaultWordChar = r`[\p{L}\p{M}\p{N}\p{Pc}]`;
function getIgnoreCaseMatchChars(char) {
if (CharsWithoutIgnoreCaseExpansion.has(char)) {
return [char];
}
const set = /* @__PURE__ */ new Set();
const lower = char.toLowerCase();
const upper = lower.toUpperCase();
const title = LowerToTitleCaseMap.get(lower);
const altLower = LowerToAlternativeLowerCaseMap.get(lower);
const altUpper = LowerToAlternativeUpperCaseMap.get(lower);
if ([...upper].length === 1) {
set.add(upper);
}
altUpper && set.add(altUpper);
title && set.add(title);
set.add(lower);
altLower && set.add(altLower);
return [...set];
}
var JsUnicodePropertyMap = /* @__PURE__ */ new Map(
`C Other
Cc Control cntrl
Cf Format
Cn Unassigned
Co Private_Use
Cs Surrogate
L Letter
LC Cased_Letter
Ll Lowercase_Letter
Lm Modifier_Letter
Lo Other_Letter
Lt Titlecase_Letter
Lu Uppercase_Letter
M Mark Combining_Mark
Mc Spacing_Mark
Me Enclosing_Mark
Mn Nonspacing_Mark
N Number
Nd Decimal_Number digit
Nl Letter_Number
No Other_Number
P Punctuation punct
Pc Connector_Punctuation
Pd Dash_Punctuation
Pe Close_Punctuation
Pf Final_Punctuation
Pi Initial_Punctuation
Po Other_Punctuation
Ps Open_Punctuation
S Symbol
Sc Currency_Symbol
Sk Modifier_Symbol
Sm Math_Symbol
So Other_Symbol
Z Separator
Zl Line_Separator
Zp Paragraph_Separator
Zs Space_Separator
ASCII
ASCII_Hex_Digit AHex
Alphabetic Alpha
Any
Assigned
Bidi_Control Bidi_C
Bidi_Mirrored Bidi_M
Case_Ignorable CI
Cased
Changes_When_Casefolded CWCF
Changes_When_Casemapped CWCM
Changes_When_Lowercased CWL
Changes_When_NFKC_Casefolded CWKCF
Changes_When_Titlecased CWT
Changes_When_Uppercased CWU
Dash
Default_Ignorable_Code_Point DI
Deprecated Dep
Diacritic Dia
Emoji
Emoji_Component EComp
Emoji_Modifier EMod
Emoji_Modifier_Base EBase
Emoji_Presentation EPres
Extended_Pictographic ExtPict
Extender Ext
Grapheme_Base Gr_Base
Grapheme_Extend Gr_Ext
Hex_Digit Hex
IDS_Binary_Operator IDSB
IDS_Trinary_Operator IDST
ID_Continue IDC
ID_Start IDS
Ideographic Ideo
Join_Control Join_C
Logical_Order_Exception LOE
Lowercase Lower
Math
Noncharacter_Code_Point NChar
Pattern_Syntax Pat_Syn
Pattern_White_Space Pat_WS
Quotation_Mark QMark
Radical
Regional_Indicator RI
Sentence_Terminal STerm
Soft_Dotted SD
Terminal_Punctuation Term
Unified_Ideograph UIdeo
Uppercase Upper
Variation_Selector VS
White_Space space
XID_Continue XIDC
XID_Start XIDS`.split(/\s/).map((p) => [w2(p), p])
);
var LowerToAlternativeLowerCaseMap = /* @__PURE__ */ new Map([
["s", cp(383)],
// s, ſ
[cp(383), "s"]
// ſ, s
]);
var LowerToAlternativeUpperCaseMap = /* @__PURE__ */ new Map([
[cp(223), cp(7838)],
// ß, ẞ
[cp(107), cp(8490)],
// k, K (Kelvin)
[cp(229), cp(8491)],
// å, Å (Angstrom)
[cp(969), cp(8486)]
// ω, Ω (Ohm)
]);
var LowerToTitleCaseMap = new Map([
titleEntry(453),
titleEntry(456),
titleEntry(459),
titleEntry(498),
...titleRange(8072, 8079),
...titleRange(8088, 8095),
...titleRange(8104, 8111),
titleEntry(8124),
titleEntry(8140),
titleEntry(8188)
]);
var PosixClassMap = /* @__PURE__ */ new Map([
["alnum", r`[\p{Alpha}\p{Nd}]`],
["alpha", r`\p{Alpha}`],
["ascii", r`\p{ASCII}`],
["blank", r`[\p{Zs}\t]`],
["cntrl", r`\p{Cc}`],
["digit", r`\p{Nd}`],
["graph", r`[\P{space}&&\P{Cc}&&\P{Cn}&&\P{Cs}]`],
["lower", r`\p{Lower}`],
["print", r`[[\P{space}&&\P{Cc}&&\P{Cn}&&\P{Cs}]\p{Zs}]`],
["punct", r`[\p{P}\p{S}]`],
// Updated value from Onig 6.9.9; changed from Unicode `\p{punct}`
["space", r`\p{space}`],
["upper", r`\p{Upper}`],
["word", r`[\p{Alpha}\p{M}\p{Nd}\p{Pc}]`],
["xdigit", r`\p{AHex}`]
]);
function range(start, end) {
const range2 = [];
for (let i2 = start; i2 <= end; i2++) {
range2.push(i2);
}
return range2;
}
function titleEntry(codePoint) {
const char = cp(codePoint);
return [char.toLowerCase(), char];
}
function titleRange(start, end) {
return range(start, end).map((codePoint) => titleEntry(codePoint));
}
var UnicodePropertiesWithSpecificCase = /* @__PURE__ */ new Set([
"Lower",
"Lowercase",
"Upper",
"Uppercase",
"Ll",
"Lowercase_Letter",
"Lt",
"Titlecase_Letter",
"Lu",
"Uppercase_Letter"
// The `Changes_When_*` properties (and their aliases) could be included, but they're very rare.
// Some other properties include a handful of chars with specific cases only, but these chars are
// generally extreme edge cases and using such properties case insensitively generally produces
// undesired behavior anyway
]);
// node_modules/.pnpm/oniguruma-parser@0.12.2/node_modules/oniguruma-parser/dist/traverser/traverse.js
function S(a2, v2, N = null) {
function b3(e, s2) {
for (let t = 0; t < e.length; t++) {
const r4 = n(e[t], s2, t, e);
t = Math.max(-1, t + r4);
}
}
function n(e, s2 = null, t = null, r4 = null) {
let i2 = 0, c = false;
const d2 = { node: e, parent: s2, key: t, container: r4, root: a2, remove() {
x2(r4).splice(Math.max(0, l2(t) + i2), 1), i2--, c = true;
}, removeAllNextSiblings() {
return x2(r4).splice(l2(t) + 1);
}, removeAllPrevSiblings() {
const o3 = l2(t) + i2;
return i2 -= o3, x2(r4).splice(0, Math.max(0, o3));
}, replaceWith(o3, m3 = {}) {
const y3 = !!m3.traverse;
r4 ? r4[Math.max(0, l2(t) + i2)] = o3 : u(s2, "Can't replace root node")[t] = o3, y3 && n(o3, s2, t, r4), c = true;
}, replaceWithMultiple(o3, m3 = {}) {
const y3 = !!m3.traverse;
if (x2(r4).splice(Math.max(0, l2(t) + i2), 1, ...o3), i2 += o3.length - 1, y3) {
let g = 0;
for (let p = 0; p < o3.length; p++) g += n(o3[p], s2, l2(t) + p + g, r4);
}
c = true;
}, skip() {
c = true;
} }, { type: f2 } = e, u2 = v2["*"], h2 = v2[f2], R3 = typeof u2 == "function" ? u2 : u2?.enter, P3 = typeof h2 == "function" ? h2 : h2?.enter;
if (R3?.(d2, N), P3?.(d2, N), !c) switch (f2) {
case "AbsenceFunction":
case "Alternative":
case "CapturingGroup":
case "CharacterClass":
case "Group":
case "LookaroundAssertion":
b3(e.body, e);
break;
case "Assertion":
case "Backreference":
case "Character":
case "CharacterSet":
case "Directive":
case "Flags":
case "NamedCallout":
case "Subroutine":
break;
case "CharacterClassRange":
n(e.min, e, "min"), n(e.max, e, "max");
break;
case "Quantifier":
n(e.body, e, "body");
break;
case "Regex":
b3(e.body, e), n(e.flags, e, "flags");
break;
default:
throw new Error(`Unexpected node type "${f2}"`);
}
return h2?.exit?.(d2, N), u2?.exit?.(d2, N), i2;
}
return n(a2), a2;
}
function x2(a2) {
if (!Array.isArray(a2)) throw new Error("Container expected");
return a2;
}
function l2(a2) {
if (typeof a2 != "number") throw new Error("Numeric key expected");
return a2;
}
// src/transform.js
function transform(ast, options) {
const opts = {
// A couple edge cases exist where options `accuracy` and `bestEffortTarget` are used:
// - `CharacterSet` kind `text_segment` (`\X`): An exact representation would require heavy
// Unicode data; a best-effort approximation requires knowing the target.
// - `CharacterSet` kind `posix` with values `graph` and `print`: Their complex Unicode
// representations would be hard to change to ASCII versions after the fact in the generator
// based on `target`/`accuracy`, so produce the appropriate structure here.
accuracy: "default",
asciiWordBoundaries: false,
avoidSubclass: false,
bestEffortTarget: "ES2025",
...options
};
addParentProperties(ast);
const firstPassState = {
accuracy: opts.accuracy,
asciiWordBoundaries: opts.asciiWordBoundaries,
avoidSubclass: opts.avoidSubclass,
flagDirectivesByAlt: /* @__PURE__ */ new Map(),
jsGroupNameMap: /* @__PURE__ */ new Map(),
minTargetEs2024: isMinTarget(opts.bestEffortTarget, "ES2024"),
passedLookbehind: false,
strategy: null,
// Subroutines can appear before the groups they ref, so collect reffed nodes for a second pass
subroutineRefMap: /* @__PURE__ */ new Map(),
supportedGNodes: /* @__PURE__ */ new Set(),
digitIsAscii: ast.flags.digitIsAscii,
spaceIsAscii: ast.flags.spaceIsAscii,
wordIsAscii: ast.flags.wordIsAscii
};
S(ast, FirstPassVisitor, firstPassState);
const globalFlags = {
dotAll: ast.flags.dotAll,
ignoreCase: ast.flags.ignoreCase
};
const secondPassState = {
currentFlags: globalFlags,
prevFlags: null,
globalFlags,
groupOriginByCopy: /* @__PURE__ */ new Map(),
groupsByName: /* @__PURE__ */ new Map(),
multiplexCapturesToLeftByRef: /* @__PURE__ */ new Map(),
openRefs: /* @__PURE__ */ new Map(),
reffedNodesByReferencer: /* @__PURE__ */ new Map(),
subroutineRefMap: firstPassState.subroutineRefMap
};
S(ast, SecondPassVisitor, secondPassState);
const thirdPassState = {
groupsByName: secondPassState.groupsByName,
highestOrphanBackref: 0,
numCapturesToLeft: 0,
reffedNodesByReferencer: secondPassState.reffedNodesByReferencer
};
S(ast, ThirdPassVisitor, thirdPassState);
ast._originMap = secondPassState.groupOriginByCopy;
ast._strategy = firstPassState.strategy;
return ast;
}
var FirstPassVisitor = {
AbsenceFunction({ node, parent, replaceWith }) {
const { body, kind } = node;
if (kind === "repeater") {
const innerGroup = A2();
innerGroup.body[0].body.push(
// Insert own alts as `body`
K2({ negate: true, body }),
Q2("Any")
);
const outerGroup = A2();
outerGroup.body[0].body.push(
_2("greedy", 0, Infinity, innerGroup)
);
replaceWith(setParentDeep(outerGroup, parent), { traverse: true });
} else {
throw new Error(`Unsupported absence function "(?~|"`);
}
},
Alternative: {
enter({ node, parent, key }, { flagDirectivesByAlt }) {
const flagDirectives = node.body.filter((el) => el.kind === "flags");
for (let i2 = key + 1; i2 < parent.body.length; i2++) {
const forwardSiblingAlt = parent.body[i2];
getOrInsert(flagDirectivesByAlt, forwardSiblingAlt, []).push(...flagDirectives);
}
},
exit({ node }, { flagDirectivesByAlt }) {
if (flagDirectivesByAlt.get(node)?.length) {
const flags = getCombinedFlagModsFromFlagNodes(flagDirectivesByAlt.get(node));
if (flags) {
const flagGroup = A2({ flags });
flagGroup.body[0].body = node.body;
node.body = [setParentDeep(flagGroup, node)];
}
}
}
},
Assertion({ node, parent, key, container, root, remove, replaceWith }, state) {
const { kind, negate } = node;
const { asciiWordBoundaries, avoidSubclass, supportedGNodes, wordIsAscii } = state;
if (kind === "text_segment_boundary") {
throw new Error(`Unsupported text segment boundary "\\${negate ? "Y" : "y"}"`);
} else if (kind === "line_end") {
replaceWith(setParentDeep(K2({ body: [
b2({ body: [F2("string_end")] }),
b2({ body: [m2(10)] })
// `\n`
] }), parent));
} else if (kind === "line_start") {
replaceWith(setParentDeep(parseFragment(r`(?<=\A|\n(?!\z))`, { skipLookbehindValidation: true }), parent));
} else if (kind === "search_start") {
if (supportedGNodes.has(node)) {
root.flags.sticky = true;
remove();
} else {
const prev = container[key - 1];
if (prev && isAlwaysNonZeroLength(prev)) {
replaceWith(setParentDeep(K2({ negate: true }), parent));
} else if (avoidSubclass) {
throw new Error(r`Uses "\G" in a way that requires a subclass`);
} else {
replaceWith(setParent(F2("string_start"), parent));
state.strategy = "clip_search";
}
}
} else if (kind === "string_end" || kind === "string_start") {
} else if (kind === "string_end_newline") {
replaceWith(setParentDeep(parseFragment(r`(?=\n?\z)`), parent));
} else if (kind === "word_boundary") {
if (!wordIsAscii && !asciiWordBoundaries) {
const b3 = `(?:(?<=${defaultWordChar})(?!${defaultWordChar})|(?<!${defaultWordChar})(?=${defaultWordChar}))`;
const B3 = `(?:(?<=${defaultWordChar})(?=${defaultWordChar})|(?<!${defaultWordChar})(?!${defaultWordChar}))`;
replaceWith(setParentDeep(parseFragment(negate ? B3 : b3), parent));
}
} else {
throw new Error(`Unexpected assertion kind "${kind}"`);
}
},
Backreference({ node }, { jsGroupNameMap }) {
let { ref } = node;
if (typeof ref === "string" && !isValidJsGroupName(ref)) {
ref = getAndStoreJsGroupName(ref, jsGroupNameMap);
node.ref = ref;
}
},
CapturingGroup({ node }, { jsGroupNameMap, subroutineRefMap }) {
let { name } = node;
if (name && !isValidJsGroupName(name)) {
name = getAndStoreJsGroupName(name, jsGroupNameMap);
node.name = name;
}
subroutineRefMap.set(node.number, node);
if (name) {
subroutineRefMap.set(name, node);
}
},
CharacterClassRange({ node, parent, replaceWith }) {
if (parent.kind === "intersection") {
const cc = C2({ body: [node] });
replaceWith(setParentDeep(cc, parent), { traverse: true });
}
},
CharacterSet({ node, parent, replaceWith }, { accuracy, minTargetEs2024, digitIsAscii, spaceIsAscii, wordIsAscii }) {
const { kind, negate, value } = node;
if (digitIsAscii && (kind === "digit" || value === "digit")) {
replaceWith(setParent(E2("digit", { negate }), parent));
return;
}
if (spaceIsAscii && (kind === "space" || value === "space")) {
replaceWith(setParentDeep(setNegate(parseFragment(asciiSpaceChar), negate), parent));
return;
}
if (wordIsAscii && (kind === "word" || value === "word")) {
replaceWith(setParent(E2("word", { negate }), parent));
return;
}
if (kind === "any") {
replaceWith(setParent(Q2("Any"), parent));
} else if (kind === "digit") {
replaceWith(setParent(Q2("Nd", { negate }), parent));
} else if (kind === "dot") {
} else if (kind === "text_segment") {
if (accuracy === "strict") {
throw new Error(r`Use of "\X" requires non-strict accuracy`);
}
const eBase = "\\p{Emoji}(?:\\p{EMod}|\\uFE0F\\u20E3?|[\\x{E0020}-\\x{E007E}]+\\x{E007F})?";
const emoji = r`\p{RI}{2}|${eBase}(?:\u200D${eBase})*`;
replaceWith(setParentDeep(parseFragment(
// Close approximation of an extended grapheme cluster; see <unicode.org/reports/tr29/>
r`(?>\r\n|${minTargetEs2024 ? r`\p{RGI_Emoji}` : emoji}|\P{M}\p{M}*)`,
// Allow JS property `RGI_Emoji` through
{ skipPropertyNameValidation: true }
), parent));
} else if (kind === "hex") {
replaceWith(setParent(Q2("AHex", { negate }), parent));
} else if (kind === "newline") {
replaceWith(setParentDeep(parseFragment(negate ? "[^\n]" : "(?>\r\n?|[\n\v\f\x85\u2028\u2029])"), parent));
} else if (kind === "posix") {
if (!minTargetEs2024 && (value === "graph" || value === "print")) {
if (accuracy === "strict") {
throw new Error(`POSIX class "${value}" requires min target ES2024 or non-strict accuracy`);
}
let ascii = {
graph: "!-~",
print: " -~"
}[value];
if (negate) {
ascii = `\0-${cp(ascii.codePointAt(0) - 1)}${cp(ascii.codePointAt(2) + 1)}-\u{10FFFF}`;
}
replaceWith(setParentDeep(parseFragment(`[${ascii}]`), parent));
} else {
replaceWith(setParentDeep(setNegate(parseFragment(PosixClassMap.get(value)), negate), parent));
}
} else if (kind === "property") {
if (!JsUnicodePropertyMap.has(w2(value))) {
node.key = "sc";
}
} else if (kind === "space") {
replaceWith(setParent(Q2("space", { negate }), parent));
} else if (kind === "word") {
replaceWith(setParentDeep(setNegate(parseFragment(defaultWordChar), negate), parent));
} else {
throw new Error(`Unexpected character set kind "${kind}"`);
}
},
Directive({ node, parent, root, remove,