import { EOL } from "node:os";
import { MustacheTypes, TagTypes, Tokenizer } from "edge-lexer";
import { generate } from "astring";
import { EdgeError } from "edge-error";
import { parse } from "acorn";
import stringify from "js-stringify";
//#region \0rolldown/runtime.js
var __defProp = Object.defineProperty;
var __exportAll = (all, no_symbols) => {
	let target = {};
	for (var name in all) __defProp(target, name, {
		get: all[name],
		enumerable: true
	});
	if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
	return target;
};
//#endregion
//#region src/stack/index.ts
/**
* Stack exposes the API to define variables and scopes. This is used by the parser
* to decide the syntax for resolving variables.
*/
var Stack = class {
	#localVariables = [];
	#scopes = [];
	/**
	* Returns the recent scope of the local variables array
	*/
	#getRecentScope() {
		return this.#scopes.length ? this.#scopes[this.#scopes.length - 1] : this.#localVariables;
	}
	/**
	* Finds item inside the list or `needle in haystack`
	*/
	#isInList(list, item) {
		return !!list.find((listItem) => listItem === item);
	}
	/**
	* Define a new custom scope
	*/
	defineScope() {
		this.#scopes.push([]);
	}
	/**
	* Clear recently created scope
	*/
	clearScope() {
		this.#scopes.pop();
	}
	/**
	* Define variable inside the stack.
	*/
	defineVariable(variableName) {
		this.#getRecentScope().push(variableName);
	}
	/**
	* Returns a boolean telling if a variable is defined inside
	* the stack
	*/
	has(variableName) {
		if (this.#isInList(this.#localVariables, variableName)) return true;
		return !!this.#scopes.find((scope) => this.#isInList(scope, variableName));
	}
	/**
	* Returns the state tree for the stack
	*/
	getState() {
		return {
			localVariables: this.#localVariables,
			scopes: this.#scopes
		};
	}
	/**
	* Returns a flat list of defined variables
	*/
	list() {
		return this.#scopes.flat().concat(this.#localVariables);
	}
};
//#endregion
//#region src/parser/stringify.ts
/**
* Convert the acorn AST to a Javascript expression string
*/
function stringify$1(astExpression) {
	return generate(astExpression);
}
//#endregion
//#region src/parser/generate_ast.ts
/**
* Patch the acorn loc to point to the correct line number
* inside the original template engine
*/
function patchLoc(loc, lexerLoc) {
	/**
	* Patch the column also, when it's the first line. The reason we do this, since
	* the first line in the actual edge file may contain the Javascript expression
	* at a different column all together
	*/
	if (loc.start.line === 1) loc.start.column = loc.start.column + lexerLoc.start.col;
	loc.start.line = loc.start.line + lexerLoc.start.line - 1;
	loc.end.line = loc.end.line + lexerLoc.start.line - 1;
}
/**
* Generates and returns the acorn AST for a given Javascript expression. Assuming
* the Javascript expression is embedded into the edge lexer token, this method
* expects you to pass the token loc and the filename.
*/
function generateAST(jsArg, lexerLoc, filename) {
	const acornOptions = {
		locations: true,
		ecmaVersion: 2020,
		allowAwaitOutsideFunction: true,
		onToken: (token) => patchLoc(token.loc, lexerLoc)
	};
	try {
		return parse(jsArg, acornOptions)["body"][0];
	} catch (error) {
		/**
		* The error loc is not passed via `onToken` event, so need
		* to patch is here seperately
		*/
		const line = error.loc.line + lexerLoc.start.line - 1;
		const col = error.loc.line === 1 ? error.loc.column + lexerLoc.start.col : error.loc.column;
		throw new EdgeError(error.message.replace(/\(\d+:\d+\)/, ""), "E_ACORN_ERROR", {
			line,
			col,
			filename
		});
	}
}
//#endregion
//#region src/parser/expression_builder/member.ts
/**
* Returns Acorn complaint AST for a member expression
*/
function makeMemberAccessor(propertyName, args) {
	return {
		type: "MemberExpression",
		object: {
			type: "Identifier",
			name: propertyName
		},
		computed: false,
		property: args
	};
}
//#endregion
//#region src/expressions/identifier.ts
var identifier_default = { toStatement(statement, _, parser) {
	if ((parser.options.localVariables || []).indexOf(statement.name) > -1 || parser.stack.has(statement.name) || global[statement.name] !== void 0) return statement;
	return makeMemberAccessor(parser.options.statePropertyName, statement);
} };
//#endregion
//#region src/expressions/member_expression.ts
var member_expression_default = { toStatement(statement, filename, parser) {
	statement.object = transformAst(statement.object, filename, parser);
	/**
	* Making the following expressions work
	*
	* types[type]
	* user[Object.keys(user).find((k) => k === 'id')]
	* [num1, num2, num3].filter((num) => num % 2 === 0)
	*/
	if (statement.computed || statement.property.type !== "Identifier") statement.property = transformAst(statement.property, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/expression_statement.ts
var expression_statement_default = { toStatement(statement, filename, parser) {
	return transformAst(statement.expression, filename, parser);
} };
//#endregion
//#region src/expressions/call_expression.ts
var call_expression_default = { toStatement(statement, filename, parser) {
	statement.callee = transformAst(statement.callee, filename, parser);
	statement.arguments = statement.arguments.map((node) => transformAst(node, filename, parser));
	return statement;
} };
//#endregion
//#region src/expressions/arrow_function_expression.ts
var arrow_function_expression_default = { toStatement(statement, filename, parser) {
	parser.stack.defineScope();
	statement.params.forEach((param) => {
		if (param.type === "Identifier") parser.stack.defineVariable(param.name);
		else if (param.type === "ObjectPattern") parser.utils.collectObjectExpressionProperties(param).forEach((prop) => {
			parser.stack.defineVariable(prop);
		});
		else if (param.type === "ArrayPattern") parser.utils.collectArrayExpressionProperties(param).forEach((prop) => {
			parser.stack.defineVariable(prop);
		});
		else {
			const { line, col } = parser.utils.getExpressionLoc(param);
			throw new EdgeError(`Report this error to the maintainers: Unexpected arrow function property type ${param.type}`, "E_PARSER_ERROR", {
				line,
				col,
				filename
			});
		}
	});
	statement.body = transformAst(statement.body, filename, parser);
	parser.stack.clearScope();
	return statement;
} };
//#endregion
//#region src/expressions/literal.ts
var literal_default = { toStatement(statement) {
	return statement;
} };
//#endregion
//#region src/expressions/template_literal.ts
var template_literal_default = { toStatement(statement, filename, parser) {
	statement.expressions = statement.expressions.map((expression) => {
		return transformAst(expression, filename, parser);
	});
	return statement;
} };
//#endregion
//#region src/expressions/binary_expression.ts
var binary_expression_default = { toStatement(statement, filename, parser) {
	statement.left = transformAst(statement.left, filename, parser);
	statement.right = transformAst(statement.right, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/array_expression.ts
var array_expression_default = { toStatement(statement, filename, parser) {
	statement.elements = statement.elements.map((element) => transformAst(element, filename, parser));
	return statement;
} };
//#endregion
//#region src/expressions/object_expression.ts
var object_expression_default = { toStatement(statement, filename, parser) {
	statement.properties = statement.properties.map((node) => {
		if (node.type === "Property") {
			/**
			* Since we change the structure of node.value, we have to
			* turnoff shorthand objects, so that the astring outputs
			* the key name explicitly
			*/
			node.shorthand = false;
			if (node.computed === true) node.key = transformAst(node.key, filename, parser);
			node.value = transformAst(node.value, filename, parser);
			return node;
		}
		if (node.type === "SpreadElement") return transformAst(node, filename, parser);
		const { line, col } = parser.utils.getExpressionLoc(node);
		throw new EdgeError(`Report this error to the maintainers: Unexpected object property type "${node.type}"`, "E_PARSER_ERROR", {
			line,
			col,
			filename
		});
	});
	return statement;
} };
//#endregion
//#region src/expressions/unary_expression.ts
var unary_expression_default = { toStatement(statement, filename, parser) {
	statement.argument = transformAst(statement.argument, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/function_declaration.ts
var function_declaration_default = { toStatement(statement) {
	return statement;
} };
//#endregion
//#region src/expressions/conditional_expression.ts
var conditional_expression_default = { toStatement(statement, filename, parser) {
	statement.test = transformAst(statement.test, filename, parser);
	statement.consequent = transformAst(statement.consequent, filename, parser);
	statement.alternate = transformAst(statement.alternate, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/logical_expression.ts
var logical_expression_default = { toStatement(statement, filename, parser) {
	statement.left = transformAst(statement.left, filename, parser);
	statement.right = transformAst(statement.right, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/sequence_expression.ts
var sequence_expression_default = { toStatement(statement, filename, parser) {
	statement.expressions = statement.expressions.map((expression) => {
		return transformAst(expression, filename, parser);
	});
	return statement;
} };
//#endregion
//#region src/expressions/assignment_expression.ts
var assignment_expression_default = { toStatement(statement, filename, parser) {
	statement.left = transformAst(statement.left, filename, parser);
	statement.right = transformAst(statement.right, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/await_expression.ts
const UNALLOWED_EXPRESSION_MESSAGE = "Make sure to render template in async mode before using await expression";
var await_expression_default = { toStatement(statement, filename, parser) {
	if (!parser.options.async) {
		const { line, col } = parser.utils.getExpressionLoc(statement);
		throw new EdgeError(UNALLOWED_EXPRESSION_MESSAGE, "E_PARSER_ERROR", {
			line,
			col,
			filename
		});
	}
	statement.argument = transformAst(statement.argument, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/new_expression.ts
var new_expression_default = { toStatement(statement, filename, parser) {
	statement.arguments = statement.arguments.map((expression) => {
		return transformAst(expression, filename, parser);
	});
	return statement;
} };
//#endregion
//#region src/expressions/block_statement.ts
var block_statement_default = { toStatement(statement, filename, parser) {
	statement.body = statement.body.map((token) => {
		return transformAst(token, filename, parser);
	});
	return statement;
} };
//#endregion
//#region src/expressions/return_statement.ts
var return_statement_default = { toStatement(statement, filename, parser) {
	statement.argument = transformAst(statement.argument, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/this_expression.ts
var this_expression_default = { toStatement(statement) {
	return statement;
} };
//#endregion
//#region src/expressions/chain_expression.ts
var chain_expression_default = { toStatement(statement, filename, parser) {
	statement.expression = transformAst(statement.expression, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/spread_element.ts
var spread_element_default = { toStatement(statement, filename, parser) {
	statement.argument = parser.utils.transformAst(statement.argument, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/update_expression.ts
var update_expression_default = { toStatement(statement, filename, parser) {
	statement.argument = transformAst(statement.argument, filename, parser);
	return statement;
} };
//#endregion
//#region src/expressions/index.ts
var expressions_exports = /* @__PURE__ */ __exportAll({
	ArrayExpression: () => array_expression_default,
	ArrowFunctionExpression: () => arrow_function_expression_default,
	AssignmentExpression: () => assignment_expression_default,
	AwaitExpression: () => await_expression_default,
	BinaryExpression: () => binary_expression_default,
	BlockStatement: () => block_statement_default,
	CallExpression: () => call_expression_default,
	ChainExpression: () => chain_expression_default,
	ConditionalExpression: () => conditional_expression_default,
	ExpressionStatement: () => expression_statement_default,
	FunctionDeclaration: () => function_declaration_default,
	Identifier: () => identifier_default,
	Literal: () => literal_default,
	LogicalExpression: () => logical_expression_default,
	MemberExpression: () => member_expression_default,
	NewExpression: () => new_expression_default,
	ObjectExpression: () => object_expression_default,
	ReturnStatement: () => return_statement_default,
	SequenceExpression: () => sequence_expression_default,
	SpreadElement: () => spread_element_default,
	TemplateLiteral: () => template_literal_default,
	ThisExpression: () => this_expression_default,
	UnaryExpression: () => unary_expression_default,
	UpdateExpression: () => update_expression_default
});
//#endregion
//#region src/parser/transform_ast.ts
/**
* Transform acorn AST to Edge AST. This must always be performed before
* writing it to the compiled template buffer.
*/
function transformAst(astExpression, filename, parser) {
	const Expression = expressions_exports[astExpression.type];
	if (Expression) return Expression.toStatement(astExpression, filename, parser);
	const { type, loc } = astExpression;
	throw new EdgeError(`"${type}" is not supported`, "E_UNALLOWED_EXPRESSION", {
		line: loc.start.line,
		col: loc.start.column,
		filename
	});
}
//#endregion
//#region src/parser/expression_builder/callable.ts
/**
* Returns Acorn complaint AST for a callable expression
*/
function makeCallable(paths, args) {
	if (typeof paths === "string") return {
		type: "CallExpression",
		callee: {
			type: "Identifier",
			name: paths
		},
		arguments: args
	};
	return {
		type: "CallExpression",
		callee: {
			type: "MemberExpression",
			object: {
				type: "Identifier",
				name: paths[0]
			},
			property: {
				type: "Identifier",
				name: paths[1]
			}
		},
		arguments: args
	};
}
//#endregion
//#region src/parser/collect_object_expression_properties.ts
function collectObjectExpressionProperties(expression) {
	return expression.properties.map((prop) => {
		if (prop.value.type !== "Identifier") throw new Error("Object destructuring should not reference dynamic properties");
		return prop.value.name;
	});
}
function collectArrayExpressionProperties(expression) {
	return expression.elements.map((prop) => {
		if (prop.type !== "Identifier") throw new Error("Array destructuring should not reference dynamic properties");
		return prop.name;
	});
}
//#endregion
//#region src/parser/main.ts
/**
* Edge parser converts template strings to an invokable function. This module
* uses [edge-lexer](https://github.com/edge-js/lexer) to generate a list
* of tokens and process them against [acorn](https://npm.im/acorn).
*
* Edge has concepts of Tags, which are not implemented by this module and must
* be provided by the consumer.
*
* ```js
* // Tags are optional
* const tags = {}
*
* // File name is required for better error reporting
* const options = { filename: 'welcome.edge' }
*
* const parser = new Parser(tags, options)
* const template = require('fs').readFileSync('welcome.edge', 'utf-8')
*
* const tokens = parser.parse(template)
* console.log(fn)
* ```
*/
var Parser = class {
	tags;
	stack;
	options;
	/**
	* A boolean to know if async mode is enabled
	*/
	asyncMode;
	constructor(tags, stack = new Stack(), options) {
		this.tags = tags;
		this.stack = stack;
		this.options = options;
		this.asyncMode = !!this.options.async;
	}
	/**
	* Parser utilities work with the AST
	*/
	utils = {
		stringify: stringify$1,
		transformAst,
		makeCallable,
		makeMemberAccessor,
		generateAST,
		makeEscapeCallable: makeCallable,
		makeStatePropertyAccessor: makeMemberAccessor,
		collectObjectExpressionProperties,
		collectArrayExpressionProperties,
		getExpressionLoc(expression) {
			const loc = expression.loc || expression.property?.loc;
			return {
				line: loc.start.line,
				col: loc.start.column
			};
		}
	};
	/**
	* Returns the options to be passed to the tokenizer
	*/
	#getTokenizerOptions(options) {
		if (!this.options) return options;
		return {
			claimTag: this.options.claimTag,
			onLine: this.options.onLine,
			filename: options.filename
		};
	}
	/**
	* Process escaped tag token by writing it as it is. However, the children
	* inside a tag are still processed.
	*/
	#processEscapedTagToken(token, buffer) {
		`@${token.properties.name}(${token.properties.jsArg})`.split("\n").forEach((line) => buffer.outputRaw(line));
		/**
		* Process all inner children of the tag
		*/
		token.children.forEach((child) => this.processToken(child, buffer));
		/**
		* Close the tag
		*/
		buffer.outputRaw(`@end${token.properties.name}`);
	}
	/**
	* Process escaped muscahe block by writing it as it is.
	*/
	#processEscapedMustache(token, buffer) {
		(token.type === MustacheTypes.EMUSTACHE ? `{{${token.properties.jsArg}}}`.split("\n") : `{{{${token.properties.jsArg}}}}`.split("\n")).forEach((line) => buffer.outputRaw(line));
	}
	/**
	* Process mustache token
	*/
	#processMustache({ properties, loc, filename, type }, buffer) {
		const node = transformAst(generateAST(properties.jsArg, loc, filename), filename, this);
		/**
		* Wrap mustache output to an escape call for preventing XSS attacks
		*/
		const expression = type === MustacheTypes.MUSTACHE ? makeCallable(this.options.escapeCallPath, [node]) : node;
		/**
		* Template literal, so there is no need to wrap it inside another
		* template string
		*/
		if (node.type === "TemplateLiteral") buffer.outputExpression(stringify$1(expression), filename, loc.start.line, false);
		else if (node.type === "FunctionDeclaration") buffer.outputExpression(stringify$1(node), filename, loc.start.line, false);
		else buffer.outputExpression(stringify$1(expression), filename, loc.start.line, true);
	}
	/**
	* Convert template to tokens
	*/
	tokenize(template, options) {
		const tokenizer = new Tokenizer(template, this.tags, this.#getTokenizerOptions(options));
		tokenizer.parse();
		return tokenizer.tokens;
	}
	/**
	* Process a lexer token. The output gets written to the buffer
	*/
	processToken(token, buffer) {
		switch (token.type) {
			case "raw":
				buffer.outputRaw(token.value);
				break;
			case "newline":
				buffer.outputRaw(EOL === "\n" ? "\n" : "\r\n");
				break;
			case TagTypes.TAG:
				if (typeof this.options.onTag === "function") this.options.onTag(token);
				this.tags[token.properties.name].compile(this, buffer, token);
				break;
			case TagTypes.ETAG:
				this.#processEscapedTagToken(token, buffer);
				break;
			case MustacheTypes.EMUSTACHE:
			case MustacheTypes.ESMUSTACHE:
				this.#processEscapedMustache(token, buffer);
				break;
			case MustacheTypes.SMUSTACHE:
			case MustacheTypes.MUSTACHE:
				if (typeof this.options.onMustache === "function") this.options.onMustache(token);
				this.#processMustache(token, buffer);
		}
	}
};
//#endregion
//#region src/edge_buffer/index.ts
/**
* Buffer class to construct template
*/
var EdgeBuffer = class EdgeBuffer {
	#outputFileAndLineNumber = true;
	#outputOutVariable = true;
	#outputReturnStatement = true;
	#wrapInsideTryCatch = true;
	#options = {
		outputVar: "",
		rethrowCallPath: "",
		fileNameVar: "$filename",
		lineVar: "$lineNumber"
	};
	/**
	* Prefixes and suffix to wrap the final output
	*/
	#prefix = [];
	#suffix = [];
	/**
	* Collected lines
	*/
	#buffer = [];
	/**
	* Current runtime line number
	*/
	#currentLineNumber = 1;
	/**
	* Input filename
	*/
	#filename;
	/**
	* Current runtime filename
	*/
	#currentFileName;
	/**
	* Cached compiled output. Once this value is set, the `flush`
	* method will become a noop
	*/
	#compiledOutput;
	/**
	* Exposing output variable name
	*/
	outputVariableName;
	constructor(filename, options) {
		this.#filename = filename;
		this.#currentFileName = this.#filename;
		this.outputVariableName = options.outputVar;
		this.#options.outputVar = options.outputVar;
		this.#options.rethrowCallPath = Array.isArray(options.rethrowCallPath) ? options.rethrowCallPath.join(".") : options.rethrowCallPath;
	}
	/**
	* Creates a new buffer instance by merging the options from the existing one
	*/
	create(filename, options) {
		return new EdgeBuffer(filename, Object.assign({}, this.#options, options));
	}
	/**
	* Returns the size of buffer text
	*/
	get size() {
		return this.#buffer.length;
	}
	/**
	* Setup template with initial set of lines
	*/
	#setup(buffer) {
		/**
		* Define output variable
		*/
		this.#outputOutVariable && buffer.push(`let ${this.outputVariableName} = "";`);
		/**
		* Define line number variable
		*/
		this.#outputFileAndLineNumber && buffer.push(`let ${this.#options.lineVar} = 1;`);
		/**
		* Define filename variable
		*/
		this.#outputFileAndLineNumber && buffer.push(`let ${this.#options.fileNameVar} = ${stringify(this.#filename)};`);
		/**
		* Write try block
		*/
		this.#wrapInsideTryCatch && buffer.push("try {");
	}
	/**
	* Tear down template by writing final set of lines
	*/
	#teardown(buffer) {
		if (this.#wrapInsideTryCatch) {
			/**
			* Close try and catch block
			*/
			buffer.push("} catch (error) {");
			/**
			* Write catch block
			*/
			buffer.push(`${this.#options.rethrowCallPath}(error, ${this.#options.fileNameVar}, ${this.#options.lineVar});`);
			/**
			* End catch block
			*/
			buffer.push("}");
		}
		/**
		* Return output variable
		*/
		this.#outputReturnStatement && buffer.push(`return ${this.outputVariableName};`);
	}
	/**
	* Update the filename at runtime
	*/
	#updateFileName(filename) {
		if (this.#currentFileName !== filename) {
			this.#currentFileName = filename;
			this.#buffer.push(`${this.#options.fileNameVar} = ${stringify(filename)};`);
		}
	}
	/**
	* Update the line number at runtime
	*/
	#updateLineNumber(lineNumber) {
		if (lineNumber > 0 && this.#currentLineNumber !== lineNumber) {
			this.#currentLineNumber = lineNumber;
			this.#buffer.push(`${this.#options.lineVar} = ${lineNumber};`);
		}
	}
	/**
	* Write raw text to the output variable
	*/
	outputRaw(text) {
		this.#buffer.push(`${this.outputVariableName} += ${stringify(text)};`);
		return this;
	}
	/**
	* Write JS expression to the output variable
	*/
	outputExpression(text, filename, lineNumber, templateLiteral) {
		this.#updateFileName(filename);
		this.#updateLineNumber(lineNumber);
		text = templateLiteral ? `\`\${${text}}\`` : text;
		this.#buffer.push(`${this.outputVariableName} += ${text};`);
		return this;
	}
	/**
	* Write JS expression
	*/
	writeExpression(text, filename, lineNumber) {
		this.#updateFileName(filename);
		this.#updateLineNumber(lineNumber);
		this.#buffer.push(`${text};`);
		return this;
	}
	/**
	* Write JS statement. Statements are not suffixed with a semi-colon. It
	* means, they can be used for writing `if/else` statements.
	*/
	writeStatement(text, filename, lineNumber) {
		this.#updateFileName(filename);
		this.#updateLineNumber(lineNumber);
		this.#buffer.push(`${text}`);
		return this;
	}
	/**
	* Wrap template with a custom prefix and suffix
	*/
	wrap(prefix, suffix) {
		this.#prefix.push(prefix);
		this.#suffix.push(suffix);
		return this;
	}
	/**
	* Disable instantiation of the file and the line number variables.
	*/
	disableFileAndLineVariables() {
		this.#outputFileAndLineNumber = false;
		return this;
	}
	/**
	* Disable instantiation of the out variable.
	*/
	disableOutVariable() {
		this.#outputOutVariable = false;
		return this;
	}
	/**
	* Disable outputting the return statement
	*/
	disableReturnStatement() {
		this.#outputReturnStatement = false;
		return this;
	}
	/**
	* Disable wrapping buffer output inside try/catch.
	*/
	disableTryCatchBlock() {
		this.#wrapInsideTryCatch = false;
		return this;
	}
	/**
	* Return template as a string
	*/
	flush() {
		if (this.#compiledOutput !== void 0) return this.#compiledOutput;
		let buffer = [];
		/**
		* Write prefixes
		*/
		this.#prefix.forEach((text) => text.split(EOL).forEach((line) => buffer.push(`${line}`)));
		/**
		* Write setup code
		*/
		this.#setup(buffer);
		/**
		* Copy template contents
		*/
		buffer = buffer.concat(this.#buffer);
		/**
		* Write teardown code
		*/
		this.#teardown(buffer);
		/**
		* Write prefixes
		*/
		this.#suffix.forEach((text) => text.split(EOL).forEach((line) => buffer.push(`${line}`)));
		this.#compiledOutput = buffer.join(EOL);
		return this.#compiledOutput;
	}
};
//#endregion
//#region index.ts
/**
* Names of supported expressions
*/
const expressions = Object.keys(expressions_exports).reduce((result, name) => {
	result[name] = name;
	return result;
}, {});
//#endregion
export { EdgeBuffer, Parser, Stack, expressions };
