build/lib/standalone.ts/getDestAbsoluteFilePath
export function createESMSourcesAndResources2(options: IOptions2): void {
	const ts = require('typescript') as typeof import('typescript');

	const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
	const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
	const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);

	const getDestAbsoluteFilePath = (file: string): string => {
		const dest = options.renames[file.replace(/\\/g, '/')] || file;
		if (dest === 'tsconfig.json') {
			return path.join(OUT_FOLDER, `tsconfig.json`);
		}
		if (/\.ts$/.test(dest)) {
			return path.join(OUT_FOLDER, dest);
		}
		return path.join(OUT_RESOURCES_FOLDER, dest);
	};

	const allFiles = walkDirRecursive(SRC_FOLDER);
	for (const file of allFiles) {

		if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
			continue;
		}

		if (file === 'tsconfig.json') {
			const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
			tsConfig.compilerOptions.module = 'es6';
			tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs').replace(/\\/g, '/');
			write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
			continue;
		}

		if (/\.d\.ts$/.test(file) || /\.css$/.test(file) || /\.js$/.test(file) || /\.ttf$/.test(file)) {
			// Transport the files directly
			write(getDestAbsoluteFilePath(file), fs.readFileSync(path.join(SRC_FOLDER, file)));
			continue;
		}

		if (/\.ts$/.test(file)) {
			// Transform the .ts file
			let fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();

			const info = ts.preProcessFile(fileContents);

			for (let i = info.importedFiles.length - 1; i >= 0; i--) {
				const importedFilename = info.importedFiles[i].fileName;
				const pos = info.importedFiles[i].pos;
				const end = info.importedFiles[i].end;

				let importedFilepath: string;
				if (/^vs\/css!/.test(importedFilename)) {
					importedFilepath = importedFilename.substr('vs/css!'.length) + '.css';
				} else {
					importedFilepath = importedFilename;
				}
				if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) {
					importedFilepath = path.join(path.dirname(file), importedFilepath);
				}

				let relativePath: string;
				if (importedFilepath === path.dirname(file).replace(/\\/g, '/')) {
					relativePath = '../' + path.basename(path.dirname(file));
				} else if (importedFilepath === path.dirname(path.dirname(file)).replace(/\\/g, '/')) {
					relativePath = '../../' + path.basename(path.dirname(path.dirname(file)));
				} else {
					relativePath = path.relative(path.dirname(file), importedFilepath);
				}
				relativePath = relativePath.replace(/\\/g, '/');
				if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) {
					relativePath = './' + relativePath;
				}
				fileContents = (
					fileContents.substring(0, pos + 1)
					+ relativePath
					+ fileContents.substring(end + 1)
				);
			}

			fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
				return `import * as ${m1} from ${m2};`;
			});

			write(getDestAbsoluteFilePath(file), fileContents);
			continue;
		}

		console.log(`UNKNOWN FILE: ${file}`);
	}


	function walkDirRecursive(dir: string): string[] {
		if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') {
			dir += '/';
		}
		const result: string[] = [];
		_walkDirRecursive(dir, result, dir.length);
		return result;
	}

	function _walkDirRecursive(dir: string, result: string[], trimPos: number): void {
		const files = fs.readdirSync(dir);
		for (let i = 0; i < files.length; i++) {
			const file = path.join(dir, files[i]);
			if (fs.statSync(file).isDirectory()) {
				_walkDirRecursive(file, result, trimPos);
			} else {
				result.push(file.substr(trimPos));
			}
		}
	}

	function write(absoluteFilePath: string, contents: string | Buffer): void {
		if (/(\.ts$)|(\.js$)/.test(absoluteFilePath)) {
			contents = toggleComments(contents.toString());
		}
		writeFile(absoluteFilePath, contents);

		function toggleComments(fileContents: string): string {
			const lines = fileContents.split(/\r\n|\r|\n/);
			let mode = 0;
			for (let i = 0; i < lines.length; i++) {
				const line = lines[i];
				if (mode === 0) {
					if (/\/\/ ESM-comment-begin/.test(line)) {
						mode = 1;
						continue;
					}
					if (/\/\/ ESM-uncomment-begin/.test(line)) {
						mode = 2;
						continue;
					}
					continue;
				}

				if (mode === 1) {
					if (/\/\/ ESM-comment-end/.test(line)) {
						mode = 0;
						continue;
					}
					lines[i] = '// ' + line;
					continue;
				}

				if (mode === 2) {
					if (/\/\/ ESM-uncomment-end/.test(line)) {
						mode = 0;
						continue;
					}
					lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) {
						return indent;
					});
				}
			}

			return lines.join('\n');
		}
	}
}