humanifyjs
Version:
> Deobfuscate Javascript code using LLMs ("AI")
1,239 lines (1,211 loc) • 1.84 MB
JavaScript
#!/usr/bin/env node
import fs from 'fs/promises';
import fs6, { existsSync, realpathSync, statSync } from 'fs';
import * as path9 from 'path';
import path9__default, { join as join$1, basename, dirname } from 'path';
import os, { homedir } from 'os';
import { Llama3_1ChatWrapper, getLlama, LlamaChatSession, LlamaGrammar } from 'node-llama-cpp';
import { downloadFile } from 'ipull';
import { Command } from 'commander';
import { webcrack as webcrack$1 } from 'webcrack';
import { createRequire, builtinModules } from 'module';
import url$1, { fileURLToPath, pathToFileURL, URL as URL$1 } from 'url';
import process3 from 'process';
import tty from 'tty';
import assert2 from 'assert';
import v8 from 'v8';
import require$$1, { format, inspect } from 'util';
import * as require$$0$1 from '@babel/types';
import require$$0__default, { toIdentifier } from '@babel/types';
import { transform, parseAsync, transformFromAstAsync } from '@babel/core';
import bautifier from 'babel-plugin-transform-beautifier';
import OpenAI from 'openai';
import dotenv from 'dotenv';
import { GoogleGenerativeAI, SchemaType } from '@google/generative-ai';
var version = "2.2.2";
function url(strings, ...values) {
return new URL(String.raw(strings, ...values));
}
function err(message, exitCode = 1) {
console.error(`\x1B[31m${message}\x1B[0m`);
process.exit(exitCode);
}
const verbose = {
log(...args) {
if (this.enabled) {
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/T/, " ").replace(/\..+/, "");
console.log(`[${timestamp}] `, ...args);
}
},
enabled: process.env["CI"] === "true"
};
const MODEL_DIRECTORY = join$1(homedir(), ".humanifyjs", "models");
const MODELS = {
"2b": {
url: url`https://huggingface.co/bartowski/Phi-3.1-mini-4k-instruct-GGUF/resolve/main/Phi-3.1-mini-4k-instruct-Q4_K_M.gguf?download=true`
},
"8b": {
url: url`https://huggingface.co/lmstudio-community/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf?download=true`,
wrapper: new Llama3_1ChatWrapper()
}
};
async function ensureModelDirectory() {
await fs.mkdir(MODEL_DIRECTORY, { recursive: true });
}
function getModelWrapper(model) {
if (!(model in MODELS)) {
err(`Model ${model} not found`);
}
return MODELS[model].wrapper;
}
async function downloadModel(model) {
await ensureModelDirectory();
const url2 = MODELS[model].url;
if (url2 === void 0) {
err(`Model ${model} not found`);
}
const path = getModelPath(model);
if (existsSync(path)) {
console.log(`Model "${model}" already downloaded`);
return;
}
const tmpPath = `${path}.part`;
const downlaoder = await downloadFile({
url: url2.toString(),
savePath: tmpPath,
cliProgress: true,
cliStyle: verbose.enabled ? "ci" : "auto"
});
await downlaoder.download();
await fs.rename(tmpPath, path);
console.log(`Model "${model}" downloaded to ${path}`);
}
const DEFAULT_MODEL = Object.keys(MODELS)[0];
function getModelPath(model) {
if (!(model in MODELS)) {
err(`Model ${model} not found`);
}
const filename = basename(MODELS[model].url.pathname);
return `${MODEL_DIRECTORY}/${filename}`;
}
function cli() {
const command = new Command();
command.showHelpAfterError(true).showSuggestionAfterError(false);
return command;
}
function download() {
const command = cli().name("download").description("Download supported models for local consumption");
for (const model in MODELS) {
command.command(model).description(`Download the ${model} model`).option("-v, --verbose", "Show verbose output").action((opts) => {
if (opts.verbose) {
verbose.enabled = true;
}
downloadModel(model);
});
}
return command;
}
const IS_CI = process.env["CI"] === "true";
async function llama(opts) {
var _a;
const disableGpu = (_a = opts.disableGpu) != null ? _a : IS_CI;
const llama2 = await getLlama({ gpu: disableGpu ? false : "auto" });
const modelOpts = {
modelPath: getModelPath(opts == null ? void 0 : opts.model),
gpuLayers: disableGpu ? 0 : void 0
};
verbose.log("Loading model with options", modelOpts);
const model = await llama2.loadModel(modelOpts);
const context = await model.createContext({ seed: opts == null ? void 0 : opts.seed });
return async (systemPrompt, userPrompt, responseGrammar) => {
const session = new LlamaChatSession({
contextSequence: context.getSequence(),
autoDisposeSequence: true,
systemPrompt,
chatWrapper: getModelWrapper(opts.model)
});
const response = await session.promptWithMeta(userPrompt, {
temperature: 0.8,
grammar: new LlamaGrammar(llama2, {
grammar: `${responseGrammar}`
}),
stopOnAbortSignal: true
});
session.dispose();
return responseGrammar.parseResult(response.responseText);
};
}
function ensureFileExists(filename) {
if (!existsSync(filename)) {
err(`File ${filename} not found`);
}
}
async function webcrack(code, outputDir) {
const cracked = await webcrack$1(code);
await cracked.save(outputDir);
const output = await fs.readdir(outputDir);
return output.filter((file) => file.endsWith(".js")).map((file) => ({ path: path9__default.join(outputDir, file) }));
}
async function unminify(filename, outputDir, plugins = []) {
ensureFileExists(filename);
const bundledCode = await fs.readFile(filename, "utf-8");
const extractedFiles = await webcrack(bundledCode, outputDir);
for (let i = 0; i < extractedFiles.length; i++) {
console.log(`Processing file ${i + 1}/${extractedFiles.length}`);
const file = extractedFiles[i];
const code = await fs.readFile(file.path, "utf-8");
if (code.trim().length === 0) {
verbose.log(`Skipping empty file ${file.path}`);
continue;
}
const formattedCode = await plugins.reduce(
(p, next) => p.then(next),
Promise.resolve(code)
);
verbose.log("Input: ", code);
verbose.log("Output: ", formattedCode);
await fs.writeFile(file.path, formattedCode);
}
console.log(`Done! You can find your unminified code in ${outputDir}`);
}
var __defProp$2 = Object.defineProperty;
var __export$1 = (target, all) => {
for (var name in all)
__defProp$2(target, name, { get: all[name], enumerable: true });
};
// src/document/public.js
var public_exports$1 = {};
__export$1(public_exports$1, {
builders: () => builders,
printer: () => printer$1,
utils: () => utils
});
// src/document/constants.js
var DOC_TYPE_STRING$1 = "string";
var DOC_TYPE_ARRAY$1 = "array";
var DOC_TYPE_CURSOR$1 = "cursor";
var DOC_TYPE_INDENT$1 = "indent";
var DOC_TYPE_ALIGN$1 = "align";
var DOC_TYPE_TRIM$1 = "trim";
var DOC_TYPE_GROUP$1 = "group";
var DOC_TYPE_FILL$1 = "fill";
var DOC_TYPE_IF_BREAK$1 = "if-break";
var DOC_TYPE_INDENT_IF_BREAK$1 = "indent-if-break";
var DOC_TYPE_LINE_SUFFIX$1 = "line-suffix";
var DOC_TYPE_LINE_SUFFIX_BOUNDARY$1 = "line-suffix-boundary";
var DOC_TYPE_LINE$1 = "line";
var DOC_TYPE_LABEL$1 = "label";
var DOC_TYPE_BREAK_PARENT$1 = "break-parent";
var VALID_OBJECT_DOC_TYPES$1 = /* @__PURE__ */ new Set([
DOC_TYPE_CURSOR$1,
DOC_TYPE_INDENT$1,
DOC_TYPE_ALIGN$1,
DOC_TYPE_TRIM$1,
DOC_TYPE_GROUP$1,
DOC_TYPE_FILL$1,
DOC_TYPE_IF_BREAK$1,
DOC_TYPE_INDENT_IF_BREAK$1,
DOC_TYPE_LINE_SUFFIX$1,
DOC_TYPE_LINE_SUFFIX_BOUNDARY$1,
DOC_TYPE_LINE$1,
DOC_TYPE_LABEL$1,
DOC_TYPE_BREAK_PARENT$1
]);
// src/document/utils/get-doc-type.js
function getDocType$1(doc) {
if (typeof doc === "string") {
return DOC_TYPE_STRING$1;
}
if (Array.isArray(doc)) {
return DOC_TYPE_ARRAY$1;
}
if (!doc) {
return;
}
const { type } = doc;
if (VALID_OBJECT_DOC_TYPES$1.has(type)) {
return type;
}
}
var get_doc_type_default$1 = getDocType$1;
// src/document/invalid-doc-error.js
var disjunctionListFormat$1 = (list) => new Intl.ListFormat("en-US", { type: "disjunction" }).format(list);
function getDocErrorMessage$1(doc) {
const type = doc === null ? "null" : typeof doc;
if (type !== "string" && type !== "object") {
return `Unexpected doc '${type}',
Expected it to be 'string' or 'object'.`;
}
if (get_doc_type_default$1(doc)) {
throw new Error("doc is valid.");
}
const objectType = Object.prototype.toString.call(doc);
if (objectType !== "[object Object]") {
return `Unexpected doc '${objectType}'.`;
}
const EXPECTED_TYPE_VALUES = disjunctionListFormat$1(
[...VALID_OBJECT_DOC_TYPES$1].map((type2) => `'${type2}'`)
);
return `Unexpected doc.type '${doc.type}'.
Expected it to be ${EXPECTED_TYPE_VALUES}.`;
}
var InvalidDocError$1 = class InvalidDocError extends Error {
name = "InvalidDocError";
constructor(doc) {
super(getDocErrorMessage$1(doc));
this.doc = doc;
}
};
var invalid_doc_error_default$1 = InvalidDocError$1;
// src/document/utils/traverse-doc.js
var traverseDocOnExitStackMarker$1 = {};
function traverseDoc$1(doc, onEnter, onExit, shouldTraverseConditionalGroups) {
const docsStack = [doc];
while (docsStack.length > 0) {
const doc2 = docsStack.pop();
if (doc2 === traverseDocOnExitStackMarker$1) {
onExit(docsStack.pop());
continue;
}
if (onExit) {
docsStack.push(doc2, traverseDocOnExitStackMarker$1);
}
const docType = get_doc_type_default$1(doc2);
if (!docType) {
throw new invalid_doc_error_default$1(doc2);
}
if ((onEnter == null ? void 0 : onEnter(doc2)) === false) {
continue;
}
switch (docType) {
case DOC_TYPE_ARRAY$1:
case DOC_TYPE_FILL$1: {
const parts = docType === DOC_TYPE_ARRAY$1 ? doc2 : doc2.parts;
for (let ic = parts.length, i = ic - 1; i >= 0; --i) {
docsStack.push(parts[i]);
}
break;
}
case DOC_TYPE_IF_BREAK$1:
docsStack.push(doc2.flatContents, doc2.breakContents);
break;
case DOC_TYPE_GROUP$1:
if (shouldTraverseConditionalGroups && doc2.expandedStates) {
for (let ic = doc2.expandedStates.length, i = ic - 1; i >= 0; --i) {
docsStack.push(doc2.expandedStates[i]);
}
} else {
docsStack.push(doc2.contents);
}
break;
case DOC_TYPE_ALIGN$1:
case DOC_TYPE_INDENT$1:
case DOC_TYPE_INDENT_IF_BREAK$1:
case DOC_TYPE_LABEL$1:
case DOC_TYPE_LINE_SUFFIX$1:
docsStack.push(doc2.contents);
break;
case DOC_TYPE_STRING$1:
case DOC_TYPE_CURSOR$1:
case DOC_TYPE_TRIM$1:
case DOC_TYPE_LINE_SUFFIX_BOUNDARY$1:
case DOC_TYPE_LINE$1:
case DOC_TYPE_BREAK_PARENT$1:
break;
default:
throw new invalid_doc_error_default$1(doc2);
}
}
}
var traverse_doc_default$1 = traverseDoc$1;
// src/document/utils/assert-doc.js
var noop = () => {
};
var assertDocArray = noop ;
// src/document/builders.js
function indent$1(contents) {
return { type: DOC_TYPE_INDENT$1, contents };
}
function align$1(widthOrString, contents) {
return { type: DOC_TYPE_ALIGN$1, contents, n: widthOrString };
}
function group(contents, opts = {}) {
assertDocArray(
opts.expandedStates);
return {
type: DOC_TYPE_GROUP$1,
id: opts.id,
contents,
break: Boolean(opts.shouldBreak),
expandedStates: opts.expandedStates
};
}
function dedentToRoot(contents) {
return align$1(Number.NEGATIVE_INFINITY, contents);
}
function markAsRoot(contents) {
return align$1({ type: "root" }, contents);
}
function dedent(contents) {
return align$1(-1, contents);
}
function conditionalGroup(states, opts) {
return group(states[0], { ...opts, expandedStates: states });
}
function fill$1(parts) {
return { type: DOC_TYPE_FILL$1, parts };
}
function ifBreak(breakContents, flatContents = "", opts = {}) {
return {
type: DOC_TYPE_IF_BREAK$1,
breakContents,
flatContents,
groupId: opts.groupId
};
}
function indentIfBreak(contents, opts) {
return {
type: DOC_TYPE_INDENT_IF_BREAK$1,
contents,
groupId: opts.groupId,
negate: opts.negate
};
}
function lineSuffix$1(contents) {
return { type: DOC_TYPE_LINE_SUFFIX$1, contents };
}
var lineSuffixBoundary = { type: DOC_TYPE_LINE_SUFFIX_BOUNDARY$1 };
var breakParent$1 = { type: DOC_TYPE_BREAK_PARENT$1 };
var trim$1 = { type: DOC_TYPE_TRIM$1 };
var hardlineWithoutBreakParent$1 = { type: DOC_TYPE_LINE$1, hard: true };
var literallineWithoutBreakParent = {
type: DOC_TYPE_LINE$1,
hard: true,
literal: true
};
var line$1 = { type: DOC_TYPE_LINE$1 };
var softline = { type: DOC_TYPE_LINE$1, soft: true };
var hardline$1 = [hardlineWithoutBreakParent$1, breakParent$1];
var literalline = [literallineWithoutBreakParent, breakParent$1];
var cursor$1 = { type: DOC_TYPE_CURSOR$1 };
function join(separator, docs) {
const parts = [];
for (let i = 0; i < docs.length; i++) {
if (i !== 0) {
parts.push(separator);
}
parts.push(docs[i]);
}
return parts;
}
function addAlignmentToDoc$1(doc, size, tabWidth) {
let aligned = doc;
if (size > 0) {
for (let i = 0; i < Math.floor(size / tabWidth); ++i) {
aligned = indent$1(aligned);
}
aligned = align$1(size % tabWidth, aligned);
aligned = align$1(Number.NEGATIVE_INFINITY, aligned);
}
return aligned;
}
function label(label2, contents) {
return label2 ? { type: DOC_TYPE_LABEL$1, label: label2, contents } : contents;
}
// scripts/build/shims/at.js
var at$1 = (isOptionalObject, object, index) => {
if (isOptionalObject && (object === void 0 || object === null)) {
return;
}
if (Array.isArray(object) || typeof object === "string") {
return object[index < 0 ? object.length + index : index];
}
return object.at(index);
};
var at_default$1 = at$1;
// scripts/build/shims/string-replace-all.js
var stringReplaceAll$1 = (isOptionalObject, original, pattern, replacement) => {
if (isOptionalObject && (original === void 0 || original === null)) {
return;
}
if (original.replaceAll) {
return original.replaceAll(pattern, replacement);
}
if (pattern.global) {
return original.replace(pattern, replacement);
}
return original.split(pattern).join(replacement);
};
var string_replace_all_default$1 = stringReplaceAll$1;
// src/common/end-of-line.js
function convertEndOfLineToChars$1(value) {
switch (value) {
case "cr":
return "\r";
case "crlf":
return "\r\n";
default:
return "\n";
}
}
// node_modules/emoji-regex/index.mjs
var emoji_regex_default$1 = () => {
return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
};
// node_modules/get-east-asian-width/lookup.js
function isFullWidth$1(x) {
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
}
function isWide$1(x) {
return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9800 && x <= 9811 || x === 9855 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 19968 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x === 94192 || x === 94193 || x >= 94208 && x <= 100343 || x >= 100352 && x <= 101589 || x >= 101632 && x <= 101640 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128727 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129672 || x >= 129680 && x <= 129725 || x >= 129727 && x <= 129733 || x >= 129742 && x <= 129755 || x >= 129760 && x <= 129768 || x >= 129776 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
}
// node_modules/get-east-asian-width/index.js
var _isNarrowWidth$1 = (codePoint) => !(isFullWidth$1(codePoint) || isWide$1(codePoint));
// src/utils/get-string-width.js
var notAsciiRegex$1 = /[^\x20-\x7F]/u;
function getStringWidth$1(text) {
if (!text) {
return 0;
}
if (!notAsciiRegex$1.test(text)) {
return text.length;
}
text = text.replace(emoji_regex_default$1(), " ");
let width = 0;
for (const character of text) {
const codePoint = character.codePointAt(0);
if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
continue;
}
if (codePoint >= 768 && codePoint <= 879) {
continue;
}
width += _isNarrowWidth$1(codePoint) ? 1 : 2;
}
return width;
}
var get_string_width_default$1 = getStringWidth$1;
// src/document/utils.js
function mapDoc$1(doc, cb) {
if (typeof doc === "string") {
return cb(doc);
}
const mapped = /* @__PURE__ */ new Map();
return rec(doc);
function rec(doc2) {
if (mapped.has(doc2)) {
return mapped.get(doc2);
}
const result = process2(doc2);
mapped.set(doc2, result);
return result;
}
function process2(doc2) {
switch (get_doc_type_default$1(doc2)) {
case DOC_TYPE_ARRAY$1:
return cb(doc2.map(rec));
case DOC_TYPE_FILL$1:
return cb({
...doc2,
parts: doc2.parts.map(rec)
});
case DOC_TYPE_IF_BREAK$1:
return cb({
...doc2,
breakContents: rec(doc2.breakContents),
flatContents: rec(doc2.flatContents)
});
case DOC_TYPE_GROUP$1: {
let {
expandedStates,
contents
} = doc2;
if (expandedStates) {
expandedStates = expandedStates.map(rec);
contents = expandedStates[0];
} else {
contents = rec(contents);
}
return cb({
...doc2,
contents,
expandedStates
});
}
case DOC_TYPE_ALIGN$1:
case DOC_TYPE_INDENT$1:
case DOC_TYPE_INDENT_IF_BREAK$1:
case DOC_TYPE_LABEL$1:
case DOC_TYPE_LINE_SUFFIX$1:
return cb({
...doc2,
contents: rec(doc2.contents)
});
case DOC_TYPE_STRING$1:
case DOC_TYPE_CURSOR$1:
case DOC_TYPE_TRIM$1:
case DOC_TYPE_LINE_SUFFIX_BOUNDARY$1:
case DOC_TYPE_LINE$1:
case DOC_TYPE_BREAK_PARENT$1:
return cb(doc2);
default:
throw new invalid_doc_error_default$1(doc2);
}
}
}
function findInDoc(doc, fn, defaultValue) {
let result = defaultValue;
let shouldSkipFurtherProcessing = false;
function findInDocOnEnterFn(doc2) {
if (shouldSkipFurtherProcessing) {
return false;
}
const maybeResult = fn(doc2);
if (maybeResult !== void 0) {
shouldSkipFurtherProcessing = true;
result = maybeResult;
}
}
traverse_doc_default$1(doc, findInDocOnEnterFn);
return result;
}
function willBreakFn(doc) {
if (doc.type === DOC_TYPE_GROUP$1 && doc.break) {
return true;
}
if (doc.type === DOC_TYPE_LINE$1 && doc.hard) {
return true;
}
if (doc.type === DOC_TYPE_BREAK_PARENT$1) {
return true;
}
}
function willBreak(doc) {
return findInDoc(doc, willBreakFn, false);
}
function breakParentGroup$1(groupStack) {
if (groupStack.length > 0) {
const parentGroup = at_default$1(
/* isOptionalObject */
false,
groupStack,
-1
);
if (!parentGroup.expandedStates && !parentGroup.break) {
parentGroup.break = "propagated";
}
}
return null;
}
function propagateBreaks$1(doc) {
const alreadyVisitedSet = /* @__PURE__ */ new Set();
const groupStack = [];
function propagateBreaksOnEnterFn(doc2) {
if (doc2.type === DOC_TYPE_BREAK_PARENT$1) {
breakParentGroup$1(groupStack);
}
if (doc2.type === DOC_TYPE_GROUP$1) {
groupStack.push(doc2);
if (alreadyVisitedSet.has(doc2)) {
return false;
}
alreadyVisitedSet.add(doc2);
}
}
function propagateBreaksOnExitFn(doc2) {
if (doc2.type === DOC_TYPE_GROUP$1) {
const group2 = groupStack.pop();
if (group2.break) {
breakParentGroup$1(groupStack);
}
}
}
traverse_doc_default$1(
doc,
propagateBreaksOnEnterFn,
propagateBreaksOnExitFn,
/* shouldTraverseConditionalGroups */
true
);
}
function removeLinesFn(doc) {
if (doc.type === DOC_TYPE_LINE$1 && !doc.hard) {
return doc.soft ? "" : " ";
}
if (doc.type === DOC_TYPE_IF_BREAK$1) {
return doc.flatContents;
}
return doc;
}
function removeLines(doc) {
return mapDoc$1(doc, removeLinesFn);
}
function stripTrailingHardlineFromParts$1(parts) {
parts = [...parts];
while (parts.length >= 2 && at_default$1(
/* isOptionalObject */
false,
parts,
-2
).type === DOC_TYPE_LINE$1 && at_default$1(
/* isOptionalObject */
false,
parts,
-1
).type === DOC_TYPE_BREAK_PARENT$1) {
parts.length -= 2;
}
if (parts.length > 0) {
const lastPart = stripTrailingHardlineFromDoc$1(at_default$1(
/* isOptionalObject */
false,
parts,
-1
));
parts[parts.length - 1] = lastPart;
}
return parts;
}
function stripTrailingHardlineFromDoc$1(doc) {
switch (get_doc_type_default$1(doc)) {
case DOC_TYPE_INDENT$1:
case DOC_TYPE_INDENT_IF_BREAK$1:
case DOC_TYPE_GROUP$1:
case DOC_TYPE_LINE_SUFFIX$1:
case DOC_TYPE_LABEL$1: {
const contents = stripTrailingHardlineFromDoc$1(doc.contents);
return {
...doc,
contents
};
}
case DOC_TYPE_IF_BREAK$1:
return {
...doc,
breakContents: stripTrailingHardlineFromDoc$1(doc.breakContents),
flatContents: stripTrailingHardlineFromDoc$1(doc.flatContents)
};
case DOC_TYPE_FILL$1:
return {
...doc,
parts: stripTrailingHardlineFromParts$1(doc.parts)
};
case DOC_TYPE_ARRAY$1:
return stripTrailingHardlineFromParts$1(doc);
case DOC_TYPE_STRING$1:
return doc.replace(/[\n\r]*$/u, "");
case DOC_TYPE_ALIGN$1:
case DOC_TYPE_CURSOR$1:
case DOC_TYPE_TRIM$1:
case DOC_TYPE_LINE_SUFFIX_BOUNDARY$1:
case DOC_TYPE_LINE$1:
case DOC_TYPE_BREAK_PARENT$1:
break;
default:
throw new invalid_doc_error_default$1(doc);
}
return doc;
}
function stripTrailingHardline$1(doc) {
return stripTrailingHardlineFromDoc$1(cleanDoc$1(doc));
}
function cleanDocFn$1(doc) {
switch (get_doc_type_default$1(doc)) {
case DOC_TYPE_FILL$1:
if (doc.parts.every((part) => part === "")) {
return "";
}
break;
case DOC_TYPE_GROUP$1:
if (!doc.contents && !doc.id && !doc.break && !doc.expandedStates) {
return "";
}
if (doc.contents.type === DOC_TYPE_GROUP$1 && doc.contents.id === doc.id && doc.contents.break === doc.break && doc.contents.expandedStates === doc.expandedStates) {
return doc.contents;
}
break;
case DOC_TYPE_ALIGN$1:
case DOC_TYPE_INDENT$1:
case DOC_TYPE_INDENT_IF_BREAK$1:
case DOC_TYPE_LINE_SUFFIX$1:
if (!doc.contents) {
return "";
}
break;
case DOC_TYPE_IF_BREAK$1:
if (!doc.flatContents && !doc.breakContents) {
return "";
}
break;
case DOC_TYPE_ARRAY$1: {
const parts = [];
for (const part of doc) {
if (!part) {
continue;
}
const [currentPart, ...restParts] = Array.isArray(part) ? part : [part];
if (typeof currentPart === "string" && typeof at_default$1(
/* isOptionalObject */
false,
parts,
-1
) === "string") {
parts[parts.length - 1] += currentPart;
} else {
parts.push(currentPart);
}
parts.push(...restParts);
}
if (parts.length === 0) {
return "";
}
if (parts.length === 1) {
return parts[0];
}
return parts;
}
case DOC_TYPE_STRING$1:
case DOC_TYPE_CURSOR$1:
case DOC_TYPE_TRIM$1:
case DOC_TYPE_LINE_SUFFIX_BOUNDARY$1:
case DOC_TYPE_LINE$1:
case DOC_TYPE_LABEL$1:
case DOC_TYPE_BREAK_PARENT$1:
break;
default:
throw new invalid_doc_error_default$1(doc);
}
return doc;
}
function cleanDoc$1(doc) {
return mapDoc$1(doc, (currentDoc) => cleanDocFn$1(currentDoc));
}
function replaceEndOfLine(doc, replacement = literalline) {
return mapDoc$1(doc, (currentDoc) => typeof currentDoc === "string" ? join(replacement, currentDoc.split("\n")) : currentDoc);
}
function canBreakFn(doc) {
if (doc.type === DOC_TYPE_LINE$1) {
return true;
}
}
function canBreak(doc) {
return findInDoc(doc, canBreakFn, false);
}
// src/document/printer.js
var MODE_BREAK$1 = Symbol("MODE_BREAK");
var MODE_FLAT$1 = Symbol("MODE_FLAT");
var CURSOR_PLACEHOLDER$1 = Symbol("cursor");
function rootIndent$1() {
return {
value: "",
length: 0,
queue: []
};
}
function makeIndent$1(ind, options) {
return generateInd$1(ind, {
type: "indent"
}, options);
}
function makeAlign$1(indent2, widthOrDoc, options) {
if (widthOrDoc === Number.NEGATIVE_INFINITY) {
return indent2.root || rootIndent$1();
}
if (widthOrDoc < 0) {
return generateInd$1(indent2, {
type: "dedent"
}, options);
}
if (!widthOrDoc) {
return indent2;
}
if (widthOrDoc.type === "root") {
return {
...indent2,
root: indent2
};
}
const alignType = typeof widthOrDoc === "string" ? "stringAlign" : "numberAlign";
return generateInd$1(indent2, {
type: alignType,
n: widthOrDoc
}, options);
}
function generateInd$1(ind, newPart, options) {
const queue = newPart.type === "dedent" ? ind.queue.slice(0, -1) : [...ind.queue, newPart];
let value = "";
let length = 0;
let lastTabs = 0;
let lastSpaces = 0;
for (const part of queue) {
switch (part.type) {
case "indent":
flush();
if (options.useTabs) {
addTabs(1);
} else {
addSpaces(options.tabWidth);
}
break;
case "stringAlign":
flush();
value += part.n;
length += part.n.length;
break;
case "numberAlign":
lastTabs += 1;
lastSpaces += part.n;
break;
default:
throw new Error(`Unexpected type '${part.type}'`);
}
}
flushSpaces();
return {
...ind,
value,
length,
queue
};
function addTabs(count) {
value += " ".repeat(count);
length += options.tabWidth * count;
}
function addSpaces(count) {
value += " ".repeat(count);
length += count;
}
function flush() {
if (options.useTabs) {
flushTabs();
} else {
flushSpaces();
}
}
function flushTabs() {
if (lastTabs > 0) {
addTabs(lastTabs);
}
resetLast();
}
function flushSpaces() {
if (lastSpaces > 0) {
addSpaces(lastSpaces);
}
resetLast();
}
function resetLast() {
lastTabs = 0;
lastSpaces = 0;
}
}
function trim2(out) {
let trimCount = 0;
let cursorCount = 0;
let outIndex = out.length;
outer: while (outIndex--) {
const last = out[outIndex];
if (last === CURSOR_PLACEHOLDER$1) {
cursorCount++;
continue;
}
for (let charIndex = last.length - 1; charIndex >= 0; charIndex--) {
const char = last[charIndex];
if (char === " " || char === " ") {
trimCount++;
} else {
out[outIndex] = last.slice(0, charIndex + 1);
break outer;
}
}
}
if (trimCount > 0 || cursorCount > 0) {
out.length = outIndex + 1;
while (cursorCount-- > 0) {
out.push(CURSOR_PLACEHOLDER$1);
}
}
return trimCount;
}
function fits$1(next, restCommands, width, hasLineSuffix, groupModeMap, mustBeFlat) {
if (width === Number.POSITIVE_INFINITY) {
return true;
}
let restIdx = restCommands.length;
const cmds = [next];
const out = [];
while (width >= 0) {
if (cmds.length === 0) {
if (restIdx === 0) {
return true;
}
cmds.push(restCommands[--restIdx]);
continue;
}
const {
mode,
doc
} = cmds.pop();
const docType = get_doc_type_default$1(doc);
switch (docType) {
case DOC_TYPE_STRING$1:
out.push(doc);
width -= get_string_width_default$1(doc);
break;
case DOC_TYPE_ARRAY$1:
case DOC_TYPE_FILL$1: {
const parts = docType === DOC_TYPE_ARRAY$1 ? doc : doc.parts;
for (let i = parts.length - 1; i >= 0; i--) {
cmds.push({
mode,
doc: parts[i]
});
}
break;
}
case DOC_TYPE_INDENT$1:
case DOC_TYPE_ALIGN$1:
case DOC_TYPE_INDENT_IF_BREAK$1:
case DOC_TYPE_LABEL$1:
cmds.push({
mode,
doc: doc.contents
});
break;
case DOC_TYPE_TRIM$1:
width += trim2(out);
break;
case DOC_TYPE_GROUP$1: {
if (mustBeFlat && doc.break) {
return false;
}
const groupMode = doc.break ? MODE_BREAK$1 : mode;
const contents = doc.expandedStates && groupMode === MODE_BREAK$1 ? at_default$1(
/* isOptionalObject */
false,
doc.expandedStates,
-1
) : doc.contents;
cmds.push({
mode: groupMode,
doc: contents
});
break;
}
case DOC_TYPE_IF_BREAK$1: {
const groupMode = doc.groupId ? groupModeMap[doc.groupId] || MODE_FLAT$1 : mode;
const contents = groupMode === MODE_BREAK$1 ? doc.breakContents : doc.flatContents;
if (contents) {
cmds.push({
mode,
doc: contents
});
}
break;
}
case DOC_TYPE_LINE$1:
if (mode === MODE_BREAK$1 || doc.hard) {
return true;
}
if (!doc.soft) {
out.push(" ");
width--;
}
break;
case DOC_TYPE_LINE_SUFFIX$1:
hasLineSuffix = true;
break;
case DOC_TYPE_LINE_SUFFIX_BOUNDARY$1:
if (hasLineSuffix) {
return false;
}
break;
}
}
return false;
}
function printDocToString$1(doc, options) {
const groupModeMap = {};
const width = options.printWidth;
const newLine = convertEndOfLineToChars$1(options.endOfLine);
let pos = 0;
const cmds = [{
ind: rootIndent$1(),
mode: MODE_BREAK$1,
doc
}];
const out = [];
let shouldRemeasure = false;
const lineSuffix2 = [];
let printedCursorCount = 0;
propagateBreaks$1(doc);
while (cmds.length > 0) {
const {
ind,
mode,
doc: doc2
} = cmds.pop();
switch (get_doc_type_default$1(doc2)) {
case DOC_TYPE_STRING$1: {
const formatted = newLine !== "\n" ? string_replace_all_default$1(
/* isOptionalObject */
false,
doc2,
"\n",
newLine
) : doc2;
out.push(formatted);
if (cmds.length > 0) {
pos += get_string_width_default$1(formatted);
}
break;
}
case DOC_TYPE_ARRAY$1:
for (let i = doc2.length - 1; i >= 0; i--) {
cmds.push({
ind,
mode,
doc: doc2[i]
});
}
break;
case DOC_TYPE_CURSOR$1:
if (printedCursorCount >= 2) {
throw new Error("There are too many 'cursor' in doc.");
}
out.push(CURSOR_PLACEHOLDER$1);
printedCursorCount++;
break;
case DOC_TYPE_INDENT$1:
cmds.push({
ind: makeIndent$1(ind, options),
mode,
doc: doc2.contents
});
break;
case DOC_TYPE_ALIGN$1:
cmds.push({
ind: makeAlign$1(ind, doc2.n, options),
mode,
doc: doc2.contents
});
break;
case DOC_TYPE_TRIM$1:
pos -= trim2(out);
break;
case DOC_TYPE_GROUP$1:
switch (mode) {
case MODE_FLAT$1:
if (!shouldRemeasure) {
cmds.push({
ind,
mode: doc2.break ? MODE_BREAK$1 : MODE_FLAT$1,
doc: doc2.contents
});
break;
}
case MODE_BREAK$1: {
shouldRemeasure = false;
const next = {
ind,
mode: MODE_FLAT$1,
doc: doc2.contents
};
const rem = width - pos;
const hasLineSuffix = lineSuffix2.length > 0;
if (!doc2.break && fits$1(next, cmds, rem, hasLineSuffix, groupModeMap)) {
cmds.push(next);
} else {
if (doc2.expandedStates) {
const mostExpanded = at_default$1(
/* isOptionalObject */
false,
doc2.expandedStates,
-1
);
if (doc2.break) {
cmds.push({
ind,
mode: MODE_BREAK$1,
doc: mostExpanded
});
break;
} else {
for (let i = 1; i < doc2.expandedStates.length + 1; i++) {
if (i >= doc2.expandedStates.length) {
cmds.push({
ind,
mode: MODE_BREAK$1,
doc: mostExpanded
});
break;
} else {
const state = doc2.expandedStates[i];
const cmd = {
ind,
mode: MODE_FLAT$1,
doc: state
};
if (fits$1(cmd, cmds, rem, hasLineSuffix, groupModeMap)) {
cmds.push(cmd);
break;
}
}
}
}
} else {
cmds.push({
ind,
mode: MODE_BREAK$1,
doc: doc2.contents
});
}
}
break;
}
}
if (doc2.id) {
groupModeMap[doc2.id] = at_default$1(
/* isOptionalObject */
false,
cmds,
-1
).mode;
}
break;
case DOC_TYPE_FILL$1: {
const rem = width - pos;
const {
parts
} = doc2;
if (parts.length === 0) {
break;
}
const [content, whitespace] = parts;
const contentFlatCmd = {
ind,
mode: MODE_FLAT$1,
doc: content
};
const contentBreakCmd = {
ind,
mode: MODE_BREAK$1,
doc: content
};
const contentFits = fits$1(contentFlatCmd, [], rem, lineSuffix2.length > 0, groupModeMap, true);
if (parts.length === 1) {
if (contentFits) {
cmds.push(contentFlatCmd);
} else {
cmds.push(contentBreakCmd);
}
break;
}
const whitespaceFlatCmd = {
ind,
mode: MODE_FLAT$1,
doc: whitespace
};
const whitespaceBreakCmd = {
ind,
mode: