diff --git a/__tests__/envvars.test.ts b/__tests__/envvars.test.ts new file mode 100644 index 000000000..1501be896 --- /dev/null +++ b/__tests__/envvars.test.ts @@ -0,0 +1,27 @@ +import { + substituteValues +} from '../src/envvars' + +describe('substituteValues', () => { + test('returns original string with no substitution placeholders', async () => { + const input = 'This is a test' + const result = await substituteValues(input) + expect(result).toBe(input) + }) + + test('Handles \'env\' substitution placeholders', async () => { + process.env.TEST_ENV1='TestEnvValue1' + process.env.TEST_ENV2='TestEnvValue2' + const input = 'TEST_ENV1: ${env:TEST_ENV1}, TEST_ENV2: ${env:TEST_ENV2}' + const result = await substituteValues(input) + expect(result).toBe('TEST_ENV1: TestEnvValue1, TEST_ENV2: TestEnvValue2') + }) + + test('ignores substitution placeholders that it doesn\'t understand', async () => { + const input = 'TEST_ENV: ${nothingToSee:TEST_ENV}' + const result = await substituteValues(input) + expect(result).toBe(input) + }) + +}) + diff --git a/__tests__/inputs.test.ts b/__tests__/inputs.test.ts index 98f916cbf..72c3c4856 100644 --- a/__tests__/inputs.test.ts +++ b/__tests__/inputs.test.ts @@ -1,4 +1,3 @@ -import parse from 'csv-parse' import { parseInputAsList, parseInputAsRecord diff --git a/dist/index.js b/dist/index.js index 80b3847fb..245e301f6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -124,6 +124,7 @@ const core = __importStar(__webpack_require__(186)); const config = __importStar(__webpack_require__(88)); const exec_1 = __webpack_require__(757); const file_1 = __webpack_require__(14); +const envvars_1 = __webpack_require__(293); function isDockerBuildXInstalled() { return __awaiter(this, void 0, void 0, function* () { const r = yield exec_1.exec('docker', 'buildx', '--help'); @@ -154,7 +155,7 @@ function buildImage(imageName, checkoutPath, subFolder) { args.push('--output=type=docker'); const buildArgs = (_b = devcontainerConfig.build) === null || _b === void 0 ? void 0 : _b.args; for (const argName in buildArgs) { - const argValue = buildArgs[argName]; + const argValue = envvars_1.substituteValues(buildArgs[argName]); args.push('--build-arg', `${argName}=${argValue}`); } args.push('-f', dockerfilePath); @@ -188,7 +189,8 @@ function runContainer(imageName, checkoutPath, subFolder, command, envs) { args.push('--workdir', workspaceFolder); args.push('--user', remoteUser); if (devcontainerConfig.runArgs) { - args.push(...devcontainerConfig.runArgs); + const subtitutedRunArgs = devcontainerConfig.runArgs.map(a => envvars_1.substituteValues(a)); + args.push(...subtitutedRunArgs); } if (envs) { for (const env of envs) { @@ -233,6 +235,42 @@ function pushImage(imageName) { exports.pushImage = pushImage; +/***/ }), + +/***/ 293: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.substituteValues = void 0; +function substituteValues(input) { + // Find all `${...}` entries and substitute + // Note the non-greedy `.+?` match to avoid matching the start of + // one placeholder up to the end of another when multiple placeholders are present + return input.replace(/\$\{(.+?)\}/g, getSubstitutionValue); +} +exports.substituteValues = substituteValues; +function getSubstitutionValue(regexMatch, placeholder) { + // Substitution values are in TYPE:KEY form + // e.g. env:MY_ENV + var _a; + const parts = placeholder.split(':'); + if (parts.length === 2) { + const type = parts[0]; + const key = parts[1]; + switch (type) { + case 'env': + case 'localenv': + return (_a = process.env[key]) !== null && _a !== void 0 ? _a : ''; + } + } + // if we can't process the format then return the original string + // as having it present in any output will likely make issues more obvious + return regexMatch; +} + + /***/ }), /***/ 757: diff --git a/dist/index.js.map b/dist/index.js.map index fd56a0bf9..2cf1f2489 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../webpack://typescript-action/./lib/config.js","../webpack://typescript-action/./lib/docker.js","../webpack://typescript-action/./lib/exec.js","../webpack://typescript-action/./lib/file.js","../webpack://typescript-action/./lib/main.js","../webpack://typescript-action/./node_modules/@actions/core/lib/command.js","../webpack://typescript-action/./node_modules/@actions/core/lib/core.js","../webpack://typescript-action/./node_modules/@actions/core/lib/file-command.js","../webpack://typescript-action/./node_modules/@actions/core/lib/utils.js","../webpack://typescript-action/./node_modules/@actions/exec/lib/exec.js","../webpack://typescript-action/./node_modules/@actions/exec/lib/toolrunner.js","../webpack://typescript-action/./node_modules/@actions/io/lib/io-util.js","../webpack://typescript-action/./node_modules/@actions/io/lib/io.js","../webpack://typescript-action/./node_modules/csv-parse/lib/ResizeableBuffer.js","../webpack://typescript-action/./node_modules/csv-parse/lib/index.js","../webpack://typescript-action/./node_modules/csv-parse/lib/sync.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/edit.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/format.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/parser.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/scanner.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/main.js","../webpack://typescript-action/external \"assert\"","../webpack://typescript-action/external \"child_process\"","../webpack://typescript-action/external \"events\"","../webpack://typescript-action/external \"fs\"","../webpack://typescript-action/external \"os\"","../webpack://typescript-action/external \"path\"","../webpack://typescript-action/external \"stream\"","../webpack://typescript-action/external \"string_decoder\"","../webpack://typescript-action/external \"timers\"","../webpack://typescript-action/external \"util\"","../webpack://typescript-action/webpack/bootstrap","../webpack://typescript-action/webpack/runtime/compat","../webpack://typescript-action/webpack/startup"],"sourcesContent":["\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getContext = exports.getDockerfile = exports.getRemoteUser = exports.getWorkspaceFolder = exports.loadFromString = exports.loadFromFile = void 0;\nconst path = __importStar(require(\"path\"));\nconst fs = __importStar(require(\"fs\"));\nconst jsoncParser = __importStar(require(\"jsonc-parser\"));\nconst { readFile } = fs.promises;\nfunction loadFromFile(filepath) {\n return __awaiter(this, void 0, void 0, function* () {\n const jsonContent = yield readFile(filepath);\n return loadFromString(jsonContent.toString());\n });\n}\nexports.loadFromFile = loadFromFile;\nfunction loadFromString(content) {\n const config = jsoncParser.parse(content);\n return config;\n}\nexports.loadFromString = loadFromString;\nfunction getWorkspaceFolder(config, repoPath) {\n // https://code.visualstudio.com/docs/remote/containers-advanced#_changing-the-default-source-code-mount\n if (config.workspaceFolder) {\n return config.workspaceFolder;\n }\n return path.join('/workspaces', path.basename(repoPath));\n}\nexports.getWorkspaceFolder = getWorkspaceFolder;\nfunction getRemoteUser(config) {\n var _a;\n // https://code.visualstudio.com/docs/remote/containers-advanced#_specifying-a-user-for-vs-code\n return (_a = config.remoteUser) !== null && _a !== void 0 ? _a : 'root';\n}\nexports.getRemoteUser = getRemoteUser;\nfunction getDockerfile(config) {\n var _a, _b;\n return (_b = (_a = config.build) === null || _a === void 0 ? void 0 : _a.dockerfile) !== null && _b !== void 0 ? _b : config.dockerFile;\n}\nexports.getDockerfile = getDockerfile;\nfunction getContext(config) {\n var _a, _b;\n return (_b = (_a = config.build) === null || _a === void 0 ? void 0 : _a.context) !== null && _b !== void 0 ? _b : config.context;\n}\nexports.getContext = getContext;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.pushImage = exports.runContainer = exports.buildImage = exports.isDockerBuildXInstalled = void 0;\nconst path_1 = __importDefault(require(\"path\"));\nconst core = __importStar(require(\"@actions/core\"));\nconst config = __importStar(require(\"./config\"));\nconst exec_1 = require(\"./exec\");\nconst file_1 = require(\"./file\");\nfunction isDockerBuildXInstalled() {\n return __awaiter(this, void 0, void 0, function* () {\n const r = yield exec_1.exec('docker', 'buildx', '--help');\n return r.exitCode === 0;\n });\n}\nexports.isDockerBuildXInstalled = isDockerBuildXInstalled;\nfunction buildImage(imageName, checkoutPath, subFolder) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n const folder = path_1.default.join(checkoutPath, subFolder);\n const devcontainerJsonPath = path_1.default.join(folder, '.devcontainer/devcontainer.json');\n const devcontainerConfig = yield config.loadFromFile(devcontainerJsonPath);\n const configDockerfile = config.getDockerfile(devcontainerConfig);\n if (!configDockerfile) {\n throw new Error('dockerfile not set in devcontainer.json - devcontainer-build-run currently only supports Dockerfile-based dev containers');\n }\n const dockerfilePath = path_1.default.join(folder, '.devcontainer', configDockerfile);\n const configContext = (_a = config.getContext(devcontainerConfig)) !== null && _a !== void 0 ? _a : '';\n const contextPath = path_1.default.join(folder, '.devcontainer', configContext);\n const args = ['buildx', 'build'];\n args.push('--tag');\n args.push(`${imageName}:latest`);\n args.push('--cache-from');\n args.push(`type=registry,ref=${imageName}:latest`);\n args.push('--cache-to');\n args.push('type=inline');\n args.push('--output=type=docker');\n const buildArgs = (_b = devcontainerConfig.build) === null || _b === void 0 ? void 0 : _b.args;\n for (const argName in buildArgs) {\n const argValue = buildArgs[argName];\n args.push('--build-arg', `${argName}=${argValue}`);\n }\n args.push('-f', dockerfilePath);\n args.push(contextPath);\n core.startGroup('🏗 Building dev container...');\n try {\n const buildResponse = yield exec_1.execWithOptions('docker', { silent: false }, ...args);\n if (buildResponse.exitCode !== 0) {\n core.setFailed(`build failed with ${buildResponse.exitCode}: ${buildResponse.stderr}`);\n return false;\n }\n core.info(buildResponse.stdout);\n return true;\n }\n finally {\n core.endGroup();\n }\n });\n}\nexports.buildImage = buildImage;\nfunction runContainer(imageName, checkoutPath, subFolder, command, envs) {\n return __awaiter(this, void 0, void 0, function* () {\n const checkoutPathAbsolute = file_1.getAbsolutePath(checkoutPath, process.cwd());\n const folder = path_1.default.join(checkoutPathAbsolute, subFolder);\n const devcontainerJsonPath = path_1.default.join(folder, '.devcontainer/devcontainer.json');\n const devcontainerConfig = yield config.loadFromFile(devcontainerJsonPath);\n const workspaceFolder = config.getWorkspaceFolder(devcontainerConfig, folder);\n const remoteUser = config.getRemoteUser(devcontainerConfig);\n const args = ['run'];\n args.push('--mount', `type=bind,src=${checkoutPathAbsolute},dst=${workspaceFolder}`);\n args.push('--workdir', workspaceFolder);\n args.push('--user', remoteUser);\n if (devcontainerConfig.runArgs) {\n args.push(...devcontainerConfig.runArgs);\n }\n if (envs) {\n for (const env of envs) {\n args.push('--env', env);\n }\n }\n args.push(`${imageName}:latest`);\n args.push('bash', '-c', `sudo chown -R $(whoami) . && ${command}`); // TODO sort out permissions/user alignment\n core.startGroup('🏃‍♀️ Running dev container...');\n try {\n const buildResponse = yield exec_1.execWithOptions('docker', { silent: false }, ...args);\n if (buildResponse.exitCode !== 0) {\n core.setFailed(`run failed with ${buildResponse.exitCode}: ${buildResponse.stderr}`);\n return false;\n }\n return true;\n }\n finally {\n core.endGroup();\n }\n });\n}\nexports.runContainer = runContainer;\nfunction pushImage(imageName) {\n return __awaiter(this, void 0, void 0, function* () {\n const args = ['push'];\n args.push(`${imageName}:latest`);\n core.startGroup('Pushing image...');\n try {\n const buildResponse = yield exec_1.execWithOptions('docker', { silent: false }, ...args);\n if (buildResponse.exitCode !== 0) {\n core.setFailed(`push failed with ${buildResponse.exitCode}: ${buildResponse.stderr}`);\n return false;\n }\n return true;\n }\n finally {\n core.endGroup();\n }\n });\n}\nexports.pushImage = pushImage;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.execWithOptions = exports.exec = void 0;\nconst actions_exec = __importStar(require(\"@actions/exec\"));\nfunction exec(command, ...args) {\n return __awaiter(this, void 0, void 0, function* () {\n return yield execWithOptions(command, {\n silent: true\n }, ...args);\n });\n}\nexports.exec = exec;\nfunction execWithOptions(command, options, ...args) {\n return __awaiter(this, void 0, void 0, function* () {\n let stdout = '';\n let stderr = '';\n const actionOptions = {\n ignoreReturnCode: true,\n silent: options.silent,\n listeners: {\n stdout: (data) => {\n stdout += data.toString();\n },\n stderr: (data) => {\n stderr += data.toString();\n }\n }\n };\n const exitCode = yield actions_exec.exec(command, args, actionOptions);\n return {\n exitCode,\n stdout,\n stderr\n };\n });\n}\nexports.execWithOptions = execWithOptions;\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getAbsolutePath = void 0;\nconst path_1 = __importDefault(require(\"path\"));\nfunction getAbsolutePath(inputPath, referencePath) {\n if (path_1.default.isAbsolute(inputPath)) {\n return inputPath;\n }\n return path_1.default.join(referencePath, inputPath);\n}\nexports.getAbsolutePath = getAbsolutePath;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst core = __importStar(require(\"@actions/core\"));\nconst sync_1 = __importDefault(require(\"csv-parse/lib/sync\"));\nconst docker_1 = require(\"./docker\");\nfunction run() {\n return __awaiter(this, void 0, void 0, function* () {\n const hasRunMain = core.getState('hasRunMain');\n if (hasRunMain === 'true') {\n return yield runPost();\n }\n else {\n core.saveState('hasRunMain', 'true');\n return yield runMain();\n }\n });\n}\nfunction runMain() {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const buildXInstalled = yield docker_1.isDockerBuildXInstalled();\n if (!buildXInstalled) {\n core.setFailed('docker buildx not available: add a step to set up with docker/setup-buildx-action');\n return;\n }\n const checkoutPath = core.getInput('checkoutPath');\n const imageName = core.getInput('imageName', { required: true });\n const subFolder = core.getInput('subFolder');\n const runCommand = core.getInput('runCmd', { required: true });\n const envs = yield getInputList('env');\n if (!(yield docker_1.buildImage(imageName, checkoutPath, subFolder))) {\n return;\n }\n if (!(yield docker_1.runContainer(imageName, checkoutPath, subFolder, runCommand, envs))) {\n return;\n }\n }\n catch (error) {\n core.setFailed(error.message);\n }\n });\n}\nfunction runPost() {\n return __awaiter(this, void 0, void 0, function* () {\n const headRef = process.env.GITHUB_HEAD_REF;\n if (headRef) {\n // headRef only set on PR builds\n core.info('Image push skipped for PR builds');\n return;\n }\n const imageName = core.getInput('imageName', { required: true });\n yield docker_1.pushImage(imageName);\n });\n}\nrun();\nfunction getInputList(name) {\n return __awaiter(this, void 0, void 0, function* () {\n const res = [];\n const input = core.getInput(name);\n if (input === '') {\n return res;\n }\n const parsedInput = (yield sync_1.default(input, {\n columns: false,\n relax: true,\n relaxColumnCount: true,\n skipLinesWithEmptyValues: true\n }));\n for (const items of parsedInput) {\n res.push(...items);\n }\n return res.map(item => item.trim());\n });\n}\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.issue = exports.issueCommand = void 0;\nconst os = __importStar(require(\"os\"));\nconst utils_1 = require(\"./utils\");\n/**\n * Commands\n *\n * Command Format:\n * ::name key=value,key=value::message\n *\n * Examples:\n * ::warning::This is the message\n * ::set-env name=MY_VAR::some value\n */\nfunction issueCommand(command, properties, message) {\n const cmd = new Command(command, properties, message);\n process.stdout.write(cmd.toString() + os.EOL);\n}\nexports.issueCommand = issueCommand;\nfunction issue(name, message = '') {\n issueCommand(name, {}, message);\n}\nexports.issue = issue;\nconst CMD_STRING = '::';\nclass Command {\n constructor(command, properties, message) {\n if (!command) {\n command = 'missing.command';\n }\n this.command = command;\n this.properties = properties;\n this.message = message;\n }\n toString() {\n let cmdStr = CMD_STRING + this.command;\n if (this.properties && Object.keys(this.properties).length > 0) {\n cmdStr += ' ';\n let first = true;\n for (const key in this.properties) {\n if (this.properties.hasOwnProperty(key)) {\n const val = this.properties[key];\n if (val) {\n if (first) {\n first = false;\n }\n else {\n cmdStr += ',';\n }\n cmdStr += `${key}=${escapeProperty(val)}`;\n }\n }\n }\n }\n cmdStr += `${CMD_STRING}${escapeData(this.message)}`;\n return cmdStr;\n }\n}\nfunction escapeData(s) {\n return utils_1.toCommandValue(s)\n .replace(/%/g, '%25')\n .replace(/\\r/g, '%0D')\n .replace(/\\n/g, '%0A');\n}\nfunction escapeProperty(s) {\n return utils_1.toCommandValue(s)\n .replace(/%/g, '%25')\n .replace(/\\r/g, '%0D')\n .replace(/\\n/g, '%0A')\n .replace(/:/g, '%3A')\n .replace(/,/g, '%2C');\n}\n//# sourceMappingURL=command.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;\nconst command_1 = require(\"./command\");\nconst file_command_1 = require(\"./file-command\");\nconst utils_1 = require(\"./utils\");\nconst os = __importStar(require(\"os\"));\nconst path = __importStar(require(\"path\"));\n/**\n * The code to exit an action\n */\nvar ExitCode;\n(function (ExitCode) {\n /**\n * A code indicating that the action was successful\n */\n ExitCode[ExitCode[\"Success\"] = 0] = \"Success\";\n /**\n * A code indicating that the action was a failure\n */\n ExitCode[ExitCode[\"Failure\"] = 1] = \"Failure\";\n})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));\n//-----------------------------------------------------------------------\n// Variables\n//-----------------------------------------------------------------------\n/**\n * Sets env variable for this action and future actions in the job\n * @param name the name of the variable to set\n * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction exportVariable(name, val) {\n const convertedVal = utils_1.toCommandValue(val);\n process.env[name] = convertedVal;\n const filePath = process.env['GITHUB_ENV'] || '';\n if (filePath) {\n const delimiter = '_GitHubActionsFileCommandDelimeter_';\n const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;\n file_command_1.issueCommand('ENV', commandValue);\n }\n else {\n command_1.issueCommand('set-env', { name }, convertedVal);\n }\n}\nexports.exportVariable = exportVariable;\n/**\n * Registers a secret which will get masked from logs\n * @param secret value of the secret\n */\nfunction setSecret(secret) {\n command_1.issueCommand('add-mask', {}, secret);\n}\nexports.setSecret = setSecret;\n/**\n * Prepends inputPath to the PATH (for this action and future actions)\n * @param inputPath\n */\nfunction addPath(inputPath) {\n const filePath = process.env['GITHUB_PATH'] || '';\n if (filePath) {\n file_command_1.issueCommand('PATH', inputPath);\n }\n else {\n command_1.issueCommand('add-path', {}, inputPath);\n }\n process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;\n}\nexports.addPath = addPath;\n/**\n * Gets the value of an input.\n * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.\n * Returns an empty string if the value is not defined.\n *\n * @param name name of the input to get\n * @param options optional. See InputOptions.\n * @returns string\n */\nfunction getInput(name, options) {\n const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';\n if (options && options.required && !val) {\n throw new Error(`Input required and not supplied: ${name}`);\n }\n if (options && options.trimWhitespace === false) {\n return val;\n }\n return val.trim();\n}\nexports.getInput = getInput;\n/**\n * Gets the input value of the boolean type in the YAML 1.2 \"core schema\" specification.\n * Support boolean input list: `true | True | TRUE | false | False | FALSE` .\n * The return value is also in boolean type.\n * ref: https://yaml.org/spec/1.2/spec.html#id2804923\n *\n * @param name name of the input to get\n * @param options optional. See InputOptions.\n * @returns boolean\n */\nfunction getBooleanInput(name, options) {\n const trueValue = ['true', 'True', 'TRUE'];\n const falseValue = ['false', 'False', 'FALSE'];\n const val = getInput(name, options);\n if (trueValue.includes(val))\n return true;\n if (falseValue.includes(val))\n return false;\n throw new TypeError(`Input does not meet YAML 1.2 \"Core Schema\" specification: ${name}\\n` +\n `Support boolean input list: \\`true | True | TRUE | false | False | FALSE\\``);\n}\nexports.getBooleanInput = getBooleanInput;\n/**\n * Sets the value of an output.\n *\n * @param name name of the output to set\n * @param value value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setOutput(name, value) {\n process.stdout.write(os.EOL);\n command_1.issueCommand('set-output', { name }, value);\n}\nexports.setOutput = setOutput;\n/**\n * Enables or disables the echoing of commands into stdout for the rest of the step.\n * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.\n *\n */\nfunction setCommandEcho(enabled) {\n command_1.issue('echo', enabled ? 'on' : 'off');\n}\nexports.setCommandEcho = setCommandEcho;\n//-----------------------------------------------------------------------\n// Results\n//-----------------------------------------------------------------------\n/**\n * Sets the action status to failed.\n * When the action exits it will be with an exit code of 1\n * @param message add error issue message\n */\nfunction setFailed(message) {\n process.exitCode = ExitCode.Failure;\n error(message);\n}\nexports.setFailed = setFailed;\n//-----------------------------------------------------------------------\n// Logging Commands\n//-----------------------------------------------------------------------\n/**\n * Gets whether Actions Step Debug is on or not\n */\nfunction isDebug() {\n return process.env['RUNNER_DEBUG'] === '1';\n}\nexports.isDebug = isDebug;\n/**\n * Writes debug message to user log\n * @param message debug message\n */\nfunction debug(message) {\n command_1.issueCommand('debug', {}, message);\n}\nexports.debug = debug;\n/**\n * Adds an error issue\n * @param message error issue message. Errors will be converted to string via toString()\n */\nfunction error(message) {\n command_1.issue('error', message instanceof Error ? message.toString() : message);\n}\nexports.error = error;\n/**\n * Adds an warning issue\n * @param message warning issue message. Errors will be converted to string via toString()\n */\nfunction warning(message) {\n command_1.issue('warning', message instanceof Error ? message.toString() : message);\n}\nexports.warning = warning;\n/**\n * Writes info to log with console.log.\n * @param message info message\n */\nfunction info(message) {\n process.stdout.write(message + os.EOL);\n}\nexports.info = info;\n/**\n * Begin an output group.\n *\n * Output until the next `groupEnd` will be foldable in this group\n *\n * @param name The name of the output group\n */\nfunction startGroup(name) {\n command_1.issue('group', name);\n}\nexports.startGroup = startGroup;\n/**\n * End an output group.\n */\nfunction endGroup() {\n command_1.issue('endgroup');\n}\nexports.endGroup = endGroup;\n/**\n * Wrap an asynchronous function call in a group.\n *\n * Returns the same type as the function itself.\n *\n * @param name The name of the group\n * @param fn The function to wrap in the group\n */\nfunction group(name, fn) {\n return __awaiter(this, void 0, void 0, function* () {\n startGroup(name);\n let result;\n try {\n result = yield fn();\n }\n finally {\n endGroup();\n }\n return result;\n });\n}\nexports.group = group;\n//-----------------------------------------------------------------------\n// Wrapper action state\n//-----------------------------------------------------------------------\n/**\n * Saves state for current action, the state can only be retrieved by this action's post job execution.\n *\n * @param name name of the state to store\n * @param value value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction saveState(name, value) {\n command_1.issueCommand('save-state', { name }, value);\n}\nexports.saveState = saveState;\n/**\n * Gets the value of an state set by this action's main execution.\n *\n * @param name name of the state to get\n * @returns string\n */\nfunction getState(name) {\n return process.env[`STATE_${name}`] || '';\n}\nexports.getState = getState;\n//# sourceMappingURL=core.js.map","\"use strict\";\n// For internal use, subject to change.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.issueCommand = void 0;\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst fs = __importStar(require(\"fs\"));\nconst os = __importStar(require(\"os\"));\nconst utils_1 = require(\"./utils\");\nfunction issueCommand(command, message) {\n const filePath = process.env[`GITHUB_${command}`];\n if (!filePath) {\n throw new Error(`Unable to find environment variable for file command ${command}`);\n }\n if (!fs.existsSync(filePath)) {\n throw new Error(`Missing file at path: ${filePath}`);\n }\n fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {\n encoding: 'utf8'\n });\n}\nexports.issueCommand = issueCommand;\n//# sourceMappingURL=file-command.js.map","\"use strict\";\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.toCommandValue = void 0;\n/**\n * Sanitizes an input into a string so it can be passed into issueCommand safely\n * @param input input to sanitize into a string\n */\nfunction toCommandValue(input) {\n if (input === null || input === undefined) {\n return '';\n }\n else if (typeof input === 'string' || input instanceof String) {\n return input;\n }\n return JSON.stringify(input);\n}\nexports.toCommandValue = toCommandValue;\n//# sourceMappingURL=utils.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getExecOutput = exports.exec = void 0;\nconst string_decoder_1 = require(\"string_decoder\");\nconst tr = __importStar(require(\"./toolrunner\"));\n/**\n * Exec a command.\n * Output will be streamed to the live console.\n * Returns promise with return code\n *\n * @param commandLine command to execute (can include additional args). Must be correctly escaped.\n * @param args optional arguments for tool. Escaping is handled by the lib.\n * @param options optional exec options. See ExecOptions\n * @returns Promise exit code\n */\nfunction exec(commandLine, args, options) {\n return __awaiter(this, void 0, void 0, function* () {\n const commandArgs = tr.argStringToArray(commandLine);\n if (commandArgs.length === 0) {\n throw new Error(`Parameter 'commandLine' cannot be null or empty.`);\n }\n // Path to tool to execute should be first arg\n const toolPath = commandArgs[0];\n args = commandArgs.slice(1).concat(args || []);\n const runner = new tr.ToolRunner(toolPath, args, options);\n return runner.exec();\n });\n}\nexports.exec = exec;\n/**\n * Exec a command and get the output.\n * Output will be streamed to the live console.\n * Returns promise with the exit code and collected stdout and stderr\n *\n * @param commandLine command to execute (can include additional args). Must be correctly escaped.\n * @param args optional arguments for tool. Escaping is handled by the lib.\n * @param options optional exec options. See ExecOptions\n * @returns Promise exit code, stdout, and stderr\n */\nfunction getExecOutput(commandLine, args, options) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n let stdout = '';\n let stderr = '';\n //Using string decoder covers the case where a mult-byte character is split\n const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');\n const stderrDecoder = new string_decoder_1.StringDecoder('utf8');\n const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;\n const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;\n const stdErrListener = (data) => {\n stderr += stderrDecoder.write(data);\n if (originalStdErrListener) {\n originalStdErrListener(data);\n }\n };\n const stdOutListener = (data) => {\n stdout += stdoutDecoder.write(data);\n if (originalStdoutListener) {\n originalStdoutListener(data);\n }\n };\n const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });\n const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));\n //flush any remaining characters\n stdout += stdoutDecoder.end();\n stderr += stderrDecoder.end();\n return {\n exitCode,\n stdout,\n stderr\n };\n });\n}\nexports.getExecOutput = getExecOutput;\n//# sourceMappingURL=exec.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.argStringToArray = exports.ToolRunner = void 0;\nconst os = __importStar(require(\"os\"));\nconst events = __importStar(require(\"events\"));\nconst child = __importStar(require(\"child_process\"));\nconst path = __importStar(require(\"path\"));\nconst io = __importStar(require(\"@actions/io\"));\nconst ioUtil = __importStar(require(\"@actions/io/lib/io-util\"));\nconst timers_1 = require(\"timers\");\n/* eslint-disable @typescript-eslint/unbound-method */\nconst IS_WINDOWS = process.platform === 'win32';\n/*\n * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.\n */\nclass ToolRunner extends events.EventEmitter {\n constructor(toolPath, args, options) {\n super();\n if (!toolPath) {\n throw new Error(\"Parameter 'toolPath' cannot be null or empty.\");\n }\n this.toolPath = toolPath;\n this.args = args || [];\n this.options = options || {};\n }\n _debug(message) {\n if (this.options.listeners && this.options.listeners.debug) {\n this.options.listeners.debug(message);\n }\n }\n _getCommandString(options, noPrefix) {\n const toolPath = this._getSpawnFileName();\n const args = this._getSpawnArgs(options);\n let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool\n if (IS_WINDOWS) {\n // Windows + cmd file\n if (this._isCmdFile()) {\n cmd += toolPath;\n for (const a of args) {\n cmd += ` ${a}`;\n }\n }\n // Windows + verbatim\n else if (options.windowsVerbatimArguments) {\n cmd += `\"${toolPath}\"`;\n for (const a of args) {\n cmd += ` ${a}`;\n }\n }\n // Windows (regular)\n else {\n cmd += this._windowsQuoteCmdArg(toolPath);\n for (const a of args) {\n cmd += ` ${this._windowsQuoteCmdArg(a)}`;\n }\n }\n }\n else {\n // OSX/Linux - this can likely be improved with some form of quoting.\n // creating processes on Unix is fundamentally different than Windows.\n // on Unix, execvp() takes an arg array.\n cmd += toolPath;\n for (const a of args) {\n cmd += ` ${a}`;\n }\n }\n return cmd;\n }\n _processLineBuffer(data, strBuffer, onLine) {\n try {\n let s = strBuffer + data.toString();\n let n = s.indexOf(os.EOL);\n while (n > -1) {\n const line = s.substring(0, n);\n onLine(line);\n // the rest of the string ...\n s = s.substring(n + os.EOL.length);\n n = s.indexOf(os.EOL);\n }\n return s;\n }\n catch (err) {\n // streaming lines to console is best effort. Don't fail a build.\n this._debug(`error processing line. Failed with error ${err}`);\n return '';\n }\n }\n _getSpawnFileName() {\n if (IS_WINDOWS) {\n if (this._isCmdFile()) {\n return process.env['COMSPEC'] || 'cmd.exe';\n }\n }\n return this.toolPath;\n }\n _getSpawnArgs(options) {\n if (IS_WINDOWS) {\n if (this._isCmdFile()) {\n let argline = `/D /S /C \"${this._windowsQuoteCmdArg(this.toolPath)}`;\n for (const a of this.args) {\n argline += ' ';\n argline += options.windowsVerbatimArguments\n ? a\n : this._windowsQuoteCmdArg(a);\n }\n argline += '\"';\n return [argline];\n }\n }\n return this.args;\n }\n _endsWith(str, end) {\n return str.endsWith(end);\n }\n _isCmdFile() {\n const upperToolPath = this.toolPath.toUpperCase();\n return (this._endsWith(upperToolPath, '.CMD') ||\n this._endsWith(upperToolPath, '.BAT'));\n }\n _windowsQuoteCmdArg(arg) {\n // for .exe, apply the normal quoting rules that libuv applies\n if (!this._isCmdFile()) {\n return this._uvQuoteCmdArg(arg);\n }\n // otherwise apply quoting rules specific to the cmd.exe command line parser.\n // the libuv rules are generic and are not designed specifically for cmd.exe\n // command line parser.\n //\n // for a detailed description of the cmd.exe command line parser, refer to\n // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912\n // need quotes for empty arg\n if (!arg) {\n return '\"\"';\n }\n // determine whether the arg needs to be quoted\n const cmdSpecialChars = [\n ' ',\n '\\t',\n '&',\n '(',\n ')',\n '[',\n ']',\n '{',\n '}',\n '^',\n '=',\n ';',\n '!',\n \"'\",\n '+',\n ',',\n '`',\n '~',\n '|',\n '<',\n '>',\n '\"'\n ];\n let needsQuotes = false;\n for (const char of arg) {\n if (cmdSpecialChars.some(x => x === char)) {\n needsQuotes = true;\n break;\n }\n }\n // short-circuit if quotes not needed\n if (!needsQuotes) {\n return arg;\n }\n // the following quoting rules are very similar to the rules that by libuv applies.\n //\n // 1) wrap the string in quotes\n //\n // 2) double-up quotes - i.e. \" => \"\"\n //\n // this is different from the libuv quoting rules. libuv replaces \" with \\\", which unfortunately\n // doesn't work well with a cmd.exe command line.\n //\n // note, replacing \" with \"\" also works well if the arg is passed to a downstream .NET console app.\n // for example, the command line:\n // foo.exe \"myarg:\"\"my val\"\"\"\n // is parsed by a .NET console app into an arg array:\n // [ \"myarg:\\\"my val\\\"\" ]\n // which is the same end result when applying libuv quoting rules. although the actual\n // command line from libuv quoting rules would look like:\n // foo.exe \"myarg:\\\"my val\\\"\"\n //\n // 3) double-up slashes that precede a quote,\n // e.g. hello \\world => \"hello \\world\"\n // hello\\\"world => \"hello\\\\\"\"world\"\n // hello\\\\\"world => \"hello\\\\\\\\\"\"world\"\n // hello world\\ => \"hello world\\\\\"\n //\n // technically this is not required for a cmd.exe command line, or the batch argument parser.\n // the reasons for including this as a .cmd quoting rule are:\n //\n // a) this is optimized for the scenario where the argument is passed from the .cmd file to an\n // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.\n //\n // b) it's what we've been doing previously (by deferring to node default behavior) and we\n // haven't heard any complaints about that aspect.\n //\n // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be\n // escaped when used on the command line directly - even though within a .cmd file % can be escaped\n // by using %%.\n //\n // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts\n // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.\n //\n // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would\n // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the\n // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args\n // to an external program.\n //\n // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.\n // % can be escaped within a .cmd file.\n let reverse = '\"';\n let quoteHit = true;\n for (let i = arg.length; i > 0; i--) {\n // walk the string in reverse\n reverse += arg[i - 1];\n if (quoteHit && arg[i - 1] === '\\\\') {\n reverse += '\\\\'; // double the slash\n }\n else if (arg[i - 1] === '\"') {\n quoteHit = true;\n reverse += '\"'; // double the quote\n }\n else {\n quoteHit = false;\n }\n }\n reverse += '\"';\n return reverse\n .split('')\n .reverse()\n .join('');\n }\n _uvQuoteCmdArg(arg) {\n // Tool runner wraps child_process.spawn() and needs to apply the same quoting as\n // Node in certain cases where the undocumented spawn option windowsVerbatimArguments\n // is used.\n //\n // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,\n // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),\n // pasting copyright notice from Node within this function:\n //\n // Copyright Joyent, Inc. and other Node contributors. All rights reserved.\n //\n // Permission is hereby granted, free of charge, to any person obtaining a copy\n // of this software and associated documentation files (the \"Software\"), to\n // deal in the Software without restriction, including without limitation the\n // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n // sell copies of the Software, and to permit persons to whom the Software is\n // furnished to do so, subject to the following conditions:\n //\n // The above copyright notice and this permission notice shall be included in\n // all copies or substantial portions of the Software.\n //\n // THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n // IN THE SOFTWARE.\n if (!arg) {\n // Need double quotation for empty argument\n return '\"\"';\n }\n if (!arg.includes(' ') && !arg.includes('\\t') && !arg.includes('\"')) {\n // No quotation needed\n return arg;\n }\n if (!arg.includes('\"') && !arg.includes('\\\\')) {\n // No embedded double quotes or backslashes, so I can just wrap\n // quote marks around the whole thing.\n return `\"${arg}\"`;\n }\n // Expected input/output:\n // input : hello\"world\n // output: \"hello\\\"world\"\n // input : hello\"\"world\n // output: \"hello\\\"\\\"world\"\n // input : hello\\world\n // output: hello\\world\n // input : hello\\\\world\n // output: hello\\\\world\n // input : hello\\\"world\n // output: \"hello\\\\\\\"world\"\n // input : hello\\\\\"world\n // output: \"hello\\\\\\\\\\\"world\"\n // input : hello world\\\n // output: \"hello world\\\\\" - note the comment in libuv actually reads \"hello world\\\"\n // but it appears the comment is wrong, it should be \"hello world\\\\\"\n let reverse = '\"';\n let quoteHit = true;\n for (let i = arg.length; i > 0; i--) {\n // walk the string in reverse\n reverse += arg[i - 1];\n if (quoteHit && arg[i - 1] === '\\\\') {\n reverse += '\\\\';\n }\n else if (arg[i - 1] === '\"') {\n quoteHit = true;\n reverse += '\\\\';\n }\n else {\n quoteHit = false;\n }\n }\n reverse += '\"';\n return reverse\n .split('')\n .reverse()\n .join('');\n }\n _cloneExecOptions(options) {\n options = options || {};\n const result = {\n cwd: options.cwd || process.cwd(),\n env: options.env || process.env,\n silent: options.silent || false,\n windowsVerbatimArguments: options.windowsVerbatimArguments || false,\n failOnStdErr: options.failOnStdErr || false,\n ignoreReturnCode: options.ignoreReturnCode || false,\n delay: options.delay || 10000\n };\n result.outStream = options.outStream || process.stdout;\n result.errStream = options.errStream || process.stderr;\n return result;\n }\n _getSpawnOptions(options, toolPath) {\n options = options || {};\n const result = {};\n result.cwd = options.cwd;\n result.env = options.env;\n result['windowsVerbatimArguments'] =\n options.windowsVerbatimArguments || this._isCmdFile();\n if (options.windowsVerbatimArguments) {\n result.argv0 = `\"${toolPath}\"`;\n }\n return result;\n }\n /**\n * Exec a tool.\n * Output will be streamed to the live console.\n * Returns promise with return code\n *\n * @param tool path to tool to exec\n * @param options optional exec options. See ExecOptions\n * @returns number\n */\n exec() {\n return __awaiter(this, void 0, void 0, function* () {\n // root the tool path if it is unrooted and contains relative pathing\n if (!ioUtil.isRooted(this.toolPath) &&\n (this.toolPath.includes('/') ||\n (IS_WINDOWS && this.toolPath.includes('\\\\')))) {\n // prefer options.cwd if it is specified, however options.cwd may also need to be rooted\n this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);\n }\n // if the tool is only a file name, then resolve it from the PATH\n // otherwise verify it exists (add extension on Windows if necessary)\n this.toolPath = yield io.which(this.toolPath, true);\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n this._debug(`exec tool: ${this.toolPath}`);\n this._debug('arguments:');\n for (const arg of this.args) {\n this._debug(` ${arg}`);\n }\n const optionsNonNull = this._cloneExecOptions(this.options);\n if (!optionsNonNull.silent && optionsNonNull.outStream) {\n optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);\n }\n const state = new ExecState(optionsNonNull, this.toolPath);\n state.on('debug', (message) => {\n this._debug(message);\n });\n if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) {\n return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));\n }\n const fileName = this._getSpawnFileName();\n const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));\n let stdbuffer = '';\n if (cp.stdout) {\n cp.stdout.on('data', (data) => {\n if (this.options.listeners && this.options.listeners.stdout) {\n this.options.listeners.stdout(data);\n }\n if (!optionsNonNull.silent && optionsNonNull.outStream) {\n optionsNonNull.outStream.write(data);\n }\n stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {\n if (this.options.listeners && this.options.listeners.stdline) {\n this.options.listeners.stdline(line);\n }\n });\n });\n }\n let errbuffer = '';\n if (cp.stderr) {\n cp.stderr.on('data', (data) => {\n state.processStderr = true;\n if (this.options.listeners && this.options.listeners.stderr) {\n this.options.listeners.stderr(data);\n }\n if (!optionsNonNull.silent &&\n optionsNonNull.errStream &&\n optionsNonNull.outStream) {\n const s = optionsNonNull.failOnStdErr\n ? optionsNonNull.errStream\n : optionsNonNull.outStream;\n s.write(data);\n }\n errbuffer = this._processLineBuffer(data, errbuffer, (line) => {\n if (this.options.listeners && this.options.listeners.errline) {\n this.options.listeners.errline(line);\n }\n });\n });\n }\n cp.on('error', (err) => {\n state.processError = err.message;\n state.processExited = true;\n state.processClosed = true;\n state.CheckComplete();\n });\n cp.on('exit', (code) => {\n state.processExitCode = code;\n state.processExited = true;\n this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);\n state.CheckComplete();\n });\n cp.on('close', (code) => {\n state.processExitCode = code;\n state.processExited = true;\n state.processClosed = true;\n this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);\n state.CheckComplete();\n });\n state.on('done', (error, exitCode) => {\n if (stdbuffer.length > 0) {\n this.emit('stdline', stdbuffer);\n }\n if (errbuffer.length > 0) {\n this.emit('errline', errbuffer);\n }\n cp.removeAllListeners();\n if (error) {\n reject(error);\n }\n else {\n resolve(exitCode);\n }\n });\n if (this.options.input) {\n if (!cp.stdin) {\n throw new Error('child process missing stdin');\n }\n cp.stdin.end(this.options.input);\n }\n }));\n });\n }\n}\nexports.ToolRunner = ToolRunner;\n/**\n * Convert an arg string to an array of args. Handles escaping\n *\n * @param argString string of arguments\n * @returns string[] array of arguments\n */\nfunction argStringToArray(argString) {\n const args = [];\n let inQuotes = false;\n let escaped = false;\n let arg = '';\n function append(c) {\n // we only escape double quotes.\n if (escaped && c !== '\"') {\n arg += '\\\\';\n }\n arg += c;\n escaped = false;\n }\n for (let i = 0; i < argString.length; i++) {\n const c = argString.charAt(i);\n if (c === '\"') {\n if (!escaped) {\n inQuotes = !inQuotes;\n }\n else {\n append(c);\n }\n continue;\n }\n if (c === '\\\\' && escaped) {\n append(c);\n continue;\n }\n if (c === '\\\\' && inQuotes) {\n escaped = true;\n continue;\n }\n if (c === ' ' && !inQuotes) {\n if (arg.length > 0) {\n args.push(arg);\n arg = '';\n }\n continue;\n }\n append(c);\n }\n if (arg.length > 0) {\n args.push(arg.trim());\n }\n return args;\n}\nexports.argStringToArray = argStringToArray;\nclass ExecState extends events.EventEmitter {\n constructor(options, toolPath) {\n super();\n this.processClosed = false; // tracks whether the process has exited and stdio is closed\n this.processError = '';\n this.processExitCode = 0;\n this.processExited = false; // tracks whether the process has exited\n this.processStderr = false; // tracks whether stderr was written to\n this.delay = 10000; // 10 seconds\n this.done = false;\n this.timeout = null;\n if (!toolPath) {\n throw new Error('toolPath must not be empty');\n }\n this.options = options;\n this.toolPath = toolPath;\n if (options.delay) {\n this.delay = options.delay;\n }\n }\n CheckComplete() {\n if (this.done) {\n return;\n }\n if (this.processClosed) {\n this._setResult();\n }\n else if (this.processExited) {\n this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);\n }\n }\n _debug(message) {\n this.emit('debug', message);\n }\n _setResult() {\n // determine whether there is an error\n let error;\n if (this.processExited) {\n if (this.processError) {\n error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);\n }\n else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {\n error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);\n }\n else if (this.processStderr && this.options.failOnStdErr) {\n error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);\n }\n }\n // clear the timeout\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n this.done = true;\n this.emit('done', error, this.processExitCode);\n }\n static HandleTimeout(state) {\n if (state.done) {\n return;\n }\n if (!state.processClosed && state.processExited) {\n const message = `The STDIO streams did not close within ${state.delay /\n 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;\n state._debug(message);\n }\n state._setResult();\n }\n}\n//# sourceMappingURL=toolrunner.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar _a;\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst assert_1 = require(\"assert\");\nconst fs = __importStar(require(\"fs\"));\nconst path = __importStar(require(\"path\"));\n_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;\nexports.IS_WINDOWS = process.platform === 'win32';\nfunction exists(fsPath) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n yield exports.stat(fsPath);\n }\n catch (err) {\n if (err.code === 'ENOENT') {\n return false;\n }\n throw err;\n }\n return true;\n });\n}\nexports.exists = exists;\nfunction isDirectory(fsPath, useStat = false) {\n return __awaiter(this, void 0, void 0, function* () {\n const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);\n return stats.isDirectory();\n });\n}\nexports.isDirectory = isDirectory;\n/**\n * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:\n * \\, \\hello, \\\\hello\\share, C:, and C:\\hello (and corresponding alternate separator cases).\n */\nfunction isRooted(p) {\n p = normalizeSeparators(p);\n if (!p) {\n throw new Error('isRooted() parameter \"p\" cannot be empty');\n }\n if (exports.IS_WINDOWS) {\n return (p.startsWith('\\\\') || /^[A-Z]:/i.test(p) // e.g. \\ or \\hello or \\\\hello\n ); // e.g. C: or C:\\hello\n }\n return p.startsWith('/');\n}\nexports.isRooted = isRooted;\n/**\n * Recursively create a directory at `fsPath`.\n *\n * This implementation is optimistic, meaning it attempts to create the full\n * path first, and backs up the path stack from there.\n *\n * @param fsPath The path to create\n * @param maxDepth The maximum recursion depth\n * @param depth The current recursion depth\n */\nfunction mkdirP(fsPath, maxDepth = 1000, depth = 1) {\n return __awaiter(this, void 0, void 0, function* () {\n assert_1.ok(fsPath, 'a path argument must be provided');\n fsPath = path.resolve(fsPath);\n if (depth >= maxDepth)\n return exports.mkdir(fsPath);\n try {\n yield exports.mkdir(fsPath);\n return;\n }\n catch (err) {\n switch (err.code) {\n case 'ENOENT': {\n yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);\n yield exports.mkdir(fsPath);\n return;\n }\n default: {\n let stats;\n try {\n stats = yield exports.stat(fsPath);\n }\n catch (err2) {\n throw err;\n }\n if (!stats.isDirectory())\n throw err;\n }\n }\n }\n });\n}\nexports.mkdirP = mkdirP;\n/**\n * Best effort attempt to determine whether a file exists and is executable.\n * @param filePath file path to check\n * @param extensions additional file extensions to try\n * @return if file exists and is executable, returns the file path. otherwise empty string.\n */\nfunction tryGetExecutablePath(filePath, extensions) {\n return __awaiter(this, void 0, void 0, function* () {\n let stats = undefined;\n try {\n // test file exists\n stats = yield exports.stat(filePath);\n }\n catch (err) {\n if (err.code !== 'ENOENT') {\n // eslint-disable-next-line no-console\n console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);\n }\n }\n if (stats && stats.isFile()) {\n if (exports.IS_WINDOWS) {\n // on Windows, test for valid extension\n const upperExt = path.extname(filePath).toUpperCase();\n if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {\n return filePath;\n }\n }\n else {\n if (isUnixExecutable(stats)) {\n return filePath;\n }\n }\n }\n // try each extension\n const originalFilePath = filePath;\n for (const extension of extensions) {\n filePath = originalFilePath + extension;\n stats = undefined;\n try {\n stats = yield exports.stat(filePath);\n }\n catch (err) {\n if (err.code !== 'ENOENT') {\n // eslint-disable-next-line no-console\n console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);\n }\n }\n if (stats && stats.isFile()) {\n if (exports.IS_WINDOWS) {\n // preserve the case of the actual file (since an extension was appended)\n try {\n const directory = path.dirname(filePath);\n const upperName = path.basename(filePath).toUpperCase();\n for (const actualName of yield exports.readdir(directory)) {\n if (upperName === actualName.toUpperCase()) {\n filePath = path.join(directory, actualName);\n break;\n }\n }\n }\n catch (err) {\n // eslint-disable-next-line no-console\n console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);\n }\n return filePath;\n }\n else {\n if (isUnixExecutable(stats)) {\n return filePath;\n }\n }\n }\n }\n return '';\n });\n}\nexports.tryGetExecutablePath = tryGetExecutablePath;\nfunction normalizeSeparators(p) {\n p = p || '';\n if (exports.IS_WINDOWS) {\n // convert slashes on Windows\n p = p.replace(/\\//g, '\\\\');\n // remove redundant slashes\n return p.replace(/\\\\\\\\+/g, '\\\\');\n }\n // remove redundant slashes\n return p.replace(/\\/\\/+/g, '/');\n}\n// on Mac/Linux, test the execute bit\n// R W X R W X R W X\n// 256 128 64 32 16 8 4 2 1\nfunction isUnixExecutable(stats) {\n return ((stats.mode & 1) > 0 ||\n ((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||\n ((stats.mode & 64) > 0 && stats.uid === process.getuid()));\n}\n//# sourceMappingURL=io-util.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst childProcess = __importStar(require(\"child_process\"));\nconst path = __importStar(require(\"path\"));\nconst util_1 = require(\"util\");\nconst ioUtil = __importStar(require(\"./io-util\"));\nconst exec = util_1.promisify(childProcess.exec);\n/**\n * Copies a file or folder.\n * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js\n *\n * @param source source path\n * @param dest destination path\n * @param options optional. See CopyOptions.\n */\nfunction cp(source, dest, options = {}) {\n return __awaiter(this, void 0, void 0, function* () {\n const { force, recursive } = readCopyOptions(options);\n const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;\n // Dest is an existing file, but not forcing\n if (destStat && destStat.isFile() && !force) {\n return;\n }\n // If dest is an existing directory, should copy inside.\n const newDest = destStat && destStat.isDirectory()\n ? path.join(dest, path.basename(source))\n : dest;\n if (!(yield ioUtil.exists(source))) {\n throw new Error(`no such file or directory: ${source}`);\n }\n const sourceStat = yield ioUtil.stat(source);\n if (sourceStat.isDirectory()) {\n if (!recursive) {\n throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);\n }\n else {\n yield cpDirRecursive(source, newDest, 0, force);\n }\n }\n else {\n if (path.relative(source, newDest) === '') {\n // a file cannot be copied to itself\n throw new Error(`'${newDest}' and '${source}' are the same file`);\n }\n yield copyFile(source, newDest, force);\n }\n });\n}\nexports.cp = cp;\n/**\n * Moves a path.\n *\n * @param source source path\n * @param dest destination path\n * @param options optional. See MoveOptions.\n */\nfunction mv(source, dest, options = {}) {\n return __awaiter(this, void 0, void 0, function* () {\n if (yield ioUtil.exists(dest)) {\n let destExists = true;\n if (yield ioUtil.isDirectory(dest)) {\n // If dest is directory copy src into dest\n dest = path.join(dest, path.basename(source));\n destExists = yield ioUtil.exists(dest);\n }\n if (destExists) {\n if (options.force == null || options.force) {\n yield rmRF(dest);\n }\n else {\n throw new Error('Destination already exists');\n }\n }\n }\n yield mkdirP(path.dirname(dest));\n yield ioUtil.rename(source, dest);\n });\n}\nexports.mv = mv;\n/**\n * Remove a path recursively with force\n *\n * @param inputPath path to remove\n */\nfunction rmRF(inputPath) {\n return __awaiter(this, void 0, void 0, function* () {\n if (ioUtil.IS_WINDOWS) {\n // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another\n // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.\n try {\n if (yield ioUtil.isDirectory(inputPath, true)) {\n yield exec(`rd /s /q \"${inputPath}\"`);\n }\n else {\n yield exec(`del /f /a \"${inputPath}\"`);\n }\n }\n catch (err) {\n // if you try to delete a file that doesn't exist, desired result is achieved\n // other errors are valid\n if (err.code !== 'ENOENT')\n throw err;\n }\n // Shelling out fails to remove a symlink folder with missing source, this unlink catches that\n try {\n yield ioUtil.unlink(inputPath);\n }\n catch (err) {\n // if you try to delete a file that doesn't exist, desired result is achieved\n // other errors are valid\n if (err.code !== 'ENOENT')\n throw err;\n }\n }\n else {\n let isDir = false;\n try {\n isDir = yield ioUtil.isDirectory(inputPath);\n }\n catch (err) {\n // if you try to delete a file that doesn't exist, desired result is achieved\n // other errors are valid\n if (err.code !== 'ENOENT')\n throw err;\n return;\n }\n if (isDir) {\n yield exec(`rm -rf \"${inputPath}\"`);\n }\n else {\n yield ioUtil.unlink(inputPath);\n }\n }\n });\n}\nexports.rmRF = rmRF;\n/**\n * Make a directory. Creates the full path with folders in between\n * Will throw if it fails\n *\n * @param fsPath path to create\n * @returns Promise\n */\nfunction mkdirP(fsPath) {\n return __awaiter(this, void 0, void 0, function* () {\n yield ioUtil.mkdirP(fsPath);\n });\n}\nexports.mkdirP = mkdirP;\n/**\n * Returns path of a tool had the tool actually been invoked. Resolves via paths.\n * If you check and the tool does not exist, it will throw.\n *\n * @param tool name of the tool\n * @param check whether to check if tool exists\n * @returns Promise path to tool\n */\nfunction which(tool, check) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!tool) {\n throw new Error(\"parameter 'tool' is required\");\n }\n // recursive when check=true\n if (check) {\n const result = yield which(tool, false);\n if (!result) {\n if (ioUtil.IS_WINDOWS) {\n throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);\n }\n else {\n throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);\n }\n }\n return result;\n }\n const matches = yield findInPath(tool);\n if (matches && matches.length > 0) {\n return matches[0];\n }\n return '';\n });\n}\nexports.which = which;\n/**\n * Returns a list of all occurrences of the given tool on the system path.\n *\n * @returns Promise the paths of the tool\n */\nfunction findInPath(tool) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!tool) {\n throw new Error(\"parameter 'tool' is required\");\n }\n // build the list of extensions to try\n const extensions = [];\n if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {\n for (const extension of process.env['PATHEXT'].split(path.delimiter)) {\n if (extension) {\n extensions.push(extension);\n }\n }\n }\n // if it's rooted, return it if exists. otherwise return empty.\n if (ioUtil.isRooted(tool)) {\n const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);\n if (filePath) {\n return [filePath];\n }\n return [];\n }\n // if any path separators, return empty\n if (tool.includes(path.sep)) {\n return [];\n }\n // build the list of directories\n //\n // Note, technically \"where\" checks the current directory on Windows. From a toolkit perspective,\n // it feels like we should not do this. Checking the current directory seems like more of a use\n // case of a shell, and the which() function exposed by the toolkit should strive for consistency\n // across platforms.\n const directories = [];\n if (process.env.PATH) {\n for (const p of process.env.PATH.split(path.delimiter)) {\n if (p) {\n directories.push(p);\n }\n }\n }\n // find all matches\n const matches = [];\n for (const directory of directories) {\n const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);\n if (filePath) {\n matches.push(filePath);\n }\n }\n return matches;\n });\n}\nexports.findInPath = findInPath;\nfunction readCopyOptions(options) {\n const force = options.force == null ? true : options.force;\n const recursive = Boolean(options.recursive);\n return { force, recursive };\n}\nfunction cpDirRecursive(sourceDir, destDir, currentDepth, force) {\n return __awaiter(this, void 0, void 0, function* () {\n // Ensure there is not a run away recursive copy\n if (currentDepth >= 255)\n return;\n currentDepth++;\n yield mkdirP(destDir);\n const files = yield ioUtil.readdir(sourceDir);\n for (const fileName of files) {\n const srcFile = `${sourceDir}/${fileName}`;\n const destFile = `${destDir}/${fileName}`;\n const srcFileStat = yield ioUtil.lstat(srcFile);\n if (srcFileStat.isDirectory()) {\n // Recurse\n yield cpDirRecursive(srcFile, destFile, currentDepth, force);\n }\n else {\n yield copyFile(srcFile, destFile, force);\n }\n }\n // Change the mode for the newly created directory\n yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);\n });\n}\n// Buffered file copy\nfunction copyFile(srcFile, destFile, force) {\n return __awaiter(this, void 0, void 0, function* () {\n if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {\n // unlink/re-link it\n try {\n yield ioUtil.lstat(destFile);\n yield ioUtil.unlink(destFile);\n }\n catch (e) {\n // Try to override file permission\n if (e.code === 'EPERM') {\n yield ioUtil.chmod(destFile, '0666');\n yield ioUtil.unlink(destFile);\n }\n // other errors = it doesn't exist, no work to do\n }\n // Copy over symlink\n const symlinkFull = yield ioUtil.readlink(srcFile);\n yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);\n }\n else if (!(yield ioUtil.exists(destFile)) || force) {\n yield ioUtil.copyFile(srcFile, destFile);\n }\n });\n}\n//# sourceMappingURL=io.js.map","\n\nclass ResizeableBuffer{\n constructor(size=100){\n this.size = size\n this.length = 0\n this.buf = Buffer.alloc(size)\n }\n prepend(val){\n if(Buffer.isBuffer(val)){\n const length = this.length + val.length\n if(length >= this.size){\n this.resize()\n if(length >= this.size){\n throw Error('INVALID_BUFFER_STATE')\n }\n }\n const buf = this.buf\n this.buf = Buffer.alloc(this.size)\n val.copy(this.buf, 0)\n buf.copy(this.buf, val.length)\n this.length += val.length\n }else{\n const length = this.length++\n if(length === this.size){\n this.resize()\n }\n const buf = this.clone()\n this.buf[0] = val\n buf.copy(this.buf,1, 0, length)\n }\n }\n append(val){\n const length = this.length++\n if(length === this.size){\n this.resize()\n }\n this.buf[length] = val\n }\n clone(){\n return Buffer.from(this.buf.slice(0, this.length))\n }\n resize(){\n const length = this.length\n this.size = this.size * 2\n const buf = Buffer.alloc(this.size)\n this.buf.copy(buf,0, 0, length)\n this.buf = buf\n }\n toString(encoding){\n if(encoding){\n return this.buf.slice(0, this.length).toString(encoding)\n }else{\n return Uint8Array.prototype.slice.call(this.buf.slice(0, this.length))\n }\n }\n toJSON(){\n return this.toString('utf8')\n }\n reset(){\n this.length = 0\n }\n}\n\nmodule.exports = ResizeableBuffer\n","\n/*\nCSV Parse\n\nPlease look at the [project documentation](https://csv.js.org/parse/) for\nadditional information.\n*/\n\nconst { Transform } = require('stream')\nconst ResizeableBuffer = require('./ResizeableBuffer')\n\n// white space characters\n// https://en.wikipedia.org/wiki/Whitespace_character\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types\n// \\f\\n\\r\\t\\v\\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff\nconst tab = 9\nconst nl = 10 // \\n, 0x0A in hexadecimal, 10 in decimal\nconst np = 12\nconst cr = 13 // \\r, 0x0D in hexadécimal, 13 in decimal\nconst space = 32\nconst boms = {\n // Note, the following are equals:\n // Buffer.from(\"\\ufeff\")\n // Buffer.from([239, 187, 191])\n // Buffer.from('EFBBBF', 'hex')\n 'utf8': Buffer.from([239, 187, 191]),\n // Note, the following are equals:\n // Buffer.from \"\\ufeff\", 'utf16le\n // Buffer.from([255, 254])\n 'utf16le': Buffer.from([255, 254])\n}\n\nclass Parser extends Transform {\n constructor(opts = {}){\n super({...{readableObjectMode: true}, ...opts, encoding: null})\n this.__originalOptions = opts\n this.__normalizeOptions(opts)\n }\n __normalizeOptions(opts){\n const options = {}\n // Merge with user options\n for(let opt in opts){\n options[underscore(opt)] = opts[opt]\n }\n // Normalize option `encoding`\n // Note: defined first because other options depends on it\n // to convert chars/strings into buffers.\n if(options.encoding === undefined || options.encoding === true){\n options.encoding = 'utf8'\n }else if(options.encoding === null || options.encoding === false){\n options.encoding = null\n }else if(typeof options.encoding !== 'string' && options.encoding !== null){\n throw new CsvError('CSV_INVALID_OPTION_ENCODING', [\n 'Invalid option encoding:',\n 'encoding must be a string or null to return a buffer,',\n `got ${JSON.stringify(options.encoding)}`\n ], options)\n }\n // Normalize option `bom`\n if(options.bom === undefined || options.bom === null || options.bom === false){\n options.bom = false\n }else if(options.bom !== true){\n throw new CsvError('CSV_INVALID_OPTION_BOM', [\n 'Invalid option bom:', 'bom must be true,',\n `got ${JSON.stringify(options.bom)}`\n ], options)\n }\n // Normalize option `cast`\n let fnCastField = null\n if(options.cast === undefined || options.cast === null || options.cast === false || options.cast === ''){\n options.cast = undefined\n }else if(typeof options.cast === 'function'){\n fnCastField = options.cast\n options.cast = true\n }else if(options.cast !== true){\n throw new CsvError('CSV_INVALID_OPTION_CAST', [\n 'Invalid option cast:', 'cast must be true or a function,',\n `got ${JSON.stringify(options.cast)}`\n ], options)\n }\n // Normalize option `cast_date`\n if(options.cast_date === undefined || options.cast_date === null || options.cast_date === false || options.cast_date === ''){\n options.cast_date = false\n }else if(options.cast_date === true){\n options.cast_date = function(value){\n const date = Date.parse(value)\n return !isNaN(date) ? new Date(date) : value\n }\n }else if(typeof options.cast_date !== 'function'){\n throw new CsvError('CSV_INVALID_OPTION_CAST_DATE', [\n 'Invalid option cast_date:', 'cast_date must be true or a function,',\n `got ${JSON.stringify(options.cast_date)}`\n ], options)\n }\n // Normalize option `columns`\n let fnFirstLineToHeaders = null\n if(options.columns === true){\n // Fields in the first line are converted as-is to columns\n fnFirstLineToHeaders = undefined\n }else if(typeof options.columns === 'function'){\n fnFirstLineToHeaders = options.columns\n options.columns = true\n }else if(Array.isArray(options.columns)){\n options.columns = normalizeColumnsArray(options.columns)\n }else if(options.columns === undefined || options.columns === null || options.columns === false){\n options.columns = false\n }else{\n throw new CsvError('CSV_INVALID_OPTION_COLUMNS', [\n 'Invalid option columns:',\n 'expect an object, a function or true,',\n `got ${JSON.stringify(options.columns)}`\n ], options)\n }\n // Normalize option `columns_duplicates_to_array`\n if(options.columns_duplicates_to_array === undefined || options.columns_duplicates_to_array === null || options.columns_duplicates_to_array === false){\n options.columns_duplicates_to_array = false\n }else if(options.columns_duplicates_to_array !== true){\n throw new CsvError('CSV_INVALID_OPTION_COLUMNS_DUPLICATES_TO_ARRAY', [\n 'Invalid option columns_duplicates_to_array:',\n 'expect an boolean,',\n `got ${JSON.stringify(options.columns_duplicates_to_array)}`\n ], options)\n }\n // Normalize option `comment`\n if(options.comment === undefined || options.comment === null || options.comment === false || options.comment === ''){\n options.comment = null\n }else{\n if(typeof options.comment === 'string'){\n options.comment = Buffer.from(options.comment, options.encoding)\n }\n if(!Buffer.isBuffer(options.comment)){\n throw new CsvError('CSV_INVALID_OPTION_COMMENT', [\n 'Invalid option comment:',\n 'comment must be a buffer or a string,',\n `got ${JSON.stringify(options.comment)}`\n ], options)\n }\n }\n // Normalize option `delimiter`\n const delimiter_json = JSON.stringify(options.delimiter)\n if(!Array.isArray(options.delimiter)) options.delimiter = [options.delimiter]\n if(options.delimiter.length === 0){\n throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [\n 'Invalid option delimiter:',\n 'delimiter must be a non empty string or buffer or array of string|buffer,',\n `got ${delimiter_json}`\n ], options)\n }\n options.delimiter = options.delimiter.map(function(delimiter){\n if(delimiter === undefined || delimiter === null || delimiter === false){\n return Buffer.from(',', options.encoding)\n }\n if(typeof delimiter === 'string'){\n delimiter = Buffer.from(delimiter, options.encoding)\n }\n if( !Buffer.isBuffer(delimiter) || delimiter.length === 0){\n throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [\n 'Invalid option delimiter:',\n 'delimiter must be a non empty string or buffer or array of string|buffer,',\n `got ${delimiter_json}`\n ], options)\n }\n return delimiter\n })\n // Normalize option `escape`\n if(options.escape === undefined || options.escape === true){\n options.escape = Buffer.from('\"', options.encoding)\n }else if(typeof options.escape === 'string'){\n options.escape = Buffer.from(options.escape, options.encoding)\n }else if (options.escape === null || options.escape === false){\n options.escape = null\n }\n if(options.escape !== null){\n if(!Buffer.isBuffer(options.escape)){\n throw new Error(`Invalid Option: escape must be a buffer, a string or a boolean, got ${JSON.stringify(options.escape)}`)\n }\n }\n // Normalize option `from`\n if(options.from === undefined || options.from === null){\n options.from = 1\n }else{\n if(typeof options.from === 'string' && /\\d+/.test(options.from)){\n options.from = parseInt(options.from)\n }\n if(Number.isInteger(options.from)){\n if(options.from < 0){\n throw new Error(`Invalid Option: from must be a positive integer, got ${JSON.stringify(opts.from)}`)\n }\n }else{\n throw new Error(`Invalid Option: from must be an integer, got ${JSON.stringify(options.from)}`)\n }\n }\n // Normalize option `from_line`\n if(options.from_line === undefined || options.from_line === null){\n options.from_line = 1\n }else{\n if(typeof options.from_line === 'string' && /\\d+/.test(options.from_line)){\n options.from_line = parseInt(options.from_line)\n }\n if(Number.isInteger(options.from_line)){\n if(options.from_line <= 0){\n throw new Error(`Invalid Option: from_line must be a positive integer greater than 0, got ${JSON.stringify(opts.from_line)}`)\n }\n }else{\n throw new Error(`Invalid Option: from_line must be an integer, got ${JSON.stringify(opts.from_line)}`)\n }\n }\n // Normalize options `ignore_last_delimiters`\n if(options.ignore_last_delimiters === undefined || options.ignore_last_delimiters === null){\n options.ignore_last_delimiters = false\n }else if(typeof options.ignore_last_delimiters === 'number'){\n options.ignore_last_delimiters = Math.floor(options.ignore_last_delimiters)\n if(options.ignore_last_delimiters === 0){\n options.ignore_last_delimiters = false\n }\n }else if(typeof options.ignore_last_delimiters !== 'boolean'){\n throw new CsvError('CSV_INVALID_OPTION_IGNORE_LAST_DELIMITERS', [\n 'Invalid option `ignore_last_delimiters`:',\n 'the value must be a boolean value or an integer,',\n `got ${JSON.stringify(options.ignore_last_delimiters)}`\n ], options)\n }\n if(options.ignore_last_delimiters === true && options.columns === false){\n throw new CsvError('CSV_IGNORE_LAST_DELIMITERS_REQUIRES_COLUMNS', [\n 'The option `ignore_last_delimiters`',\n 'requires the activation of the `columns` option'\n ], options)\n }\n // Normalize option `info`\n if(options.info === undefined || options.info === null || options.info === false){\n options.info = false\n }else if(options.info !== true){\n throw new Error(`Invalid Option: info must be true, got ${JSON.stringify(options.info)}`)\n }\n // Normalize option `max_record_size`\n if(options.max_record_size === undefined || options.max_record_size === null || options.max_record_size === false){\n options.max_record_size = 0\n }else if(Number.isInteger(options.max_record_size) && options.max_record_size >= 0){\n // Great, nothing to do\n }else if(typeof options.max_record_size === 'string' && /\\d+/.test(options.max_record_size)){\n options.max_record_size = parseInt(options.max_record_size)\n }else{\n throw new Error(`Invalid Option: max_record_size must be a positive integer, got ${JSON.stringify(options.max_record_size)}`)\n }\n // Normalize option `objname`\n if(options.objname === undefined || options.objname === null || options.objname === false){\n options.objname = undefined\n }else if(Buffer.isBuffer(options.objname)){\n if(options.objname.length === 0){\n throw new Error(`Invalid Option: objname must be a non empty buffer`)\n }\n if(options.encoding === null){\n // Don't call `toString`, leave objname as a buffer\n }else{\n options.objname = options.objname.toString(options.encoding)\n }\n }else if(typeof options.objname === 'string'){\n if(options.objname.length === 0){\n throw new Error(`Invalid Option: objname must be a non empty string`)\n }\n // Great, nothing to do\n }else{\n throw new Error(`Invalid Option: objname must be a string or a buffer, got ${options.objname}`)\n }\n // Normalize option `on_record`\n if(options.on_record === undefined || options.on_record === null){\n options.on_record = undefined\n }else if(typeof options.on_record !== 'function'){\n throw new CsvError('CSV_INVALID_OPTION_ON_RECORD', [\n 'Invalid option `on_record`:',\n 'expect a function,',\n `got ${JSON.stringify(options.on_record)}`\n ], options)\n }\n // Normalize option `quote`\n if(options.quote === null || options.quote === false || options.quote === ''){\n options.quote = null\n }else{\n if(options.quote === undefined || options.quote === true){\n options.quote = Buffer.from('\"', options.encoding)\n }else if(typeof options.quote === 'string'){\n options.quote = Buffer.from(options.quote, options.encoding)\n }\n if(!Buffer.isBuffer(options.quote)){\n throw new Error(`Invalid Option: quote must be a buffer or a string, got ${JSON.stringify(options.quote)}`)\n }\n }\n // Normalize option `raw`\n if(options.raw === undefined || options.raw === null || options.raw === false){\n options.raw = false\n }else if(options.raw !== true){\n throw new Error(`Invalid Option: raw must be true, got ${JSON.stringify(options.raw)}`)\n }\n // Normalize option `record_delimiter`\n if(!options.record_delimiter){\n options.record_delimiter = []\n }else if(!Array.isArray(options.record_delimiter)){\n options.record_delimiter = [options.record_delimiter]\n }\n options.record_delimiter = options.record_delimiter.map( function(rd){\n if(typeof rd === 'string'){\n rd = Buffer.from(rd, options.encoding)\n }\n return rd\n })\n // Normalize option `relax`\n if(typeof options.relax === 'boolean'){\n // Great, nothing to do\n }else if(options.relax === undefined || options.relax === null){\n options.relax = false\n }else{\n throw new Error(`Invalid Option: relax must be a boolean, got ${JSON.stringify(options.relax)}`)\n }\n // Normalize option `relax_column_count`\n if(typeof options.relax_column_count === 'boolean'){\n // Great, nothing to do\n }else if(options.relax_column_count === undefined || options.relax_column_count === null){\n options.relax_column_count = false\n }else{\n throw new Error(`Invalid Option: relax_column_count must be a boolean, got ${JSON.stringify(options.relax_column_count)}`)\n }\n if(typeof options.relax_column_count_less === 'boolean'){\n // Great, nothing to do\n }else if(options.relax_column_count_less === undefined || options.relax_column_count_less === null){\n options.relax_column_count_less = false\n }else{\n throw new Error(`Invalid Option: relax_column_count_less must be a boolean, got ${JSON.stringify(options.relax_column_count_less)}`)\n }\n if(typeof options.relax_column_count_more === 'boolean'){\n // Great, nothing to do\n }else if(options.relax_column_count_more === undefined || options.relax_column_count_more === null){\n options.relax_column_count_more = false\n }else{\n throw new Error(`Invalid Option: relax_column_count_more must be a boolean, got ${JSON.stringify(options.relax_column_count_more)}`)\n }\n // Normalize option `skip_empty_lines`\n if(typeof options.skip_empty_lines === 'boolean'){\n // Great, nothing to do\n }else if(options.skip_empty_lines === undefined || options.skip_empty_lines === null){\n options.skip_empty_lines = false\n }else{\n throw new Error(`Invalid Option: skip_empty_lines must be a boolean, got ${JSON.stringify(options.skip_empty_lines)}`)\n }\n // Normalize option `skip_lines_with_empty_values`\n if(typeof options.skip_lines_with_empty_values === 'boolean'){\n // Great, nothing to do\n }else if(options.skip_lines_with_empty_values === undefined || options.skip_lines_with_empty_values === null){\n options.skip_lines_with_empty_values = false\n }else{\n throw new Error(`Invalid Option: skip_lines_with_empty_values must be a boolean, got ${JSON.stringify(options.skip_lines_with_empty_values)}`)\n }\n // Normalize option `skip_lines_with_error`\n if(typeof options.skip_lines_with_error === 'boolean'){\n // Great, nothing to do\n }else if(options.skip_lines_with_error === undefined || options.skip_lines_with_error === null){\n options.skip_lines_with_error = false\n }else{\n throw new Error(`Invalid Option: skip_lines_with_error must be a boolean, got ${JSON.stringify(options.skip_lines_with_error)}`)\n }\n // Normalize option `rtrim`\n if(options.rtrim === undefined || options.rtrim === null || options.rtrim === false){\n options.rtrim = false\n }else if(options.rtrim !== true){\n throw new Error(`Invalid Option: rtrim must be a boolean, got ${JSON.stringify(options.rtrim)}`)\n }\n // Normalize option `ltrim`\n if(options.ltrim === undefined || options.ltrim === null || options.ltrim === false){\n options.ltrim = false\n }else if(options.ltrim !== true){\n throw new Error(`Invalid Option: ltrim must be a boolean, got ${JSON.stringify(options.ltrim)}`)\n }\n // Normalize option `trim`\n if(options.trim === undefined || options.trim === null || options.trim === false){\n options.trim = false\n }else if(options.trim !== true){\n throw new Error(`Invalid Option: trim must be a boolean, got ${JSON.stringify(options.trim)}`)\n }\n // Normalize options `trim`, `ltrim` and `rtrim`\n if(options.trim === true && opts.ltrim !== false){\n options.ltrim = true\n }else if(options.ltrim !== true){\n options.ltrim = false\n }\n if(options.trim === true && opts.rtrim !== false){\n options.rtrim = true\n }else if(options.rtrim !== true){\n options.rtrim = false\n }\n // Normalize option `to`\n if(options.to === undefined || options.to === null){\n options.to = -1\n }else{\n if(typeof options.to === 'string' && /\\d+/.test(options.to)){\n options.to = parseInt(options.to)\n }\n if(Number.isInteger(options.to)){\n if(options.to <= 0){\n throw new Error(`Invalid Option: to must be a positive integer greater than 0, got ${JSON.stringify(opts.to)}`)\n }\n }else{\n throw new Error(`Invalid Option: to must be an integer, got ${JSON.stringify(opts.to)}`)\n }\n }\n // Normalize option `to_line`\n if(options.to_line === undefined || options.to_line === null){\n options.to_line = -1\n }else{\n if(typeof options.to_line === 'string' && /\\d+/.test(options.to_line)){\n options.to_line = parseInt(options.to_line)\n }\n if(Number.isInteger(options.to_line)){\n if(options.to_line <= 0){\n throw new Error(`Invalid Option: to_line must be a positive integer greater than 0, got ${JSON.stringify(opts.to_line)}`)\n }\n }else{\n throw new Error(`Invalid Option: to_line must be an integer, got ${JSON.stringify(opts.to_line)}`)\n }\n }\n this.info = {\n comment_lines: 0,\n empty_lines: 0,\n invalid_field_length: 0,\n lines: 1,\n records: 0\n }\n this.options = options\n this.state = {\n bomSkipped: false,\n castField: fnCastField,\n commenting: false,\n // Current error encountered by a record\n error: undefined,\n enabled: options.from_line === 1,\n escaping: false,\n // escapeIsQuote: options.escape === options.quote,\n escapeIsQuote: Buffer.isBuffer(options.escape) && Buffer.isBuffer(options.quote) && Buffer.compare(options.escape, options.quote) === 0,\n expectedRecordLength: options.columns === null ? 0 : options.columns.length,\n field: new ResizeableBuffer(20),\n firstLineToHeaders: fnFirstLineToHeaders,\n info: Object.assign({}, this.info),\n needMoreDataSize: Math.max(\n // Skip if the remaining buffer smaller than comment\n options.comment !== null ? options.comment.length : 0,\n // Skip if the remaining buffer can be delimiter\n ...options.delimiter.map( (delimiter) => delimiter.length),\n // Skip if the remaining buffer can be escape sequence\n options.quote !== null ? options.quote.length : 0,\n ),\n previousBuf: undefined,\n quoting: false,\n stop: false,\n rawBuffer: new ResizeableBuffer(100),\n record: [],\n recordHasError: false,\n record_length: 0,\n recordDelimiterMaxLength: options.record_delimiter.length === 0 ? 2 : Math.max(...options.record_delimiter.map( (v) => v.length)),\n trimChars: [Buffer.from(' ', options.encoding)[0], Buffer.from('\\t', options.encoding)[0]],\n wasQuoting: false,\n wasRowDelimiter: false\n }\n }\n // Implementation of `Transform._transform`\n _transform(buf, encoding, callback){\n if(this.state.stop === true){\n return\n }\n const err = this.__parse(buf, false)\n if(err !== undefined){\n this.state.stop = true\n }\n callback(err)\n }\n // Implementation of `Transform._flush`\n _flush(callback){\n if(this.state.stop === true){\n return\n }\n const err = this.__parse(undefined, true)\n callback(err)\n }\n // Central parser implementation\n __parse(nextBuf, end){\n const {bom, comment, escape, from_line, info, ltrim, max_record_size, quote, raw, relax, rtrim, skip_empty_lines, to, to_line} = this.options\n let {record_delimiter} = this.options\n const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state\n let buf\n if(previousBuf === undefined){\n if(nextBuf === undefined){\n // Handle empty string\n this.push(null)\n return\n }else{\n buf = nextBuf\n }\n }else if(previousBuf !== undefined && nextBuf === undefined){\n buf = previousBuf\n }else{\n buf = Buffer.concat([previousBuf, nextBuf])\n }\n // Handle UTF BOM\n if(bomSkipped === false){\n if(bom === false){\n this.state.bomSkipped = true\n }else if(buf.length < 3){\n // No enough data\n if(end === false){\n // Wait for more data\n this.state.previousBuf = buf\n return\n }\n }else{\n for(let encoding in boms){\n if(boms[encoding].compare(buf, 0, boms[encoding].length) === 0){\n // Skip BOM\n buf = buf.slice(boms[encoding].length)\n // Renormalize original options with the new encoding\n this.__normalizeOptions({...this.__originalOptions, encoding: encoding})\n break\n }\n }\n this.state.bomSkipped = true\n }\n }\n const bufLen = buf.length\n let pos\n for(pos = 0; pos < bufLen; pos++){\n // Ensure we get enough space to look ahead\n // There should be a way to move this out of the loop\n if(this.__needMoreData(pos, bufLen, end)){\n break\n }\n if(this.state.wasRowDelimiter === true){\n this.info.lines++\n if(info === true && this.state.record.length === 0 && this.state.field.length === 0 && this.state.wasQuoting === false){\n this.state.info = Object.assign({}, this.info)\n }\n this.state.wasRowDelimiter = false\n }\n if(to_line !== -1 && this.info.lines > to_line){\n this.state.stop = true\n this.push(null)\n return\n }\n // Auto discovery of record_delimiter, unix, mac and windows supported\n if(this.state.quoting === false && record_delimiter.length === 0){\n const record_delimiterCount = this.__autoDiscoverRecordDelimiter(buf, pos)\n if(record_delimiterCount){\n record_delimiter = this.options.record_delimiter\n }\n }\n const chr = buf[pos]\n if(raw === true){\n rawBuffer.append(chr)\n }\n if((chr === cr || chr === nl) && this.state.wasRowDelimiter === false ){\n this.state.wasRowDelimiter = true\n }\n // Previous char was a valid escape char\n // treat the current char as a regular char\n if(this.state.escaping === true){\n this.state.escaping = false\n }else{\n // Escape is only active inside quoted fields\n // We are quoting, the char is an escape chr and there is a chr to escape\n // if(escape !== null && this.state.quoting === true && chr === escape && pos + 1 < bufLen){\n if(escape !== null && this.state.quoting === true && this.__isEscape(buf, pos, chr) && pos + escape.length < bufLen){\n if(escapeIsQuote){\n if(this.__isQuote(buf, pos+escape.length)){\n this.state.escaping = true\n pos += escape.length - 1\n continue\n }\n }else{\n this.state.escaping = true\n pos += escape.length - 1\n continue\n }\n }\n // Not currently escaping and chr is a quote\n // TODO: need to compare bytes instead of single char\n if(this.state.commenting === false && this.__isQuote(buf, pos)){\n if(this.state.quoting === true){\n const nextChr = buf[pos+quote.length]\n const isNextChrTrimable = rtrim && this.__isCharTrimable(nextChr)\n const isNextChrComment = comment !== null && this.__compareBytes(comment, buf, pos+quote.length, nextChr)\n const isNextChrDelimiter = this.__isDelimiter(buf, pos+quote.length, nextChr)\n const isNextChrRecordDelimiter = record_delimiter.length === 0 ? this.__autoDiscoverRecordDelimiter(buf, pos+quote.length) : this.__isRecordDelimiter(nextChr, buf, pos+quote.length)\n // Escape a quote\n // Treat next char as a regular character\n if(escape !== null && this.__isEscape(buf, pos, chr) && this.__isQuote(buf, pos + escape.length)){\n pos += escape.length - 1\n }else if(!nextChr || isNextChrDelimiter || isNextChrRecordDelimiter || isNextChrComment || isNextChrTrimable){\n this.state.quoting = false\n this.state.wasQuoting = true\n pos += quote.length - 1\n continue\n }else if(relax === false){\n const err = this.__error(\n new CsvError('CSV_INVALID_CLOSING_QUOTE', [\n 'Invalid Closing Quote:',\n `got \"${String.fromCharCode(nextChr)}\"`,\n `at line ${this.info.lines}`,\n 'instead of delimiter, record delimiter, trimable character',\n '(if activated) or comment',\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }else{\n this.state.quoting = false\n this.state.wasQuoting = true\n this.state.field.prepend(quote)\n pos += quote.length - 1\n }\n }else{\n if(this.state.field.length !== 0){\n // In relax mode, treat opening quote preceded by chrs as regular\n if( relax === false ){\n const err = this.__error(\n new CsvError('INVALID_OPENING_QUOTE', [\n 'Invalid Opening Quote:',\n `a quote is found inside a field at line ${this.info.lines}`,\n ], this.options, this.__context(), {\n field: this.state.field,\n })\n )\n if(err !== undefined) return err\n }\n }else{\n this.state.quoting = true\n pos += quote.length - 1\n continue\n }\n }\n }\n if(this.state.quoting === false){\n let recordDelimiterLength = this.__isRecordDelimiter(chr, buf, pos)\n if(recordDelimiterLength !== 0){\n // Do not emit comments which take a full line\n const skipCommentLine = this.state.commenting && (this.state.wasQuoting === false && this.state.record.length === 0 && this.state.field.length === 0)\n if(skipCommentLine){\n this.info.comment_lines++\n // Skip full comment line\n }else{\n // Activate records emition if above from_line\n if(this.state.enabled === false && this.info.lines + (this.state.wasRowDelimiter === true ? 1: 0) >= from_line){\n this.state.enabled = true\n this.__resetField()\n this.__resetRecord()\n pos += recordDelimiterLength - 1\n continue\n }\n // Skip if line is empty and skip_empty_lines activated\n if(skip_empty_lines === true && this.state.wasQuoting === false && this.state.record.length === 0 && this.state.field.length === 0){\n this.info.empty_lines++\n pos += recordDelimiterLength - 1\n continue\n }\n const errField = this.__onField()\n if(errField !== undefined) return errField\n const errRecord = this.__onRecord()\n if(errRecord !== undefined) return errRecord\n if(to !== -1 && this.info.records >= to){\n this.state.stop = true\n this.push(null)\n return\n }\n }\n this.state.commenting = false\n pos += recordDelimiterLength - 1\n continue\n }\n if(this.state.commenting){\n continue\n }\n const commentCount = comment === null ? 0 : this.__compareBytes(comment, buf, pos, chr)\n if(commentCount !== 0){\n this.state.commenting = true\n continue\n }\n let delimiterLength = this.__isDelimiter(buf, pos, chr)\n if(delimiterLength !== 0){\n const errField = this.__onField()\n if(errField !== undefined) return errField\n pos += delimiterLength - 1\n continue\n }\n }\n }\n if(this.state.commenting === false){\n if(max_record_size !== 0 && this.state.record_length + this.state.field.length > max_record_size){\n const err = this.__error(\n new CsvError('CSV_MAX_RECORD_SIZE', [\n 'Max Record Size:',\n 'record exceed the maximum number of tolerated bytes',\n `of ${max_record_size}`,\n `at line ${this.info.lines}`,\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }\n }\n\n const lappend = ltrim === false || this.state.quoting === true || this.state.field.length !== 0 || !this.__isCharTrimable(chr)\n // rtrim in non quoting is handle in __onField\n const rappend = rtrim === false || this.state.wasQuoting === false\n if( lappend === true && rappend === true ){\n this.state.field.append(chr)\n }else if(rtrim === true && !this.__isCharTrimable(chr)){\n const err = this.__error(\n new CsvError('CSV_NON_TRIMABLE_CHAR_AFTER_CLOSING_QUOTE', [\n 'Invalid Closing Quote:',\n 'found non trimable byte after quote',\n `at line ${this.info.lines}`,\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }\n }\n if(end === true){\n // Ensure we are not ending in a quoting state\n if(this.state.quoting === true){\n const err = this.__error(\n new CsvError('CSV_QUOTE_NOT_CLOSED', [\n 'Quote Not Closed:',\n `the parsing is finished with an opening quote at line ${this.info.lines}`,\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }else{\n // Skip last line if it has no characters\n if(this.state.wasQuoting === true || this.state.record.length !== 0 || this.state.field.length !== 0){\n const errField = this.__onField()\n if(errField !== undefined) return errField\n const errRecord = this.__onRecord()\n if(errRecord !== undefined) return errRecord\n }else if(this.state.wasRowDelimiter === true){\n this.info.empty_lines++\n }else if(this.state.commenting === true){\n this.info.comment_lines++\n }\n }\n }else{\n this.state.previousBuf = buf.slice(pos)\n }\n if(this.state.wasRowDelimiter === true){\n this.info.lines++\n this.state.wasRowDelimiter = false\n }\n }\n __onRecord(){\n const {columns, columns_duplicates_to_array, encoding, info, from, relax_column_count, relax_column_count_less, relax_column_count_more, raw, skip_lines_with_empty_values} = this.options\n const {enabled, record} = this.state\n if(enabled === false){\n return this.__resetRecord()\n }\n // Convert the first line into column names\n const recordLength = record.length\n if(columns === true){\n if(isRecordEmpty(record)){\n this.__resetRecord()\n return\n }\n return this.__firstLineToColumns(record)\n }\n if(columns === false && this.info.records === 0){\n this.state.expectedRecordLength = recordLength\n }\n if(recordLength !== this.state.expectedRecordLength){\n const err = columns === false ?\n // Todo: rename CSV_INCONSISTENT_RECORD_LENGTH to\n // CSV_RECORD_INCONSISTENT_FIELDS_LENGTH\n new CsvError('CSV_INCONSISTENT_RECORD_LENGTH', [\n 'Invalid Record Length:',\n `expect ${this.state.expectedRecordLength},`,\n `got ${recordLength} on line ${this.info.lines}`,\n ], this.options, this.__context(), {\n record: record,\n })\n :\n // Todo: rename CSV_RECORD_DONT_MATCH_COLUMNS_LENGTH to\n // CSV_RECORD_INCONSISTENT_COLUMNS\n new CsvError('CSV_RECORD_DONT_MATCH_COLUMNS_LENGTH', [\n 'Invalid Record Length:',\n `columns length is ${columns.length},`, // rename columns\n `got ${recordLength} on line ${this.info.lines}`,\n ], this.options, this.__context(), {\n record: record,\n })\n if(relax_column_count === true ||\n (relax_column_count_less === true && recordLength < this.state.expectedRecordLength) ||\n (relax_column_count_more === true && recordLength > this.state.expectedRecordLength) ){\n this.info.invalid_field_length++\n this.state.error = err\n // Error is undefined with skip_lines_with_error\n }else{\n const finalErr = this.__error(err)\n if(finalErr) return finalErr\n }\n }\n if(skip_lines_with_empty_values === true){\n if(isRecordEmpty(record)){\n this.__resetRecord()\n return\n }\n }\n if(this.state.recordHasError === true){\n this.__resetRecord()\n this.state.recordHasError = false\n return\n }\n this.info.records++\n if(from === 1 || this.info.records >= from){\n if(columns !== false){\n const obj = {}\n // Transform record array to an object\n for(let i = 0, l = record.length; i < l; i++){\n if(columns[i] === undefined || columns[i].disabled) continue\n // Turn duplicate columns into an array\n if (columns_duplicates_to_array === true && obj[columns[i].name] !== undefined) {\n if (Array.isArray(obj[columns[i].name])) {\n obj[columns[i].name] = obj[columns[i].name].concat(record[i])\n } else {\n obj[columns[i].name] = [obj[columns[i].name], record[i]]\n }\n } else {\n obj[columns[i].name] = record[i]\n }\n }\n const {objname} = this.options\n if(objname === undefined){\n if(raw === true || info === true){\n const err = this.__push(Object.assign(\n {record: obj},\n (raw === true ? {raw: this.state.rawBuffer.toString(encoding)}: {}),\n (info === true ? {info: this.state.info}: {})\n ))\n if(err){\n return err\n }\n }else{\n const err = this.__push(obj)\n if(err){\n return err\n }\n }\n }else{\n if(raw === true || info === true){\n const err = this.__push(Object.assign(\n {record: [obj[objname], obj]},\n raw === true ? {raw: this.state.rawBuffer.toString(encoding)}: {},\n info === true ? {info: this.state.info}: {}\n ))\n if(err){\n return err\n }\n }else{\n const err = this.__push([obj[objname], obj])\n if(err){\n return err\n }\n }\n }\n }else{\n if(raw === true || info === true){\n const err = this.__push(Object.assign(\n {record: record},\n raw === true ? {raw: this.state.rawBuffer.toString(encoding)}: {},\n info === true ? {info: this.state.info}: {}\n ))\n if(err){\n return err\n }\n }else{\n const err = this.__push(record)\n if(err){\n return err\n }\n }\n }\n }\n this.__resetRecord()\n }\n __firstLineToColumns(record){\n const {firstLineToHeaders} = this.state\n try{\n const headers = firstLineToHeaders === undefined ? record : firstLineToHeaders.call(null, record)\n if(!Array.isArray(headers)){\n return this.__error(\n new CsvError('CSV_INVALID_COLUMN_MAPPING', [\n 'Invalid Column Mapping:',\n 'expect an array from column function,',\n `got ${JSON.stringify(headers)}`\n ], this.options, this.__context(), {\n headers: headers,\n })\n )\n }\n const normalizedHeaders = normalizeColumnsArray(headers)\n this.state.expectedRecordLength = normalizedHeaders.length\n this.options.columns = normalizedHeaders\n this.__resetRecord()\n return\n }catch(err){\n return err\n }\n }\n __resetRecord(){\n if(this.options.raw === true){\n this.state.rawBuffer.reset()\n }\n this.state.error = undefined\n this.state.record = []\n this.state.record_length = 0\n }\n __onField(){\n const {cast, encoding, rtrim, max_record_size} = this.options\n const {enabled, wasQuoting} = this.state\n // Short circuit for the from_line options\n if(enabled === false){ /* this.options.columns !== true && */\n return this.__resetField()\n }\n let field = this.state.field.toString(encoding)\n if(rtrim === true && wasQuoting === false){\n field = field.trimRight()\n }\n if(cast === true){\n const [err, f] = this.__cast(field)\n if(err !== undefined) return err\n field = f\n }\n this.state.record.push(field)\n // Increment record length if record size must not exceed a limit\n if(max_record_size !== 0 && typeof field === 'string'){\n this.state.record_length += field.length\n }\n this.__resetField()\n }\n __resetField(){\n this.state.field.reset()\n this.state.wasQuoting = false\n }\n __push(record){\n const {on_record} = this.options\n if(on_record !== undefined){\n const context = this.__context()\n try{\n record = on_record.call(null, record, context)\n }catch(err){\n return err\n }\n if(record === undefined || record === null){ return }\n }\n this.push(record)\n }\n // Return a tuple with the error and the casted value\n __cast(field){\n const {columns, relax_column_count} = this.options\n const isColumns = Array.isArray(columns)\n // Dont loose time calling cast\n // because the final record is an object\n // and this field can't be associated to a key present in columns\n if( isColumns === true && relax_column_count && this.options.columns.length <= this.state.record.length ){\n return [undefined, undefined]\n }\n const context = this.__context()\n if(this.state.castField !== null){\n try{\n return [undefined, this.state.castField.call(null, field, context)]\n }catch(err){\n return [err]\n }\n }\n if(this.__isFloat(field)){\n return [undefined, parseFloat(field)]\n }else if(this.options.cast_date !== false){\n return [undefined, this.options.cast_date.call(null, field, context)]\n }\n return [undefined, field]\n }\n // Helper to test if a character is a space or a line delimiter\n __isCharTrimable(chr){\n return chr === space || chr === tab || chr === cr || chr === nl || chr === np\n }\n // Keep it in case we implement the `cast_int` option\n // __isInt(value){\n // // return Number.isInteger(parseInt(value))\n // // return !isNaN( parseInt( obj ) );\n // return /^(\\-|\\+)?[1-9][0-9]*$/.test(value)\n // }\n __isFloat(value){\n return (value - parseFloat( value ) + 1) >= 0 // Borrowed from jquery\n }\n __compareBytes(sourceBuf, targetBuf, targetPos, firstByte){\n if(sourceBuf[0] !== firstByte) return 0\n const sourceLength = sourceBuf.length\n for(let i = 1; i < sourceLength; i++){\n if(sourceBuf[i] !== targetBuf[targetPos+i]) return 0\n }\n return sourceLength\n }\n __needMoreData(i, bufLen, end){\n if(end) return false\n const {quote} = this.options\n const {quoting, needMoreDataSize, recordDelimiterMaxLength} = this.state\n const numOfCharLeft = bufLen - i - 1\n const requiredLength = Math.max(\n needMoreDataSize,\n // Skip if the remaining buffer smaller than record delimiter\n recordDelimiterMaxLength,\n // Skip if the remaining buffer can be record delimiter following the closing quote\n // 1 is for quote.length\n quoting ? (quote.length + recordDelimiterMaxLength) : 0,\n )\n return numOfCharLeft < requiredLength\n }\n __isDelimiter(buf, pos, chr){\n const {delimiter, ignore_last_delimiters} = this.options\n if(ignore_last_delimiters === true && this.state.record.length === this.options.columns.length - 1){\n return 0\n }else if(ignore_last_delimiters !== false && typeof ignore_last_delimiters === 'number' && this.state.record.length === ignore_last_delimiters - 1){\n return 0\n }\n loop1: for(let i = 0; i < delimiter.length; i++){\n const del = delimiter[i]\n if(del[0] === chr){\n for(let j = 1; j < del.length; j++){\n if(del[j] !== buf[pos+j]) continue loop1\n }\n return del.length\n }\n }\n return 0\n }\n __isRecordDelimiter(chr, buf, pos){\n const {record_delimiter} = this.options\n const recordDelimiterLength = record_delimiter.length\n loop1: for(let i = 0; i < recordDelimiterLength; i++){\n const rd = record_delimiter[i]\n const rdLength = rd.length\n if(rd[0] !== chr){\n continue\n }\n for(let j = 1; j < rdLength; j++){\n if(rd[j] !== buf[pos+j]){\n continue loop1\n }\n }\n return rd.length\n }\n return 0\n }\n __isEscape(buf, pos, chr){\n const {escape} = this.options\n if(escape === null) return false\n const l = escape.length\n if(escape[0] === chr){\n for(let i = 0; i < l; i++){\n if(escape[i] !== buf[pos+i]){\n return false\n }\n }\n return true\n }\n return false\n }\n __isQuote(buf, pos){\n const {quote} = this.options\n if(quote === null) return false\n const l = quote.length\n for(let i = 0; i < l; i++){\n if(quote[i] !== buf[pos+i]){\n return false\n }\n }\n return true\n }\n __autoDiscoverRecordDelimiter(buf, pos){\n const {encoding} = this.options\n const chr = buf[pos]\n if(chr === cr){\n if(buf[pos+1] === nl){\n this.options.record_delimiter.push(Buffer.from('\\r\\n', encoding))\n this.state.recordDelimiterMaxLength = 2\n return 2\n }else{\n this.options.record_delimiter.push(Buffer.from('\\r', encoding))\n this.state.recordDelimiterMaxLength = 1\n return 1\n }\n }else if(chr === nl){\n this.options.record_delimiter.push(Buffer.from('\\n', encoding))\n this.state.recordDelimiterMaxLength = 1\n return 1\n }\n return 0\n }\n __error(msg){\n const {skip_lines_with_error} = this.options\n const err = typeof msg === 'string' ? new Error(msg) : msg\n if(skip_lines_with_error){\n this.state.recordHasError = true\n this.emit('skip', err)\n return undefined\n }else{\n return err\n }\n }\n __context(){\n const {columns} = this.options\n const isColumns = Array.isArray(columns)\n return {\n column: isColumns === true ?\n ( columns.length > this.state.record.length ?\n columns[this.state.record.length].name :\n null\n ) :\n this.state.record.length,\n empty_lines: this.info.empty_lines,\n error: this.state.error,\n header: columns === true,\n index: this.state.record.length,\n invalid_field_length: this.info.invalid_field_length,\n quoting: this.state.wasQuoting,\n lines: this.info.lines,\n records: this.info.records\n }\n }\n}\n\nconst parse = function(){\n let data, options, callback\n for(let i in arguments){\n const argument = arguments[i]\n const type = typeof argument\n if(data === undefined && (typeof argument === 'string' || Buffer.isBuffer(argument))){\n data = argument\n }else if(options === undefined && isObject(argument)){\n options = argument\n }else if(callback === undefined && type === 'function'){\n callback = argument\n }else{\n throw new CsvError('CSV_INVALID_ARGUMENT', [\n 'Invalid argument:',\n `got ${JSON.stringify(argument)} at index ${i}`\n ], this.options)\n }\n }\n const parser = new Parser(options)\n if(callback){\n const records = options === undefined || options.objname === undefined ? [] : {}\n parser.on('readable', function(){\n let record\n while((record = this.read()) !== null){\n if(options === undefined || options.objname === undefined){\n records.push(record)\n }else{\n records[record[0]] = record[1]\n }\n }\n })\n parser.on('error', function(err){\n callback(err, undefined, parser.info)\n })\n parser.on('end', function(){\n callback(undefined, records, parser.info)\n })\n }\n if(data !== undefined){\n // Give a chance for events to be registered later\n if(typeof setImmediate === 'function'){\n setImmediate(function(){\n parser.write(data)\n parser.end()\n })\n }else{\n parser.write(data)\n parser.end()\n }\n }\n return parser\n}\n\nclass CsvError extends Error {\n constructor(code, message, options, ...contexts) {\n if(Array.isArray(message)) message = message.join(' ')\n super(message)\n if(Error.captureStackTrace !== undefined){\n Error.captureStackTrace(this, CsvError)\n }\n this.code = code\n for(const context of contexts){\n for(const key in context){\n const value = context[key]\n this[key] = Buffer.isBuffer(value) ? value.toString(options.encoding) : value == null ? value : JSON.parse(JSON.stringify(value))\n }\n }\n }\n}\n\nparse.Parser = Parser\n\nparse.CsvError = CsvError\n\nmodule.exports = parse\n\nconst underscore = function(str){\n return str.replace(/([A-Z])/g, function(_, match){\n return '_' + match.toLowerCase()\n })\n}\n\nconst isObject = function(obj){\n return (typeof obj === 'object' && obj !== null && !Array.isArray(obj))\n}\n\nconst isRecordEmpty = function(record){\n return record.every( (field) => field == null || field.toString && field.toString().trim() === '' )\n}\n\nconst normalizeColumnsArray = function(columns){\n const normalizedColumns = [];\n for(let i = 0, l = columns.length; i < l; i++){\n const column = columns[i]\n if(column === undefined || column === null || column === false){\n normalizedColumns[i] = { disabled: true }\n }else if(typeof column === 'string'){\n normalizedColumns[i] = { name: column }\n }else if(isObject(column)){\n if(typeof column.name !== 'string'){\n throw new CsvError('CSV_OPTION_COLUMNS_MISSING_NAME', [\n 'Option columns missing name:',\n `property \"name\" is required at position ${i}`,\n 'when column is an object literal'\n ])\n }\n normalizedColumns[i] = column\n }else{\n throw new CsvError('CSV_INVALID_COLUMN_DEFINITION', [\n 'Invalid column definition:',\n 'expect a string or a literal object,',\n `got ${JSON.stringify(column)} at position ${i}`\n ])\n }\n }\n return normalizedColumns;\n}\n","\nconst parse = require('.')\n\nmodule.exports = function(data, options={}){\n if(typeof data === 'string'){\n data = Buffer.from(data)\n }\n const records = options && options.objname ? {} : []\n const parser = new parse.Parser(options)\n parser.push = function(record){\n if(record === null){\n return\n }\n if(options.objname === undefined)\n records.push(record)\n else{\n records[record[0]] = record[1]\n }\n }\n const err1 = parser.__parse(data, false)\n if(err1 !== undefined) throw err1\n const err2 = parser.__parse(undefined, true)\n if(err2 !== undefined) throw err2\n return records\n}\n",null,null,null,null,null,"module.exports = require(\"assert\");;","module.exports = require(\"child_process\");;","module.exports = require(\"events\");;","module.exports = require(\"fs\");;","module.exports = require(\"os\");;","module.exports = require(\"path\");;","module.exports = require(\"stream\");;","module.exports = require(\"string_decoder\");;","module.exports = require(\"timers\");;","module.exports = require(\"util\");;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tvar threw = true;\n\ttry {\n\t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\t\tthrew = false;\n\t} finally {\n\t\tif(threw) delete __webpack_module_cache__[moduleId];\n\t}\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","\n__webpack_require__.ab = __dirname + \"/\";","// module exports must be returned from runtime so entry inlining is disabled\n// startup\n// Load entry module and return exports\nreturn __webpack_require__(109);\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACnJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACvRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACvGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1mBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;ACxTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;AC/tCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;AC1BA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;;ACRA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5BA;AACA;ACDA;AACA;AACA;AACA;;A","sourceRoot":""} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../webpack://typescript-action/./lib/config.js","../webpack://typescript-action/./lib/docker.js","../webpack://typescript-action/./lib/envvars.js","../webpack://typescript-action/./lib/exec.js","../webpack://typescript-action/./lib/file.js","../webpack://typescript-action/./lib/main.js","../webpack://typescript-action/./node_modules/@actions/core/lib/command.js","../webpack://typescript-action/./node_modules/@actions/core/lib/core.js","../webpack://typescript-action/./node_modules/@actions/core/lib/file-command.js","../webpack://typescript-action/./node_modules/@actions/core/lib/utils.js","../webpack://typescript-action/./node_modules/@actions/exec/lib/exec.js","../webpack://typescript-action/./node_modules/@actions/exec/lib/toolrunner.js","../webpack://typescript-action/./node_modules/@actions/io/lib/io-util.js","../webpack://typescript-action/./node_modules/@actions/io/lib/io.js","../webpack://typescript-action/./node_modules/csv-parse/lib/ResizeableBuffer.js","../webpack://typescript-action/./node_modules/csv-parse/lib/index.js","../webpack://typescript-action/./node_modules/csv-parse/lib/sync.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/edit.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/format.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/parser.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/impl/scanner.js","../webpack://typescript-action/./node_modules/jsonc-parser/lib/umd/main.js","../webpack://typescript-action/external \"assert\"","../webpack://typescript-action/external \"child_process\"","../webpack://typescript-action/external \"events\"","../webpack://typescript-action/external \"fs\"","../webpack://typescript-action/external \"os\"","../webpack://typescript-action/external \"path\"","../webpack://typescript-action/external \"stream\"","../webpack://typescript-action/external \"string_decoder\"","../webpack://typescript-action/external \"timers\"","../webpack://typescript-action/external \"util\"","../webpack://typescript-action/webpack/bootstrap","../webpack://typescript-action/webpack/runtime/compat","../webpack://typescript-action/webpack/startup"],"sourcesContent":["\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getContext = exports.getDockerfile = exports.getRemoteUser = exports.getWorkspaceFolder = exports.loadFromString = exports.loadFromFile = void 0;\nconst path = __importStar(require(\"path\"));\nconst fs = __importStar(require(\"fs\"));\nconst jsoncParser = __importStar(require(\"jsonc-parser\"));\nconst { readFile } = fs.promises;\nfunction loadFromFile(filepath) {\n return __awaiter(this, void 0, void 0, function* () {\n const jsonContent = yield readFile(filepath);\n return loadFromString(jsonContent.toString());\n });\n}\nexports.loadFromFile = loadFromFile;\nfunction loadFromString(content) {\n const config = jsoncParser.parse(content);\n return config;\n}\nexports.loadFromString = loadFromString;\nfunction getWorkspaceFolder(config, repoPath) {\n // https://code.visualstudio.com/docs/remote/containers-advanced#_changing-the-default-source-code-mount\n if (config.workspaceFolder) {\n return config.workspaceFolder;\n }\n return path.join('/workspaces', path.basename(repoPath));\n}\nexports.getWorkspaceFolder = getWorkspaceFolder;\nfunction getRemoteUser(config) {\n var _a;\n // https://code.visualstudio.com/docs/remote/containers-advanced#_specifying-a-user-for-vs-code\n return (_a = config.remoteUser) !== null && _a !== void 0 ? _a : 'root';\n}\nexports.getRemoteUser = getRemoteUser;\nfunction getDockerfile(config) {\n var _a, _b;\n return (_b = (_a = config.build) === null || _a === void 0 ? void 0 : _a.dockerfile) !== null && _b !== void 0 ? _b : config.dockerFile;\n}\nexports.getDockerfile = getDockerfile;\nfunction getContext(config) {\n var _a, _b;\n return (_b = (_a = config.build) === null || _a === void 0 ? void 0 : _a.context) !== null && _b !== void 0 ? _b : config.context;\n}\nexports.getContext = getContext;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.pushImage = exports.runContainer = exports.buildImage = exports.isDockerBuildXInstalled = void 0;\nconst path_1 = __importDefault(require(\"path\"));\nconst core = __importStar(require(\"@actions/core\"));\nconst config = __importStar(require(\"./config\"));\nconst exec_1 = require(\"./exec\");\nconst file_1 = require(\"./file\");\nconst envvars_1 = require(\"./envvars\");\nfunction isDockerBuildXInstalled() {\n return __awaiter(this, void 0, void 0, function* () {\n const r = yield exec_1.exec('docker', 'buildx', '--help');\n return r.exitCode === 0;\n });\n}\nexports.isDockerBuildXInstalled = isDockerBuildXInstalled;\nfunction buildImage(imageName, checkoutPath, subFolder) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n const folder = path_1.default.join(checkoutPath, subFolder);\n const devcontainerJsonPath = path_1.default.join(folder, '.devcontainer/devcontainer.json');\n const devcontainerConfig = yield config.loadFromFile(devcontainerJsonPath);\n const configDockerfile = config.getDockerfile(devcontainerConfig);\n if (!configDockerfile) {\n throw new Error('dockerfile not set in devcontainer.json - devcontainer-build-run currently only supports Dockerfile-based dev containers');\n }\n const dockerfilePath = path_1.default.join(folder, '.devcontainer', configDockerfile);\n const configContext = (_a = config.getContext(devcontainerConfig)) !== null && _a !== void 0 ? _a : '';\n const contextPath = path_1.default.join(folder, '.devcontainer', configContext);\n const args = ['buildx', 'build'];\n args.push('--tag');\n args.push(`${imageName}:latest`);\n args.push('--cache-from');\n args.push(`type=registry,ref=${imageName}:latest`);\n args.push('--cache-to');\n args.push('type=inline');\n args.push('--output=type=docker');\n const buildArgs = (_b = devcontainerConfig.build) === null || _b === void 0 ? void 0 : _b.args;\n for (const argName in buildArgs) {\n const argValue = envvars_1.substituteValues(buildArgs[argName]);\n args.push('--build-arg', `${argName}=${argValue}`);\n }\n args.push('-f', dockerfilePath);\n args.push(contextPath);\n core.startGroup('🏗 Building dev container...');\n try {\n const buildResponse = yield exec_1.execWithOptions('docker', { silent: false }, ...args);\n if (buildResponse.exitCode !== 0) {\n core.setFailed(`build failed with ${buildResponse.exitCode}: ${buildResponse.stderr}`);\n return false;\n }\n core.info(buildResponse.stdout);\n return true;\n }\n finally {\n core.endGroup();\n }\n });\n}\nexports.buildImage = buildImage;\nfunction runContainer(imageName, checkoutPath, subFolder, command, envs) {\n return __awaiter(this, void 0, void 0, function* () {\n const checkoutPathAbsolute = file_1.getAbsolutePath(checkoutPath, process.cwd());\n const folder = path_1.default.join(checkoutPathAbsolute, subFolder);\n const devcontainerJsonPath = path_1.default.join(folder, '.devcontainer/devcontainer.json');\n const devcontainerConfig = yield config.loadFromFile(devcontainerJsonPath);\n const workspaceFolder = config.getWorkspaceFolder(devcontainerConfig, folder);\n const remoteUser = config.getRemoteUser(devcontainerConfig);\n const args = ['run'];\n args.push('--mount', `type=bind,src=${checkoutPathAbsolute},dst=${workspaceFolder}`);\n args.push('--workdir', workspaceFolder);\n args.push('--user', remoteUser);\n if (devcontainerConfig.runArgs) {\n const subtitutedRunArgs = devcontainerConfig.runArgs.map(a => envvars_1.substituteValues(a));\n args.push(...subtitutedRunArgs);\n }\n if (envs) {\n for (const env of envs) {\n args.push('--env', env);\n }\n }\n args.push(`${imageName}:latest`);\n args.push('bash', '-c', `sudo chown -R $(whoami) . && ${command}`); // TODO sort out permissions/user alignment\n core.startGroup('🏃‍♀️ Running dev container...');\n try {\n const buildResponse = yield exec_1.execWithOptions('docker', { silent: false }, ...args);\n if (buildResponse.exitCode !== 0) {\n core.setFailed(`run failed with ${buildResponse.exitCode}: ${buildResponse.stderr}`);\n return false;\n }\n return true;\n }\n finally {\n core.endGroup();\n }\n });\n}\nexports.runContainer = runContainer;\nfunction pushImage(imageName) {\n return __awaiter(this, void 0, void 0, function* () {\n const args = ['push'];\n args.push(`${imageName}:latest`);\n core.startGroup('Pushing image...');\n try {\n const buildResponse = yield exec_1.execWithOptions('docker', { silent: false }, ...args);\n if (buildResponse.exitCode !== 0) {\n core.setFailed(`push failed with ${buildResponse.exitCode}: ${buildResponse.stderr}`);\n return false;\n }\n return true;\n }\n finally {\n core.endGroup();\n }\n });\n}\nexports.pushImage = pushImage;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.substituteValues = void 0;\nfunction substituteValues(input) {\n // Find all `${...}` entries and substitute\n // Note the non-greedy `.+?` match to avoid matching the start of\n // one placeholder up to the end of another when multiple placeholders are present\n return input.replace(/\\$\\{(.+?)\\}/g, getSubstitutionValue);\n}\nexports.substituteValues = substituteValues;\nfunction getSubstitutionValue(regexMatch, placeholder) {\n // Substitution values are in TYPE:KEY form\n // e.g. env:MY_ENV\n var _a;\n const parts = placeholder.split(':');\n if (parts.length === 2) {\n const type = parts[0];\n const key = parts[1];\n switch (type) {\n case 'env':\n case 'localenv':\n return (_a = process.env[key]) !== null && _a !== void 0 ? _a : '';\n }\n }\n // if we can't process the format then return the original string\n // as having it present in any output will likely make issues more obvious\n return regexMatch;\n}\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.execWithOptions = exports.exec = void 0;\nconst actions_exec = __importStar(require(\"@actions/exec\"));\nfunction exec(command, ...args) {\n return __awaiter(this, void 0, void 0, function* () {\n return yield execWithOptions(command, {\n silent: true\n }, ...args);\n });\n}\nexports.exec = exec;\nfunction execWithOptions(command, options, ...args) {\n return __awaiter(this, void 0, void 0, function* () {\n let stdout = '';\n let stderr = '';\n const actionOptions = {\n ignoreReturnCode: true,\n silent: options.silent,\n listeners: {\n stdout: (data) => {\n stdout += data.toString();\n },\n stderr: (data) => {\n stderr += data.toString();\n }\n }\n };\n const exitCode = yield actions_exec.exec(command, args, actionOptions);\n return {\n exitCode,\n stdout,\n stderr\n };\n });\n}\nexports.execWithOptions = execWithOptions;\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getAbsolutePath = void 0;\nconst path_1 = __importDefault(require(\"path\"));\nfunction getAbsolutePath(inputPath, referencePath) {\n if (path_1.default.isAbsolute(inputPath)) {\n return inputPath;\n }\n return path_1.default.join(referencePath, inputPath);\n}\nexports.getAbsolutePath = getAbsolutePath;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst core = __importStar(require(\"@actions/core\"));\nconst sync_1 = __importDefault(require(\"csv-parse/lib/sync\"));\nconst docker_1 = require(\"./docker\");\nfunction run() {\n return __awaiter(this, void 0, void 0, function* () {\n const hasRunMain = core.getState('hasRunMain');\n if (hasRunMain === 'true') {\n return yield runPost();\n }\n else {\n core.saveState('hasRunMain', 'true');\n return yield runMain();\n }\n });\n}\nfunction runMain() {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const buildXInstalled = yield docker_1.isDockerBuildXInstalled();\n if (!buildXInstalled) {\n core.setFailed('docker buildx not available: add a step to set up with docker/setup-buildx-action');\n return;\n }\n const checkoutPath = core.getInput('checkoutPath');\n const imageName = core.getInput('imageName', { required: true });\n const subFolder = core.getInput('subFolder');\n const runCommand = core.getInput('runCmd', { required: true });\n const envs = yield getInputList('env');\n if (!(yield docker_1.buildImage(imageName, checkoutPath, subFolder))) {\n return;\n }\n if (!(yield docker_1.runContainer(imageName, checkoutPath, subFolder, runCommand, envs))) {\n return;\n }\n }\n catch (error) {\n core.setFailed(error.message);\n }\n });\n}\nfunction runPost() {\n return __awaiter(this, void 0, void 0, function* () {\n const headRef = process.env.GITHUB_HEAD_REF;\n if (headRef) {\n // headRef only set on PR builds\n core.info('Image push skipped for PR builds');\n return;\n }\n const imageName = core.getInput('imageName', { required: true });\n yield docker_1.pushImage(imageName);\n });\n}\nrun();\nfunction getInputList(name) {\n return __awaiter(this, void 0, void 0, function* () {\n const res = [];\n const input = core.getInput(name);\n if (input === '') {\n return res;\n }\n const parsedInput = (yield sync_1.default(input, {\n columns: false,\n relax: true,\n relaxColumnCount: true,\n skipLinesWithEmptyValues: true\n }));\n for (const items of parsedInput) {\n res.push(...items);\n }\n return res.map(item => item.trim());\n });\n}\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.issue = exports.issueCommand = void 0;\nconst os = __importStar(require(\"os\"));\nconst utils_1 = require(\"./utils\");\n/**\n * Commands\n *\n * Command Format:\n * ::name key=value,key=value::message\n *\n * Examples:\n * ::warning::This is the message\n * ::set-env name=MY_VAR::some value\n */\nfunction issueCommand(command, properties, message) {\n const cmd = new Command(command, properties, message);\n process.stdout.write(cmd.toString() + os.EOL);\n}\nexports.issueCommand = issueCommand;\nfunction issue(name, message = '') {\n issueCommand(name, {}, message);\n}\nexports.issue = issue;\nconst CMD_STRING = '::';\nclass Command {\n constructor(command, properties, message) {\n if (!command) {\n command = 'missing.command';\n }\n this.command = command;\n this.properties = properties;\n this.message = message;\n }\n toString() {\n let cmdStr = CMD_STRING + this.command;\n if (this.properties && Object.keys(this.properties).length > 0) {\n cmdStr += ' ';\n let first = true;\n for (const key in this.properties) {\n if (this.properties.hasOwnProperty(key)) {\n const val = this.properties[key];\n if (val) {\n if (first) {\n first = false;\n }\n else {\n cmdStr += ',';\n }\n cmdStr += `${key}=${escapeProperty(val)}`;\n }\n }\n }\n }\n cmdStr += `${CMD_STRING}${escapeData(this.message)}`;\n return cmdStr;\n }\n}\nfunction escapeData(s) {\n return utils_1.toCommandValue(s)\n .replace(/%/g, '%25')\n .replace(/\\r/g, '%0D')\n .replace(/\\n/g, '%0A');\n}\nfunction escapeProperty(s) {\n return utils_1.toCommandValue(s)\n .replace(/%/g, '%25')\n .replace(/\\r/g, '%0D')\n .replace(/\\n/g, '%0A')\n .replace(/:/g, '%3A')\n .replace(/,/g, '%2C');\n}\n//# sourceMappingURL=command.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;\nconst command_1 = require(\"./command\");\nconst file_command_1 = require(\"./file-command\");\nconst utils_1 = require(\"./utils\");\nconst os = __importStar(require(\"os\"));\nconst path = __importStar(require(\"path\"));\n/**\n * The code to exit an action\n */\nvar ExitCode;\n(function (ExitCode) {\n /**\n * A code indicating that the action was successful\n */\n ExitCode[ExitCode[\"Success\"] = 0] = \"Success\";\n /**\n * A code indicating that the action was a failure\n */\n ExitCode[ExitCode[\"Failure\"] = 1] = \"Failure\";\n})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));\n//-----------------------------------------------------------------------\n// Variables\n//-----------------------------------------------------------------------\n/**\n * Sets env variable for this action and future actions in the job\n * @param name the name of the variable to set\n * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction exportVariable(name, val) {\n const convertedVal = utils_1.toCommandValue(val);\n process.env[name] = convertedVal;\n const filePath = process.env['GITHUB_ENV'] || '';\n if (filePath) {\n const delimiter = '_GitHubActionsFileCommandDelimeter_';\n const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;\n file_command_1.issueCommand('ENV', commandValue);\n }\n else {\n command_1.issueCommand('set-env', { name }, convertedVal);\n }\n}\nexports.exportVariable = exportVariable;\n/**\n * Registers a secret which will get masked from logs\n * @param secret value of the secret\n */\nfunction setSecret(secret) {\n command_1.issueCommand('add-mask', {}, secret);\n}\nexports.setSecret = setSecret;\n/**\n * Prepends inputPath to the PATH (for this action and future actions)\n * @param inputPath\n */\nfunction addPath(inputPath) {\n const filePath = process.env['GITHUB_PATH'] || '';\n if (filePath) {\n file_command_1.issueCommand('PATH', inputPath);\n }\n else {\n command_1.issueCommand('add-path', {}, inputPath);\n }\n process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;\n}\nexports.addPath = addPath;\n/**\n * Gets the value of an input.\n * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.\n * Returns an empty string if the value is not defined.\n *\n * @param name name of the input to get\n * @param options optional. See InputOptions.\n * @returns string\n */\nfunction getInput(name, options) {\n const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';\n if (options && options.required && !val) {\n throw new Error(`Input required and not supplied: ${name}`);\n }\n if (options && options.trimWhitespace === false) {\n return val;\n }\n return val.trim();\n}\nexports.getInput = getInput;\n/**\n * Gets the input value of the boolean type in the YAML 1.2 \"core schema\" specification.\n * Support boolean input list: `true | True | TRUE | false | False | FALSE` .\n * The return value is also in boolean type.\n * ref: https://yaml.org/spec/1.2/spec.html#id2804923\n *\n * @param name name of the input to get\n * @param options optional. See InputOptions.\n * @returns boolean\n */\nfunction getBooleanInput(name, options) {\n const trueValue = ['true', 'True', 'TRUE'];\n const falseValue = ['false', 'False', 'FALSE'];\n const val = getInput(name, options);\n if (trueValue.includes(val))\n return true;\n if (falseValue.includes(val))\n return false;\n throw new TypeError(`Input does not meet YAML 1.2 \"Core Schema\" specification: ${name}\\n` +\n `Support boolean input list: \\`true | True | TRUE | false | False | FALSE\\``);\n}\nexports.getBooleanInput = getBooleanInput;\n/**\n * Sets the value of an output.\n *\n * @param name name of the output to set\n * @param value value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setOutput(name, value) {\n process.stdout.write(os.EOL);\n command_1.issueCommand('set-output', { name }, value);\n}\nexports.setOutput = setOutput;\n/**\n * Enables or disables the echoing of commands into stdout for the rest of the step.\n * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.\n *\n */\nfunction setCommandEcho(enabled) {\n command_1.issue('echo', enabled ? 'on' : 'off');\n}\nexports.setCommandEcho = setCommandEcho;\n//-----------------------------------------------------------------------\n// Results\n//-----------------------------------------------------------------------\n/**\n * Sets the action status to failed.\n * When the action exits it will be with an exit code of 1\n * @param message add error issue message\n */\nfunction setFailed(message) {\n process.exitCode = ExitCode.Failure;\n error(message);\n}\nexports.setFailed = setFailed;\n//-----------------------------------------------------------------------\n// Logging Commands\n//-----------------------------------------------------------------------\n/**\n * Gets whether Actions Step Debug is on or not\n */\nfunction isDebug() {\n return process.env['RUNNER_DEBUG'] === '1';\n}\nexports.isDebug = isDebug;\n/**\n * Writes debug message to user log\n * @param message debug message\n */\nfunction debug(message) {\n command_1.issueCommand('debug', {}, message);\n}\nexports.debug = debug;\n/**\n * Adds an error issue\n * @param message error issue message. Errors will be converted to string via toString()\n */\nfunction error(message) {\n command_1.issue('error', message instanceof Error ? message.toString() : message);\n}\nexports.error = error;\n/**\n * Adds an warning issue\n * @param message warning issue message. Errors will be converted to string via toString()\n */\nfunction warning(message) {\n command_1.issue('warning', message instanceof Error ? message.toString() : message);\n}\nexports.warning = warning;\n/**\n * Writes info to log with console.log.\n * @param message info message\n */\nfunction info(message) {\n process.stdout.write(message + os.EOL);\n}\nexports.info = info;\n/**\n * Begin an output group.\n *\n * Output until the next `groupEnd` will be foldable in this group\n *\n * @param name The name of the output group\n */\nfunction startGroup(name) {\n command_1.issue('group', name);\n}\nexports.startGroup = startGroup;\n/**\n * End an output group.\n */\nfunction endGroup() {\n command_1.issue('endgroup');\n}\nexports.endGroup = endGroup;\n/**\n * Wrap an asynchronous function call in a group.\n *\n * Returns the same type as the function itself.\n *\n * @param name The name of the group\n * @param fn The function to wrap in the group\n */\nfunction group(name, fn) {\n return __awaiter(this, void 0, void 0, function* () {\n startGroup(name);\n let result;\n try {\n result = yield fn();\n }\n finally {\n endGroup();\n }\n return result;\n });\n}\nexports.group = group;\n//-----------------------------------------------------------------------\n// Wrapper action state\n//-----------------------------------------------------------------------\n/**\n * Saves state for current action, the state can only be retrieved by this action's post job execution.\n *\n * @param name name of the state to store\n * @param value value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction saveState(name, value) {\n command_1.issueCommand('save-state', { name }, value);\n}\nexports.saveState = saveState;\n/**\n * Gets the value of an state set by this action's main execution.\n *\n * @param name name of the state to get\n * @returns string\n */\nfunction getState(name) {\n return process.env[`STATE_${name}`] || '';\n}\nexports.getState = getState;\n//# sourceMappingURL=core.js.map","\"use strict\";\n// For internal use, subject to change.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.issueCommand = void 0;\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst fs = __importStar(require(\"fs\"));\nconst os = __importStar(require(\"os\"));\nconst utils_1 = require(\"./utils\");\nfunction issueCommand(command, message) {\n const filePath = process.env[`GITHUB_${command}`];\n if (!filePath) {\n throw new Error(`Unable to find environment variable for file command ${command}`);\n }\n if (!fs.existsSync(filePath)) {\n throw new Error(`Missing file at path: ${filePath}`);\n }\n fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {\n encoding: 'utf8'\n });\n}\nexports.issueCommand = issueCommand;\n//# sourceMappingURL=file-command.js.map","\"use strict\";\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.toCommandValue = void 0;\n/**\n * Sanitizes an input into a string so it can be passed into issueCommand safely\n * @param input input to sanitize into a string\n */\nfunction toCommandValue(input) {\n if (input === null || input === undefined) {\n return '';\n }\n else if (typeof input === 'string' || input instanceof String) {\n return input;\n }\n return JSON.stringify(input);\n}\nexports.toCommandValue = toCommandValue;\n//# sourceMappingURL=utils.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getExecOutput = exports.exec = void 0;\nconst string_decoder_1 = require(\"string_decoder\");\nconst tr = __importStar(require(\"./toolrunner\"));\n/**\n * Exec a command.\n * Output will be streamed to the live console.\n * Returns promise with return code\n *\n * @param commandLine command to execute (can include additional args). Must be correctly escaped.\n * @param args optional arguments for tool. Escaping is handled by the lib.\n * @param options optional exec options. See ExecOptions\n * @returns Promise exit code\n */\nfunction exec(commandLine, args, options) {\n return __awaiter(this, void 0, void 0, function* () {\n const commandArgs = tr.argStringToArray(commandLine);\n if (commandArgs.length === 0) {\n throw new Error(`Parameter 'commandLine' cannot be null or empty.`);\n }\n // Path to tool to execute should be first arg\n const toolPath = commandArgs[0];\n args = commandArgs.slice(1).concat(args || []);\n const runner = new tr.ToolRunner(toolPath, args, options);\n return runner.exec();\n });\n}\nexports.exec = exec;\n/**\n * Exec a command and get the output.\n * Output will be streamed to the live console.\n * Returns promise with the exit code and collected stdout and stderr\n *\n * @param commandLine command to execute (can include additional args). Must be correctly escaped.\n * @param args optional arguments for tool. Escaping is handled by the lib.\n * @param options optional exec options. See ExecOptions\n * @returns Promise exit code, stdout, and stderr\n */\nfunction getExecOutput(commandLine, args, options) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n let stdout = '';\n let stderr = '';\n //Using string decoder covers the case where a mult-byte character is split\n const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');\n const stderrDecoder = new string_decoder_1.StringDecoder('utf8');\n const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;\n const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;\n const stdErrListener = (data) => {\n stderr += stderrDecoder.write(data);\n if (originalStdErrListener) {\n originalStdErrListener(data);\n }\n };\n const stdOutListener = (data) => {\n stdout += stdoutDecoder.write(data);\n if (originalStdoutListener) {\n originalStdoutListener(data);\n }\n };\n const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });\n const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));\n //flush any remaining characters\n stdout += stdoutDecoder.end();\n stderr += stderrDecoder.end();\n return {\n exitCode,\n stdout,\n stderr\n };\n });\n}\nexports.getExecOutput = getExecOutput;\n//# sourceMappingURL=exec.js.map","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.argStringToArray = exports.ToolRunner = void 0;\nconst os = __importStar(require(\"os\"));\nconst events = __importStar(require(\"events\"));\nconst child = __importStar(require(\"child_process\"));\nconst path = __importStar(require(\"path\"));\nconst io = __importStar(require(\"@actions/io\"));\nconst ioUtil = __importStar(require(\"@actions/io/lib/io-util\"));\nconst timers_1 = require(\"timers\");\n/* eslint-disable @typescript-eslint/unbound-method */\nconst IS_WINDOWS = process.platform === 'win32';\n/*\n * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.\n */\nclass ToolRunner extends events.EventEmitter {\n constructor(toolPath, args, options) {\n super();\n if (!toolPath) {\n throw new Error(\"Parameter 'toolPath' cannot be null or empty.\");\n }\n this.toolPath = toolPath;\n this.args = args || [];\n this.options = options || {};\n }\n _debug(message) {\n if (this.options.listeners && this.options.listeners.debug) {\n this.options.listeners.debug(message);\n }\n }\n _getCommandString(options, noPrefix) {\n const toolPath = this._getSpawnFileName();\n const args = this._getSpawnArgs(options);\n let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool\n if (IS_WINDOWS) {\n // Windows + cmd file\n if (this._isCmdFile()) {\n cmd += toolPath;\n for (const a of args) {\n cmd += ` ${a}`;\n }\n }\n // Windows + verbatim\n else if (options.windowsVerbatimArguments) {\n cmd += `\"${toolPath}\"`;\n for (const a of args) {\n cmd += ` ${a}`;\n }\n }\n // Windows (regular)\n else {\n cmd += this._windowsQuoteCmdArg(toolPath);\n for (const a of args) {\n cmd += ` ${this._windowsQuoteCmdArg(a)}`;\n }\n }\n }\n else {\n // OSX/Linux - this can likely be improved with some form of quoting.\n // creating processes on Unix is fundamentally different than Windows.\n // on Unix, execvp() takes an arg array.\n cmd += toolPath;\n for (const a of args) {\n cmd += ` ${a}`;\n }\n }\n return cmd;\n }\n _processLineBuffer(data, strBuffer, onLine) {\n try {\n let s = strBuffer + data.toString();\n let n = s.indexOf(os.EOL);\n while (n > -1) {\n const line = s.substring(0, n);\n onLine(line);\n // the rest of the string ...\n s = s.substring(n + os.EOL.length);\n n = s.indexOf(os.EOL);\n }\n return s;\n }\n catch (err) {\n // streaming lines to console is best effort. Don't fail a build.\n this._debug(`error processing line. Failed with error ${err}`);\n return '';\n }\n }\n _getSpawnFileName() {\n if (IS_WINDOWS) {\n if (this._isCmdFile()) {\n return process.env['COMSPEC'] || 'cmd.exe';\n }\n }\n return this.toolPath;\n }\n _getSpawnArgs(options) {\n if (IS_WINDOWS) {\n if (this._isCmdFile()) {\n let argline = `/D /S /C \"${this._windowsQuoteCmdArg(this.toolPath)}`;\n for (const a of this.args) {\n argline += ' ';\n argline += options.windowsVerbatimArguments\n ? a\n : this._windowsQuoteCmdArg(a);\n }\n argline += '\"';\n return [argline];\n }\n }\n return this.args;\n }\n _endsWith(str, end) {\n return str.endsWith(end);\n }\n _isCmdFile() {\n const upperToolPath = this.toolPath.toUpperCase();\n return (this._endsWith(upperToolPath, '.CMD') ||\n this._endsWith(upperToolPath, '.BAT'));\n }\n _windowsQuoteCmdArg(arg) {\n // for .exe, apply the normal quoting rules that libuv applies\n if (!this._isCmdFile()) {\n return this._uvQuoteCmdArg(arg);\n }\n // otherwise apply quoting rules specific to the cmd.exe command line parser.\n // the libuv rules are generic and are not designed specifically for cmd.exe\n // command line parser.\n //\n // for a detailed description of the cmd.exe command line parser, refer to\n // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912\n // need quotes for empty arg\n if (!arg) {\n return '\"\"';\n }\n // determine whether the arg needs to be quoted\n const cmdSpecialChars = [\n ' ',\n '\\t',\n '&',\n '(',\n ')',\n '[',\n ']',\n '{',\n '}',\n '^',\n '=',\n ';',\n '!',\n \"'\",\n '+',\n ',',\n '`',\n '~',\n '|',\n '<',\n '>',\n '\"'\n ];\n let needsQuotes = false;\n for (const char of arg) {\n if (cmdSpecialChars.some(x => x === char)) {\n needsQuotes = true;\n break;\n }\n }\n // short-circuit if quotes not needed\n if (!needsQuotes) {\n return arg;\n }\n // the following quoting rules are very similar to the rules that by libuv applies.\n //\n // 1) wrap the string in quotes\n //\n // 2) double-up quotes - i.e. \" => \"\"\n //\n // this is different from the libuv quoting rules. libuv replaces \" with \\\", which unfortunately\n // doesn't work well with a cmd.exe command line.\n //\n // note, replacing \" with \"\" also works well if the arg is passed to a downstream .NET console app.\n // for example, the command line:\n // foo.exe \"myarg:\"\"my val\"\"\"\n // is parsed by a .NET console app into an arg array:\n // [ \"myarg:\\\"my val\\\"\" ]\n // which is the same end result when applying libuv quoting rules. although the actual\n // command line from libuv quoting rules would look like:\n // foo.exe \"myarg:\\\"my val\\\"\"\n //\n // 3) double-up slashes that precede a quote,\n // e.g. hello \\world => \"hello \\world\"\n // hello\\\"world => \"hello\\\\\"\"world\"\n // hello\\\\\"world => \"hello\\\\\\\\\"\"world\"\n // hello world\\ => \"hello world\\\\\"\n //\n // technically this is not required for a cmd.exe command line, or the batch argument parser.\n // the reasons for including this as a .cmd quoting rule are:\n //\n // a) this is optimized for the scenario where the argument is passed from the .cmd file to an\n // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.\n //\n // b) it's what we've been doing previously (by deferring to node default behavior) and we\n // haven't heard any complaints about that aspect.\n //\n // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be\n // escaped when used on the command line directly - even though within a .cmd file % can be escaped\n // by using %%.\n //\n // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts\n // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.\n //\n // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would\n // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the\n // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args\n // to an external program.\n //\n // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.\n // % can be escaped within a .cmd file.\n let reverse = '\"';\n let quoteHit = true;\n for (let i = arg.length; i > 0; i--) {\n // walk the string in reverse\n reverse += arg[i - 1];\n if (quoteHit && arg[i - 1] === '\\\\') {\n reverse += '\\\\'; // double the slash\n }\n else if (arg[i - 1] === '\"') {\n quoteHit = true;\n reverse += '\"'; // double the quote\n }\n else {\n quoteHit = false;\n }\n }\n reverse += '\"';\n return reverse\n .split('')\n .reverse()\n .join('');\n }\n _uvQuoteCmdArg(arg) {\n // Tool runner wraps child_process.spawn() and needs to apply the same quoting as\n // Node in certain cases where the undocumented spawn option windowsVerbatimArguments\n // is used.\n //\n // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,\n // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),\n // pasting copyright notice from Node within this function:\n //\n // Copyright Joyent, Inc. and other Node contributors. All rights reserved.\n //\n // Permission is hereby granted, free of charge, to any person obtaining a copy\n // of this software and associated documentation files (the \"Software\"), to\n // deal in the Software without restriction, including without limitation the\n // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n // sell copies of the Software, and to permit persons to whom the Software is\n // furnished to do so, subject to the following conditions:\n //\n // The above copyright notice and this permission notice shall be included in\n // all copies or substantial portions of the Software.\n //\n // THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n // IN THE SOFTWARE.\n if (!arg) {\n // Need double quotation for empty argument\n return '\"\"';\n }\n if (!arg.includes(' ') && !arg.includes('\\t') && !arg.includes('\"')) {\n // No quotation needed\n return arg;\n }\n if (!arg.includes('\"') && !arg.includes('\\\\')) {\n // No embedded double quotes or backslashes, so I can just wrap\n // quote marks around the whole thing.\n return `\"${arg}\"`;\n }\n // Expected input/output:\n // input : hello\"world\n // output: \"hello\\\"world\"\n // input : hello\"\"world\n // output: \"hello\\\"\\\"world\"\n // input : hello\\world\n // output: hello\\world\n // input : hello\\\\world\n // output: hello\\\\world\n // input : hello\\\"world\n // output: \"hello\\\\\\\"world\"\n // input : hello\\\\\"world\n // output: \"hello\\\\\\\\\\\"world\"\n // input : hello world\\\n // output: \"hello world\\\\\" - note the comment in libuv actually reads \"hello world\\\"\n // but it appears the comment is wrong, it should be \"hello world\\\\\"\n let reverse = '\"';\n let quoteHit = true;\n for (let i = arg.length; i > 0; i--) {\n // walk the string in reverse\n reverse += arg[i - 1];\n if (quoteHit && arg[i - 1] === '\\\\') {\n reverse += '\\\\';\n }\n else if (arg[i - 1] === '\"') {\n quoteHit = true;\n reverse += '\\\\';\n }\n else {\n quoteHit = false;\n }\n }\n reverse += '\"';\n return reverse\n .split('')\n .reverse()\n .join('');\n }\n _cloneExecOptions(options) {\n options = options || {};\n const result = {\n cwd: options.cwd || process.cwd(),\n env: options.env || process.env,\n silent: options.silent || false,\n windowsVerbatimArguments: options.windowsVerbatimArguments || false,\n failOnStdErr: options.failOnStdErr || false,\n ignoreReturnCode: options.ignoreReturnCode || false,\n delay: options.delay || 10000\n };\n result.outStream = options.outStream || process.stdout;\n result.errStream = options.errStream || process.stderr;\n return result;\n }\n _getSpawnOptions(options, toolPath) {\n options = options || {};\n const result = {};\n result.cwd = options.cwd;\n result.env = options.env;\n result['windowsVerbatimArguments'] =\n options.windowsVerbatimArguments || this._isCmdFile();\n if (options.windowsVerbatimArguments) {\n result.argv0 = `\"${toolPath}\"`;\n }\n return result;\n }\n /**\n * Exec a tool.\n * Output will be streamed to the live console.\n * Returns promise with return code\n *\n * @param tool path to tool to exec\n * @param options optional exec options. See ExecOptions\n * @returns number\n */\n exec() {\n return __awaiter(this, void 0, void 0, function* () {\n // root the tool path if it is unrooted and contains relative pathing\n if (!ioUtil.isRooted(this.toolPath) &&\n (this.toolPath.includes('/') ||\n (IS_WINDOWS && this.toolPath.includes('\\\\')))) {\n // prefer options.cwd if it is specified, however options.cwd may also need to be rooted\n this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);\n }\n // if the tool is only a file name, then resolve it from the PATH\n // otherwise verify it exists (add extension on Windows if necessary)\n this.toolPath = yield io.which(this.toolPath, true);\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n this._debug(`exec tool: ${this.toolPath}`);\n this._debug('arguments:');\n for (const arg of this.args) {\n this._debug(` ${arg}`);\n }\n const optionsNonNull = this._cloneExecOptions(this.options);\n if (!optionsNonNull.silent && optionsNonNull.outStream) {\n optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);\n }\n const state = new ExecState(optionsNonNull, this.toolPath);\n state.on('debug', (message) => {\n this._debug(message);\n });\n if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) {\n return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));\n }\n const fileName = this._getSpawnFileName();\n const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));\n let stdbuffer = '';\n if (cp.stdout) {\n cp.stdout.on('data', (data) => {\n if (this.options.listeners && this.options.listeners.stdout) {\n this.options.listeners.stdout(data);\n }\n if (!optionsNonNull.silent && optionsNonNull.outStream) {\n optionsNonNull.outStream.write(data);\n }\n stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {\n if (this.options.listeners && this.options.listeners.stdline) {\n this.options.listeners.stdline(line);\n }\n });\n });\n }\n let errbuffer = '';\n if (cp.stderr) {\n cp.stderr.on('data', (data) => {\n state.processStderr = true;\n if (this.options.listeners && this.options.listeners.stderr) {\n this.options.listeners.stderr(data);\n }\n if (!optionsNonNull.silent &&\n optionsNonNull.errStream &&\n optionsNonNull.outStream) {\n const s = optionsNonNull.failOnStdErr\n ? optionsNonNull.errStream\n : optionsNonNull.outStream;\n s.write(data);\n }\n errbuffer = this._processLineBuffer(data, errbuffer, (line) => {\n if (this.options.listeners && this.options.listeners.errline) {\n this.options.listeners.errline(line);\n }\n });\n });\n }\n cp.on('error', (err) => {\n state.processError = err.message;\n state.processExited = true;\n state.processClosed = true;\n state.CheckComplete();\n });\n cp.on('exit', (code) => {\n state.processExitCode = code;\n state.processExited = true;\n this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);\n state.CheckComplete();\n });\n cp.on('close', (code) => {\n state.processExitCode = code;\n state.processExited = true;\n state.processClosed = true;\n this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);\n state.CheckComplete();\n });\n state.on('done', (error, exitCode) => {\n if (stdbuffer.length > 0) {\n this.emit('stdline', stdbuffer);\n }\n if (errbuffer.length > 0) {\n this.emit('errline', errbuffer);\n }\n cp.removeAllListeners();\n if (error) {\n reject(error);\n }\n else {\n resolve(exitCode);\n }\n });\n if (this.options.input) {\n if (!cp.stdin) {\n throw new Error('child process missing stdin');\n }\n cp.stdin.end(this.options.input);\n }\n }));\n });\n }\n}\nexports.ToolRunner = ToolRunner;\n/**\n * Convert an arg string to an array of args. Handles escaping\n *\n * @param argString string of arguments\n * @returns string[] array of arguments\n */\nfunction argStringToArray(argString) {\n const args = [];\n let inQuotes = false;\n let escaped = false;\n let arg = '';\n function append(c) {\n // we only escape double quotes.\n if (escaped && c !== '\"') {\n arg += '\\\\';\n }\n arg += c;\n escaped = false;\n }\n for (let i = 0; i < argString.length; i++) {\n const c = argString.charAt(i);\n if (c === '\"') {\n if (!escaped) {\n inQuotes = !inQuotes;\n }\n else {\n append(c);\n }\n continue;\n }\n if (c === '\\\\' && escaped) {\n append(c);\n continue;\n }\n if (c === '\\\\' && inQuotes) {\n escaped = true;\n continue;\n }\n if (c === ' ' && !inQuotes) {\n if (arg.length > 0) {\n args.push(arg);\n arg = '';\n }\n continue;\n }\n append(c);\n }\n if (arg.length > 0) {\n args.push(arg.trim());\n }\n return args;\n}\nexports.argStringToArray = argStringToArray;\nclass ExecState extends events.EventEmitter {\n constructor(options, toolPath) {\n super();\n this.processClosed = false; // tracks whether the process has exited and stdio is closed\n this.processError = '';\n this.processExitCode = 0;\n this.processExited = false; // tracks whether the process has exited\n this.processStderr = false; // tracks whether stderr was written to\n this.delay = 10000; // 10 seconds\n this.done = false;\n this.timeout = null;\n if (!toolPath) {\n throw new Error('toolPath must not be empty');\n }\n this.options = options;\n this.toolPath = toolPath;\n if (options.delay) {\n this.delay = options.delay;\n }\n }\n CheckComplete() {\n if (this.done) {\n return;\n }\n if (this.processClosed) {\n this._setResult();\n }\n else if (this.processExited) {\n this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);\n }\n }\n _debug(message) {\n this.emit('debug', message);\n }\n _setResult() {\n // determine whether there is an error\n let error;\n if (this.processExited) {\n if (this.processError) {\n error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);\n }\n else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {\n error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);\n }\n else if (this.processStderr && this.options.failOnStdErr) {\n error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);\n }\n }\n // clear the timeout\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n this.done = true;\n this.emit('done', error, this.processExitCode);\n }\n static HandleTimeout(state) {\n if (state.done) {\n return;\n }\n if (!state.processClosed && state.processExited) {\n const message = `The STDIO streams did not close within ${state.delay /\n 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;\n state._debug(message);\n }\n state._setResult();\n }\n}\n//# sourceMappingURL=toolrunner.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar _a;\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst assert_1 = require(\"assert\");\nconst fs = __importStar(require(\"fs\"));\nconst path = __importStar(require(\"path\"));\n_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;\nexports.IS_WINDOWS = process.platform === 'win32';\nfunction exists(fsPath) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n yield exports.stat(fsPath);\n }\n catch (err) {\n if (err.code === 'ENOENT') {\n return false;\n }\n throw err;\n }\n return true;\n });\n}\nexports.exists = exists;\nfunction isDirectory(fsPath, useStat = false) {\n return __awaiter(this, void 0, void 0, function* () {\n const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);\n return stats.isDirectory();\n });\n}\nexports.isDirectory = isDirectory;\n/**\n * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:\n * \\, \\hello, \\\\hello\\share, C:, and C:\\hello (and corresponding alternate separator cases).\n */\nfunction isRooted(p) {\n p = normalizeSeparators(p);\n if (!p) {\n throw new Error('isRooted() parameter \"p\" cannot be empty');\n }\n if (exports.IS_WINDOWS) {\n return (p.startsWith('\\\\') || /^[A-Z]:/i.test(p) // e.g. \\ or \\hello or \\\\hello\n ); // e.g. C: or C:\\hello\n }\n return p.startsWith('/');\n}\nexports.isRooted = isRooted;\n/**\n * Recursively create a directory at `fsPath`.\n *\n * This implementation is optimistic, meaning it attempts to create the full\n * path first, and backs up the path stack from there.\n *\n * @param fsPath The path to create\n * @param maxDepth The maximum recursion depth\n * @param depth The current recursion depth\n */\nfunction mkdirP(fsPath, maxDepth = 1000, depth = 1) {\n return __awaiter(this, void 0, void 0, function* () {\n assert_1.ok(fsPath, 'a path argument must be provided');\n fsPath = path.resolve(fsPath);\n if (depth >= maxDepth)\n return exports.mkdir(fsPath);\n try {\n yield exports.mkdir(fsPath);\n return;\n }\n catch (err) {\n switch (err.code) {\n case 'ENOENT': {\n yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);\n yield exports.mkdir(fsPath);\n return;\n }\n default: {\n let stats;\n try {\n stats = yield exports.stat(fsPath);\n }\n catch (err2) {\n throw err;\n }\n if (!stats.isDirectory())\n throw err;\n }\n }\n }\n });\n}\nexports.mkdirP = mkdirP;\n/**\n * Best effort attempt to determine whether a file exists and is executable.\n * @param filePath file path to check\n * @param extensions additional file extensions to try\n * @return if file exists and is executable, returns the file path. otherwise empty string.\n */\nfunction tryGetExecutablePath(filePath, extensions) {\n return __awaiter(this, void 0, void 0, function* () {\n let stats = undefined;\n try {\n // test file exists\n stats = yield exports.stat(filePath);\n }\n catch (err) {\n if (err.code !== 'ENOENT') {\n // eslint-disable-next-line no-console\n console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);\n }\n }\n if (stats && stats.isFile()) {\n if (exports.IS_WINDOWS) {\n // on Windows, test for valid extension\n const upperExt = path.extname(filePath).toUpperCase();\n if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {\n return filePath;\n }\n }\n else {\n if (isUnixExecutable(stats)) {\n return filePath;\n }\n }\n }\n // try each extension\n const originalFilePath = filePath;\n for (const extension of extensions) {\n filePath = originalFilePath + extension;\n stats = undefined;\n try {\n stats = yield exports.stat(filePath);\n }\n catch (err) {\n if (err.code !== 'ENOENT') {\n // eslint-disable-next-line no-console\n console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);\n }\n }\n if (stats && stats.isFile()) {\n if (exports.IS_WINDOWS) {\n // preserve the case of the actual file (since an extension was appended)\n try {\n const directory = path.dirname(filePath);\n const upperName = path.basename(filePath).toUpperCase();\n for (const actualName of yield exports.readdir(directory)) {\n if (upperName === actualName.toUpperCase()) {\n filePath = path.join(directory, actualName);\n break;\n }\n }\n }\n catch (err) {\n // eslint-disable-next-line no-console\n console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);\n }\n return filePath;\n }\n else {\n if (isUnixExecutable(stats)) {\n return filePath;\n }\n }\n }\n }\n return '';\n });\n}\nexports.tryGetExecutablePath = tryGetExecutablePath;\nfunction normalizeSeparators(p) {\n p = p || '';\n if (exports.IS_WINDOWS) {\n // convert slashes on Windows\n p = p.replace(/\\//g, '\\\\');\n // remove redundant slashes\n return p.replace(/\\\\\\\\+/g, '\\\\');\n }\n // remove redundant slashes\n return p.replace(/\\/\\/+/g, '/');\n}\n// on Mac/Linux, test the execute bit\n// R W X R W X R W X\n// 256 128 64 32 16 8 4 2 1\nfunction isUnixExecutable(stats) {\n return ((stats.mode & 1) > 0 ||\n ((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||\n ((stats.mode & 64) > 0 && stats.uid === process.getuid()));\n}\n//# sourceMappingURL=io-util.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst childProcess = __importStar(require(\"child_process\"));\nconst path = __importStar(require(\"path\"));\nconst util_1 = require(\"util\");\nconst ioUtil = __importStar(require(\"./io-util\"));\nconst exec = util_1.promisify(childProcess.exec);\n/**\n * Copies a file or folder.\n * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js\n *\n * @param source source path\n * @param dest destination path\n * @param options optional. See CopyOptions.\n */\nfunction cp(source, dest, options = {}) {\n return __awaiter(this, void 0, void 0, function* () {\n const { force, recursive } = readCopyOptions(options);\n const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;\n // Dest is an existing file, but not forcing\n if (destStat && destStat.isFile() && !force) {\n return;\n }\n // If dest is an existing directory, should copy inside.\n const newDest = destStat && destStat.isDirectory()\n ? path.join(dest, path.basename(source))\n : dest;\n if (!(yield ioUtil.exists(source))) {\n throw new Error(`no such file or directory: ${source}`);\n }\n const sourceStat = yield ioUtil.stat(source);\n if (sourceStat.isDirectory()) {\n if (!recursive) {\n throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);\n }\n else {\n yield cpDirRecursive(source, newDest, 0, force);\n }\n }\n else {\n if (path.relative(source, newDest) === '') {\n // a file cannot be copied to itself\n throw new Error(`'${newDest}' and '${source}' are the same file`);\n }\n yield copyFile(source, newDest, force);\n }\n });\n}\nexports.cp = cp;\n/**\n * Moves a path.\n *\n * @param source source path\n * @param dest destination path\n * @param options optional. See MoveOptions.\n */\nfunction mv(source, dest, options = {}) {\n return __awaiter(this, void 0, void 0, function* () {\n if (yield ioUtil.exists(dest)) {\n let destExists = true;\n if (yield ioUtil.isDirectory(dest)) {\n // If dest is directory copy src into dest\n dest = path.join(dest, path.basename(source));\n destExists = yield ioUtil.exists(dest);\n }\n if (destExists) {\n if (options.force == null || options.force) {\n yield rmRF(dest);\n }\n else {\n throw new Error('Destination already exists');\n }\n }\n }\n yield mkdirP(path.dirname(dest));\n yield ioUtil.rename(source, dest);\n });\n}\nexports.mv = mv;\n/**\n * Remove a path recursively with force\n *\n * @param inputPath path to remove\n */\nfunction rmRF(inputPath) {\n return __awaiter(this, void 0, void 0, function* () {\n if (ioUtil.IS_WINDOWS) {\n // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another\n // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.\n try {\n if (yield ioUtil.isDirectory(inputPath, true)) {\n yield exec(`rd /s /q \"${inputPath}\"`);\n }\n else {\n yield exec(`del /f /a \"${inputPath}\"`);\n }\n }\n catch (err) {\n // if you try to delete a file that doesn't exist, desired result is achieved\n // other errors are valid\n if (err.code !== 'ENOENT')\n throw err;\n }\n // Shelling out fails to remove a symlink folder with missing source, this unlink catches that\n try {\n yield ioUtil.unlink(inputPath);\n }\n catch (err) {\n // if you try to delete a file that doesn't exist, desired result is achieved\n // other errors are valid\n if (err.code !== 'ENOENT')\n throw err;\n }\n }\n else {\n let isDir = false;\n try {\n isDir = yield ioUtil.isDirectory(inputPath);\n }\n catch (err) {\n // if you try to delete a file that doesn't exist, desired result is achieved\n // other errors are valid\n if (err.code !== 'ENOENT')\n throw err;\n return;\n }\n if (isDir) {\n yield exec(`rm -rf \"${inputPath}\"`);\n }\n else {\n yield ioUtil.unlink(inputPath);\n }\n }\n });\n}\nexports.rmRF = rmRF;\n/**\n * Make a directory. Creates the full path with folders in between\n * Will throw if it fails\n *\n * @param fsPath path to create\n * @returns Promise\n */\nfunction mkdirP(fsPath) {\n return __awaiter(this, void 0, void 0, function* () {\n yield ioUtil.mkdirP(fsPath);\n });\n}\nexports.mkdirP = mkdirP;\n/**\n * Returns path of a tool had the tool actually been invoked. Resolves via paths.\n * If you check and the tool does not exist, it will throw.\n *\n * @param tool name of the tool\n * @param check whether to check if tool exists\n * @returns Promise path to tool\n */\nfunction which(tool, check) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!tool) {\n throw new Error(\"parameter 'tool' is required\");\n }\n // recursive when check=true\n if (check) {\n const result = yield which(tool, false);\n if (!result) {\n if (ioUtil.IS_WINDOWS) {\n throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);\n }\n else {\n throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);\n }\n }\n return result;\n }\n const matches = yield findInPath(tool);\n if (matches && matches.length > 0) {\n return matches[0];\n }\n return '';\n });\n}\nexports.which = which;\n/**\n * Returns a list of all occurrences of the given tool on the system path.\n *\n * @returns Promise the paths of the tool\n */\nfunction findInPath(tool) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!tool) {\n throw new Error(\"parameter 'tool' is required\");\n }\n // build the list of extensions to try\n const extensions = [];\n if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {\n for (const extension of process.env['PATHEXT'].split(path.delimiter)) {\n if (extension) {\n extensions.push(extension);\n }\n }\n }\n // if it's rooted, return it if exists. otherwise return empty.\n if (ioUtil.isRooted(tool)) {\n const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);\n if (filePath) {\n return [filePath];\n }\n return [];\n }\n // if any path separators, return empty\n if (tool.includes(path.sep)) {\n return [];\n }\n // build the list of directories\n //\n // Note, technically \"where\" checks the current directory on Windows. From a toolkit perspective,\n // it feels like we should not do this. Checking the current directory seems like more of a use\n // case of a shell, and the which() function exposed by the toolkit should strive for consistency\n // across platforms.\n const directories = [];\n if (process.env.PATH) {\n for (const p of process.env.PATH.split(path.delimiter)) {\n if (p) {\n directories.push(p);\n }\n }\n }\n // find all matches\n const matches = [];\n for (const directory of directories) {\n const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);\n if (filePath) {\n matches.push(filePath);\n }\n }\n return matches;\n });\n}\nexports.findInPath = findInPath;\nfunction readCopyOptions(options) {\n const force = options.force == null ? true : options.force;\n const recursive = Boolean(options.recursive);\n return { force, recursive };\n}\nfunction cpDirRecursive(sourceDir, destDir, currentDepth, force) {\n return __awaiter(this, void 0, void 0, function* () {\n // Ensure there is not a run away recursive copy\n if (currentDepth >= 255)\n return;\n currentDepth++;\n yield mkdirP(destDir);\n const files = yield ioUtil.readdir(sourceDir);\n for (const fileName of files) {\n const srcFile = `${sourceDir}/${fileName}`;\n const destFile = `${destDir}/${fileName}`;\n const srcFileStat = yield ioUtil.lstat(srcFile);\n if (srcFileStat.isDirectory()) {\n // Recurse\n yield cpDirRecursive(srcFile, destFile, currentDepth, force);\n }\n else {\n yield copyFile(srcFile, destFile, force);\n }\n }\n // Change the mode for the newly created directory\n yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);\n });\n}\n// Buffered file copy\nfunction copyFile(srcFile, destFile, force) {\n return __awaiter(this, void 0, void 0, function* () {\n if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {\n // unlink/re-link it\n try {\n yield ioUtil.lstat(destFile);\n yield ioUtil.unlink(destFile);\n }\n catch (e) {\n // Try to override file permission\n if (e.code === 'EPERM') {\n yield ioUtil.chmod(destFile, '0666');\n yield ioUtil.unlink(destFile);\n }\n // other errors = it doesn't exist, no work to do\n }\n // Copy over symlink\n const symlinkFull = yield ioUtil.readlink(srcFile);\n yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);\n }\n else if (!(yield ioUtil.exists(destFile)) || force) {\n yield ioUtil.copyFile(srcFile, destFile);\n }\n });\n}\n//# sourceMappingURL=io.js.map","\n\nclass ResizeableBuffer{\n constructor(size=100){\n this.size = size\n this.length = 0\n this.buf = Buffer.alloc(size)\n }\n prepend(val){\n if(Buffer.isBuffer(val)){\n const length = this.length + val.length\n if(length >= this.size){\n this.resize()\n if(length >= this.size){\n throw Error('INVALID_BUFFER_STATE')\n }\n }\n const buf = this.buf\n this.buf = Buffer.alloc(this.size)\n val.copy(this.buf, 0)\n buf.copy(this.buf, val.length)\n this.length += val.length\n }else{\n const length = this.length++\n if(length === this.size){\n this.resize()\n }\n const buf = this.clone()\n this.buf[0] = val\n buf.copy(this.buf,1, 0, length)\n }\n }\n append(val){\n const length = this.length++\n if(length === this.size){\n this.resize()\n }\n this.buf[length] = val\n }\n clone(){\n return Buffer.from(this.buf.slice(0, this.length))\n }\n resize(){\n const length = this.length\n this.size = this.size * 2\n const buf = Buffer.alloc(this.size)\n this.buf.copy(buf,0, 0, length)\n this.buf = buf\n }\n toString(encoding){\n if(encoding){\n return this.buf.slice(0, this.length).toString(encoding)\n }else{\n return Uint8Array.prototype.slice.call(this.buf.slice(0, this.length))\n }\n }\n toJSON(){\n return this.toString('utf8')\n }\n reset(){\n this.length = 0\n }\n}\n\nmodule.exports = ResizeableBuffer\n","\n/*\nCSV Parse\n\nPlease look at the [project documentation](https://csv.js.org/parse/) for\nadditional information.\n*/\n\nconst { Transform } = require('stream')\nconst ResizeableBuffer = require('./ResizeableBuffer')\n\n// white space characters\n// https://en.wikipedia.org/wiki/Whitespace_character\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types\n// \\f\\n\\r\\t\\v\\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff\nconst tab = 9\nconst nl = 10 // \\n, 0x0A in hexadecimal, 10 in decimal\nconst np = 12\nconst cr = 13 // \\r, 0x0D in hexadécimal, 13 in decimal\nconst space = 32\nconst boms = {\n // Note, the following are equals:\n // Buffer.from(\"\\ufeff\")\n // Buffer.from([239, 187, 191])\n // Buffer.from('EFBBBF', 'hex')\n 'utf8': Buffer.from([239, 187, 191]),\n // Note, the following are equals:\n // Buffer.from \"\\ufeff\", 'utf16le\n // Buffer.from([255, 254])\n 'utf16le': Buffer.from([255, 254])\n}\n\nclass Parser extends Transform {\n constructor(opts = {}){\n super({...{readableObjectMode: true}, ...opts, encoding: null})\n this.__originalOptions = opts\n this.__normalizeOptions(opts)\n }\n __normalizeOptions(opts){\n const options = {}\n // Merge with user options\n for(let opt in opts){\n options[underscore(opt)] = opts[opt]\n }\n // Normalize option `encoding`\n // Note: defined first because other options depends on it\n // to convert chars/strings into buffers.\n if(options.encoding === undefined || options.encoding === true){\n options.encoding = 'utf8'\n }else if(options.encoding === null || options.encoding === false){\n options.encoding = null\n }else if(typeof options.encoding !== 'string' && options.encoding !== null){\n throw new CsvError('CSV_INVALID_OPTION_ENCODING', [\n 'Invalid option encoding:',\n 'encoding must be a string or null to return a buffer,',\n `got ${JSON.stringify(options.encoding)}`\n ], options)\n }\n // Normalize option `bom`\n if(options.bom === undefined || options.bom === null || options.bom === false){\n options.bom = false\n }else if(options.bom !== true){\n throw new CsvError('CSV_INVALID_OPTION_BOM', [\n 'Invalid option bom:', 'bom must be true,',\n `got ${JSON.stringify(options.bom)}`\n ], options)\n }\n // Normalize option `cast`\n let fnCastField = null\n if(options.cast === undefined || options.cast === null || options.cast === false || options.cast === ''){\n options.cast = undefined\n }else if(typeof options.cast === 'function'){\n fnCastField = options.cast\n options.cast = true\n }else if(options.cast !== true){\n throw new CsvError('CSV_INVALID_OPTION_CAST', [\n 'Invalid option cast:', 'cast must be true or a function,',\n `got ${JSON.stringify(options.cast)}`\n ], options)\n }\n // Normalize option `cast_date`\n if(options.cast_date === undefined || options.cast_date === null || options.cast_date === false || options.cast_date === ''){\n options.cast_date = false\n }else if(options.cast_date === true){\n options.cast_date = function(value){\n const date = Date.parse(value)\n return !isNaN(date) ? new Date(date) : value\n }\n }else if(typeof options.cast_date !== 'function'){\n throw new CsvError('CSV_INVALID_OPTION_CAST_DATE', [\n 'Invalid option cast_date:', 'cast_date must be true or a function,',\n `got ${JSON.stringify(options.cast_date)}`\n ], options)\n }\n // Normalize option `columns`\n let fnFirstLineToHeaders = null\n if(options.columns === true){\n // Fields in the first line are converted as-is to columns\n fnFirstLineToHeaders = undefined\n }else if(typeof options.columns === 'function'){\n fnFirstLineToHeaders = options.columns\n options.columns = true\n }else if(Array.isArray(options.columns)){\n options.columns = normalizeColumnsArray(options.columns)\n }else if(options.columns === undefined || options.columns === null || options.columns === false){\n options.columns = false\n }else{\n throw new CsvError('CSV_INVALID_OPTION_COLUMNS', [\n 'Invalid option columns:',\n 'expect an object, a function or true,',\n `got ${JSON.stringify(options.columns)}`\n ], options)\n }\n // Normalize option `columns_duplicates_to_array`\n if(options.columns_duplicates_to_array === undefined || options.columns_duplicates_to_array === null || options.columns_duplicates_to_array === false){\n options.columns_duplicates_to_array = false\n }else if(options.columns_duplicates_to_array !== true){\n throw new CsvError('CSV_INVALID_OPTION_COLUMNS_DUPLICATES_TO_ARRAY', [\n 'Invalid option columns_duplicates_to_array:',\n 'expect an boolean,',\n `got ${JSON.stringify(options.columns_duplicates_to_array)}`\n ], options)\n }\n // Normalize option `comment`\n if(options.comment === undefined || options.comment === null || options.comment === false || options.comment === ''){\n options.comment = null\n }else{\n if(typeof options.comment === 'string'){\n options.comment = Buffer.from(options.comment, options.encoding)\n }\n if(!Buffer.isBuffer(options.comment)){\n throw new CsvError('CSV_INVALID_OPTION_COMMENT', [\n 'Invalid option comment:',\n 'comment must be a buffer or a string,',\n `got ${JSON.stringify(options.comment)}`\n ], options)\n }\n }\n // Normalize option `delimiter`\n const delimiter_json = JSON.stringify(options.delimiter)\n if(!Array.isArray(options.delimiter)) options.delimiter = [options.delimiter]\n if(options.delimiter.length === 0){\n throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [\n 'Invalid option delimiter:',\n 'delimiter must be a non empty string or buffer or array of string|buffer,',\n `got ${delimiter_json}`\n ], options)\n }\n options.delimiter = options.delimiter.map(function(delimiter){\n if(delimiter === undefined || delimiter === null || delimiter === false){\n return Buffer.from(',', options.encoding)\n }\n if(typeof delimiter === 'string'){\n delimiter = Buffer.from(delimiter, options.encoding)\n }\n if( !Buffer.isBuffer(delimiter) || delimiter.length === 0){\n throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [\n 'Invalid option delimiter:',\n 'delimiter must be a non empty string or buffer or array of string|buffer,',\n `got ${delimiter_json}`\n ], options)\n }\n return delimiter\n })\n // Normalize option `escape`\n if(options.escape === undefined || options.escape === true){\n options.escape = Buffer.from('\"', options.encoding)\n }else if(typeof options.escape === 'string'){\n options.escape = Buffer.from(options.escape, options.encoding)\n }else if (options.escape === null || options.escape === false){\n options.escape = null\n }\n if(options.escape !== null){\n if(!Buffer.isBuffer(options.escape)){\n throw new Error(`Invalid Option: escape must be a buffer, a string or a boolean, got ${JSON.stringify(options.escape)}`)\n }\n }\n // Normalize option `from`\n if(options.from === undefined || options.from === null){\n options.from = 1\n }else{\n if(typeof options.from === 'string' && /\\d+/.test(options.from)){\n options.from = parseInt(options.from)\n }\n if(Number.isInteger(options.from)){\n if(options.from < 0){\n throw new Error(`Invalid Option: from must be a positive integer, got ${JSON.stringify(opts.from)}`)\n }\n }else{\n throw new Error(`Invalid Option: from must be an integer, got ${JSON.stringify(options.from)}`)\n }\n }\n // Normalize option `from_line`\n if(options.from_line === undefined || options.from_line === null){\n options.from_line = 1\n }else{\n if(typeof options.from_line === 'string' && /\\d+/.test(options.from_line)){\n options.from_line = parseInt(options.from_line)\n }\n if(Number.isInteger(options.from_line)){\n if(options.from_line <= 0){\n throw new Error(`Invalid Option: from_line must be a positive integer greater than 0, got ${JSON.stringify(opts.from_line)}`)\n }\n }else{\n throw new Error(`Invalid Option: from_line must be an integer, got ${JSON.stringify(opts.from_line)}`)\n }\n }\n // Normalize options `ignore_last_delimiters`\n if(options.ignore_last_delimiters === undefined || options.ignore_last_delimiters === null){\n options.ignore_last_delimiters = false\n }else if(typeof options.ignore_last_delimiters === 'number'){\n options.ignore_last_delimiters = Math.floor(options.ignore_last_delimiters)\n if(options.ignore_last_delimiters === 0){\n options.ignore_last_delimiters = false\n }\n }else if(typeof options.ignore_last_delimiters !== 'boolean'){\n throw new CsvError('CSV_INVALID_OPTION_IGNORE_LAST_DELIMITERS', [\n 'Invalid option `ignore_last_delimiters`:',\n 'the value must be a boolean value or an integer,',\n `got ${JSON.stringify(options.ignore_last_delimiters)}`\n ], options)\n }\n if(options.ignore_last_delimiters === true && options.columns === false){\n throw new CsvError('CSV_IGNORE_LAST_DELIMITERS_REQUIRES_COLUMNS', [\n 'The option `ignore_last_delimiters`',\n 'requires the activation of the `columns` option'\n ], options)\n }\n // Normalize option `info`\n if(options.info === undefined || options.info === null || options.info === false){\n options.info = false\n }else if(options.info !== true){\n throw new Error(`Invalid Option: info must be true, got ${JSON.stringify(options.info)}`)\n }\n // Normalize option `max_record_size`\n if(options.max_record_size === undefined || options.max_record_size === null || options.max_record_size === false){\n options.max_record_size = 0\n }else if(Number.isInteger(options.max_record_size) && options.max_record_size >= 0){\n // Great, nothing to do\n }else if(typeof options.max_record_size === 'string' && /\\d+/.test(options.max_record_size)){\n options.max_record_size = parseInt(options.max_record_size)\n }else{\n throw new Error(`Invalid Option: max_record_size must be a positive integer, got ${JSON.stringify(options.max_record_size)}`)\n }\n // Normalize option `objname`\n if(options.objname === undefined || options.objname === null || options.objname === false){\n options.objname = undefined\n }else if(Buffer.isBuffer(options.objname)){\n if(options.objname.length === 0){\n throw new Error(`Invalid Option: objname must be a non empty buffer`)\n }\n if(options.encoding === null){\n // Don't call `toString`, leave objname as a buffer\n }else{\n options.objname = options.objname.toString(options.encoding)\n }\n }else if(typeof options.objname === 'string'){\n if(options.objname.length === 0){\n throw new Error(`Invalid Option: objname must be a non empty string`)\n }\n // Great, nothing to do\n }else{\n throw new Error(`Invalid Option: objname must be a string or a buffer, got ${options.objname}`)\n }\n // Normalize option `on_record`\n if(options.on_record === undefined || options.on_record === null){\n options.on_record = undefined\n }else if(typeof options.on_record !== 'function'){\n throw new CsvError('CSV_INVALID_OPTION_ON_RECORD', [\n 'Invalid option `on_record`:',\n 'expect a function,',\n `got ${JSON.stringify(options.on_record)}`\n ], options)\n }\n // Normalize option `quote`\n if(options.quote === null || options.quote === false || options.quote === ''){\n options.quote = null\n }else{\n if(options.quote === undefined || options.quote === true){\n options.quote = Buffer.from('\"', options.encoding)\n }else if(typeof options.quote === 'string'){\n options.quote = Buffer.from(options.quote, options.encoding)\n }\n if(!Buffer.isBuffer(options.quote)){\n throw new Error(`Invalid Option: quote must be a buffer or a string, got ${JSON.stringify(options.quote)}`)\n }\n }\n // Normalize option `raw`\n if(options.raw === undefined || options.raw === null || options.raw === false){\n options.raw = false\n }else if(options.raw !== true){\n throw new Error(`Invalid Option: raw must be true, got ${JSON.stringify(options.raw)}`)\n }\n // Normalize option `record_delimiter`\n if(!options.record_delimiter){\n options.record_delimiter = []\n }else if(!Array.isArray(options.record_delimiter)){\n options.record_delimiter = [options.record_delimiter]\n }\n options.record_delimiter = options.record_delimiter.map( function(rd){\n if(typeof rd === 'string'){\n rd = Buffer.from(rd, options.encoding)\n }\n return rd\n })\n // Normalize option `relax`\n if(typeof options.relax === 'boolean'){\n // Great, nothing to do\n }else if(options.relax === undefined || options.relax === null){\n options.relax = false\n }else{\n throw new Error(`Invalid Option: relax must be a boolean, got ${JSON.stringify(options.relax)}`)\n }\n // Normalize option `relax_column_count`\n if(typeof options.relax_column_count === 'boolean'){\n // Great, nothing to do\n }else if(options.relax_column_count === undefined || options.relax_column_count === null){\n options.relax_column_count = false\n }else{\n throw new Error(`Invalid Option: relax_column_count must be a boolean, got ${JSON.stringify(options.relax_column_count)}`)\n }\n if(typeof options.relax_column_count_less === 'boolean'){\n // Great, nothing to do\n }else if(options.relax_column_count_less === undefined || options.relax_column_count_less === null){\n options.relax_column_count_less = false\n }else{\n throw new Error(`Invalid Option: relax_column_count_less must be a boolean, got ${JSON.stringify(options.relax_column_count_less)}`)\n }\n if(typeof options.relax_column_count_more === 'boolean'){\n // Great, nothing to do\n }else if(options.relax_column_count_more === undefined || options.relax_column_count_more === null){\n options.relax_column_count_more = false\n }else{\n throw new Error(`Invalid Option: relax_column_count_more must be a boolean, got ${JSON.stringify(options.relax_column_count_more)}`)\n }\n // Normalize option `skip_empty_lines`\n if(typeof options.skip_empty_lines === 'boolean'){\n // Great, nothing to do\n }else if(options.skip_empty_lines === undefined || options.skip_empty_lines === null){\n options.skip_empty_lines = false\n }else{\n throw new Error(`Invalid Option: skip_empty_lines must be a boolean, got ${JSON.stringify(options.skip_empty_lines)}`)\n }\n // Normalize option `skip_lines_with_empty_values`\n if(typeof options.skip_lines_with_empty_values === 'boolean'){\n // Great, nothing to do\n }else if(options.skip_lines_with_empty_values === undefined || options.skip_lines_with_empty_values === null){\n options.skip_lines_with_empty_values = false\n }else{\n throw new Error(`Invalid Option: skip_lines_with_empty_values must be a boolean, got ${JSON.stringify(options.skip_lines_with_empty_values)}`)\n }\n // Normalize option `skip_lines_with_error`\n if(typeof options.skip_lines_with_error === 'boolean'){\n // Great, nothing to do\n }else if(options.skip_lines_with_error === undefined || options.skip_lines_with_error === null){\n options.skip_lines_with_error = false\n }else{\n throw new Error(`Invalid Option: skip_lines_with_error must be a boolean, got ${JSON.stringify(options.skip_lines_with_error)}`)\n }\n // Normalize option `rtrim`\n if(options.rtrim === undefined || options.rtrim === null || options.rtrim === false){\n options.rtrim = false\n }else if(options.rtrim !== true){\n throw new Error(`Invalid Option: rtrim must be a boolean, got ${JSON.stringify(options.rtrim)}`)\n }\n // Normalize option `ltrim`\n if(options.ltrim === undefined || options.ltrim === null || options.ltrim === false){\n options.ltrim = false\n }else if(options.ltrim !== true){\n throw new Error(`Invalid Option: ltrim must be a boolean, got ${JSON.stringify(options.ltrim)}`)\n }\n // Normalize option `trim`\n if(options.trim === undefined || options.trim === null || options.trim === false){\n options.trim = false\n }else if(options.trim !== true){\n throw new Error(`Invalid Option: trim must be a boolean, got ${JSON.stringify(options.trim)}`)\n }\n // Normalize options `trim`, `ltrim` and `rtrim`\n if(options.trim === true && opts.ltrim !== false){\n options.ltrim = true\n }else if(options.ltrim !== true){\n options.ltrim = false\n }\n if(options.trim === true && opts.rtrim !== false){\n options.rtrim = true\n }else if(options.rtrim !== true){\n options.rtrim = false\n }\n // Normalize option `to`\n if(options.to === undefined || options.to === null){\n options.to = -1\n }else{\n if(typeof options.to === 'string' && /\\d+/.test(options.to)){\n options.to = parseInt(options.to)\n }\n if(Number.isInteger(options.to)){\n if(options.to <= 0){\n throw new Error(`Invalid Option: to must be a positive integer greater than 0, got ${JSON.stringify(opts.to)}`)\n }\n }else{\n throw new Error(`Invalid Option: to must be an integer, got ${JSON.stringify(opts.to)}`)\n }\n }\n // Normalize option `to_line`\n if(options.to_line === undefined || options.to_line === null){\n options.to_line = -1\n }else{\n if(typeof options.to_line === 'string' && /\\d+/.test(options.to_line)){\n options.to_line = parseInt(options.to_line)\n }\n if(Number.isInteger(options.to_line)){\n if(options.to_line <= 0){\n throw new Error(`Invalid Option: to_line must be a positive integer greater than 0, got ${JSON.stringify(opts.to_line)}`)\n }\n }else{\n throw new Error(`Invalid Option: to_line must be an integer, got ${JSON.stringify(opts.to_line)}`)\n }\n }\n this.info = {\n comment_lines: 0,\n empty_lines: 0,\n invalid_field_length: 0,\n lines: 1,\n records: 0\n }\n this.options = options\n this.state = {\n bomSkipped: false,\n castField: fnCastField,\n commenting: false,\n // Current error encountered by a record\n error: undefined,\n enabled: options.from_line === 1,\n escaping: false,\n // escapeIsQuote: options.escape === options.quote,\n escapeIsQuote: Buffer.isBuffer(options.escape) && Buffer.isBuffer(options.quote) && Buffer.compare(options.escape, options.quote) === 0,\n expectedRecordLength: options.columns === null ? 0 : options.columns.length,\n field: new ResizeableBuffer(20),\n firstLineToHeaders: fnFirstLineToHeaders,\n info: Object.assign({}, this.info),\n needMoreDataSize: Math.max(\n // Skip if the remaining buffer smaller than comment\n options.comment !== null ? options.comment.length : 0,\n // Skip if the remaining buffer can be delimiter\n ...options.delimiter.map( (delimiter) => delimiter.length),\n // Skip if the remaining buffer can be escape sequence\n options.quote !== null ? options.quote.length : 0,\n ),\n previousBuf: undefined,\n quoting: false,\n stop: false,\n rawBuffer: new ResizeableBuffer(100),\n record: [],\n recordHasError: false,\n record_length: 0,\n recordDelimiterMaxLength: options.record_delimiter.length === 0 ? 2 : Math.max(...options.record_delimiter.map( (v) => v.length)),\n trimChars: [Buffer.from(' ', options.encoding)[0], Buffer.from('\\t', options.encoding)[0]],\n wasQuoting: false,\n wasRowDelimiter: false\n }\n }\n // Implementation of `Transform._transform`\n _transform(buf, encoding, callback){\n if(this.state.stop === true){\n return\n }\n const err = this.__parse(buf, false)\n if(err !== undefined){\n this.state.stop = true\n }\n callback(err)\n }\n // Implementation of `Transform._flush`\n _flush(callback){\n if(this.state.stop === true){\n return\n }\n const err = this.__parse(undefined, true)\n callback(err)\n }\n // Central parser implementation\n __parse(nextBuf, end){\n const {bom, comment, escape, from_line, info, ltrim, max_record_size, quote, raw, relax, rtrim, skip_empty_lines, to, to_line} = this.options\n let {record_delimiter} = this.options\n const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state\n let buf\n if(previousBuf === undefined){\n if(nextBuf === undefined){\n // Handle empty string\n this.push(null)\n return\n }else{\n buf = nextBuf\n }\n }else if(previousBuf !== undefined && nextBuf === undefined){\n buf = previousBuf\n }else{\n buf = Buffer.concat([previousBuf, nextBuf])\n }\n // Handle UTF BOM\n if(bomSkipped === false){\n if(bom === false){\n this.state.bomSkipped = true\n }else if(buf.length < 3){\n // No enough data\n if(end === false){\n // Wait for more data\n this.state.previousBuf = buf\n return\n }\n }else{\n for(let encoding in boms){\n if(boms[encoding].compare(buf, 0, boms[encoding].length) === 0){\n // Skip BOM\n buf = buf.slice(boms[encoding].length)\n // Renormalize original options with the new encoding\n this.__normalizeOptions({...this.__originalOptions, encoding: encoding})\n break\n }\n }\n this.state.bomSkipped = true\n }\n }\n const bufLen = buf.length\n let pos\n for(pos = 0; pos < bufLen; pos++){\n // Ensure we get enough space to look ahead\n // There should be a way to move this out of the loop\n if(this.__needMoreData(pos, bufLen, end)){\n break\n }\n if(this.state.wasRowDelimiter === true){\n this.info.lines++\n if(info === true && this.state.record.length === 0 && this.state.field.length === 0 && this.state.wasQuoting === false){\n this.state.info = Object.assign({}, this.info)\n }\n this.state.wasRowDelimiter = false\n }\n if(to_line !== -1 && this.info.lines > to_line){\n this.state.stop = true\n this.push(null)\n return\n }\n // Auto discovery of record_delimiter, unix, mac and windows supported\n if(this.state.quoting === false && record_delimiter.length === 0){\n const record_delimiterCount = this.__autoDiscoverRecordDelimiter(buf, pos)\n if(record_delimiterCount){\n record_delimiter = this.options.record_delimiter\n }\n }\n const chr = buf[pos]\n if(raw === true){\n rawBuffer.append(chr)\n }\n if((chr === cr || chr === nl) && this.state.wasRowDelimiter === false ){\n this.state.wasRowDelimiter = true\n }\n // Previous char was a valid escape char\n // treat the current char as a regular char\n if(this.state.escaping === true){\n this.state.escaping = false\n }else{\n // Escape is only active inside quoted fields\n // We are quoting, the char is an escape chr and there is a chr to escape\n // if(escape !== null && this.state.quoting === true && chr === escape && pos + 1 < bufLen){\n if(escape !== null && this.state.quoting === true && this.__isEscape(buf, pos, chr) && pos + escape.length < bufLen){\n if(escapeIsQuote){\n if(this.__isQuote(buf, pos+escape.length)){\n this.state.escaping = true\n pos += escape.length - 1\n continue\n }\n }else{\n this.state.escaping = true\n pos += escape.length - 1\n continue\n }\n }\n // Not currently escaping and chr is a quote\n // TODO: need to compare bytes instead of single char\n if(this.state.commenting === false && this.__isQuote(buf, pos)){\n if(this.state.quoting === true){\n const nextChr = buf[pos+quote.length]\n const isNextChrTrimable = rtrim && this.__isCharTrimable(nextChr)\n const isNextChrComment = comment !== null && this.__compareBytes(comment, buf, pos+quote.length, nextChr)\n const isNextChrDelimiter = this.__isDelimiter(buf, pos+quote.length, nextChr)\n const isNextChrRecordDelimiter = record_delimiter.length === 0 ? this.__autoDiscoverRecordDelimiter(buf, pos+quote.length) : this.__isRecordDelimiter(nextChr, buf, pos+quote.length)\n // Escape a quote\n // Treat next char as a regular character\n if(escape !== null && this.__isEscape(buf, pos, chr) && this.__isQuote(buf, pos + escape.length)){\n pos += escape.length - 1\n }else if(!nextChr || isNextChrDelimiter || isNextChrRecordDelimiter || isNextChrComment || isNextChrTrimable){\n this.state.quoting = false\n this.state.wasQuoting = true\n pos += quote.length - 1\n continue\n }else if(relax === false){\n const err = this.__error(\n new CsvError('CSV_INVALID_CLOSING_QUOTE', [\n 'Invalid Closing Quote:',\n `got \"${String.fromCharCode(nextChr)}\"`,\n `at line ${this.info.lines}`,\n 'instead of delimiter, record delimiter, trimable character',\n '(if activated) or comment',\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }else{\n this.state.quoting = false\n this.state.wasQuoting = true\n this.state.field.prepend(quote)\n pos += quote.length - 1\n }\n }else{\n if(this.state.field.length !== 0){\n // In relax mode, treat opening quote preceded by chrs as regular\n if( relax === false ){\n const err = this.__error(\n new CsvError('INVALID_OPENING_QUOTE', [\n 'Invalid Opening Quote:',\n `a quote is found inside a field at line ${this.info.lines}`,\n ], this.options, this.__context(), {\n field: this.state.field,\n })\n )\n if(err !== undefined) return err\n }\n }else{\n this.state.quoting = true\n pos += quote.length - 1\n continue\n }\n }\n }\n if(this.state.quoting === false){\n let recordDelimiterLength = this.__isRecordDelimiter(chr, buf, pos)\n if(recordDelimiterLength !== 0){\n // Do not emit comments which take a full line\n const skipCommentLine = this.state.commenting && (this.state.wasQuoting === false && this.state.record.length === 0 && this.state.field.length === 0)\n if(skipCommentLine){\n this.info.comment_lines++\n // Skip full comment line\n }else{\n // Activate records emition if above from_line\n if(this.state.enabled === false && this.info.lines + (this.state.wasRowDelimiter === true ? 1: 0) >= from_line){\n this.state.enabled = true\n this.__resetField()\n this.__resetRecord()\n pos += recordDelimiterLength - 1\n continue\n }\n // Skip if line is empty and skip_empty_lines activated\n if(skip_empty_lines === true && this.state.wasQuoting === false && this.state.record.length === 0 && this.state.field.length === 0){\n this.info.empty_lines++\n pos += recordDelimiterLength - 1\n continue\n }\n const errField = this.__onField()\n if(errField !== undefined) return errField\n const errRecord = this.__onRecord()\n if(errRecord !== undefined) return errRecord\n if(to !== -1 && this.info.records >= to){\n this.state.stop = true\n this.push(null)\n return\n }\n }\n this.state.commenting = false\n pos += recordDelimiterLength - 1\n continue\n }\n if(this.state.commenting){\n continue\n }\n const commentCount = comment === null ? 0 : this.__compareBytes(comment, buf, pos, chr)\n if(commentCount !== 0){\n this.state.commenting = true\n continue\n }\n let delimiterLength = this.__isDelimiter(buf, pos, chr)\n if(delimiterLength !== 0){\n const errField = this.__onField()\n if(errField !== undefined) return errField\n pos += delimiterLength - 1\n continue\n }\n }\n }\n if(this.state.commenting === false){\n if(max_record_size !== 0 && this.state.record_length + this.state.field.length > max_record_size){\n const err = this.__error(\n new CsvError('CSV_MAX_RECORD_SIZE', [\n 'Max Record Size:',\n 'record exceed the maximum number of tolerated bytes',\n `of ${max_record_size}`,\n `at line ${this.info.lines}`,\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }\n }\n\n const lappend = ltrim === false || this.state.quoting === true || this.state.field.length !== 0 || !this.__isCharTrimable(chr)\n // rtrim in non quoting is handle in __onField\n const rappend = rtrim === false || this.state.wasQuoting === false\n if( lappend === true && rappend === true ){\n this.state.field.append(chr)\n }else if(rtrim === true && !this.__isCharTrimable(chr)){\n const err = this.__error(\n new CsvError('CSV_NON_TRIMABLE_CHAR_AFTER_CLOSING_QUOTE', [\n 'Invalid Closing Quote:',\n 'found non trimable byte after quote',\n `at line ${this.info.lines}`,\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }\n }\n if(end === true){\n // Ensure we are not ending in a quoting state\n if(this.state.quoting === true){\n const err = this.__error(\n new CsvError('CSV_QUOTE_NOT_CLOSED', [\n 'Quote Not Closed:',\n `the parsing is finished with an opening quote at line ${this.info.lines}`,\n ], this.options, this.__context())\n )\n if(err !== undefined) return err\n }else{\n // Skip last line if it has no characters\n if(this.state.wasQuoting === true || this.state.record.length !== 0 || this.state.field.length !== 0){\n const errField = this.__onField()\n if(errField !== undefined) return errField\n const errRecord = this.__onRecord()\n if(errRecord !== undefined) return errRecord\n }else if(this.state.wasRowDelimiter === true){\n this.info.empty_lines++\n }else if(this.state.commenting === true){\n this.info.comment_lines++\n }\n }\n }else{\n this.state.previousBuf = buf.slice(pos)\n }\n if(this.state.wasRowDelimiter === true){\n this.info.lines++\n this.state.wasRowDelimiter = false\n }\n }\n __onRecord(){\n const {columns, columns_duplicates_to_array, encoding, info, from, relax_column_count, relax_column_count_less, relax_column_count_more, raw, skip_lines_with_empty_values} = this.options\n const {enabled, record} = this.state\n if(enabled === false){\n return this.__resetRecord()\n }\n // Convert the first line into column names\n const recordLength = record.length\n if(columns === true){\n if(isRecordEmpty(record)){\n this.__resetRecord()\n return\n }\n return this.__firstLineToColumns(record)\n }\n if(columns === false && this.info.records === 0){\n this.state.expectedRecordLength = recordLength\n }\n if(recordLength !== this.state.expectedRecordLength){\n const err = columns === false ?\n // Todo: rename CSV_INCONSISTENT_RECORD_LENGTH to\n // CSV_RECORD_INCONSISTENT_FIELDS_LENGTH\n new CsvError('CSV_INCONSISTENT_RECORD_LENGTH', [\n 'Invalid Record Length:',\n `expect ${this.state.expectedRecordLength},`,\n `got ${recordLength} on line ${this.info.lines}`,\n ], this.options, this.__context(), {\n record: record,\n })\n :\n // Todo: rename CSV_RECORD_DONT_MATCH_COLUMNS_LENGTH to\n // CSV_RECORD_INCONSISTENT_COLUMNS\n new CsvError('CSV_RECORD_DONT_MATCH_COLUMNS_LENGTH', [\n 'Invalid Record Length:',\n `columns length is ${columns.length},`, // rename columns\n `got ${recordLength} on line ${this.info.lines}`,\n ], this.options, this.__context(), {\n record: record,\n })\n if(relax_column_count === true ||\n (relax_column_count_less === true && recordLength < this.state.expectedRecordLength) ||\n (relax_column_count_more === true && recordLength > this.state.expectedRecordLength) ){\n this.info.invalid_field_length++\n this.state.error = err\n // Error is undefined with skip_lines_with_error\n }else{\n const finalErr = this.__error(err)\n if(finalErr) return finalErr\n }\n }\n if(skip_lines_with_empty_values === true){\n if(isRecordEmpty(record)){\n this.__resetRecord()\n return\n }\n }\n if(this.state.recordHasError === true){\n this.__resetRecord()\n this.state.recordHasError = false\n return\n }\n this.info.records++\n if(from === 1 || this.info.records >= from){\n if(columns !== false){\n const obj = {}\n // Transform record array to an object\n for(let i = 0, l = record.length; i < l; i++){\n if(columns[i] === undefined || columns[i].disabled) continue\n // Turn duplicate columns into an array\n if (columns_duplicates_to_array === true && obj[columns[i].name] !== undefined) {\n if (Array.isArray(obj[columns[i].name])) {\n obj[columns[i].name] = obj[columns[i].name].concat(record[i])\n } else {\n obj[columns[i].name] = [obj[columns[i].name], record[i]]\n }\n } else {\n obj[columns[i].name] = record[i]\n }\n }\n const {objname} = this.options\n if(objname === undefined){\n if(raw === true || info === true){\n const err = this.__push(Object.assign(\n {record: obj},\n (raw === true ? {raw: this.state.rawBuffer.toString(encoding)}: {}),\n (info === true ? {info: this.state.info}: {})\n ))\n if(err){\n return err\n }\n }else{\n const err = this.__push(obj)\n if(err){\n return err\n }\n }\n }else{\n if(raw === true || info === true){\n const err = this.__push(Object.assign(\n {record: [obj[objname], obj]},\n raw === true ? {raw: this.state.rawBuffer.toString(encoding)}: {},\n info === true ? {info: this.state.info}: {}\n ))\n if(err){\n return err\n }\n }else{\n const err = this.__push([obj[objname], obj])\n if(err){\n return err\n }\n }\n }\n }else{\n if(raw === true || info === true){\n const err = this.__push(Object.assign(\n {record: record},\n raw === true ? {raw: this.state.rawBuffer.toString(encoding)}: {},\n info === true ? {info: this.state.info}: {}\n ))\n if(err){\n return err\n }\n }else{\n const err = this.__push(record)\n if(err){\n return err\n }\n }\n }\n }\n this.__resetRecord()\n }\n __firstLineToColumns(record){\n const {firstLineToHeaders} = this.state\n try{\n const headers = firstLineToHeaders === undefined ? record : firstLineToHeaders.call(null, record)\n if(!Array.isArray(headers)){\n return this.__error(\n new CsvError('CSV_INVALID_COLUMN_MAPPING', [\n 'Invalid Column Mapping:',\n 'expect an array from column function,',\n `got ${JSON.stringify(headers)}`\n ], this.options, this.__context(), {\n headers: headers,\n })\n )\n }\n const normalizedHeaders = normalizeColumnsArray(headers)\n this.state.expectedRecordLength = normalizedHeaders.length\n this.options.columns = normalizedHeaders\n this.__resetRecord()\n return\n }catch(err){\n return err\n }\n }\n __resetRecord(){\n if(this.options.raw === true){\n this.state.rawBuffer.reset()\n }\n this.state.error = undefined\n this.state.record = []\n this.state.record_length = 0\n }\n __onField(){\n const {cast, encoding, rtrim, max_record_size} = this.options\n const {enabled, wasQuoting} = this.state\n // Short circuit for the from_line options\n if(enabled === false){ /* this.options.columns !== true && */\n return this.__resetField()\n }\n let field = this.state.field.toString(encoding)\n if(rtrim === true && wasQuoting === false){\n field = field.trimRight()\n }\n if(cast === true){\n const [err, f] = this.__cast(field)\n if(err !== undefined) return err\n field = f\n }\n this.state.record.push(field)\n // Increment record length if record size must not exceed a limit\n if(max_record_size !== 0 && typeof field === 'string'){\n this.state.record_length += field.length\n }\n this.__resetField()\n }\n __resetField(){\n this.state.field.reset()\n this.state.wasQuoting = false\n }\n __push(record){\n const {on_record} = this.options\n if(on_record !== undefined){\n const context = this.__context()\n try{\n record = on_record.call(null, record, context)\n }catch(err){\n return err\n }\n if(record === undefined || record === null){ return }\n }\n this.push(record)\n }\n // Return a tuple with the error and the casted value\n __cast(field){\n const {columns, relax_column_count} = this.options\n const isColumns = Array.isArray(columns)\n // Dont loose time calling cast\n // because the final record is an object\n // and this field can't be associated to a key present in columns\n if( isColumns === true && relax_column_count && this.options.columns.length <= this.state.record.length ){\n return [undefined, undefined]\n }\n const context = this.__context()\n if(this.state.castField !== null){\n try{\n return [undefined, this.state.castField.call(null, field, context)]\n }catch(err){\n return [err]\n }\n }\n if(this.__isFloat(field)){\n return [undefined, parseFloat(field)]\n }else if(this.options.cast_date !== false){\n return [undefined, this.options.cast_date.call(null, field, context)]\n }\n return [undefined, field]\n }\n // Helper to test if a character is a space or a line delimiter\n __isCharTrimable(chr){\n return chr === space || chr === tab || chr === cr || chr === nl || chr === np\n }\n // Keep it in case we implement the `cast_int` option\n // __isInt(value){\n // // return Number.isInteger(parseInt(value))\n // // return !isNaN( parseInt( obj ) );\n // return /^(\\-|\\+)?[1-9][0-9]*$/.test(value)\n // }\n __isFloat(value){\n return (value - parseFloat( value ) + 1) >= 0 // Borrowed from jquery\n }\n __compareBytes(sourceBuf, targetBuf, targetPos, firstByte){\n if(sourceBuf[0] !== firstByte) return 0\n const sourceLength = sourceBuf.length\n for(let i = 1; i < sourceLength; i++){\n if(sourceBuf[i] !== targetBuf[targetPos+i]) return 0\n }\n return sourceLength\n }\n __needMoreData(i, bufLen, end){\n if(end) return false\n const {quote} = this.options\n const {quoting, needMoreDataSize, recordDelimiterMaxLength} = this.state\n const numOfCharLeft = bufLen - i - 1\n const requiredLength = Math.max(\n needMoreDataSize,\n // Skip if the remaining buffer smaller than record delimiter\n recordDelimiterMaxLength,\n // Skip if the remaining buffer can be record delimiter following the closing quote\n // 1 is for quote.length\n quoting ? (quote.length + recordDelimiterMaxLength) : 0,\n )\n return numOfCharLeft < requiredLength\n }\n __isDelimiter(buf, pos, chr){\n const {delimiter, ignore_last_delimiters} = this.options\n if(ignore_last_delimiters === true && this.state.record.length === this.options.columns.length - 1){\n return 0\n }else if(ignore_last_delimiters !== false && typeof ignore_last_delimiters === 'number' && this.state.record.length === ignore_last_delimiters - 1){\n return 0\n }\n loop1: for(let i = 0; i < delimiter.length; i++){\n const del = delimiter[i]\n if(del[0] === chr){\n for(let j = 1; j < del.length; j++){\n if(del[j] !== buf[pos+j]) continue loop1\n }\n return del.length\n }\n }\n return 0\n }\n __isRecordDelimiter(chr, buf, pos){\n const {record_delimiter} = this.options\n const recordDelimiterLength = record_delimiter.length\n loop1: for(let i = 0; i < recordDelimiterLength; i++){\n const rd = record_delimiter[i]\n const rdLength = rd.length\n if(rd[0] !== chr){\n continue\n }\n for(let j = 1; j < rdLength; j++){\n if(rd[j] !== buf[pos+j]){\n continue loop1\n }\n }\n return rd.length\n }\n return 0\n }\n __isEscape(buf, pos, chr){\n const {escape} = this.options\n if(escape === null) return false\n const l = escape.length\n if(escape[0] === chr){\n for(let i = 0; i < l; i++){\n if(escape[i] !== buf[pos+i]){\n return false\n }\n }\n return true\n }\n return false\n }\n __isQuote(buf, pos){\n const {quote} = this.options\n if(quote === null) return false\n const l = quote.length\n for(let i = 0; i < l; i++){\n if(quote[i] !== buf[pos+i]){\n return false\n }\n }\n return true\n }\n __autoDiscoverRecordDelimiter(buf, pos){\n const {encoding} = this.options\n const chr = buf[pos]\n if(chr === cr){\n if(buf[pos+1] === nl){\n this.options.record_delimiter.push(Buffer.from('\\r\\n', encoding))\n this.state.recordDelimiterMaxLength = 2\n return 2\n }else{\n this.options.record_delimiter.push(Buffer.from('\\r', encoding))\n this.state.recordDelimiterMaxLength = 1\n return 1\n }\n }else if(chr === nl){\n this.options.record_delimiter.push(Buffer.from('\\n', encoding))\n this.state.recordDelimiterMaxLength = 1\n return 1\n }\n return 0\n }\n __error(msg){\n const {skip_lines_with_error} = this.options\n const err = typeof msg === 'string' ? new Error(msg) : msg\n if(skip_lines_with_error){\n this.state.recordHasError = true\n this.emit('skip', err)\n return undefined\n }else{\n return err\n }\n }\n __context(){\n const {columns} = this.options\n const isColumns = Array.isArray(columns)\n return {\n column: isColumns === true ?\n ( columns.length > this.state.record.length ?\n columns[this.state.record.length].name :\n null\n ) :\n this.state.record.length,\n empty_lines: this.info.empty_lines,\n error: this.state.error,\n header: columns === true,\n index: this.state.record.length,\n invalid_field_length: this.info.invalid_field_length,\n quoting: this.state.wasQuoting,\n lines: this.info.lines,\n records: this.info.records\n }\n }\n}\n\nconst parse = function(){\n let data, options, callback\n for(let i in arguments){\n const argument = arguments[i]\n const type = typeof argument\n if(data === undefined && (typeof argument === 'string' || Buffer.isBuffer(argument))){\n data = argument\n }else if(options === undefined && isObject(argument)){\n options = argument\n }else if(callback === undefined && type === 'function'){\n callback = argument\n }else{\n throw new CsvError('CSV_INVALID_ARGUMENT', [\n 'Invalid argument:',\n `got ${JSON.stringify(argument)} at index ${i}`\n ], this.options)\n }\n }\n const parser = new Parser(options)\n if(callback){\n const records = options === undefined || options.objname === undefined ? [] : {}\n parser.on('readable', function(){\n let record\n while((record = this.read()) !== null){\n if(options === undefined || options.objname === undefined){\n records.push(record)\n }else{\n records[record[0]] = record[1]\n }\n }\n })\n parser.on('error', function(err){\n callback(err, undefined, parser.info)\n })\n parser.on('end', function(){\n callback(undefined, records, parser.info)\n })\n }\n if(data !== undefined){\n // Give a chance for events to be registered later\n if(typeof setImmediate === 'function'){\n setImmediate(function(){\n parser.write(data)\n parser.end()\n })\n }else{\n parser.write(data)\n parser.end()\n }\n }\n return parser\n}\n\nclass CsvError extends Error {\n constructor(code, message, options, ...contexts) {\n if(Array.isArray(message)) message = message.join(' ')\n super(message)\n if(Error.captureStackTrace !== undefined){\n Error.captureStackTrace(this, CsvError)\n }\n this.code = code\n for(const context of contexts){\n for(const key in context){\n const value = context[key]\n this[key] = Buffer.isBuffer(value) ? value.toString(options.encoding) : value == null ? value : JSON.parse(JSON.stringify(value))\n }\n }\n }\n}\n\nparse.Parser = Parser\n\nparse.CsvError = CsvError\n\nmodule.exports = parse\n\nconst underscore = function(str){\n return str.replace(/([A-Z])/g, function(_, match){\n return '_' + match.toLowerCase()\n })\n}\n\nconst isObject = function(obj){\n return (typeof obj === 'object' && obj !== null && !Array.isArray(obj))\n}\n\nconst isRecordEmpty = function(record){\n return record.every( (field) => field == null || field.toString && field.toString().trim() === '' )\n}\n\nconst normalizeColumnsArray = function(columns){\n const normalizedColumns = [];\n for(let i = 0, l = columns.length; i < l; i++){\n const column = columns[i]\n if(column === undefined || column === null || column === false){\n normalizedColumns[i] = { disabled: true }\n }else if(typeof column === 'string'){\n normalizedColumns[i] = { name: column }\n }else if(isObject(column)){\n if(typeof column.name !== 'string'){\n throw new CsvError('CSV_OPTION_COLUMNS_MISSING_NAME', [\n 'Option columns missing name:',\n `property \"name\" is required at position ${i}`,\n 'when column is an object literal'\n ])\n }\n normalizedColumns[i] = column\n }else{\n throw new CsvError('CSV_INVALID_COLUMN_DEFINITION', [\n 'Invalid column definition:',\n 'expect a string or a literal object,',\n `got ${JSON.stringify(column)} at position ${i}`\n ])\n }\n }\n return normalizedColumns;\n}\n","\nconst parse = require('.')\n\nmodule.exports = function(data, options={}){\n if(typeof data === 'string'){\n data = Buffer.from(data)\n }\n const records = options && options.objname ? {} : []\n const parser = new parse.Parser(options)\n parser.push = function(record){\n if(record === null){\n return\n }\n if(options.objname === undefined)\n records.push(record)\n else{\n records[record[0]] = record[1]\n }\n }\n const err1 = parser.__parse(data, false)\n if(err1 !== undefined) throw err1\n const err2 = parser.__parse(undefined, true)\n if(err2 !== undefined) throw err2\n return records\n}\n",null,null,null,null,null,"module.exports = require(\"assert\");;","module.exports = require(\"child_process\");;","module.exports = require(\"events\");;","module.exports = require(\"fs\");;","module.exports = require(\"os\");;","module.exports = require(\"path\");;","module.exports = require(\"stream\");;","module.exports = require(\"string_decoder\");;","module.exports = require(\"timers\");;","module.exports = require(\"util\");;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tvar threw = true;\n\ttry {\n\t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\t\tthrew = false;\n\t} finally {\n\t\tif(threw) delete __webpack_module_cache__[moduleId];\n\t}\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","\n__webpack_require__.ab = __dirname + \"/\";","// module exports must be returned from runtime so entry inlining is disabled\n// startup\n// Load entry module and return exports\nreturn __webpack_require__(109);\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACrJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACvRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;ACvGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1mBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;;AC1MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;ACxTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;AC/tCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;;;;AC1BA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;ACRA;;AAEA;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;;ACRA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;;;ACDA;AACA;A;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5BA;AACA;ACDA;AACA;AACA;AACA;;A","sourceRoot":""} \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 1e59424ea..192338615 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,6 +16,7 @@ export interface DevContainerConfig { args?: Record } runArgs?: string[] + mounts?: string[] } export async function loadFromFile( diff --git a/src/docker.ts b/src/docker.ts index c7cdd256b..61b83f9c8 100644 --- a/src/docker.ts +++ b/src/docker.ts @@ -3,6 +3,7 @@ import * as core from '@actions/core' import * as config from './config' import {exec, execWithOptions} from './exec' import {getAbsolutePath} from './file' +import {substituteValues} from './envvars' export async function isDockerBuildXInstalled(): Promise { const r = await exec('docker', 'buildx', '--help') @@ -43,7 +44,7 @@ export async function buildImage( const buildArgs = devcontainerConfig.build?.args for (const argName in buildArgs) { - const argValue = buildArgs[argName] + const argValue = substituteValues(buildArgs[argName]) args.push('--build-arg', `${argName}=${argValue}`) } @@ -98,7 +99,10 @@ export async function runContainer( args.push('--workdir', workspaceFolder) args.push('--user', remoteUser) if (devcontainerConfig.runArgs) { - args.push(...devcontainerConfig.runArgs) + const subtitutedRunArgs = devcontainerConfig.runArgs.map(a => + substituteValues(a) + ) + args.push(...subtitutedRunArgs) } if (envs) { for (const env of envs) { diff --git a/src/envvars.ts b/src/envvars.ts new file mode 100644 index 000000000..37e8760b2 --- /dev/null +++ b/src/envvars.ts @@ -0,0 +1,26 @@ +export function substituteValues(input: string): string { + // Find all `${...}` entries and substitute + // Note the non-greedy `.+?` match to avoid matching the start of + // one placeholder up to the end of another when multiple placeholders are present + return input.replace(/\$\{(.+?)\}/g, getSubstitutionValue) +} + +function getSubstitutionValue(regexMatch: string, placeholder: string): string { + // Substitution values are in TYPE:KEY form + // e.g. env:MY_ENV + + const parts = placeholder.split(':') + if (parts.length === 2) { + const type = parts[0] + const key = parts[1] + switch (type) { + case 'env': + case 'localenv': + return process.env[key] ?? '' + } + } + + // if we can't process the format then return the original string + // as having it present in any output will likely make issues more obvious + return regexMatch +}