From 7265dc534431d847f1c6b59590d65c4fc0cd307e Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 3 Jul 2022 05:22:51 +0000
Subject: [PATCH] Release v5.22.0
---
dist/index.js | 52179 ++++++++++++++++++++++++++++++++++-
dist/index.js.map | 2 +-
dist/licenses.txt | 1638 ++
dist/presets/divx.js | 14 +
dist/presets/flashvideo.js | 16 +
dist/presets/podcast.js | 16 +
6 files changed, 53544 insertions(+), 321 deletions(-)
create mode 100644 dist/presets/divx.js
create mode 100644 dist/presets/flashvideo.js
create mode 100644 dist/presets/podcast.js
diff --git a/dist/index.js b/dist/index.js
index 6d715cb..77e39a7 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,7 +1,34 @@
require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
-/***/ 536:
+/***/ 5850:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.writeText = void 0;
+const fs_1 = __importDefault(__nccwpck_require__(7147));
+const writeText = async (path, textFilePath) => {
+ //Add text to first of line
+ let text = fs_1.default.readFileSync(textFilePath, 'utf8');
+ const content = await fs_1.default.readFileSync(path, 'utf8');
+ const lines = content.split('\n');
+ const firstLine = lines[0];
+ text = text.replace(/\n/g, '\n//');
+ let newContent = `//${text}\n${firstLine}`;
+ newContent += lines.slice(1).join('\n');
+ return await fs_1.default.writeFileSync(path, newContent, 'utf8');
+};
+exports.writeText = writeText;
+
+
+/***/ }),
+
+/***/ 1732:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -29,20 +56,294 @@ var __importStar = (this && this.__importStar) || function (mod) {
__setModuleDefault(result, mod);
return result;
};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-const core = __importStar(__nccwpck_require__(186));
-const run_1 = __nccwpck_require__(995);
-const main = async () => {
- await (0, run_1.run)({
- name: core.getInput('name', { required: true }),
+exports.concatYanAudio = void 0;
+const core = __importStar(__nccwpck_require__(2186));
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-var-requires */
+const audioconcat = __nccwpck_require__(9165);
+const fs_1 = __importDefault(__nccwpck_require__(7147));
+const child_process_1 = __nccwpck_require__(2081);
+const concatYanAudio = (audioSrc, yarnSrc) => {
+ return new Promise((resolve, reject) => {
+ //Run ffmpeg command
+ // exec(`ffmpeg -i "concat:${audioSrc}|${yarnSrc}" -acodec copy ${audioSrc}-yan.mp3`, (err, stdout, stderr) => {
+ // exec(`ffmpeg -i ${audioSrc} -i ${yarnSrc} -filter_complex "[1]adelay=Ns|Ns[a1];[0:a][a1]amix=inputs=2[a]" -map "[a]" ${audioSrc}-yan.mp3`, (err, stdout, stderr) => {
+ (0, child_process_1.exec)(`ffmpeg -i ${audioSrc} -i ${yarnSrc} -filter_complex "[0][1]amerge=inputs=2,pan=stereo|FL {
+ if (err) {
+ core.error(`Error: ${err}`);
+ reject(err);
+ }
+ else {
+ core.info(`stdout: ${stdout}`);
+ //delete old and rename new file
+ fs_1.default.unlink(audioSrc, (err) => {
+ if (err) {
+ core.error(`Error: ${err}`);
+ reject(err);
+ }
+ else {
+ fs_1.default.rename(`${audioSrc}-yan.mp3`, audioSrc, (err) => {
+ if (err) {
+ core.error(`Error: ${err}`);
+ reject(err);
+ }
+ resolve();
+ });
+ }
+ });
+ }
+ });
+ });
+};
+exports.concatYanAudio = concatYanAudio;
+
+
+/***/ }),
+
+/***/ 147:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.compositeYan = void 0;
+const core = __importStar(__nccwpck_require__(2186));
+const jimp_1 = __importDefault(__nccwpck_require__(3794));
+const compositeYan = async (imgSrc, yanSrc) => {
+ const image = await jimp_1.default.read(imgSrc);
+ const yan = await jimp_1.default.read(yanSrc);
+ const xMargin = (image.bitmap.width * 5) / 100;
+ const yMargin = (image.bitmap.width * 5) / 100;
+ const X = image.bitmap.width - yan.bitmap.width - xMargin;
+ const Y = image.bitmap.height - yan.bitmap.height - yMargin;
+ core.info(`writing image : ${imgSrc}`);
+ const img = image.composite(yan, X, Y);
+ img.write(imgSrc);
+ return img;
+};
+exports.compositeYan = compositeYan;
+
+
+/***/ }),
+
+/***/ 1886:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+const path_1 = __importDefault(__nccwpck_require__(1017));
+const fs_1 = __importDefault(__nccwpck_require__(7147));
+const core = __importStar(__nccwpck_require__(2186));
+const fsPromises = fs_1.default.promises;
+const defaultAssetURL = {
+ assci: path_1.default.resolve(__dirname, '..', 'assets', 'ascii.txt'),
+ image: path_1.default.resolve(__dirname, '..', 'assets', 'image.png'),
+ audio: path_1.default.resolve(__dirname, '..', 'assets', 'audio.mp3'),
+};
+const loadDefaultAsset = async () => {
+ return new Promise(async (resolve) => {
+ const base = (process.env.GITHUB_WORKSPACE || path_1.default.resolve(__dirname, '..')) + '/.monk/';
+ core.info(`base: ${base}`);
+ const loc = {
+ assci: base + 'ascii.txt',
+ image: base + 'image.png',
+ audio: base + 'audio.mp3',
+ };
+ //Check if base folder not exist create it
+ if (!fs_1.default.existsSync(base)) {
+ await fsPromises.mkdir(base);
+ }
+ //Check if assci file not exist download it
+ if (!fs_1.default.existsSync(loc.assci))
+ loc.assci = defaultAssetURL.assci;
+ //Check if image file not exist download it
+ if (!fs_1.default.existsSync(loc.image))
+ loc.image = defaultAssetURL.image;
+ //Check if audio file not exist download it
+ if (!fs_1.default.existsSync(loc.audio))
+ loc.audio = defaultAssetURL.audio;
+ resolve(loc);
+ });
+};
+exports["default"] = loadDefaultAsset;
+
+
+/***/ }),
+
+/***/ 2459:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+const child_process_1 = __nccwpck_require__(2081);
+const core = __importStar(__nccwpck_require__(2186));
+const fs_1 = __importDefault(__nccwpck_require__(7147));
+const mergeVideo = async (filePath, imagePath, audioSrc) => {
+ return new Promise((resolve, reject) => {
+ let result = (0, child_process_1.exec)(`ffmpeg -i ${filePath} -i ${imagePath} -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -codec:a copy ${filePath}-yanad.mp4`, (err) => {
+ if (err) {
+ reject(err);
+ }
+ (0, child_process_1.exec)(`ffmpeg -i ${filePath}-yanad.mp4 -i ${audioSrc} -filter_complex "[0][1]amerge=inputs=2,pan=stereo|FL {
+ if (err) {
+ core.error(`Error: ${err}`);
+ reject(err);
+ }
+ else {
+ core.info(`stdout: ${stdout}`);
+ //delete old and rename new file
+ fs_1.default.unlinkSync(`${filePath}-yanad.mp4`);
+ fs_1.default.unlink(filePath, (err) => {
+ if (err) {
+ core.error(`Error: ${err}`);
+ reject(err);
+ }
+ else {
+ fs_1.default.rename(`${filePath}-yanfinish.mp4`, filePath, (err) => {
+ if (err) {
+ core.error(`Error: ${err}`);
+ reject(err);
+ }
+ resolve();
+ });
+ }
+ });
+ }
+ });
+ });
});
};
+exports["default"] = mergeVideo;
+
+
+/***/ }),
+
+/***/ 9536:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+const core = __importStar(__nccwpck_require__(2186));
+const run_1 = __nccwpck_require__(3995);
+const main = async () => {
+ await (0, run_1.run)({ path: core.getInput('path') });
+};
main().catch((e) => core.setFailed(e instanceof Error ? e.message : JSON.stringify(e)));
/***/ }),
-/***/ 995:
+/***/ 3995:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -70,19 +371,86 @@ var __importStar = (this && this.__importStar) || function (mod) {
__setModuleDefault(result, mod);
return result;
};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.run = void 0;
-const core = __importStar(__nccwpck_require__(186));
+const core = __importStar(__nccwpck_require__(2186));
+const fs_1 = __nccwpck_require__(7147);
+const ignore_walk_1 = __importDefault(__nccwpck_require__(6296));
+const path_1 = __importDefault(__nccwpck_require__(1017));
+const ascii_1 = __nccwpck_require__(5850);
+const image_1 = __nccwpck_require__(147);
+const loadDefaultAsset_1 = __importDefault(__nccwpck_require__(1886));
+const audio_1 = __nccwpck_require__(1732);
+const video_1 = __importDefault(__nccwpck_require__(2459));
// eslint-disable-next-line @typescript-eslint/require-await
-const run = async (inputs) => {
- core.info(`my name is ${inputs.name}`);
+const run = async (input) => {
+ try {
+ const filePath = path_1.default.resolve(input.path);
+ const files = await (0, ignore_walk_1.default)({
+ path: filePath,
+ includeEmpty: false,
+ ignoreFiles: ['.gitignore', '.prettierignore'],
+ });
+ const filteredFiles = files.filter((i) => i.indexOf('.git/') === -1).filter((i) => i.indexOf('.monk/') === -1).filter((i) => i.indexOf('.github/') === -1);
+ const lists = filteredFiles.map((i) => path_1.default.join(filePath, i));
+ const loc = await (0, loadDefaultAsset_1.default)();
+ const promises = Promise.all(lists.map(async (i) => {
+ //Check if file size not zero and less than 40MB
+ const stats = await fs_1.promises.stat(i);
+ if (stats.size > 0 && stats.size < 40 * 1024 * 1024) {
+ const fileExtension = path_1.default.extname(i);
+ switch (fileExtension) {
+ //Video
+ case '.mp4':
+ case '.mov':
+ case '.avi':
+ case '.flv':
+ case '.wmv':
+ case '.m4v':
+ case '.mpg':
+ case '.mpeg':
+ case '.webm':
+ await (0, video_1.default)(i, loc.image, loc.audio);
+ break;
+ //Music and audio
+ case '.mp3':
+ case '.wav':
+ case '.ogg':
+ case '.flac':
+ case '.aac':
+ case '.m4a':
+ case '.wma':
+ await (0, audio_1.concatYanAudio)(i, loc.audio);
+ break;
+ //Image
+ case '.jpg':
+ case '.png':
+ case '.gif':
+ case '.jpeg':
+ case '.bmp':
+ await (0, image_1.compositeYan)(i, loc.image);
+ break;
+ default:
+ await (0, ascii_1.writeText)(i, loc.assci);
+ break;
+ }
+ }
+ }));
+ core.info(`Results: ${JSON.stringify(lists)}`);
+ }
+ catch (err) {
+ core.error(`sumting wrong with something: ${err}`);
+ }
};
exports.run = run;
/***/ }),
-/***/ 351:
+/***/ 7351:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -108,8 +476,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.issue = exports.issueCommand = void 0;
-const os = __importStar(__nccwpck_require__(37));
-const utils_1 = __nccwpck_require__(278);
+const os = __importStar(__nccwpck_require__(2037));
+const utils_1 = __nccwpck_require__(5278);
/**
* Commands
*
@@ -181,7 +549,7 @@ function escapeProperty(s) {
/***/ }),
-/***/ 186:
+/***/ 2186:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -216,12 +584,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;
-const command_1 = __nccwpck_require__(351);
+const command_1 = __nccwpck_require__(7351);
const file_command_1 = __nccwpck_require__(717);
-const utils_1 = __nccwpck_require__(278);
-const os = __importStar(__nccwpck_require__(37));
-const path = __importStar(__nccwpck_require__(17));
-const oidc_utils_1 = __nccwpck_require__(41);
+const utils_1 = __nccwpck_require__(5278);
+const os = __importStar(__nccwpck_require__(2037));
+const path = __importStar(__nccwpck_require__(1017));
+const oidc_utils_1 = __nccwpck_require__(8041);
/**
* The code to exit an action
*/
@@ -499,17 +867,17 @@ exports.getIDToken = getIDToken;
/**
* Summary exports
*/
-var summary_1 = __nccwpck_require__(327);
+var summary_1 = __nccwpck_require__(1327);
Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } }));
/**
* @deprecated use core.summary
*/
-var summary_2 = __nccwpck_require__(327);
+var summary_2 = __nccwpck_require__(1327);
Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } }));
/**
* Path exports
*/
-var path_utils_1 = __nccwpck_require__(981);
+var path_utils_1 = __nccwpck_require__(2981);
Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } }));
Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } }));
Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } }));
@@ -546,9 +914,9 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.issueCommand = void 0;
// We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */
-const fs = __importStar(__nccwpck_require__(147));
-const os = __importStar(__nccwpck_require__(37));
-const utils_1 = __nccwpck_require__(278);
+const fs = __importStar(__nccwpck_require__(7147));
+const os = __importStar(__nccwpck_require__(2037));
+const utils_1 = __nccwpck_require__(5278);
function issueCommand(command, message) {
const filePath = process.env[`GITHUB_${command}`];
if (!filePath) {
@@ -566,7 +934,7 @@ exports.issueCommand = issueCommand;
/***/ }),
-/***/ 41:
+/***/ 8041:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -582,9 +950,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OidcClient = void 0;
-const http_client_1 = __nccwpck_require__(255);
-const auth_1 = __nccwpck_require__(526);
-const core_1 = __nccwpck_require__(186);
+const http_client_1 = __nccwpck_require__(6255);
+const auth_1 = __nccwpck_require__(5526);
+const core_1 = __nccwpck_require__(2186);
class OidcClient {
static createHttpClient(allowRetry = true, maxRetry = 10) {
const requestOptions = {
@@ -650,7 +1018,7 @@ exports.OidcClient = OidcClient;
/***/ }),
-/***/ 981:
+/***/ 2981:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -676,7 +1044,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0;
-const path = __importStar(__nccwpck_require__(17));
+const path = __importStar(__nccwpck_require__(1017));
/**
* toPosixPath converts the given path to the posix form. On Windows, \\ will be
* replaced with /.
@@ -715,7 +1083,7 @@ exports.toPlatformPath = toPlatformPath;
/***/ }),
-/***/ 327:
+/***/ 1327:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -731,8 +1099,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0;
-const os_1 = __nccwpck_require__(37);
-const fs_1 = __nccwpck_require__(147);
+const os_1 = __nccwpck_require__(2037);
+const fs_1 = __nccwpck_require__(7147);
const { access, appendFile, writeFile } = fs_1.promises;
exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY';
exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary';
@@ -1005,7 +1373,7 @@ exports.summary = _summary;
/***/ }),
-/***/ 278:
+/***/ 5278:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
@@ -1052,7 +1420,7 @@ exports.toCommandProperties = toCommandProperties;
/***/ }),
-/***/ 526:
+/***/ 5526:
/***/ (function(__unused_webpack_module, exports) {
"use strict";
@@ -1140,7 +1508,7 @@ exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHand
/***/ }),
-/***/ 255:
+/***/ 6255:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -1176,10 +1544,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0;
-const http = __importStar(__nccwpck_require__(685));
-const https = __importStar(__nccwpck_require__(687));
-const pm = __importStar(__nccwpck_require__(835));
-const tunnel = __importStar(__nccwpck_require__(294));
+const http = __importStar(__nccwpck_require__(3685));
+const https = __importStar(__nccwpck_require__(5687));
+const pm = __importStar(__nccwpck_require__(9835));
+const tunnel = __importStar(__nccwpck_require__(4294));
var HttpCodes;
(function (HttpCodes) {
HttpCodes[HttpCodes["OK"] = 200] = "OK";
@@ -1752,7 +2120,7 @@ const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCa
/***/ }),
-/***/ 835:
+/***/ 9835:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
@@ -1820,363 +2188,51522 @@ exports.checkBypass = checkBypass;
/***/ }),
-/***/ 294:
-/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+/***/ 4858:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
-module.exports = __nccwpck_require__(219);
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _bmpJs = _interopRequireDefault(__nccwpck_require__(9030));
+
+var _utils = __nccwpck_require__(7403);
+
+var MIME_TYPE = 'image/bmp';
+var MIME_TYPE_SECOND = 'image/x-ms-bmp';
+
+function toAGBR(image) {
+ return (0, _utils.scan)(image, 0, 0, image.bitmap.width, image.bitmap.height, function (x, y, index) {
+ var red = this.bitmap.data[index + 0];
+ var green = this.bitmap.data[index + 1];
+ var blue = this.bitmap.data[index + 2];
+ var alpha = this.bitmap.data[index + 3];
+ this.bitmap.data[index + 0] = alpha;
+ this.bitmap.data[index + 1] = blue;
+ this.bitmap.data[index + 2] = green;
+ this.bitmap.data[index + 3] = red;
+ }).bitmap;
+}
+
+function fromAGBR(bitmap) {
+ return (0, _utils.scan)({
+ bitmap: bitmap
+ }, 0, 0, bitmap.width, bitmap.height, function (x, y, index) {
+ var alpha = this.bitmap.data[index + 0];
+ var blue = this.bitmap.data[index + 1];
+ var green = this.bitmap.data[index + 2];
+ var red = this.bitmap.data[index + 3];
+ this.bitmap.data[index + 0] = red;
+ this.bitmap.data[index + 1] = green;
+ this.bitmap.data[index + 2] = blue;
+ this.bitmap.data[index + 3] = bitmap.is_with_alpha ? alpha : 0xff;
+ }).bitmap;
+}
+
+var decode = function decode(data) {
+ return fromAGBR(_bmpJs["default"].decode(data));
+};
+
+var encode = function encode(image) {
+ return _bmpJs["default"].encode(toAGBR(image)).data;
+};
+
+var _default = function _default() {
+ var _decoders, _encoders;
+
+ return {
+ mime: (0, _defineProperty2["default"])({}, MIME_TYPE, ['bmp']),
+ constants: {
+ MIME_BMP: MIME_TYPE,
+ MIME_X_MS_BMP: MIME_TYPE_SECOND
+ },
+ decoders: (_decoders = {}, (0, _defineProperty2["default"])(_decoders, MIME_TYPE, decode), (0, _defineProperty2["default"])(_decoders, MIME_TYPE_SECOND, decode), _decoders),
+ encoders: (_encoders = {}, (0, _defineProperty2["default"])(_encoders, MIME_TYPE, encode), (0, _defineProperty2["default"])(_encoders, MIME_TYPE_SECOND, encode), _encoders)
+ };
+};
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
/***/ }),
-/***/ 219:
-/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+/***/ 8284:
+/***/ ((__unused_webpack_module, exports) => {
"use strict";
-var net = __nccwpck_require__(808);
-var tls = __nccwpck_require__(404);
-var http = __nccwpck_require__(685);
-var https = __nccwpck_require__(687);
-var events = __nccwpck_require__(361);
-var assert = __nccwpck_require__(491);
-var util = __nccwpck_require__(837);
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.srcOver = srcOver;
+exports.dstOver = dstOver;
+exports.multiply = multiply;
+exports.add = add;
+exports.screen = screen;
+exports.overlay = overlay;
+exports.darken = darken;
+exports.lighten = lighten;
+exports.hardLight = hardLight;
+exports.difference = difference;
+exports.exclusion = exclusion;
+function srcOver(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var r = (src.r * src.a + dst.r * dst.a * (1 - src.a)) / a;
+ var g = (src.g * src.a + dst.g * dst.a * (1 - src.a)) / a;
+ var b = (src.b * src.a + dst.b * dst.a * (1 - src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
-exports.httpOverHttp = httpOverHttp;
-exports.httpsOverHttp = httpsOverHttp;
-exports.httpOverHttps = httpOverHttps;
-exports.httpsOverHttps = httpsOverHttps;
+function dstOver(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var r = (dst.r * dst.a + src.r * src.a * (1 - dst.a)) / a;
+ var g = (dst.g * dst.a + src.g * src.a * (1 - dst.a)) / a;
+ var b = (dst.b * dst.a + src.b * src.a * (1 - dst.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
+function multiply(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (sra * dra + sra * (1 - dst.a) + dra * (1 - src.a)) / a;
+ var g = (sga * dga + sga * (1 - dst.a) + dga * (1 - src.a)) / a;
+ var b = (sba * dba + sba * (1 - dst.a) + dba * (1 - src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
-function httpOverHttp(options) {
- var agent = new TunnelingAgent(options);
- agent.request = http.request;
- return agent;
+function add(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (sra + dra) / a;
+ var g = (sga + dga) / a;
+ var b = (sba + dba) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
}
-function httpsOverHttp(options) {
- var agent = new TunnelingAgent(options);
- agent.request = http.request;
- agent.createSocket = createSecureSocket;
- agent.defaultPort = 443;
- return agent;
+function screen(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (sra * dst.a + dra * src.a - sra * dra + sra * (1 - dst.a) + dra * (1 - src.a)) / a;
+ var g = (sga * dst.a + dga * src.a - sga * dga + sga * (1 - dst.a) + dga * (1 - src.a)) / a;
+ var b = (sba * dst.a + dba * src.a - sba * dba + sba * (1 - dst.a) + dba * (1 - src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
}
-function httpOverHttps(options) {
- var agent = new TunnelingAgent(options);
- agent.request = https.request;
- return agent;
+function overlay(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (2 * dra <= dst.a ? 2 * sra * dra + sra * (1 - dst.a) + dra * (1 - src.a) : sra * (1 + dst.a) + dra * (1 + src.a) - 2 * dra * sra - dst.a * src.a) / a;
+ var g = (2 * dga <= dst.a ? 2 * sga * dga + sga * (1 - dst.a) + dga * (1 - src.a) : sga * (1 + dst.a) + dga * (1 + src.a) - 2 * dga * sga - dst.a * src.a) / a;
+ var b = (2 * dba <= dst.a ? 2 * sba * dba + sba * (1 - dst.a) + dba * (1 - src.a) : sba * (1 + dst.a) + dba * (1 + src.a) - 2 * dba * sba - dst.a * src.a) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
}
-function httpsOverHttps(options) {
- var agent = new TunnelingAgent(options);
- agent.request = https.request;
- agent.createSocket = createSecureSocket;
- agent.defaultPort = 443;
- return agent;
+function darken(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (Math.min(sra * dst.a, dra * src.a) + sra * (1 - dst.a) + dra * (1 - src.a)) / a;
+ var g = (Math.min(sga * dst.a, dga * src.a) + sga * (1 - dst.a) + dga * (1 - src.a)) / a;
+ var b = (Math.min(sba * dst.a, dba * src.a) + sba * (1 - dst.a) + dba * (1 - src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
}
+function lighten(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (Math.max(sra * dst.a, dra * src.a) + sra * (1 - dst.a) + dra * (1 - src.a)) / a;
+ var g = (Math.max(sga * dst.a, dga * src.a) + sga * (1 - dst.a) + dga * (1 - src.a)) / a;
+ var b = (Math.max(sba * dst.a, dba * src.a) + sba * (1 - dst.a) + dba * (1 - src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
-function TunnelingAgent(options) {
- var self = this;
- self.options = options || {};
- self.proxyOptions = self.options.proxy || {};
- self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;
- self.requests = [];
- self.sockets = [];
+function hardLight(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (2 * sra <= src.a ? 2 * sra * dra + sra * (1 - dst.a) + dra * (1 - src.a) : sra * (1 + dst.a) + dra * (1 + src.a) - 2 * dra * sra - dst.a * src.a) / a;
+ var g = (2 * sga <= src.a ? 2 * sga * dga + sga * (1 - dst.a) + dga * (1 - src.a) : sga * (1 + dst.a) + dga * (1 + src.a) - 2 * dga * sga - dst.a * src.a) / a;
+ var b = (2 * sba <= src.a ? 2 * sba * dba + sba * (1 - dst.a) + dba * (1 - src.a) : sba * (1 + dst.a) + dba * (1 + src.a) - 2 * dba * sba - dst.a * src.a) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
- self.on('free', function onFree(socket, host, port, localAddress) {
- var options = toOptions(host, port, localAddress);
- for (var i = 0, len = self.requests.length; i < len; ++i) {
- var pending = self.requests[i];
- if (pending.host === options.host && pending.port === options.port) {
- // Detect the request to connect same origin server,
- // reuse the connection.
- self.requests.splice(i, 1);
- pending.request.onSocket(socket);
- return;
- }
- }
- socket.destroy();
- self.removeSocket(socket);
+function difference(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (sra + dra - 2 * Math.min(sra * dst.a, dra * src.a)) / a;
+ var g = (sga + dga - 2 * Math.min(sga * dst.a, dga * src.a)) / a;
+ var b = (sba + dba - 2 * Math.min(sba * dst.a, dba * src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
+
+function exclusion(src, dst) {
+ var ops = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+ src.a *= ops;
+ var a = dst.a + src.a - dst.a * src.a;
+ var sra = src.r * src.a;
+ var sga = src.g * src.a;
+ var sba = src.b * src.a;
+ var dra = dst.r * dst.a;
+ var dga = dst.g * dst.a;
+ var dba = dst.b * dst.a;
+ var r = (sra * dst.a + dra * src.a - 2 * sra * dra + sra * (1 - dst.a) + dra * (1 - src.a)) / a;
+ var g = (sga * dst.a + dga * src.a - 2 * sga * dga + sga * (1 - dst.a) + dga * (1 - src.a)) / a;
+ var b = (sba * dst.a + dba * src.a - 2 * sba * dba + sba * (1 - dst.a) + dba * (1 - src.a)) / a;
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+}
+//# sourceMappingURL=composite-modes.js.map
+
+/***/ }),
+
+/***/ 5141:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireWildcard = __nccwpck_require__(4405);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = composite;
+
+var _utils = __nccwpck_require__(7403);
+
+var constants = _interopRequireWildcard(__nccwpck_require__(4619));
+
+var compositeModes = _interopRequireWildcard(__nccwpck_require__(8284));
+
+/**
+ * Composites a source image over to this image respecting alpha channels
+ * @param {Jimp} src the source Jimp instance
+ * @param {number} x the x position to blit the image
+ * @param {number} y the y position to blit the image
+ * @param {object} options determine what mode to use
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+function composite(src, x, y) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+ var cb = arguments.length > 4 ? arguments[4] : undefined;
+
+ if (typeof options === 'function') {
+ cb = options;
+ options = {};
+ }
+
+ if (!(src instanceof this.constructor)) {
+ return _utils.throwError.call(this, 'The source must be a Jimp image', cb);
+ }
+
+ if (typeof x !== 'number' || typeof y !== 'number') {
+ return _utils.throwError.call(this, 'x and y must be numbers', cb);
+ }
+
+ var _options = options,
+ mode = _options.mode,
+ opacitySource = _options.opacitySource,
+ opacityDest = _options.opacityDest;
+
+ if (!mode) {
+ mode = constants.BLEND_SOURCE_OVER;
+ }
+
+ if (typeof opacitySource !== 'number' || opacitySource < 0 || opacitySource > 1) {
+ opacitySource = 1.0;
+ }
+
+ if (typeof opacityDest !== 'number' || opacityDest < 0 || opacityDest > 1) {
+ opacityDest = 1.0;
+ }
+
+ var blendmode = compositeModes[mode]; // round input
+
+ x = Math.round(x);
+ y = Math.round(y);
+ var baseImage = this;
+
+ if (opacityDest !== 1.0) {
+ baseImage.opacity(opacityDest);
+ }
+
+ src.scanQuiet(0, 0, src.bitmap.width, src.bitmap.height, function (sx, sy, idx) {
+ var dstIdx = baseImage.getPixelIndex(x + sx, y + sy, constants.EDGE_CROP);
+ var blended = blendmode({
+ r: this.bitmap.data[idx + 0] / 255,
+ g: this.bitmap.data[idx + 1] / 255,
+ b: this.bitmap.data[idx + 2] / 255,
+ a: this.bitmap.data[idx + 3] / 255
+ }, {
+ r: baseImage.bitmap.data[dstIdx + 0] / 255,
+ g: baseImage.bitmap.data[dstIdx + 1] / 255,
+ b: baseImage.bitmap.data[dstIdx + 2] / 255,
+ a: baseImage.bitmap.data[dstIdx + 3] / 255
+ }, opacitySource);
+ baseImage.bitmap.data[dstIdx + 0] = this.constructor.limit255(blended.r * 255);
+ baseImage.bitmap.data[dstIdx + 1] = this.constructor.limit255(blended.g * 255);
+ baseImage.bitmap.data[dstIdx + 2] = this.constructor.limit255(blended.b * 255);
+ baseImage.bitmap.data[dstIdx + 3] = this.constructor.limit255(blended.a * 255);
});
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
}
-util.inherits(TunnelingAgent, events.EventEmitter);
-TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {
- var self = this;
- var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
- if (self.sockets.length >= this.maxSockets) {
- // We are over limit so we'll add it to the queue.
- self.requests.push(options);
- return;
+/***/ }),
+
+/***/ 4619:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.EDGE_CROP = exports.EDGE_WRAP = exports.EDGE_EXTEND = exports.BLEND_EXCLUSION = exports.BLEND_DIFFERENCE = exports.BLEND_HARDLIGHT = exports.BLEND_LIGHTEN = exports.BLEND_DARKEN = exports.BLEND_OVERLAY = exports.BLEND_SCREEN = exports.BLEND_ADD = exports.BLEND_MULTIPLY = exports.BLEND_DESTINATION_OVER = exports.BLEND_SOURCE_OVER = exports.VERTICAL_ALIGN_BOTTOM = exports.VERTICAL_ALIGN_MIDDLE = exports.VERTICAL_ALIGN_TOP = exports.HORIZONTAL_ALIGN_RIGHT = exports.HORIZONTAL_ALIGN_CENTER = exports.HORIZONTAL_ALIGN_LEFT = exports.AUTO = void 0;
+// used to auto resizing etc.
+var AUTO = -1; // Align modes for cover, contain, bit masks
+
+exports.AUTO = AUTO;
+var HORIZONTAL_ALIGN_LEFT = 1;
+exports.HORIZONTAL_ALIGN_LEFT = HORIZONTAL_ALIGN_LEFT;
+var HORIZONTAL_ALIGN_CENTER = 2;
+exports.HORIZONTAL_ALIGN_CENTER = HORIZONTAL_ALIGN_CENTER;
+var HORIZONTAL_ALIGN_RIGHT = 4;
+exports.HORIZONTAL_ALIGN_RIGHT = HORIZONTAL_ALIGN_RIGHT;
+var VERTICAL_ALIGN_TOP = 8;
+exports.VERTICAL_ALIGN_TOP = VERTICAL_ALIGN_TOP;
+var VERTICAL_ALIGN_MIDDLE = 16;
+exports.VERTICAL_ALIGN_MIDDLE = VERTICAL_ALIGN_MIDDLE;
+var VERTICAL_ALIGN_BOTTOM = 32; // blend modes
+
+exports.VERTICAL_ALIGN_BOTTOM = VERTICAL_ALIGN_BOTTOM;
+var BLEND_SOURCE_OVER = 'srcOver';
+exports.BLEND_SOURCE_OVER = BLEND_SOURCE_OVER;
+var BLEND_DESTINATION_OVER = 'dstOver';
+exports.BLEND_DESTINATION_OVER = BLEND_DESTINATION_OVER;
+var BLEND_MULTIPLY = 'multiply';
+exports.BLEND_MULTIPLY = BLEND_MULTIPLY;
+var BLEND_ADD = 'add';
+exports.BLEND_ADD = BLEND_ADD;
+var BLEND_SCREEN = 'screen';
+exports.BLEND_SCREEN = BLEND_SCREEN;
+var BLEND_OVERLAY = 'overlay';
+exports.BLEND_OVERLAY = BLEND_OVERLAY;
+var BLEND_DARKEN = 'darken';
+exports.BLEND_DARKEN = BLEND_DARKEN;
+var BLEND_LIGHTEN = 'lighten';
+exports.BLEND_LIGHTEN = BLEND_LIGHTEN;
+var BLEND_HARDLIGHT = 'hardLight';
+exports.BLEND_HARDLIGHT = BLEND_HARDLIGHT;
+var BLEND_DIFFERENCE = 'difference';
+exports.BLEND_DIFFERENCE = BLEND_DIFFERENCE;
+var BLEND_EXCLUSION = 'exclusion'; // Edge Handling
+
+exports.BLEND_EXCLUSION = BLEND_EXCLUSION;
+var EDGE_EXTEND = 1;
+exports.EDGE_EXTEND = EDGE_EXTEND;
+var EDGE_WRAP = 2;
+exports.EDGE_WRAP = EDGE_WRAP;
+var EDGE_CROP = 3;
+exports.EDGE_CROP = EDGE_CROP;
+//# sourceMappingURL=constants.js.map
+
+/***/ }),
+
+/***/ 678:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireWildcard = __nccwpck_require__(4405);
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.addConstants = addConstants;
+exports.addJimpMethods = addJimpMethods;
+exports.jimpEvMethod = jimpEvMethod;
+exports.jimpEvChange = jimpEvChange;
+Object.defineProperty(exports, "addType", ({
+ enumerable: true,
+ get: function get() {
+ return MIME.addType;
}
+}));
+exports["default"] = void 0;
- // If we are under maxSockets create a new one.
- self.createSocket(options, function(socket) {
- socket.on('free', onFree);
- socket.on('close', onCloseOrRemove);
- socket.on('agentRemove', onCloseOrRemove);
- req.onSocket(socket);
+var _construct2 = _interopRequireDefault(__nccwpck_require__(807));
- function onFree() {
- self.emit('free', socket, options);
- }
+var _slicedToArray2 = _interopRequireDefault(__nccwpck_require__(8209));
- function onCloseOrRemove(err) {
- self.removeSocket(socket);
- socket.removeListener('free', onFree);
- socket.removeListener('close', onCloseOrRemove);
- socket.removeListener('agentRemove', onCloseOrRemove);
+var _classCallCheck2 = _interopRequireDefault(__nccwpck_require__(6383));
+
+var _createClass2 = _interopRequireDefault(__nccwpck_require__(1957));
+
+var _possibleConstructorReturn2 = _interopRequireDefault(__nccwpck_require__(6066));
+
+var _getPrototypeOf2 = _interopRequireDefault(__nccwpck_require__(2369));
+
+var _assertThisInitialized2 = _interopRequireDefault(__nccwpck_require__(5492));
+
+var _inherits2 = _interopRequireDefault(__nccwpck_require__(2946));
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605));
+
+var _fs = _interopRequireDefault(__nccwpck_require__(7147));
+
+var _path = _interopRequireDefault(__nccwpck_require__(1017));
+
+var _events = _interopRequireDefault(__nccwpck_require__(2361));
+
+var _utils = __nccwpck_require__(7403);
+
+var _anyBase = _interopRequireDefault(__nccwpck_require__(8720));
+
+var _mkdirp = _interopRequireDefault(__nccwpck_require__(6186));
+
+var _pixelmatch = _interopRequireDefault(__nccwpck_require__(6097));
+
+var _tinycolor = _interopRequireDefault(__nccwpck_require__(5479));
+
+var _phash = _interopRequireDefault(__nccwpck_require__(7025));
+
+var _request = _interopRequireDefault(__nccwpck_require__(4310));
+
+var _composite = _interopRequireDefault(__nccwpck_require__(5141));
+
+var _promisify = _interopRequireDefault(__nccwpck_require__(6826));
+
+var MIME = _interopRequireWildcard(__nccwpck_require__(3153));
+
+var _imageBitmap = __nccwpck_require__(3946);
+
+var constants = _interopRequireWildcard(__nccwpck_require__(4619));
+
+var alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'; // an array storing the maximum string length of hashes at various bases
+// 0 and 1 do not exist as possible hash lengths
+
+var maxHashLength = [NaN, NaN];
+
+for (var i = 2; i < 65; i++) {
+ var maxHash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, i))(new Array(64 + 1).join('1'));
+ maxHashLength.push(maxHash.length);
+} // no operation
+
+
+function noop() {} // error checking methods
+
+
+function isArrayBuffer(test) {
+ return Object.prototype.toString.call(test).toLowerCase().indexOf('arraybuffer') > -1;
+} // Prepare a Buffer object from the arrayBuffer. Necessary in the browser > node conversion,
+// But this function is not useful when running in node directly
+
+
+function bufferFromArrayBuffer(arrayBuffer) {
+ var buffer = Buffer.alloc(arrayBuffer.byteLength);
+ var view = new Uint8Array(arrayBuffer);
+
+ for (var _i = 0; _i < buffer.length; ++_i) {
+ buffer[_i] = view[_i];
+ }
+
+ return buffer;
+}
+
+function loadFromURL(options, cb) {
+ (0, _request["default"])(options, function (err, response, data) {
+ if (err) {
+ return cb(err);
}
- });
-};
-TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
- var self = this;
- var placeholder = {};
- self.sockets.push(placeholder);
+ if ('headers' in response && 'location' in response.headers) {
+ options.url = response.headers.location;
+ return loadFromURL(options, cb);
+ }
- var connectOptions = mergeOptions({}, self.proxyOptions, {
- method: 'CONNECT',
- path: options.host + ':' + options.port,
- agent: false,
- headers: {
- host: options.host + ':' + options.port
+ if ((0, _typeof2["default"])(data) === 'object' && Buffer.isBuffer(data)) {
+ return cb(null, data);
}
+
+ var msg = 'Could not load Buffer from <' + options.url + '> ' + '(HTTP: ' + response.statusCode + ')';
+ return new Error(msg);
});
- if (options.localAddress) {
- connectOptions.localAddress = options.localAddress;
- }
- if (connectOptions.proxyAuth) {
- connectOptions.headers = connectOptions.headers || {};
- connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
- new Buffer(connectOptions.proxyAuth).toString('base64');
+}
+
+function loadBufferFromPath(src, cb) {
+ if (_fs["default"] && typeof _fs["default"].readFile === 'function' && !src.match(/^(http|ftp)s?:\/\/./)) {
+ _fs["default"].readFile(src, cb);
+ } else {
+ loadFromURL({
+ url: src
+ }, cb);
}
+}
- debug('making CONNECT request');
- var connectReq = self.request(connectOptions);
- connectReq.useChunkedEncodingByDefault = false; // for v0.6
- connectReq.once('response', onResponse); // for v0.6
- connectReq.once('upgrade', onUpgrade); // for v0.6
- connectReq.once('connect', onConnect); // for v0.7 or later
- connectReq.once('error', onError);
- connectReq.end();
+function isRawRGBAData(obj) {
+ return obj && (0, _typeof2["default"])(obj) === 'object' && typeof obj.width === 'number' && typeof obj.height === 'number' && (Buffer.isBuffer(obj.data) || obj.data instanceof Uint8Array || typeof Uint8ClampedArray === 'function' && obj.data instanceof Uint8ClampedArray) && (obj.data.length === obj.width * obj.height * 4 || obj.data.length === obj.width * obj.height * 3);
+}
- function onResponse(res) {
- // Very hacky. This is necessary to avoid http-parser leaks.
- res.upgrade = true;
+function makeRGBABufferFromRGB(buffer) {
+ if (buffer.length % 3 !== 0) {
+ throw new Error('Buffer length is incorrect');
}
- function onUpgrade(res, socket, head) {
- // Hacky.
- process.nextTick(function() {
- onConnect(res, socket, head);
- });
+ var rgbaBuffer = Buffer.allocUnsafe(buffer.length / 3 * 4);
+ var j = 0;
+
+ for (var _i2 = 0; _i2 < buffer.length; _i2++) {
+ rgbaBuffer[j] = buffer[_i2];
+
+ if ((_i2 + 1) % 3 === 0) {
+ rgbaBuffer[++j] = 255;
+ }
+
+ j++;
}
- function onConnect(res, socket, head) {
- connectReq.removeAllListeners();
- socket.removeAllListeners();
+ return rgbaBuffer;
+}
- if (res.statusCode !== 200) {
- debug('tunneling socket could not be established, statusCode=%d',
- res.statusCode);
- socket.destroy();
- var error = new Error('tunneling socket could not be established, ' +
- 'statusCode=' + res.statusCode);
- error.code = 'ECONNRESET';
- options.request.emit('error', error);
- self.removeSocket(placeholder);
- return;
+var emptyBitmap = {
+ data: null,
+ width: null,
+ height: null
+};
+/**
+ * Jimp constructor (from a file)
+ * @param path a path to the image
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
+ */
+
+/**
+ * Jimp constructor (from a url with options)
+ * @param options { url, otherOptions}
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
+ */
+
+/**
+ * Jimp constructor (from another Jimp image or raw image data)
+ * @param image a Jimp image to clone
+ * @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap
+ */
+
+/**
+ * Jimp constructor (from a Buffer)
+ * @param data a Buffer containing the image data
+ * @param {function(Error, Jimp)} cb a function to call when the image is parsed to a bitmap
+ */
+
+/**
+ * Jimp constructor (to generate a new image)
+ * @param w the width of the image
+ * @param h the height of the image
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
+ */
+
+/**
+ * Jimp constructor (to generate a new image)
+ * @param w the width of the image
+ * @param h the height of the image
+ * @param background color to fill the image with
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the image is parsed to a bitmap
+ */
+
+var Jimp =
+/*#__PURE__*/
+function (_EventEmitter) {
+ (0, _inherits2["default"])(Jimp, _EventEmitter);
+
+ // An object representing a bitmap in memory, comprising:
+ // - data: a buffer of the bitmap data
+ // - width: the width of the image in pixels
+ // - height: the height of the image in pixels
+ // Default colour to use for new pixels
+ // Default MIME is PNG
+ // Exif data for the image
+ // Whether Transparency supporting formats will be exported as RGB or RGBA
+ function Jimp() {
+ var _this;
+
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
}
- if (head.length > 0) {
- debug('got illegal response body from proxy');
- socket.destroy();
- var error = new Error('got illegal response body from proxy');
- error.code = 'ECONNRESET';
- options.request.emit('error', error);
- self.removeSocket(placeholder);
- return;
+
+ (0, _classCallCheck2["default"])(this, Jimp);
+ _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Jimp).call(this));
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "bitmap", emptyBitmap);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_background", 0x00000000);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_originalMime", Jimp.MIME_PNG);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_exif", null);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rgba", true);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "writeAsync", function (path) {
+ return (0, _promisify["default"])(_this.write, (0, _assertThisInitialized2["default"])(_this), path);
+ });
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBase64Async", function (mime) {
+ return (0, _promisify["default"])(_this.getBase64, (0, _assertThisInitialized2["default"])(_this), mime);
+ });
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBuffer", _imageBitmap.getBuffer);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBufferAsync", _imageBitmap.getBufferAsync);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getPixelColour", _this.getPixelColor);
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "setPixelColour", _this.setPixelColor);
+ var jimpInstance = (0, _assertThisInitialized2["default"])(_this);
+ var cb = noop;
+
+ if (isArrayBuffer(args[0])) {
+ args[0] = bufferFromArrayBuffer(args[0]);
+ }
+
+ function finish() {
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args[_key2] = arguments[_key2];
+ }
+
+ var err = args[0];
+ var evData = err || {};
+ evData.methodName = 'constructor';
+ setTimeout(function () {
+ var _cb;
+
+ // run on next tick.
+ if (err && cb === noop) {
+ jimpInstance.emitError('constructor', err);
+ } else if (!err) {
+ jimpInstance.emitMulti('constructor', 'initialized');
+ }
+
+ (_cb = cb).call.apply(_cb, [jimpInstance].concat(args));
+ }, 1);
+ }
+
+ if (typeof args[0] === 'number' && typeof args[1] === 'number' || parseInt(args[0], 10) && parseInt(args[1], 10)) {
+ // create a new image
+ var w = parseInt(args[0], 10);
+ var h = parseInt(args[1], 10);
+ cb = args[2]; // with a hex color
+
+ if (typeof args[2] === 'number') {
+ _this._background = args[2];
+ cb = args[3];
+ } // with a css color
+
+
+ if (typeof args[2] === 'string') {
+ _this._background = Jimp.cssColorToHex(args[2]);
+ cb = args[3];
+ }
+
+ if (typeof cb === 'undefined') {
+ cb = noop;
+ }
+
+ if (typeof cb !== 'function') {
+ return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
+ }
+
+ _this.bitmap = {
+ data: Buffer.alloc(w * h * 4),
+ width: w,
+ height: h
+ };
+
+ for (var _i3 = 0; _i3 < _this.bitmap.data.length; _i3 += 4) {
+ _this.bitmap.data.writeUInt32BE(_this._background, _i3);
+ }
+
+ finish(null, (0, _assertThisInitialized2["default"])(_this));
+ } else if ((0, _typeof2["default"])(args[0]) === 'object' && args[0].url) {
+ cb = args[1] || noop;
+
+ if (typeof cb !== 'function') {
+ return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
+ }
+
+ loadFromURL(args[0], function (err, data) {
+ if (err) {
+ return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
+ }
+
+ _this.parseBitmap(data, args[0].url, finish);
+ });
+ } else if (args[0] instanceof Jimp) {
+ // clone an existing Jimp
+ var original = args[0];
+ cb = args[1];
+
+ if (typeof cb === 'undefined') {
+ cb = noop;
+ }
+
+ if (typeof cb !== 'function') {
+ return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
+ }
+
+ _this.bitmap = {
+ data: Buffer.from(original.bitmap.data),
+ width: original.bitmap.width,
+ height: original.bitmap.height
+ };
+ _this._quality = original._quality;
+ _this._deflateLevel = original._deflateLevel;
+ _this._deflateStrategy = original._deflateStrategy;
+ _this._filterType = original._filterType;
+ _this._rgba = original._rgba;
+ _this._background = original._background;
+ _this._originalMime = original._originalMime;
+ finish(null, (0, _assertThisInitialized2["default"])(_this));
+ } else if (isRawRGBAData(args[0])) {
+ var imageData = args[0];
+ cb = args[1] || noop;
+ var isRGBA = imageData.width * imageData.height * 4 === imageData.data.length;
+ var buffer = isRGBA ? Buffer.from(imageData.data) : makeRGBABufferFromRGB(imageData.data);
+ _this.bitmap = {
+ data: buffer,
+ width: imageData.width,
+ height: imageData.height
+ };
+ finish(null, (0, _assertThisInitialized2["default"])(_this));
+ } else if (typeof args[0] === 'string') {
+ // read from a path
+ var path = args[0];
+ cb = args[1];
+
+ if (typeof cb === 'undefined') {
+ cb = noop;
+ }
+
+ if (typeof cb !== 'function') {
+ return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
+ }
+
+ loadBufferFromPath(path, function (err, data) {
+ if (err) {
+ return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
+ }
+
+ _this.parseBitmap(data, path, finish);
+ });
+ } else if ((0, _typeof2["default"])(args[0]) === 'object' && Buffer.isBuffer(args[0])) {
+ // read from a buffer
+ var data = args[0];
+ cb = args[1];
+
+ if (typeof cb !== 'function') {
+ return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'cb must be a function', finish));
+ }
+
+ _this.parseBitmap(data, null, finish);
+ } else {
+ // Allow client libs to add new ways to build a Jimp object.
+ // Extra constructors must be added by `Jimp.appendConstructorOption()`
+ cb = args[args.length - 1];
+
+ if (typeof cb !== 'function') {
+ // TODO: try to solve the args after cb problem.
+ cb = args[args.length - 2];
+
+ if (typeof cb !== 'function') {
+ cb = noop;
+ }
+ }
+
+ var extraConstructor = Jimp.__extraConstructors.find(function (c) {
+ return c.test.apply(c, args);
+ });
+
+ if (extraConstructor) {
+ new Promise(function (resolve, reject) {
+ var _extraConstructor$run;
+
+ return (_extraConstructor$run = extraConstructor.run).call.apply(_extraConstructor$run, [(0, _assertThisInitialized2["default"])(_this), resolve, reject].concat(args));
+ }).then(function () {
+ return finish(null, (0, _assertThisInitialized2["default"])(_this));
+ })["catch"](finish);
+ } else {
+ return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), 'No matching constructor overloading was found. ' + 'Please see the docs for how to call the Jimp constructor.', finish));
+ }
+ }
+
+ return _this;
+ }
+ /**
+ * Parse a bitmap with the loaded image types.
+ *
+ * @param {Buffer} data raw image data
+ * @param {string} path optional path to file
+ * @param {function(Error, Jimp)} finish (optional) a callback for when complete
+ * @memberof Jimp
+ */
+
+
+ (0, _createClass2["default"])(Jimp, [{
+ key: "parseBitmap",
+ value: function parseBitmap(data, path, finish) {
+ _imageBitmap.parseBitmap.call(this, data, null, finish);
+ }
+ /**
+ * Sets the type of the image (RGB or RGBA) when saving in a format that supports transparency (default is RGBA)
+ * @param {boolean} bool A Boolean, true to use RGBA or false to use RGB
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+
+ }, {
+ key: "rgba",
+ value: function rgba(bool, cb) {
+ if (typeof bool !== 'boolean') {
+ return _utils.throwError.call(this, 'bool must be a boolean, true for RGBA or false for RGB', cb);
+ }
+
+ this._rgba = bool;
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ /**
+ * Emit for multiple listeners
+ * @param {string} methodName name of the method to emit an error for
+ * @param {string} eventName name of the eventName to emit an error for
+ * @param {object} data to emit
+ */
+
+ }, {
+ key: "emitMulti",
+ value: function emitMulti(methodName, eventName) {
+ var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+ data = Object.assign(data, {
+ methodName: methodName,
+ eventName: eventName
+ });
+ this.emit('any', data);
+
+ if (methodName) {
+ this.emit(methodName, data);
+ }
+
+ this.emit(eventName, data);
+ }
+ }, {
+ key: "emitError",
+ value: function emitError(methodName, err) {
+ this.emitMulti(methodName, 'error', err);
+ }
+ /**
+ * Get the current height of the image
+ * @return {number} height of the image
+ */
+
+ }, {
+ key: "getHeight",
+ value: function getHeight() {
+ return this.bitmap.height;
+ }
+ /**
+ * Get the current width of the image
+ * @return {number} width of the image
+ */
+
+ }, {
+ key: "getWidth",
+ value: function getWidth() {
+ return this.bitmap.width;
+ }
+ /**
+ * Nicely format Jimp object when sent to the console e.g. console.log(image)
+ * @returns {string} pretty printed
+ */
+
+ }, {
+ key: "inspect",
+ value: function inspect() {
+ return '';
+ }
+ /**
+ * Nicely format Jimp object when converted to a string
+ * @returns {string} pretty printed
+ */
+
+ }, {
+ key: "toString",
+ value: function toString() {
+ return '[object Jimp]';
+ }
+ /**
+ * Returns the original MIME of the image (default: "image/png")
+ * @returns {string} the MIME
+ */
+
+ }, {
+ key: "getMIME",
+ value: function getMIME() {
+ var mime = this._originalMime || Jimp.MIME_PNG;
+ return mime;
+ }
+ /**
+ * Returns the appropriate file extension for the original MIME of the image (default: "png")
+ * @returns {string} the file extension
+ */
+
+ }, {
+ key: "getExtension",
+ value: function getExtension() {
+ var mime = this.getMIME();
+ return MIME.getExtension(mime);
+ }
+ /**
+ * Writes the image to a file
+ * @param {string} path a path to the destination file
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the image is saved to disk
+ * @returns {Jimp} this for chaining of methods
+ */
+
+ }, {
+ key: "write",
+ value: function write(path, cb) {
+ var _this2 = this;
+
+ if (!_fs["default"] || !_fs["default"].createWriteStream) {
+ throw new Error('Cant access the filesystem. You can use the getBase64 method.');
+ }
+
+ if (typeof path !== 'string') {
+ return _utils.throwError.call(this, 'path must be a string', cb);
+ }
+
+ if (typeof cb === 'undefined') {
+ cb = noop;
+ }
+
+ if (typeof cb !== 'function') {
+ return _utils.throwError.call(this, 'cb must be a function', cb);
+ }
+
+ var mime = MIME.getType(path) || this.getMIME();
+
+ var pathObj = _path["default"].parse(path);
+
+ if (pathObj.dir) {
+ _mkdirp["default"].sync(pathObj.dir);
+ }
+
+ this.getBuffer(mime, function (err, buffer) {
+ if (err) {
+ return _utils.throwError.call(_this2, err, cb);
+ }
+
+ var stream = _fs["default"].createWriteStream(path);
+
+ stream.on('open', function () {
+ stream.write(buffer);
+ stream.end();
+ }).on('error', function (err) {
+ return _utils.throwError.call(_this2, err, cb);
+ });
+ stream.on('finish', function () {
+ cb.call(_this2, null, _this2);
+ });
+ });
+ return this;
+ }
+ }, {
+ key: "getBase64",
+
+ /**
+ * Converts the image to a base 64 string
+ * @param {string} mime the mime type of the image data to be created
+ * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
+ * @returns {Jimp} this for chaining of methods
+ */
+ value: function getBase64(mime, cb) {
+ if (mime === Jimp.AUTO) {
+ // allow auto MIME detection
+ mime = this.getMIME();
+ }
+
+ if (typeof mime !== 'string') {
+ return _utils.throwError.call(this, 'mime must be a string', cb);
+ }
+
+ if (typeof cb !== 'function') {
+ return _utils.throwError.call(this, 'cb must be a function', cb);
+ }
+
+ this.getBuffer(mime, function (err, data) {
+ if (err) {
+ return _utils.throwError.call(this, err, cb);
+ }
+
+ var src = 'data:' + mime + ';base64,' + data.toString('base64');
+ cb.call(this, null, src);
+ });
+ return this;
+ }
+ }, {
+ key: "hash",
+
+ /**
+ * Generates a perceptual hash of the image . And pads the string. Can configure base.
+ * @param {number} base (optional) a number between 2 and 64 representing the base for the hash (e.g. 2 is binary, 10 is decimal, 16 is hex, 64 is base 64). Defaults to 64.
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {string} a string representing the hash
+ */
+ value: function hash(base, cb) {
+ base = base || 64;
+
+ if (typeof base === 'function') {
+ cb = base;
+ base = 64;
+ }
+
+ if (typeof base !== 'number') {
+ return _utils.throwError.call(this, 'base must be a number', cb);
+ }
+
+ if (base < 2 || base > 64) {
+ return _utils.throwError.call(this, 'base must be a number between 2 and 64', cb);
+ }
+
+ var hash = this.pHash();
+ hash = (0, _anyBase["default"])(_anyBase["default"].BIN, alphabet.slice(0, base))(hash);
+
+ while (hash.length < maxHashLength[base]) {
+ hash = '0' + hash; // pad out with leading zeros
+ }
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, hash);
+ }
+
+ return hash;
+ }
+ /**
+ * Calculates the perceptual hash
+ * @returns {number} the perceptual hash
+ */
+
+ }, {
+ key: "pHash",
+ value: function pHash() {
+ var pHash = new _phash["default"]();
+ return pHash.getHash(this);
+ }
+ /**
+ * Calculates the hamming distance of the current image and a hash based on their perceptual hash
+ * @param {hash} compareHash hash to compare to
+ * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
+ */
+
+ }, {
+ key: "distanceFromHash",
+ value: function distanceFromHash(compareHash) {
+ var pHash = new _phash["default"]();
+ var currentHash = pHash.getHash(this);
+ return pHash.distance(currentHash, compareHash);
+ }
+ /**
+ * Converts the image to a buffer
+ * @param {string} mime the mime type of the image buffer to be created
+ * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
+ * @returns {Jimp} this for chaining of methods
+ */
+
+ }, {
+ key: "getPixelIndex",
+
+ /**
+ * Returns the offset of a pixel in the bitmap buffer
+ * @param {number} x the x coordinate
+ * @param {number} y the y coordinate
+ * @param {string} edgeHandling (optional) define how to sum pixels from outside the border
+ * @param {number} cb (optional) a callback for when complete
+ * @returns {number} the index of the pixel or -1 if not found
+ */
+ value: function getPixelIndex(x, y, edgeHandling, cb) {
+ var xi;
+ var yi;
+
+ if (typeof edgeHandling === 'function' && typeof cb === 'undefined') {
+ cb = edgeHandling;
+ edgeHandling = null;
+ }
+
+ if (!edgeHandling) {
+ edgeHandling = Jimp.EDGE_EXTEND;
+ }
+
+ if (typeof x !== 'number' || typeof y !== 'number') {
+ return _utils.throwError.call(this, 'x and y must be numbers', cb);
+ } // round input
+
+
+ x = Math.round(x);
+ y = Math.round(y);
+ xi = x;
+ yi = y;
+
+ if (edgeHandling === Jimp.EDGE_EXTEND) {
+ if (x < 0) xi = 0;
+ if (x >= this.bitmap.width) xi = this.bitmap.width - 1;
+ if (y < 0) yi = 0;
+ if (y >= this.bitmap.height) yi = this.bitmap.height - 1;
+ }
+
+ if (edgeHandling === Jimp.EDGE_WRAP) {
+ if (x < 0) {
+ xi = this.bitmap.width + x;
+ }
+
+ if (x >= this.bitmap.width) {
+ xi = x % this.bitmap.width;
+ }
+
+ if (y < 0) {
+ xi = this.bitmap.height + y;
+ }
+
+ if (y >= this.bitmap.height) {
+ yi = y % this.bitmap.height;
+ }
+ }
+
+ var i = this.bitmap.width * yi + xi << 2; // if out of bounds index is -1
+
+ if (xi < 0 || xi >= this.bitmap.width) {
+ i = -1;
+ }
+
+ if (yi < 0 || yi >= this.bitmap.height) {
+ i = -1;
+ }
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, i);
+ }
+
+ return i;
+ }
+ /**
+ * Returns the hex colour value of a pixel
+ * @param {number} x the x coordinate
+ * @param {number} y the y coordinate
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {number} the color of the pixel
+ */
+
+ }, {
+ key: "getPixelColor",
+ value: function getPixelColor(x, y, cb) {
+ if (typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'x and y must be numbers', cb); // round input
+
+ x = Math.round(x);
+ y = Math.round(y);
+ var idx = this.getPixelIndex(x, y);
+ var hex = this.bitmap.data.readUInt32BE(idx);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, hex);
+ }
+
+ return hex;
+ }
+ }, {
+ key: "setPixelColor",
+
+ /**
+ * Returns the hex colour value of a pixel
+ * @param {number} hex color to set
+ * @param {number} x the x coordinate
+ * @param {number} y the y coordinate
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {number} the index of the pixel or -1 if not found
+ */
+ value: function setPixelColor(hex, x, y, cb) {
+ if (typeof hex !== 'number' || typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'hex, x and y must be numbers', cb); // round input
+
+ x = Math.round(x);
+ y = Math.round(y);
+ var idx = this.getPixelIndex(x, y);
+ this.bitmap.data.writeUInt32BE(hex, idx);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ }, {
+ key: "hasAlpha",
+
+ /**
+ * Determine if the image contains opaque pixels.
+ * @return {boolean} hasAlpha whether the image contains opaque pixels
+ */
+ value: function hasAlpha() {
+ for (var yIndex = 0; yIndex < this.bitmap.height; yIndex++) {
+ for (var xIndex = 0; xIndex < this.bitmap.width; xIndex++) {
+ var idx = this.bitmap.width * yIndex + xIndex << 2;
+ var alpha = this.bitmap.data[idx + 3];
+
+ if (alpha !== 0xff) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ /**
+ * Iterate scan through a region of the bitmap
+ * @param {number} x the x coordinate to begin the scan at
+ * @param {number} y the y coordinate to begin the scan at
+ * @param w the width of the scan region
+ * @param h the height of the scan region
+ * @returns {IterableIterator<{x: number, y: number, idx: number, image: Jimp}>}
+ */
+
+ }, {
+ key: "scanIterator",
+ value: function scanIterator(x, y, w, h) {
+ if (typeof x !== 'number' || typeof y !== 'number') {
+ return _utils.throwError.call(this, 'x and y must be numbers');
+ }
+
+ if (typeof w !== 'number' || typeof h !== 'number') {
+ return _utils.throwError.call(this, 'w and h must be numbers');
+ }
+
+ return (0, _utils.scanIterator)(this, x, y, w, h);
+ }
+ }]);
+ return Jimp;
+}(_events["default"]);
+
+function addConstants(constants) {
+ var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;
+ Object.entries(constants).forEach(function (_ref) {
+ var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
+ name = _ref2[0],
+ value = _ref2[1];
+
+ jimpInstance[name] = value;
+ });
+}
+
+function addJimpMethods(methods) {
+ var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Jimp;
+ Object.entries(methods).forEach(function (_ref3) {
+ var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
+ name = _ref4[0],
+ value = _ref4[1];
+
+ jimpInstance.prototype[name] = value;
+ });
+}
+
+addConstants(constants);
+addJimpMethods({
+ composite: _composite["default"]
+});
+Jimp.__extraConstructors = [];
+/**
+ * Allow client libs to add new ways to build a Jimp object.
+ * @param {string} name identify the extra constructor.
+ * @param {function} test a function that returns true when it accepts the arguments passed to the main constructor.
+ * @param {function} run where the magic happens.
+ */
+
+Jimp.appendConstructorOption = function (name, test, run) {
+ Jimp.__extraConstructors.push({
+ name: name,
+ test: test,
+ run: run
+ });
+};
+/**
+ * Read an image from a file or a Buffer. Takes the same args as the constructor
+ * @returns {Promise} a promise
+ */
+
+
+Jimp.read = function () {
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args[_key3] = arguments[_key3];
+ }
+
+ return new Promise(function (resolve, reject) {
+ (0, _construct2["default"])(Jimp, args.concat([function (err, image) {
+ if (err) reject(err);else resolve(image);
+ }]));
+ });
+};
+
+Jimp.create = Jimp.read;
+/**
+ * A static helper method that converts RGBA values to a single integer value
+ * @param {number} r the red value (0-255)
+ * @param {number} g the green value (0-255)
+ * @param {number} b the blue value (0-255)
+ * @param {number} a the alpha value (0-255)
+ * @param {function(Error, Jimp)} cb (optional) A callback for when complete
+ * @returns {number} an single integer colour value
+ */
+
+Jimp.rgbaToInt = function (r, g, b, a, cb) {
+ if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' || typeof a !== 'number') {
+ return _utils.throwError.call(this, 'r, g, b and a must be numbers', cb);
+ }
+
+ if (r < 0 || r > 255) {
+ return _utils.throwError.call(this, 'r must be between 0 and 255', cb);
+ }
+
+ if (g < 0 || g > 255) {
+ _utils.throwError.call(this, 'g must be between 0 and 255', cb);
+ }
+
+ if (b < 0 || b > 255) {
+ return _utils.throwError.call(this, 'b must be between 0 and 255', cb);
+ }
+
+ if (a < 0 || a > 255) {
+ return _utils.throwError.call(this, 'a must be between 0 and 255', cb);
+ }
+
+ r = Math.round(r);
+ b = Math.round(b);
+ g = Math.round(g);
+ a = Math.round(a);
+ var i = r * Math.pow(256, 3) + g * Math.pow(256, 2) + b * Math.pow(256, 1) + a * Math.pow(256, 0);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, i);
+ }
+
+ return i;
+};
+/**
+ * A static helper method that converts RGBA values to a single integer value
+ * @param {number} i a single integer value representing an RGBA colour (e.g. 0xFF0000FF for red)
+ * @param {function(Error, Jimp)} cb (optional) A callback for when complete
+ * @returns {object} an object with the properties r, g, b and a representing RGBA values
+ */
+
+
+Jimp.intToRGBA = function (i, cb) {
+ if (typeof i !== 'number') {
+ return _utils.throwError.call(this, 'i must be a number', cb);
+ }
+
+ var rgba = {};
+ rgba.r = Math.floor(i / Math.pow(256, 3));
+ rgba.g = Math.floor((i - rgba.r * Math.pow(256, 3)) / Math.pow(256, 2));
+ rgba.b = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2)) / Math.pow(256, 1));
+ rgba.a = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2) - rgba.b * Math.pow(256, 1)) / Math.pow(256, 0));
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, rgba);
+ }
+
+ return rgba;
+};
+/**
+ * Converts a css color (Hex, 8-digit (RGBA) Hex, RGB, RGBA, HSL, HSLA, HSV, HSVA, Named) to a hex number
+ * @param {string} cssColor a number
+ * @returns {number} a hex number representing a color
+ */
+
+
+Jimp.cssColorToHex = function (cssColor) {
+ cssColor = cssColor || 0; // 0, null, undefined, NaN
+
+ if (typeof cssColor === 'number') return Number(cssColor);
+ return parseInt((0, _tinycolor["default"])(cssColor).toHex8(), 16);
+};
+/**
+ * Limits a number to between 0 or 255
+ * @param {number} n a number
+ * @returns {number} the number limited to between 0 or 255
+ */
+
+
+Jimp.limit255 = function (n) {
+ n = Math.max(n, 0);
+ n = Math.min(n, 255);
+ return n;
+};
+/**
+ * Diffs two images and returns
+ * @param {Jimp} img1 a Jimp image to compare
+ * @param {Jimp} img2 a Jimp image to compare
+ * @param {number} threshold (optional) a number, 0 to 1, the smaller the value the more sensitive the comparison (default: 0.1)
+ * @returns {object} an object { percent: percent similar, diff: a Jimp image highlighting differences }
+ */
+
+
+Jimp.diff = function (img1, img2) {
+ var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.1;
+ if (!(img1 instanceof Jimp) || !(img2 instanceof Jimp)) return _utils.throwError.call(this, 'img1 and img2 must be an Jimp images');
+ var bmp1 = img1.bitmap;
+ var bmp2 = img2.bitmap;
+
+ if (bmp1.width !== bmp2.width || bmp1.height !== bmp2.height) {
+ if (bmp1.width * bmp1.height > bmp2.width * bmp2.height) {
+ // img1 is bigger
+ img1 = img1.cloneQuiet().resize(bmp2.width, bmp2.height);
+ } else {
+ // img2 is bigger (or they are the same in area)
+ img2 = img2.cloneQuiet().resize(bmp1.width, bmp1.height);
+ }
+ }
+
+ if (typeof threshold !== 'number' || threshold < 0 || threshold > 1) {
+ return _utils.throwError.call(this, 'threshold must be a number between 0 and 1');
+ }
+
+ var diff = new Jimp(bmp1.width, bmp1.height, 0xffffffff);
+ var numDiffPixels = (0, _pixelmatch["default"])(bmp1.data, bmp2.data, diff.bitmap.data, diff.bitmap.width, diff.bitmap.height, {
+ threshold: threshold
+ });
+ return {
+ percent: numDiffPixels / (diff.bitmap.width * diff.bitmap.height),
+ image: diff
+ };
+};
+/**
+ * Calculates the hamming distance of two images based on their perceptual hash
+ * @param {Jimp} img1 a Jimp image to compare
+ * @param {Jimp} img2 a Jimp image to compare
+ * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
+ */
+
+
+Jimp.distance = function (img1, img2) {
+ var phash = new _phash["default"]();
+ var hash1 = phash.getHash(img1);
+ var hash2 = phash.getHash(img2);
+ return phash.distance(hash1, hash2);
+};
+/**
+ * Calculates the hamming distance of two images based on their perceptual hash
+ * @param {hash} hash1 a pHash
+ * @param {hash} hash2 a pHash
+ * @returns {number} a number ranging from 0 to 1, 0 means they are believed to be identical
+ */
+
+
+Jimp.compareHashes = function (hash1, hash2) {
+ var phash = new _phash["default"]();
+ return phash.distance(hash1, hash2);
+};
+/**
+ * Compute color difference
+ * 0 means no difference, 1 means maximum difference.
+ * @param {number} rgba1: first color to compare.
+ * @param {number} rgba2: second color to compare.
+ * Both parameters must be an color object {r:val, g:val, b:val, a:val}
+ * Where `a` is optional and `val` is an integer between 0 and 255.
+ * @returns {number} float between 0 and 1.
+ */
+
+
+Jimp.colorDiff = function (rgba1, rgba2) {
+ var pow = function pow(n) {
+ return Math.pow(n, 2);
+ };
+
+ var max = Math.max;
+ var maxVal = 255 * 255 * 3;
+
+ if (rgba1.a !== 0 && !rgba1.a) {
+ rgba1.a = 255;
+ }
+
+ if (rgba2.a !== 0 && !rgba2.a) {
+ rgba2.a = 255;
+ }
+
+ return (max(pow(rgba1.r - rgba2.r), pow(rgba1.r - rgba2.r - rgba1.a + rgba2.a)) + max(pow(rgba1.g - rgba2.g), pow(rgba1.g - rgba2.g - rgba1.a + rgba2.a)) + max(pow(rgba1.b - rgba2.b), pow(rgba1.b - rgba2.b - rgba1.a + rgba2.a))) / maxVal;
+};
+/**
+ * Helper to create Jimp methods that emit events before and after its execution.
+ * @param {string} methodName The name to be appended to Jimp prototype.
+ * @param {string} evName The event name to be called.
+ * It will be prefixed by `before-` and emitted when on method call.
+ * It will be appended by `ed` and emitted after the method run.
+ * @param {function} method A function implementing the method itself.
+ * It will also create a quiet version that will not emit events, to not
+ * mess the user code with many `changed` event calls. You can call with
+ * `methodName + "Quiet"`.
+ *
+ * The emitted event comes with a object parameter to the listener with the
+ * `methodName` as one attribute.
+ */
+
+
+function jimpEvMethod(methodName, evName, method) {
+ var evNameBefore = 'before-' + evName;
+ var evNameAfter = evName.replace(/e$/, '') + 'ed';
+
+ Jimp.prototype[methodName] = function () {
+ var wrappedCb;
+
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
+ args[_key4] = arguments[_key4];
+ }
+
+ var cb = args[method.length - 1];
+ var jimpInstance = this;
+
+ if (typeof cb === 'function') {
+ wrappedCb = function wrappedCb() {
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
+ args[_key5] = arguments[_key5];
+ }
+
+ var err = args[0],
+ data = args[1];
+
+ if (err) {
+ jimpInstance.emitError(methodName, err);
+ } else {
+ jimpInstance.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, data));
+ }
+
+ cb.apply(this, args);
+ };
+
+ args[args.length - 1] = wrappedCb;
+ } else {
+ wrappedCb = false;
+ }
+
+ this.emitMulti(methodName, evNameBefore);
+ var result;
+
+ try {
+ result = method.apply(this, args);
+
+ if (!wrappedCb) {
+ this.emitMulti(methodName, evNameAfter, (0, _defineProperty2["default"])({}, methodName, result));
+ }
+ } catch (error) {
+ error.methodName = methodName;
+ this.emitError(methodName, error);
+ }
+
+ return result;
+ };
+
+ Jimp.prototype[methodName + 'Quiet'] = method;
+}
+/**
+ * Creates a new image that is a clone of this one.
+ * @param {function(Error, Jimp)} cb (optional) A callback for when complete
+ * @returns the new image
+ */
+
+
+jimpEvMethod('clone', 'clone', function (cb) {
+ var clone = new Jimp(this);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(clone, null, clone);
+ }
+
+ return clone;
+});
+/**
+ * Simplify jimpEvMethod call for the common `change` evName.
+ * @param {string} methodName name of the method
+ * @param {function} method to watch changes for
+ */
+
+function jimpEvChange(methodName, method) {
+ jimpEvMethod(methodName, 'change', method);
+}
+/**
+ * Sets the type of the image (RGB or RGBA) when saving as PNG format (default is RGBA)
+ * @param b A Boolean, true to use RGBA or false to use RGB
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+
+
+jimpEvChange('background', function (hex, cb) {
+ if (typeof hex !== 'number') {
+ return _utils.throwError.call(this, 'hex must be a hexadecimal rgba value', cb);
+ }
+
+ this._background = hex;
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+});
+/**
+ * Scans through a region of the bitmap, calling a function for each pixel.
+ * @param {number} x the x coordinate to begin the scan at
+ * @param {number} y the y coordinate to begin the scan at
+ * @param w the width of the scan region
+ * @param h the height of the scan region
+ * @param f a function to call on even pixel; the (x, y) position of the pixel
+ * and the index of the pixel in the bitmap buffer are passed to the function
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+
+jimpEvChange('scan', function (x, y, w, h, f, cb) {
+ if (typeof x !== 'number' || typeof y !== 'number') {
+ return _utils.throwError.call(this, 'x and y must be numbers', cb);
+ }
+
+ if (typeof w !== 'number' || typeof h !== 'number') {
+ return _utils.throwError.call(this, 'w and h must be numbers', cb);
+ }
+
+ if (typeof f !== 'function') {
+ return _utils.throwError.call(this, 'f must be a function', cb);
+ }
+
+ var result = (0, _utils.scan)(this, x, y, w, h, f);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, result);
+ }
+
+ return result;
+});
+
+if (process.env.ENVIRONMENT === 'BROWSER') {
+ // For use in a web browser or web worker
+
+ /* global self */
+ var gl;
+
+ if (typeof window !== 'undefined' && (typeof window === "undefined" ? "undefined" : (0, _typeof2["default"])(window)) === 'object') {
+ gl = window;
+ }
+
+ if (typeof self !== 'undefined' && (typeof self === "undefined" ? "undefined" : (0, _typeof2["default"])(self)) === 'object') {
+ gl = self;
+ }
+
+ gl.Jimp = Jimp;
+ gl.Buffer = Buffer;
+}
+
+var _default = Jimp;
+exports["default"] = _default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 7025:
+/***/ ((module) => {
+
+"use strict";
+
+
+/*
+Copyright (c) 2011 Elliot Shepherd
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+// https://code.google.com/p/ironchef-team21/source/browse/ironchef_team21/src/ImagePHash.java
+
+/*
+ * pHash-like image hash.
+ * Author: Elliot Shepherd (elliot@jarofworms.com
+ * Based On: http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
+ */
+function ImagePHash(size, smallerSize) {
+ this.size = this.size || size;
+ this.smallerSize = this.smallerSize || smallerSize;
+ initCoefficients(this.size);
+}
+
+ImagePHash.prototype.size = 32;
+ImagePHash.prototype.smallerSize = 8;
+
+ImagePHash.prototype.distance = function (s1, s2) {
+ var counter = 0;
+
+ for (var k = 0; k < s1.length; k++) {
+ if (s1[k] !== s2[k]) {
+ counter++;
+ }
+ }
+
+ return counter / s1.length;
+}; // Returns a 'binary string' (like. 001010111011100010) which is easy to do a hamming distance on.
+
+
+ImagePHash.prototype.getHash = function (img) {
+ /* 1. Reduce size.
+ * Like Average Hash, pHash starts with a small image.
+ * However, the image is larger than 8x8; 32x32 is a good size.
+ * This is really done to simplify the DCT computation and not
+ * because it is needed to reduce the high frequencies.
+ */
+ img = img.clone().resize(this.size, this.size);
+ /* 2. Reduce color.
+ * The image is reduced to a grayscale just to further simplify
+ * the number of computations.
+ */
+
+ img.grayscale();
+ var vals = [];
+
+ for (var x = 0; x < img.bitmap.width; x++) {
+ vals[x] = [];
+
+ for (var y = 0; y < img.bitmap.height; y++) {
+ vals[x][y] = intToRGBA(img.getPixelColor(x, y)).b;
+ }
+ }
+ /* 3. Compute the DCT.
+ * The DCT separates the image into a collection of frequencies
+ * and scalars. While JPEG uses an 8x8 DCT, this algorithm uses
+ * a 32x32 DCT.
+ */
+
+
+ var dctVals = applyDCT(vals, this.size);
+ /* 4. Reduce the DCT.
+ * This is the magic step. While the DCT is 32x32, just keep the
+ * top-left 8x8. Those represent the lowest frequencies in the
+ * picture.
+ */
+
+ /* 5. Compute the average value.
+ * Like the Average Hash, compute the mean DCT value (using only
+ * the 8x8 DCT low-frequency values and excluding the first term
+ * since the DC coefficient can be significantly different from
+ * the other values and will throw off the average).
+ */
+
+ var total = 0;
+
+ for (var _x = 0; _x < this.smallerSize; _x++) {
+ for (var _y = 0; _y < this.smallerSize; _y++) {
+ total += dctVals[_x][_y];
+ }
+ }
+
+ var avg = total / (this.smallerSize * this.smallerSize);
+ /* 6. Further reduce the DCT.
+ * This is the magic step. Set the 64 hash bits to 0 or 1
+ * depending on whether each of the 64 DCT values is above or
+ * below the average value. The result doesn't tell us the
+ * actual low frequencies; it just tells us the very-rough
+ * relative scale of the frequencies to the mean. The result
+ * will not vary as long as the overall structure of the image
+ * remains the same; this can survive gamma and color histogram
+ * adjustments without a problem.
+ */
+
+ var hash = '';
+
+ for (var _x2 = 0; _x2 < this.smallerSize; _x2++) {
+ for (var _y2 = 0; _y2 < this.smallerSize; _y2++) {
+ hash += dctVals[_x2][_y2] > avg ? '1' : '0';
+ }
+ }
+
+ return hash;
+}; // DCT function stolen from http://stackoverflow.com/questions/4240490/problems-with-dct-and-idct-algorithm-in-java
+
+
+function intToRGBA(i) {
+ var rgba = {};
+ rgba.r = Math.floor(i / Math.pow(256, 3));
+ rgba.g = Math.floor((i - rgba.r * Math.pow(256, 3)) / Math.pow(256, 2));
+ rgba.b = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2)) / Math.pow(256, 1));
+ rgba.a = Math.floor((i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2) - rgba.b * Math.pow(256, 1)) / Math.pow(256, 0));
+ return rgba;
+}
+
+var c = [];
+
+function initCoefficients(size) {
+ for (var i = 1; i < size; i++) {
+ c[i] = 1;
+ }
+
+ c[0] = 1 / Math.sqrt(2.0);
+}
+
+function applyDCT(f, size) {
+ var N = size;
+ var F = [];
+
+ for (var u = 0; u < N; u++) {
+ F[u] = [];
+
+ for (var v = 0; v < N; v++) {
+ var sum = 0;
+
+ for (var i = 0; i < N; i++) {
+ for (var j = 0; j < N; j++) {
+ sum += Math.cos((2 * i + 1) / (2.0 * N) * u * Math.PI) * Math.cos((2 * j + 1) / (2.0 * N) * v * Math.PI) * f[i][j];
+ }
+ }
+
+ sum *= c[u] * c[v] / 4;
+ F[u][v] = sum;
+ }
+ }
+
+ return F;
+}
+
+module.exports = ImagePHash;
+//# sourceMappingURL=phash.js.map
+
+/***/ }),
+
+/***/ 4310:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _extends2 = _interopRequireDefault(__nccwpck_require__(7299));
+
+function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
+
+/* global XMLHttpRequest */
+if (process.browser || process.env.ENVIRONMENT === 'BROWSER' || typeof process.versions.electron !== 'undefined' && process.type === 'renderer' && typeof XMLHttpRequest === 'function') {
+ // If we run into a browser or the electron renderer process,
+ // use XHR method instead of Request node module.
+ module.exports = function (options, cb) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', options.url, true);
+ xhr.responseType = 'arraybuffer';
+ xhr.addEventListener('load', function () {
+ if (xhr.status < 400) {
+ try {
+ var data = Buffer.from(this.response);
+ cb(null, xhr, data);
+ } catch (error) {
+ return cb(new Error('Response is not a buffer for url ' + options.url + '. Error: ' + error.message));
+ }
+ } else {
+ cb(new Error('HTTP Status ' + xhr.status + ' for url ' + options.url));
+ }
+ });
+ xhr.addEventListener('error', function (e) {
+ cb(e);
+ });
+ xhr.send();
+ };
+} else {
+ module.exports = function (_ref, cb) {
+ var options = (0, _extends2["default"])({}, _ref);
+
+ var p = __nccwpck_require__(6130);
+
+ p(_objectSpread({
+ compression: true
+ }, options), function (err, res) {
+ if (err === null) {
+ cb(null, res, res.body);
+ } else {
+ cb(err);
+ }
+ });
+ };
+}
+//# sourceMappingURL=request.js.map
+
+/***/ }),
+
+/***/ 3946:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireWildcard = __nccwpck_require__(4405);
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.parseBitmap = parseBitmap;
+exports.getBuffer = getBuffer;
+exports.getBufferAsync = getBufferAsync;
+
+var _slicedToArray2 = _interopRequireDefault(__nccwpck_require__(8209));
+
+var _fileType = _interopRequireDefault(__nccwpck_require__(4930));
+
+var _exifParser = _interopRequireDefault(__nccwpck_require__(6621));
+
+var _utils = __nccwpck_require__(7403);
+
+var constants = _interopRequireWildcard(__nccwpck_require__(4619));
+
+var MIME = _interopRequireWildcard(__nccwpck_require__(3153));
+
+var _promisify = _interopRequireDefault(__nccwpck_require__(6826));
+
+function getMIMEFromBuffer(buffer, path) {
+ var fileTypeFromBuffer = (0, _fileType["default"])(buffer);
+
+ if (fileTypeFromBuffer) {
+ // If fileType returns something for buffer, then return the mime given
+ return fileTypeFromBuffer.mime;
+ }
+
+ if (path) {
+ // If a path is supplied, and fileType yields no results, then retry with MIME
+ // Path can be either a file path or a url
+ return MIME.getType(path);
+ }
+
+ return null;
+}
+/*
+ * Obtains image orientation from EXIF metadata.
+ *
+ * @param img {Jimp} a Jimp image object
+ * @returns {number} a number 1-8 representing EXIF orientation,
+ * in particular 1 if orientation tag is missing
+ */
+
+
+function getExifOrientation(img) {
+ return img._exif && img._exif.tags && img._exif.tags.Orientation || 1;
+}
+/**
+ * Returns a function which translates EXIF-rotated coordinates into
+ * non-rotated ones.
+ *
+ * Transformation reference: http://sylvana.net/jpegcrop/exif_orientation.html.
+ *
+ * @param img {Jimp} a Jimp image object
+ * @returns {function} transformation function for transformBitmap().
+ */
+
+
+function getExifOrientationTransformation(img) {
+ var w = img.getWidth();
+ var h = img.getHeight();
+
+ switch (getExifOrientation(img)) {
+ case 1:
+ // Horizontal (normal)
+ // does not need to be supported here
+ return null;
+
+ case 2:
+ // Mirror horizontal
+ return function (x, y) {
+ return [w - x - 1, y];
+ };
+
+ case 3:
+ // Rotate 180
+ return function (x, y) {
+ return [w - x - 1, h - y - 1];
+ };
+
+ case 4:
+ // Mirror vertical
+ return function (x, y) {
+ return [x, h - y - 1];
+ };
+
+ case 5:
+ // Mirror horizontal and rotate 270 CW
+ return function (x, y) {
+ return [y, x];
+ };
+
+ case 6:
+ // Rotate 90 CW
+ return function (x, y) {
+ return [y, h - x - 1];
+ };
+
+ case 7:
+ // Mirror horizontal and rotate 90 CW
+ return function (x, y) {
+ return [w - y - 1, h - x - 1];
+ };
+
+ case 8:
+ // Rotate 270 CW
+ return function (x, y) {
+ return [w - y - 1, x];
+ };
+
+ default:
+ return null;
+ }
+}
+/*
+ * Transforms bitmap in place (moves pixels around) according to given
+ * transformation function.
+ *
+ * @param img {Jimp} a Jimp image object, which bitmap is supposed to
+ * be transformed
+ * @param width {number} bitmap width after the transformation
+ * @param height {number} bitmap height after the transformation
+ * @param transformation {function} transformation function which defines pixel
+ * mapping between new and source bitmap. It takes a pair of coordinates
+ * in the target, and returns a respective pair of coordinates in
+ * the source bitmap, i.e. has following form:
+ * `function(new_x, new_y) { return [src_x, src_y] }`.
+ */
+
+
+function transformBitmap(img, width, height, transformation) {
+ // Underscore-prefixed values are related to the source bitmap
+ // Their counterparts with no prefix are related to the target bitmap
+ var _data = img.bitmap.data;
+ var _width = img.bitmap.width;
+ var data = Buffer.alloc(_data.length);
+
+ for (var x = 0; x < width; x++) {
+ for (var y = 0; y < height; y++) {
+ var _transformation = transformation(x, y),
+ _transformation2 = (0, _slicedToArray2["default"])(_transformation, 2),
+ _x = _transformation2[0],
+ _y = _transformation2[1];
+
+ var idx = width * y + x << 2;
+
+ var _idx = _width * _y + _x << 2;
+
+ var pixel = _data.readUInt32BE(_idx);
+
+ data.writeUInt32BE(pixel, idx);
+ }
+ }
+
+ img.bitmap.data = data;
+ img.bitmap.width = width;
+ img.bitmap.height = height;
+}
+/*
+ * Automagically rotates an image based on its EXIF data (if present).
+ * @param img {Jimp} a Jimp image object
+ */
+
+
+function exifRotate(img) {
+ if (getExifOrientation(img) < 2) return;
+ var transformation = getExifOrientationTransformation(img);
+ var swapDimensions = getExifOrientation(img) > 4;
+ var newWidth = swapDimensions ? img.bitmap.height : img.bitmap.width;
+ var newHeight = swapDimensions ? img.bitmap.width : img.bitmap.height;
+ transformBitmap(img, newWidth, newHeight, transformation);
+} // parses a bitmap from the constructor to the JIMP bitmap property
+
+
+function parseBitmap(data, path, cb) {
+ var mime = getMIMEFromBuffer(data, path);
+
+ if (typeof mime !== 'string') {
+ return cb(new Error('Could not find MIME for Buffer <' + path + '>'));
+ }
+
+ this._originalMime = mime.toLowerCase();
+
+ try {
+ var _mime = this.getMIME();
+
+ if (this.constructor.decoders[_mime]) {
+ this.bitmap = this.constructor.decoders[_mime](data);
+ } else {
+ return _utils.throwError.call(this, 'Unsupported MIME type: ' + _mime, cb);
+ }
+ } catch (error) {
+ return cb.call(this, error, this);
+ }
+
+ try {
+ this._exif = _exifParser["default"].create(data).parse();
+ exifRotate(this); // EXIF data
+ } catch (error) {
+ /* meh */
+ }
+
+ cb.call(this, null, this);
+ return this;
+}
+
+function compositeBitmapOverBackground(Jimp, image) {
+ return new Jimp(image.bitmap.width, image.bitmap.height, image._background).composite(image, 0, 0).bitmap;
+}
+/**
+ * Converts the image to a buffer
+ * @param {string} mime the mime type of the image buffer to be created
+ * @param {function(Error, Jimp)} cb a Node-style function to call with the buffer as the second argument
+ * @returns {Jimp} this for chaining of methods
+ */
+
+
+function getBuffer(mime, cb) {
+ if (mime === constants.AUTO) {
+ // allow auto MIME detection
+ mime = this.getMIME();
+ }
+
+ if (typeof mime !== 'string') {
+ return _utils.throwError.call(this, 'mime must be a string', cb);
+ }
+
+ if (typeof cb !== 'function') {
+ return _utils.throwError.call(this, 'cb must be a function', cb);
+ }
+
+ mime = mime.toLowerCase();
+
+ if (this._rgba && this.constructor.hasAlpha[mime]) {
+ this.bitmap.data = Buffer.from(this.bitmap.data);
+ } else {
+ // when format doesn't support alpha
+ // composite onto a new image so that the background shows through alpha channels
+ this.bitmap.data = compositeBitmapOverBackground(this.constructor, this).data;
+ }
+
+ if (this.constructor.encoders[mime]) {
+ var buffer = this.constructor.encoders[mime](this);
+ cb.call(this, null, buffer);
+ } else {
+ cb.call(this, 'Unsupported MIME type: ' + mime);
+ }
+
+ return this;
+}
+
+function getBufferAsync(mime) {
+ return (0, _promisify["default"])(getBuffer, this, mime);
+}
+//# sourceMappingURL=image-bitmap.js.map
+
+/***/ }),
+
+/***/ 3153:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.getExtension = exports.getType = exports.addType = void 0;
+var mimeTypes = {};
+
+var findType = function findType(extension) {
+ return Object.entries(mimeTypes).find(function (type) {
+ return type[1].includes(extension);
+ }) || [];
+};
+
+var addType = function addType(mime, extensions) {
+ mimeTypes[mime] = extensions;
+};
+/**
+ * Lookup a mime type based on extension
+ * @param {string} path path to find extension for
+ * @returns {string} mime found mime type
+ */
+
+
+exports.addType = addType;
+
+var getType = function getType(path) {
+ var pathParts = path.split('/').slice(-1);
+ var extension = pathParts[pathParts.length - 1].split('.').pop();
+ var type = findType(extension);
+ return type[0];
+};
+/**
+ * Return file extension associated with a mime type
+ * @param {string} type mime type to look up
+ * @returns {string} extension file extension
+ */
+
+
+exports.getType = getType;
+
+var getExtension = function getExtension(type) {
+ return (mimeTypes[type.toLowerCase()] || [])[0];
+};
+
+exports.getExtension = getExtension;
+//# sourceMappingURL=mime.js.map
+
+/***/ }),
+
+/***/ 6826:
+/***/ ((module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var promisify = function promisify(fun, ctx) {
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ return new Promise(function (resolve, reject) {
+ args.push(function (err, data) {
+ if (err) {
+ reject(err);
+ }
+
+ resolve(data);
+ });
+ fun.bind(ctx).apply(void 0, args);
+ });
+};
+
+var _default = promisify;
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=promisify.js.map
+
+/***/ }),
+
+/***/ 9472:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireWildcard = __nccwpck_require__(4405);
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = configure;
+
+var _toConsumableArray2 = _interopRequireDefault(__nccwpck_require__(3195));
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _slicedToArray2 = _interopRequireDefault(__nccwpck_require__(8209));
+
+var _core = _interopRequireWildcard(__nccwpck_require__(678));
+
+function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
+
+function configure(configuration) {
+ var jimpInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _core["default"];
+ var jimpConfig = {
+ hasAlpha: {},
+ encoders: {},
+ decoders: {},
+ "class": {},
+ constants: {}
+ };
+
+ function addToConfig(newConfig) {
+ Object.entries(newConfig).forEach(function (_ref) {
+ var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
+ key = _ref2[0],
+ value = _ref2[1];
+
+ jimpConfig[key] = _objectSpread({}, jimpConfig[key], {}, value);
+ });
+ }
+
+ function addImageType(typeModule) {
+ var type = typeModule();
+
+ if (Array.isArray(type.mime)) {
+ _core.addType.apply(void 0, (0, _toConsumableArray2["default"])(type.mime));
+ } else {
+ Object.entries(type.mime).forEach(function (mimeType) {
+ return _core.addType.apply(void 0, (0, _toConsumableArray2["default"])(mimeType));
+ });
+ }
+
+ delete type.mime;
+ addToConfig(type);
+ }
+
+ function addPlugin(pluginModule) {
+ var plugin = pluginModule(_core.jimpEvChange) || {};
+
+ if (!plugin["class"] && !plugin.constants) {
+ // Default to class function
+ addToConfig({
+ "class": plugin
+ });
+ } else {
+ addToConfig(plugin);
+ }
+ }
+
+ if (configuration.types) {
+ configuration.types.forEach(addImageType);
+ jimpInstance.decoders = _objectSpread({}, jimpInstance.decoders, {}, jimpConfig.decoders);
+ jimpInstance.encoders = _objectSpread({}, jimpInstance.encoders, {}, jimpConfig.encoders);
+ jimpInstance.hasAlpha = _objectSpread({}, jimpInstance.hasAlpha, {}, jimpConfig.hasAlpha);
+ }
+
+ if (configuration.plugins) {
+ configuration.plugins.forEach(addPlugin);
+ }
+
+ (0, _core.addJimpMethods)(jimpConfig["class"], jimpInstance);
+ (0, _core.addConstants)(jimpConfig.constants, jimpInstance);
+ return _core["default"];
+}
+
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 8257:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _omggif = _interopRequireDefault(__nccwpck_require__(9717));
+
+var _gifwrap = __nccwpck_require__(7304);
+
+var MIME_TYPE = 'image/gif';
+
+var _default = function _default() {
+ return {
+ mime: (0, _defineProperty2["default"])({}, MIME_TYPE, ['gif']),
+ constants: {
+ MIME_GIF: MIME_TYPE
+ },
+ decoders: (0, _defineProperty2["default"])({}, MIME_TYPE, function (data) {
+ var gifObj = new _omggif["default"].GifReader(data);
+ var gifData = Buffer.alloc(gifObj.width * gifObj.height * 4);
+ gifObj.decodeAndBlitFrameRGBA(0, gifData);
+ return {
+ data: gifData,
+ width: gifObj.width,
+ height: gifObj.height
+ };
+ }),
+ encoders: (0, _defineProperty2["default"])({}, MIME_TYPE, function (data) {
+ var bitmap = new _gifwrap.BitmapImage(data.bitmap);
+
+ _gifwrap.GifUtil.quantizeDekker(bitmap, 256);
+
+ var newFrame = new _gifwrap.GifFrame(bitmap);
+ var gifCodec = new _gifwrap.GifCodec();
+ return gifCodec.encodeGif([newFrame], {}).then(function (newGif) {
+ return newGif.buffer;
+ });
+ })
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 5177:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _jpegJs = _interopRequireDefault(__nccwpck_require__(8541));
+
+var _utils = __nccwpck_require__(7403);
+
+var MIME_TYPE = 'image/jpeg';
+
+var _default = function _default() {
+ return {
+ mime: (0, _defineProperty2["default"])({}, MIME_TYPE, ['jpeg', 'jpg', 'jpe']),
+ constants: {
+ MIME_JPEG: MIME_TYPE
+ },
+ decoders: (0, _defineProperty2["default"])({}, MIME_TYPE, _jpegJs["default"].decode),
+ encoders: (0, _defineProperty2["default"])({}, MIME_TYPE, function (image) {
+ return _jpegJs["default"].encode(image.bitmap, image._quality).data;
+ }),
+ "class": {
+ // The quality to be used when saving JPEG images
+ _quality: 100,
+
+ /**
+ * Sets the quality of the image when saving as JPEG format (default is 100)
+ * @param {number} n The quality to use 0-100
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ quality: function quality(n, cb) {
+ if (typeof n !== 'number') {
+ return _utils.throwError.call(this, 'n must be a number', cb);
+ }
+
+ if (n < 0 || n > 100) {
+ return _utils.throwError.call(this, 'n must be a number 0 - 100', cb);
+ }
+
+ this._quality = Math.round(n);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 1485:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605));
+
+var _utils = __nccwpck_require__(7403);
+
+var _default = function _default() {
+ return {
+ /**
+ * Blits a source image on to this image
+ * @param {Jimp} src the source Jimp instance
+ * @param {number} x the x position to blit the image
+ * @param {number} y the y position to blit the image
+ * @param {number} srcx (optional) the x position from which to crop the source image
+ * @param {number} srcy (optional) the y position from which to crop the source image
+ * @param {number} srcw (optional) the width to which to crop the source image
+ * @param {number} srch (optional) the height to which to crop the source image
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ blit: function blit(src, x, y, srcx, srcy, srcw, srch, cb) {
+ if (!(src instanceof this.constructor)) {
+ return _utils.throwError.call(this, 'The source must be a Jimp image', cb);
+ }
+
+ if (typeof x !== 'number' || typeof y !== 'number') {
+ return _utils.throwError.call(this, 'x and y must be numbers', cb);
+ }
+
+ if (typeof srcx === 'function') {
+ cb = srcx;
+ srcx = 0;
+ srcy = 0;
+ srcw = src.bitmap.width;
+ srch = src.bitmap.height;
+ } else if ((0, _typeof2["default"])(srcx) === (0, _typeof2["default"])(srcy) && (0, _typeof2["default"])(srcy) === (0, _typeof2["default"])(srcw) && (0, _typeof2["default"])(srcw) === (0, _typeof2["default"])(srch)) {
+ srcx = srcx || 0;
+ srcy = srcy || 0;
+ srcw = srcw || src.bitmap.width;
+ srch = srch || src.bitmap.height;
+ } else {
+ return _utils.throwError.call(this, 'srcx, srcy, srcw, srch must be numbers', cb);
+ } // round input
+
+
+ x = Math.round(x);
+ y = Math.round(y); // round input
+
+ srcx = Math.round(srcx);
+ srcy = Math.round(srcy);
+ srcw = Math.round(srcw);
+ srch = Math.round(srch);
+ var maxWidth = this.bitmap.width;
+ var maxHeight = this.bitmap.height;
+ var baseImage = this;
+ src.scanQuiet(srcx, srcy, srcw, srch, function (sx, sy, idx) {
+ var xOffset = x + sx - srcx;
+ var yOffset = y + sy - srcy;
+
+ if (xOffset >= 0 && yOffset >= 0 && maxWidth - xOffset > 0 && maxHeight - yOffset > 0) {
+ var dstIdx = baseImage.getPixelIndex(xOffset, yOffset);
+ var _src = {
+ r: this.bitmap.data[idx],
+ g: this.bitmap.data[idx + 1],
+ b: this.bitmap.data[idx + 2],
+ a: this.bitmap.data[idx + 3]
+ };
+ var dst = {
+ r: baseImage.bitmap.data[dstIdx],
+ g: baseImage.bitmap.data[dstIdx + 1],
+ b: baseImage.bitmap.data[dstIdx + 2],
+ a: baseImage.bitmap.data[dstIdx + 3]
+ };
+ baseImage.bitmap.data[dstIdx] = (_src.a * (_src.r - dst.r) - dst.r + 255 >> 8) + dst.r;
+ baseImage.bitmap.data[dstIdx + 1] = (_src.a * (_src.g - dst.g) - dst.g + 255 >> 8) + dst.g;
+ baseImage.bitmap.data[dstIdx + 2] = (_src.a * (_src.b - dst.b) - dst.b + 255 >> 8) + dst.b;
+ baseImage.bitmap.data[dstIdx + 3] = this.constructor.limit255(dst.a + _src.a);
+ }
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 5803:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.shgTable = exports.mulTable = void 0;
+var mulTable = [1, 57, 41, 21, 203, 34, 97, 73, 227, 91, 149, 62, 105, 45, 39, 137, 241, 107, 3, 173, 39, 71, 65, 238, 219, 101, 187, 87, 81, 151, 141, 133, 249, 117, 221, 209, 197, 187, 177, 169, 5, 153, 73, 139, 133, 127, 243, 233, 223, 107, 103, 99, 191, 23, 177, 171, 165, 159, 77, 149, 9, 139, 135, 131, 253, 245, 119, 231, 224, 109, 211, 103, 25, 195, 189, 23, 45, 175, 171, 83, 81, 79, 155, 151, 147, 9, 141, 137, 67, 131, 129, 251, 123, 30, 235, 115, 113, 221, 217, 53, 13, 51, 50, 49, 193, 189, 185, 91, 179, 175, 43, 169, 83, 163, 5, 79, 155, 19, 75, 147, 145, 143, 35, 69, 17, 67, 33, 65, 255, 251, 247, 243, 239, 59, 29, 229, 113, 111, 219, 27, 213, 105, 207, 51, 201, 199, 49, 193, 191, 47, 93, 183, 181, 179, 11, 87, 43, 85, 167, 165, 163, 161, 159, 157, 155, 77, 19, 75, 37, 73, 145, 143, 141, 35, 138, 137, 135, 67, 33, 131, 129, 255, 63, 250, 247, 61, 121, 239, 237, 117, 29, 229, 227, 225, 111, 55, 109, 216, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 48, 190, 47, 93, 185, 183, 181, 179, 178, 176, 175, 173, 171, 85, 21, 167, 165, 41, 163, 161, 5, 79, 157, 78, 154, 153, 19, 75, 149, 74, 147, 73, 144, 143, 71, 141, 140, 139, 137, 17, 135, 134, 133, 66, 131, 65, 129, 1];
+exports.mulTable = mulTable;
+var shgTable = [0, 9, 10, 10, 14, 12, 14, 14, 16, 15, 16, 15, 16, 15, 15, 17, 18, 17, 12, 18, 16, 17, 17, 19, 19, 18, 19, 18, 18, 19, 19, 19, 20, 19, 20, 20, 20, 20, 20, 20, 15, 20, 19, 20, 20, 20, 21, 21, 21, 20, 20, 20, 21, 18, 21, 21, 21, 21, 20, 21, 17, 21, 21, 21, 22, 22, 21, 22, 22, 21, 22, 21, 19, 22, 22, 19, 20, 22, 22, 21, 21, 21, 22, 22, 22, 18, 22, 22, 21, 22, 22, 23, 22, 20, 23, 22, 22, 23, 23, 21, 19, 21, 21, 21, 23, 23, 23, 22, 23, 23, 21, 23, 22, 23, 18, 22, 23, 20, 22, 23, 23, 23, 21, 22, 20, 22, 21, 22, 24, 24, 24, 24, 24, 22, 21, 24, 23, 23, 24, 21, 24, 23, 24, 22, 24, 24, 22, 24, 24, 22, 23, 24, 24, 24, 20, 23, 22, 23, 24, 24, 24, 24, 24, 24, 24, 23, 21, 23, 22, 23, 24, 24, 24, 22, 24, 24, 24, 23, 22, 24, 24, 25, 23, 25, 25, 23, 24, 25, 25, 24, 22, 25, 25, 25, 24, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 23, 25, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 22, 25, 25, 23, 25, 25, 20, 24, 25, 24, 25, 25, 22, 24, 25, 24, 25, 24, 25, 25, 24, 25, 25, 25, 25, 22, 25, 25, 25, 24, 25, 24, 25, 18];
+exports.shgTable = shgTable;
+//# sourceMappingURL=blur-tables.js.map
+
+/***/ }),
+
+/***/ 6223:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+var _blurTables = __nccwpck_require__(5803);
+
+/*
+ Superfast Blur (0.5)
+ http://www.quasimondo.com/BoxBlurForCanvas/FastBlur.js
+
+ Copyright (c) 2011 Mario Klingemann
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+var _default = function _default() {
+ return {
+ /**
+ * A fast blur algorithm that produces similar effect to a Gaussian blur - but MUCH quicker
+ * @param {number} r the pixel radius of the blur
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ blur: function blur(r, cb) {
+ if (typeof r !== 'number') return _utils.throwError.call(this, 'r must be a number', cb);
+ if (r < 1) return _utils.throwError.call(this, 'r must be greater than 0', cb);
+ var rsum;
+ var gsum;
+ var bsum;
+ var asum;
+ var x;
+ var y;
+ var i;
+ var p;
+ var p1;
+ var p2;
+ var yp;
+ var yi;
+ var yw;
+ var pa;
+ var wm = this.bitmap.width - 1;
+ var hm = this.bitmap.height - 1; // const wh = this.bitmap.width * this.bitmap.height;
+
+ var rad1 = r + 1;
+ var mulSum = _blurTables.mulTable[r];
+ var shgSum = _blurTables.shgTable[r];
+ var red = [];
+ var green = [];
+ var blue = [];
+ var alpha = [];
+ var vmin = [];
+ var vmax = [];
+ var iterations = 2;
+
+ while (iterations-- > 0) {
+ yi = 0;
+ yw = 0;
+
+ for (y = 0; y < this.bitmap.height; y++) {
+ rsum = this.bitmap.data[yw] * rad1;
+ gsum = this.bitmap.data[yw + 1] * rad1;
+ bsum = this.bitmap.data[yw + 2] * rad1;
+ asum = this.bitmap.data[yw + 3] * rad1;
+
+ for (i = 1; i <= r; i++) {
+ p = yw + ((i > wm ? wm : i) << 2);
+ rsum += this.bitmap.data[p++];
+ gsum += this.bitmap.data[p++];
+ bsum += this.bitmap.data[p++];
+ asum += this.bitmap.data[p];
+ }
+
+ for (x = 0; x < this.bitmap.width; x++) {
+ red[yi] = rsum;
+ green[yi] = gsum;
+ blue[yi] = bsum;
+ alpha[yi] = asum;
+
+ if (y === 0) {
+ vmin[x] = ((p = x + rad1) < wm ? p : wm) << 2;
+ vmax[x] = (p = x - r) > 0 ? p << 2 : 0;
+ }
+
+ p1 = yw + vmin[x];
+ p2 = yw + vmax[x];
+ rsum += this.bitmap.data[p1++] - this.bitmap.data[p2++];
+ gsum += this.bitmap.data[p1++] - this.bitmap.data[p2++];
+ bsum += this.bitmap.data[p1++] - this.bitmap.data[p2++];
+ asum += this.bitmap.data[p1] - this.bitmap.data[p2];
+ yi++;
+ }
+
+ yw += this.bitmap.width << 2;
+ }
+
+ for (x = 0; x < this.bitmap.width; x++) {
+ yp = x;
+ rsum = red[yp] * rad1;
+ gsum = green[yp] * rad1;
+ bsum = blue[yp] * rad1;
+ asum = alpha[yp] * rad1;
+
+ for (i = 1; i <= r; i++) {
+ yp += i > hm ? 0 : this.bitmap.width;
+ rsum += red[yp];
+ gsum += green[yp];
+ bsum += blue[yp];
+ asum += alpha[yp];
+ }
+
+ yi = x << 2;
+
+ for (y = 0; y < this.bitmap.height; y++) {
+ pa = asum * mulSum >>> shgSum;
+ this.bitmap.data[yi + 3] = pa; // normalize alpha
+
+ if (pa > 255) {
+ this.bitmap.data[yi + 3] = 255;
+ }
+
+ if (pa > 0) {
+ pa = 255 / pa;
+ this.bitmap.data[yi] = (rsum * mulSum >>> shgSum) * pa;
+ this.bitmap.data[yi + 1] = (gsum * mulSum >>> shgSum) * pa;
+ this.bitmap.data[yi + 2] = (bsum * mulSum >>> shgSum) * pa;
+ } else {
+ this.bitmap.data[yi + 2] = 0;
+ this.bitmap.data[yi + 1] = 0;
+ this.bitmap.data[yi] = 0;
+ }
+
+ if (x === 0) {
+ vmin[y] = ((p = y + rad1) < hm ? p : hm) * this.bitmap.width;
+ vmax[y] = (p = y - r) > 0 ? p * this.bitmap.width : 0;
+ }
+
+ p1 = x + vmin[y];
+ p2 = x + vmax[y];
+ rsum += red[p1] - red[p2];
+ gsum += green[p1] - green[p2];
+ bsum += blue[p1] - blue[p2];
+ asum += alpha[p1] - alpha[p2];
+ yi += this.bitmap.width << 2;
+ }
+ }
+ }
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 2005:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Creates a circle out of an image.
+ * @param {function(Error, Jimp)} options (optional) radius, x, y
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ circle: function circle() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var cb = arguments.length > 1 ? arguments[1] : undefined;
+
+ if (typeof options === 'function') {
+ cb = options;
+ options = {};
+ }
+
+ var radius = options.radius || (this.bitmap.width > this.bitmap.height ? this.bitmap.height : this.bitmap.width) / 2;
+ var center = {
+ x: typeof options.x === 'number' ? options.x : this.bitmap.width / 2,
+ y: typeof options.y === 'number' ? options.y : this.bitmap.height / 2
+ };
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var curR = Math.sqrt(Math.pow(x - center.x, 2) + Math.pow(y - center.y, 2));
+
+ if (radius - curR <= 0.0) {
+ this.bitmap.data[idx + 3] = 0;
+ } else if (radius - curR < 1.0) {
+ this.bitmap.data[idx + 3] = 255 * (radius - curR);
+ }
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 5432:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _toConsumableArray2 = _interopRequireDefault(__nccwpck_require__(3195));
+
+var _tinycolor = _interopRequireDefault(__nccwpck_require__(5479));
+
+var _utils = __nccwpck_require__(7403);
+
+function applyKernel(im, kernel, x, y) {
+ var value = [0, 0, 0];
+ var size = (kernel.length - 1) / 2;
+
+ for (var kx = 0; kx < kernel.length; kx += 1) {
+ for (var ky = 0; ky < kernel[kx].length; ky += 1) {
+ var idx = im.getPixelIndex(x + kx - size, y + ky - size);
+ value[0] += im.bitmap.data[idx] * kernel[kx][ky];
+ value[1] += im.bitmap.data[idx + 1] * kernel[kx][ky];
+ value[2] += im.bitmap.data[idx + 2] * kernel[kx][ky];
+ }
+ }
+
+ return value;
+}
+
+var isDef = function isDef(v) {
+ return typeof v !== 'undefined' && v !== null;
+};
+
+function greyscale(cb) {
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var grey = parseInt(0.2126 * this.bitmap.data[idx] + 0.7152 * this.bitmap.data[idx + 1] + 0.0722 * this.bitmap.data[idx + 2], 10);
+ this.bitmap.data[idx] = grey;
+ this.bitmap.data[idx + 1] = grey;
+ this.bitmap.data[idx + 2] = grey;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+}
+
+function mix(clr, clr2) {
+ var p = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 50;
+ return {
+ r: (clr2.r - clr.r) * (p / 100) + clr.r,
+ g: (clr2.g - clr.g) * (p / 100) + clr.g,
+ b: (clr2.b - clr.b) * (p / 100) + clr.b
+ };
+}
+
+function colorFn(actions, cb) {
+ var _this = this;
+
+ if (!actions || !Array.isArray(actions)) {
+ return _utils.throwError.call(this, 'actions must be an array', cb);
+ }
+
+ actions = actions.map(function (action) {
+ if (action.apply === 'xor' || action.apply === 'mix') {
+ action.params[0] = (0, _tinycolor["default"])(action.params[0]).toRgb();
+ }
+
+ return action;
+ });
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var clr = {
+ r: _this.bitmap.data[idx],
+ g: _this.bitmap.data[idx + 1],
+ b: _this.bitmap.data[idx + 2]
+ };
+
+ var colorModifier = function colorModifier(i, amount) {
+ return _this.constructor.limit255(clr[i] + amount);
+ };
+
+ actions.forEach(function (action) {
+ if (action.apply === 'mix') {
+ clr = mix(clr, action.params[0], action.params[1]);
+ } else if (action.apply === 'tint') {
+ clr = mix(clr, {
+ r: 255,
+ g: 255,
+ b: 255
+ }, action.params[0]);
+ } else if (action.apply === 'shade') {
+ clr = mix(clr, {
+ r: 0,
+ g: 0,
+ b: 0
+ }, action.params[0]);
+ } else if (action.apply === 'xor') {
+ clr = {
+ r: clr.r ^ action.params[0].r,
+ g: clr.g ^ action.params[0].g,
+ b: clr.b ^ action.params[0].b
+ };
+ } else if (action.apply === 'red') {
+ clr.r = colorModifier('r', action.params[0]);
+ } else if (action.apply === 'green') {
+ clr.g = colorModifier('g', action.params[0]);
+ } else if (action.apply === 'blue') {
+ clr.b = colorModifier('b', action.params[0]);
+ } else {
+ var _clr;
+
+ if (action.apply === 'hue') {
+ action.apply = 'spin';
+ }
+
+ clr = (0, _tinycolor["default"])(clr);
+
+ if (!clr[action.apply]) {
+ return _utils.throwError.call(_this, 'action ' + action.apply + ' not supported', cb);
+ }
+
+ clr = (_clr = clr)[action.apply].apply(_clr, (0, _toConsumableArray2["default"])(action.params)).toRgb();
+ }
+ });
+ _this.bitmap.data[idx] = clr.r;
+ _this.bitmap.data[idx + 1] = clr.g;
+ _this.bitmap.data[idx + 2] = clr.b;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+}
+
+var _default = function _default() {
+ return {
+ /**
+ * Adjusts the brightness of the image
+ * @param {number} val the amount to adjust the brightness, a number between -1 and +1
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ brightness: function brightness(val, cb) {
+ if (typeof val !== 'number') {
+ return _utils.throwError.call(this, 'val must be numbers', cb);
+ }
+
+ if (val < -1 || val > +1) {
+ return _utils.throwError.call(this, 'val must be a number between -1 and +1', cb);
+ }
+
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ if (val < 0.0) {
+ this.bitmap.data[idx] = this.bitmap.data[idx] * (1 + val);
+ this.bitmap.data[idx + 1] = this.bitmap.data[idx + 1] * (1 + val);
+ this.bitmap.data[idx + 2] = this.bitmap.data[idx + 2] * (1 + val);
+ } else {
+ this.bitmap.data[idx] = this.bitmap.data[idx] + (255 - this.bitmap.data[idx]) * val;
+ this.bitmap.data[idx + 1] = this.bitmap.data[idx + 1] + (255 - this.bitmap.data[idx + 1]) * val;
+ this.bitmap.data[idx + 2] = this.bitmap.data[idx + 2] + (255 - this.bitmap.data[idx + 2]) * val;
+ }
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Adjusts the contrast of the image
+ * @param {number} val the amount to adjust the contrast, a number between -1 and +1
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ contrast: function contrast(val, cb) {
+ if (typeof val !== 'number') {
+ return _utils.throwError.call(this, 'val must be numbers', cb);
+ }
+
+ if (val < -1 || val > +1) {
+ return _utils.throwError.call(this, 'val must be a number between -1 and +1', cb);
+ }
+
+ var factor = (val + 1) / (1 - val);
+
+ function adjust(value) {
+ value = Math.floor(factor * (value - 127) + 127);
+ return value < 0 ? 0 : value > 255 ? 255 : value;
+ }
+
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ this.bitmap.data[idx] = adjust(this.bitmap.data[idx]);
+ this.bitmap.data[idx + 1] = adjust(this.bitmap.data[idx + 1]);
+ this.bitmap.data[idx + 2] = adjust(this.bitmap.data[idx + 2]);
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Apply a posterize effect
+ * @param {number} n the amount to adjust the contrast, minimum threshold is two
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ posterize: function posterize(n, cb) {
+ if (typeof n !== 'number') {
+ return _utils.throwError.call(this, 'n must be numbers', cb);
+ }
+
+ if (n < 2) {
+ n = 2;
+ } // minimum of 2 levels
+
+
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ this.bitmap.data[idx] = Math.floor(this.bitmap.data[idx] / 255 * (n - 1)) / (n - 1) * 255;
+ this.bitmap.data[idx + 1] = Math.floor(this.bitmap.data[idx + 1] / 255 * (n - 1)) / (n - 1) * 255;
+ this.bitmap.data[idx + 2] = Math.floor(this.bitmap.data[idx + 2] / 255 * (n - 1)) / (n - 1) * 255;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Removes colour from the image using ITU Rec 709 luminance values
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ greyscale: greyscale,
+ // Alias of greyscale for our American friends
+ grayscale: greyscale,
+
+ /**
+ * Multiplies the opacity of each pixel by a factor between 0 and 1
+ * @param {number} f A number, the factor by which to multiply the opacity of each pixel
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ opacity: function opacity(f, cb) {
+ if (typeof f !== 'number') return _utils.throwError.call(this, 'f must be a number', cb);
+ if (f < 0 || f > 1) return _utils.throwError.call(this, 'f must be a number from 0 to 1', cb);
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var v = this.bitmap.data[idx + 3] * f;
+ this.bitmap.data[idx + 3] = v;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Applies a sepia tone to the image
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ sepia: function sepia(cb) {
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var red = this.bitmap.data[idx];
+ var green = this.bitmap.data[idx + 1];
+ var blue = this.bitmap.data[idx + 2];
+ red = red * 0.393 + green * 0.769 + blue * 0.189;
+ green = red * 0.349 + green * 0.686 + blue * 0.168;
+ blue = red * 0.272 + green * 0.534 + blue * 0.131;
+ this.bitmap.data[idx] = red < 255 ? red : 255;
+ this.bitmap.data[idx + 1] = green < 255 ? green : 255;
+ this.bitmap.data[idx + 2] = blue < 255 ? blue : 255;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Fades each pixel by a factor between 0 and 1
+ * @param {number} f A number from 0 to 1. 0 will haven no effect. 1 will turn the image completely transparent.
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ fade: function fade(f, cb) {
+ if (typeof f !== 'number') {
+ return _utils.throwError.call(this, 'f must be a number', cb);
+ }
+
+ if (f < 0 || f > 1) {
+ return _utils.throwError.call(this, 'f must be a number from 0 to 1', cb);
+ } // this method is an alternative to opacity (which may be deprecated)
+
+
+ this.opacity(1 - f);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Adds each element of the image to its local neighbors, weighted by the kernel
+ * @param {array} kernel a matrix to weight the neighbors sum
+ * @param {string} edgeHandling (optional) define how to sum pixels from outside the border
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ convolution: function convolution(kernel, edgeHandling, cb) {
+ if (typeof edgeHandling === 'function' && typeof cb === 'undefined') {
+ cb = edgeHandling;
+ edgeHandling = null;
+ }
+
+ if (!edgeHandling) {
+ edgeHandling = this.constructor.EDGE_EXTEND;
+ }
+
+ var newData = Buffer.from(this.bitmap.data);
+ var kRows = kernel.length;
+ var kCols = kernel[0].length;
+ var rowEnd = Math.floor(kRows / 2);
+ var colEnd = Math.floor(kCols / 2);
+ var rowIni = -rowEnd;
+ var colIni = -colEnd;
+ var weight;
+ var rSum;
+ var gSum;
+ var bSum;
+ var ri;
+ var gi;
+ var bi;
+ var xi;
+ var yi;
+ var idxi;
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ bSum = 0;
+ gSum = 0;
+ rSum = 0;
+
+ for (var row = rowIni; row <= rowEnd; row++) {
+ for (var col = colIni; col <= colEnd; col++) {
+ xi = x + col;
+ yi = y + row;
+ weight = kernel[row + rowEnd][col + colEnd];
+ idxi = this.getPixelIndex(xi, yi, edgeHandling);
+
+ if (idxi === -1) {
+ bi = 0;
+ gi = 0;
+ ri = 0;
+ } else {
+ ri = this.bitmap.data[idxi + 0];
+ gi = this.bitmap.data[idxi + 1];
+ bi = this.bitmap.data[idxi + 2];
+ }
+
+ rSum += weight * ri;
+ gSum += weight * gi;
+ bSum += weight * bi;
+ }
+ }
+
+ if (rSum < 0) {
+ rSum = 0;
+ }
+
+ if (gSum < 0) {
+ gSum = 0;
+ }
+
+ if (bSum < 0) {
+ bSum = 0;
+ }
+
+ if (rSum > 255) {
+ rSum = 255;
+ }
+
+ if (gSum > 255) {
+ gSum = 255;
+ }
+
+ if (bSum > 255) {
+ bSum = 255;
+ }
+
+ newData[idx + 0] = rSum;
+ newData[idx + 1] = gSum;
+ newData[idx + 2] = bSum;
+ });
+ this.bitmap.data = newData;
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Set the alpha channel on every pixel to fully opaque
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ opaque: function opaque(cb) {
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ this.bitmap.data[idx + 3] = 255;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Pixelates the image or a region
+ * @param {number} size the size of the pixels
+ * @param {number} x (optional) the x position of the region to pixelate
+ * @param {number} y (optional) the y position of the region to pixelate
+ * @param {number} w (optional) the width of the region to pixelate
+ * @param {number} h (optional) the height of the region to pixelate
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ pixelate: function pixelate(size, x, y, w, h, cb) {
+ if (typeof x === 'function') {
+ cb = x;
+ h = null;
+ w = null;
+ y = null;
+ x = null;
+ } else {
+ if (typeof size !== 'number') {
+ return _utils.throwError.call(this, 'size must be a number', cb);
+ }
+
+ if (isDef(x) && typeof x !== 'number') {
+ return _utils.throwError.call(this, 'x must be a number', cb);
+ }
+
+ if (isDef(y) && typeof y !== 'number') {
+ return _utils.throwError.call(this, 'y must be a number', cb);
+ }
+
+ if (isDef(w) && typeof w !== 'number') {
+ return _utils.throwError.call(this, 'w must be a number', cb);
+ }
+
+ if (isDef(h) && typeof h !== 'number') {
+ return _utils.throwError.call(this, 'h must be a number', cb);
+ }
+ }
+
+ var kernel = [[1 / 16, 2 / 16, 1 / 16], [2 / 16, 4 / 16, 2 / 16], [1 / 16, 2 / 16, 1 / 16]];
+ x = x || 0;
+ y = y || 0;
+ w = isDef(w) ? w : this.bitmap.width - x;
+ h = isDef(h) ? h : this.bitmap.height - y;
+ var source = this.cloneQuiet();
+ this.scanQuiet(x, y, w, h, function (xx, yx, idx) {
+ xx = size * Math.floor(xx / size);
+ yx = size * Math.floor(yx / size);
+ var value = applyKernel(source, kernel, xx, yx);
+ this.bitmap.data[idx] = value[0];
+ this.bitmap.data[idx + 1] = value[1];
+ this.bitmap.data[idx + 2] = value[2];
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Applies a convolution kernel to the image or a region
+ * @param {array} kernel the convolution kernel
+ * @param {number} x (optional) the x position of the region to apply convolution to
+ * @param {number} y (optional) the y position of the region to apply convolution to
+ * @param {number} w (optional) the width of the region to apply convolution to
+ * @param {number} h (optional) the height of the region to apply convolution to
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ convolute: function convolute(kernel, x, y, w, h, cb) {
+ if (!Array.isArray(kernel)) return _utils.throwError.call(this, 'the kernel must be an array', cb);
+
+ if (typeof x === 'function') {
+ cb = x;
+ x = null;
+ y = null;
+ w = null;
+ h = null;
+ } else {
+ if (isDef(x) && typeof x !== 'number') {
+ return _utils.throwError.call(this, 'x must be a number', cb);
+ }
+
+ if (isDef(y) && typeof y !== 'number') {
+ return _utils.throwError.call(this, 'y must be a number', cb);
+ }
+
+ if (isDef(w) && typeof w !== 'number') {
+ return _utils.throwError.call(this, 'w must be a number', cb);
+ }
+
+ if (isDef(h) && typeof h !== 'number') {
+ return _utils.throwError.call(this, 'h must be a number', cb);
+ }
+ }
+
+ var ksize = (kernel.length - 1) / 2;
+ x = isDef(x) ? x : ksize;
+ y = isDef(y) ? y : ksize;
+ w = isDef(w) ? w : this.bitmap.width - x;
+ h = isDef(h) ? h : this.bitmap.height - y;
+ var source = this.cloneQuiet();
+ this.scanQuiet(x, y, w, h, function (xx, yx, idx) {
+ var value = applyKernel(source, kernel, xx, yx);
+ this.bitmap.data[idx] = this.constructor.limit255(value[0]);
+ this.bitmap.data[idx + 1] = this.constructor.limit255(value[1]);
+ this.bitmap.data[idx + 2] = this.constructor.limit255(value[2]);
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Apply multiple color modification rules
+ * @param {array} actions list of color modification rules, in following format: { apply: '', params: [ ] }
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp }this for chaining of methods
+ */
+ color: colorFn,
+ colour: colorFn
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 7125:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Scale the image to the given width and height keeping the aspect ratio. Some parts of the image may be letter boxed.
+ * @param {number} w the width to resize the image to
+ * @param {number} h the height to resize the image to
+ * @param {number} alignBits (optional) A bitmask for horizontal and vertical alignment
+ * @param {string} mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ contain: function contain(w, h, alignBits, mode, cb) {
+ if (typeof w !== 'number' || typeof h !== 'number') {
+ return _utils.throwError.call(this, 'w and h must be numbers', cb);
+ } // permit any sort of optional parameters combination
+
+
+ if (typeof alignBits === 'string') {
+ if (typeof mode === 'function' && typeof cb === 'undefined') cb = mode;
+ mode = alignBits;
+ alignBits = null;
+ }
+
+ if (typeof alignBits === 'function') {
+ if (typeof cb === 'undefined') cb = alignBits;
+ mode = null;
+ alignBits = null;
+ }
+
+ if (typeof mode === 'function' && typeof cb === 'undefined') {
+ cb = mode;
+ mode = null;
+ }
+
+ alignBits = alignBits || this.constructor.HORIZONTAL_ALIGN_CENTER | this.constructor.VERTICAL_ALIGN_MIDDLE;
+ var hbits = alignBits & (1 << 3) - 1;
+ var vbits = alignBits >> 3; // check if more flags than one is in the bit sets
+
+ if (!(hbits !== 0 && !(hbits & hbits - 1) || vbits !== 0 && !(vbits & vbits - 1))) {
+ return _utils.throwError.call(this, 'only use one flag per alignment direction', cb);
+ }
+
+ var alignH = hbits >> 1; // 0, 1, 2
+
+ var alignV = vbits >> 1; // 0, 1, 2
+
+ var f = w / h > this.bitmap.width / this.bitmap.height ? h / this.bitmap.height : w / this.bitmap.width;
+ var c = this.cloneQuiet().scale(f, mode);
+ this.resize(w, h, mode);
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ this.bitmap.data.writeUInt32BE(this._background, idx);
+ });
+ this.blit(c, (this.bitmap.width - c.bitmap.width) / 2 * alignH, (this.bitmap.height - c.bitmap.height) / 2 * alignV);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 937:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Scale the image so the given width and height keeping the aspect ratio. Some parts of the image may be clipped.
+ * @param {number} w the width to resize the image to
+ * @param {number} h the height to resize the image to
+ * @param {number} alignBits (optional) A bitmask for horizontal and vertical alignment
+ * @param {string} mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ cover: function cover(w, h, alignBits, mode, cb) {
+ if (typeof w !== 'number' || typeof h !== 'number') {
+ return _utils.throwError.call(this, 'w and h must be numbers', cb);
+ }
+
+ if (alignBits && typeof alignBits === 'function' && typeof cb === 'undefined') {
+ cb = alignBits;
+ alignBits = null;
+ mode = null;
+ } else if (typeof mode === 'function' && typeof cb === 'undefined') {
+ cb = mode;
+ mode = null;
+ }
+
+ alignBits = alignBits || this.constructor.HORIZONTAL_ALIGN_CENTER | this.constructor.VERTICAL_ALIGN_MIDDLE;
+ var hbits = alignBits & (1 << 3) - 1;
+ var vbits = alignBits >> 3; // check if more flags than one is in the bit sets
+
+ if (!(hbits !== 0 && !(hbits & hbits - 1) || vbits !== 0 && !(vbits & vbits - 1))) return _utils.throwError.call(this, 'only use one flag per alignment direction', cb);
+ var alignH = hbits >> 1; // 0, 1, 2
+
+ var alignV = vbits >> 1; // 0, 1, 2
+
+ var f = w / h > this.bitmap.width / this.bitmap.height ? w / this.bitmap.width : h / this.bitmap.height;
+ this.scale(f, mode);
+ this.crop((this.bitmap.width - w) / 2 * alignH, (this.bitmap.height - h) / 2 * alignV, w, h);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 1623:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = pluginCrop;
+
+var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605));
+
+var _utils = __nccwpck_require__(7403);
+
+/* eslint-disable no-labels */
+function pluginCrop(event) {
+ /**
+ * Crops the image at a given point to a give size
+ * @param {number} x the x coordinate to crop form
+ * @param {number} y the y coordinate to crop form
+ * @param w the width of the crop region
+ * @param h the height of the crop region
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ event('crop', function (x, y, w, h, cb) {
+ if (typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'x and y must be numbers', cb);
+ if (typeof w !== 'number' || typeof h !== 'number') return _utils.throwError.call(this, 'w and h must be numbers', cb); // round input
+
+ x = Math.round(x);
+ y = Math.round(y);
+ w = Math.round(w);
+ h = Math.round(h);
+
+ if (x === 0 && w === this.bitmap.width) {
+ // shortcut
+ var start = w * y + x << 2;
+ var end = start + h * w << 2;
+ this.bitmap.data = this.bitmap.data.slice(start, end);
+ } else {
+ var bitmap = Buffer.allocUnsafe(w * h * 4);
+ var offset = 0;
+ this.scanQuiet(x, y, w, h, function (x, y, idx) {
+ var data = this.bitmap.data.readUInt32BE(idx, true);
+ bitmap.writeUInt32BE(data, offset, true);
+ offset += 4;
+ });
+ this.bitmap.data = bitmap;
+ }
+
+ this.bitmap.width = w;
+ this.bitmap.height = h;
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ });
+ return {
+ "class": {
+ /**
+ * Autocrop same color borders from this image
+ * @param {number} tolerance (optional): a percent value of tolerance for pixels color difference (default: 0.0002%)
+ * @param {boolean} cropOnlyFrames (optional): flag to crop only real frames: all 4 sides of the image must have some border (default: true)
+ * @param {function(Error, Jimp)} cb (optional): a callback for when complete (default: no callback)
+ * @returns {Jimp} this for chaining of methods
+ */
+ autocrop: function autocrop() {
+ var w = this.bitmap.width;
+ var h = this.bitmap.height;
+ var minPixelsPerSide = 1; // to avoid cropping completely the image, resulting in an invalid 0 sized image
+
+ var cb; // callback
+
+ var leaveBorder = 0; // Amount of pixels in border to leave
+
+ var tolerance = 0.0002; // percent of color difference tolerance (default value)
+
+ var cropOnlyFrames = true; // flag to force cropping only if the image has a real "frame"
+ // i.e. all 4 sides have some border (default value)
+
+ var cropSymmetric = false; // flag to force cropping top be symmetric.
+ // i.e. north and south / east and west are cropped by the same value
+
+ var ignoreSides = {
+ north: false,
+ south: false,
+ east: false,
+ west: false
+ }; // parse arguments
+
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ for (var a = 0, len = args.length; a < len; a++) {
+ if (typeof args[a] === 'number') {
+ // tolerance value passed
+ tolerance = args[a];
+ }
+
+ if (typeof args[a] === 'boolean') {
+ // cropOnlyFrames value passed
+ cropOnlyFrames = args[a];
+ }
+
+ if (typeof args[a] === 'function') {
+ // callback value passed
+ cb = args[a];
+ }
+
+ if ((0, _typeof2["default"])(args[a]) === 'object') {
+ // config object passed
+ var config = args[a];
+
+ if (typeof config.tolerance !== 'undefined') {
+ tolerance = config.tolerance;
+ }
+
+ if (typeof config.cropOnlyFrames !== 'undefined') {
+ cropOnlyFrames = config.cropOnlyFrames;
+ }
+
+ if (typeof config.cropSymmetric !== 'undefined') {
+ cropSymmetric = config.cropSymmetric;
+ }
+
+ if (typeof config.leaveBorder !== 'undefined') {
+ leaveBorder = config.leaveBorder;
+ }
+
+ if (typeof config.ignoreSides !== 'undefined') {
+ ignoreSides = config.ignoreSides;
+ }
+ }
+ }
+ /**
+ * All borders must be of the same color as the top left pixel, to be cropped.
+ * It should be possible to crop borders each with a different color,
+ * but since there are many ways for corners to intersect, it would
+ * introduce unnecessary complexity to the algorithm.
+ */
+ // scan each side for same color borders
+
+
+ var colorTarget = this.getPixelColor(0, 0); // top left pixel color is the target color
+
+ var rgba1 = this.constructor.intToRGBA(colorTarget); // for north and east sides
+
+ var northPixelsToCrop = 0;
+ var eastPixelsToCrop = 0;
+ var southPixelsToCrop = 0;
+ var westPixelsToCrop = 0; // north side (scan rows from north to south)
+
+ colorTarget = this.getPixelColor(0, 0);
+
+ if (!ignoreSides.north) {
+ north: for (var y = 0; y < h - minPixelsPerSide; y++) {
+ for (var x = 0; x < w; x++) {
+ var colorXY = this.getPixelColor(x, y);
+ var rgba2 = this.constructor.intToRGBA(colorXY);
+
+ if (this.constructor.colorDiff(rgba1, rgba2) > tolerance) {
+ // this pixel is too distant from the first one: abort this side scan
+ break north;
+ }
+ } // this row contains all pixels with the same color: increment this side pixels to crop
+
+
+ northPixelsToCrop++;
+ }
+ } // east side (scan columns from east to west)
+
+
+ colorTarget = this.getPixelColor(w, 0);
+
+ if (!ignoreSides.east) {
+ east: for (var _x = 0; _x < w - minPixelsPerSide; _x++) {
+ for (var _y = 0 + northPixelsToCrop; _y < h; _y++) {
+ var _colorXY = this.getPixelColor(_x, _y);
+
+ var _rgba = this.constructor.intToRGBA(_colorXY);
+
+ if (this.constructor.colorDiff(rgba1, _rgba) > tolerance) {
+ // this pixel is too distant from the first one: abort this side scan
+ break east;
+ }
+ } // this column contains all pixels with the same color: increment this side pixels to crop
+
+
+ eastPixelsToCrop++;
+ }
+ } // south side (scan rows from south to north)
+
+
+ colorTarget = this.getPixelColor(0, h);
+
+ if (!ignoreSides.south) {
+ south: for (var _y2 = h - 1; _y2 >= northPixelsToCrop + minPixelsPerSide; _y2--) {
+ for (var _x2 = w - eastPixelsToCrop - 1; _x2 >= 0; _x2--) {
+ var _colorXY2 = this.getPixelColor(_x2, _y2);
+
+ var _rgba2 = this.constructor.intToRGBA(_colorXY2);
+
+ if (this.constructor.colorDiff(rgba1, _rgba2) > tolerance) {
+ // this pixel is too distant from the first one: abort this side scan
+ break south;
+ }
+ } // this row contains all pixels with the same color: increment this side pixels to crop
+
+
+ southPixelsToCrop++;
+ }
+ } // west side (scan columns from west to east)
+
+
+ colorTarget = this.getPixelColor(w, h);
+
+ if (!ignoreSides.west) {
+ west: for (var _x3 = w - 1; _x3 >= 0 + eastPixelsToCrop + minPixelsPerSide; _x3--) {
+ for (var _y3 = h - 1; _y3 >= 0 + northPixelsToCrop; _y3--) {
+ var _colorXY3 = this.getPixelColor(_x3, _y3);
+
+ var _rgba3 = this.constructor.intToRGBA(_colorXY3);
+
+ if (this.constructor.colorDiff(rgba1, _rgba3) > tolerance) {
+ // this pixel is too distant from the first one: abort this side scan
+ break west;
+ }
+ } // this column contains all pixels with the same color: increment this side pixels to crop
+
+
+ westPixelsToCrop++;
+ }
+ } // decide if a crop is needed
+
+
+ var doCrop = false; // apply leaveBorder
+
+ westPixelsToCrop -= leaveBorder;
+ eastPixelsToCrop -= leaveBorder;
+ northPixelsToCrop -= leaveBorder;
+ southPixelsToCrop -= leaveBorder;
+
+ if (cropSymmetric) {
+ var horizontal = Math.min(eastPixelsToCrop, westPixelsToCrop);
+ var vertical = Math.min(northPixelsToCrop, southPixelsToCrop);
+ westPixelsToCrop = horizontal;
+ eastPixelsToCrop = horizontal;
+ northPixelsToCrop = vertical;
+ southPixelsToCrop = vertical;
+ } // make sure that crops are >= 0
+
+
+ westPixelsToCrop = westPixelsToCrop >= 0 ? westPixelsToCrop : 0;
+ eastPixelsToCrop = eastPixelsToCrop >= 0 ? eastPixelsToCrop : 0;
+ northPixelsToCrop = northPixelsToCrop >= 0 ? northPixelsToCrop : 0;
+ southPixelsToCrop = southPixelsToCrop >= 0 ? southPixelsToCrop : 0; // safety checks
+
+ var widthOfRemainingPixels = w - (westPixelsToCrop + eastPixelsToCrop);
+ var heightOfRemainingPixels = h - (southPixelsToCrop + northPixelsToCrop);
+
+ if (cropOnlyFrames) {
+ // crop image if all sides should be cropped
+ doCrop = eastPixelsToCrop !== 0 && northPixelsToCrop !== 0 && westPixelsToCrop !== 0 && southPixelsToCrop !== 0;
+ } else {
+ // crop image if at least one side should be cropped
+ doCrop = eastPixelsToCrop !== 0 || northPixelsToCrop !== 0 || westPixelsToCrop !== 0 || southPixelsToCrop !== 0;
+ }
+
+ if (doCrop) {
+ // do the real crop
+ this.crop(eastPixelsToCrop, northPixelsToCrop, widthOfRemainingPixels, heightOfRemainingPixels);
+ }
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ }
+ };
+}
+
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 6096:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605));
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Displaces the image based on the provided displacement map
+ * @param {object} map the source Jimp instance
+ * @param {number} offset the maximum displacement value
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ displace: function displace(map, offset, cb) {
+ if ((0, _typeof2["default"])(map) !== 'object' || map.constructor !== this.constructor) {
+ return _utils.throwError.call(this, 'The source must be a Jimp image', cb);
+ }
+
+ if (typeof offset !== 'number') {
+ return _utils.throwError.call(this, 'factor must be a number', cb);
+ }
+
+ var source = this.cloneQuiet();
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var displacement = map.bitmap.data[idx] / 256 * offset;
+ displacement = Math.round(displacement);
+ var ids = this.getPixelIndex(x + displacement, y);
+ this.bitmap.data[ids] = source.bitmap.data[idx];
+ this.bitmap.data[ids + 1] = source.bitmap.data[idx + 1];
+ this.bitmap.data[ids + 2] = source.bitmap.data[idx + 2];
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 5808:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Apply a ordered dithering effect
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+function dither(cb) {
+ var rgb565Matrix = [1, 9, 3, 11, 13, 5, 15, 7, 4, 12, 2, 10, 16, 8, 14, 6];
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var thresholdId = ((y & 3) << 2) + x % 4;
+ var dither = rgb565Matrix[thresholdId];
+ this.bitmap.data[idx] = Math.min(this.bitmap.data[idx] + dither, 0xff);
+ this.bitmap.data[idx + 1] = Math.min(this.bitmap.data[idx + 1] + dither, 0xff);
+ this.bitmap.data[idx + 2] = Math.min(this.bitmap.data[idx + 2] + dither, 0xff);
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+}
+
+var _default = function _default() {
+ return {
+ dither565: dither,
+ dither16: dither
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 1885:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Creates a circle out of an image.
+ * @param {object} options (optional) r: radius of effect
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ fisheye: function fisheye() {
+ var _this = this;
+
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
+ r: 2.5
+ };
+ var cb = arguments.length > 1 ? arguments[1] : undefined;
+
+ if (typeof options === 'function') {
+ cb = options;
+ options = {
+ r: 2.5
+ };
+ }
+
+ var source = this.cloneQuiet();
+ var _source$bitmap = source.bitmap,
+ width = _source$bitmap.width,
+ height = _source$bitmap.height;
+ source.scanQuiet(0, 0, width, height, function (x, y) {
+ var hx = x / width;
+ var hy = y / height;
+ var r = Math.sqrt(Math.pow(hx - 0.5, 2) + Math.pow(hy - 0.5, 2));
+ var rn = 2 * Math.pow(r, options.r);
+ var cosA = (hx - 0.5) / r;
+ var sinA = (hy - 0.5) / r;
+ var newX = Math.round((rn * cosA + 0.5) * width);
+ var newY = Math.round((rn * sinA + 0.5) * height);
+ var color = source.getPixelColor(newX, newY);
+
+ _this.setPixelColor(color, x, y);
+ });
+ /* Set center pixel color, otherwise it will be transparent */
+
+ this.setPixelColor(source.getPixelColor(width / 2, height / 2), width / 2, height / 2);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 2818:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Flip the image horizontally
+ * @param {boolean} horizontal a Boolean, if true the image will be flipped horizontally
+ * @param {boolean} vertical a Boolean, if true the image will be flipped vertically
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+function flipFn(horizontal, vertical, cb) {
+ if (typeof horizontal !== 'boolean' || typeof vertical !== 'boolean') return _utils.throwError.call(this, 'horizontal and vertical must be Booleans', cb);
+ var bitmap = Buffer.alloc(this.bitmap.data.length);
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var _x = horizontal ? this.bitmap.width - 1 - x : x;
+
+ var _y = vertical ? this.bitmap.height - 1 - y : y;
+
+ var _idx = this.bitmap.width * _y + _x << 2;
+
+ var data = this.bitmap.data.readUInt32BE(idx);
+ bitmap.writeUInt32BE(data, _idx);
+ });
+ this.bitmap.data = Buffer.from(bitmap);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+}
+
+var _default = function _default() {
+ return {
+ flip: flipFn,
+ mirror: flipFn
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 2135:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Applies a true Gaussian blur to the image (warning: this is VERY slow)
+ * @param {number} r the pixel radius of the blur
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ gaussian: function gaussian(r, cb) {
+ // http://blog.ivank.net/fastest-gaussian-blur.html
+ if (typeof r !== 'number') {
+ return _utils.throwError.call(this, 'r must be a number', cb);
+ }
+
+ if (r < 1) {
+ return _utils.throwError.call(this, 'r must be greater than 0', cb);
+ }
+
+ var rs = Math.ceil(r * 2.57); // significant radius
+
+ var range = rs * 2 + 1;
+ var rr2 = r * r * 2;
+ var rr2pi = rr2 * Math.PI;
+ var weights = [];
+
+ for (var y = 0; y < range; y++) {
+ weights[y] = [];
+
+ for (var x = 0; x < range; x++) {
+ var dsq = Math.pow(x - rs, 2) + Math.pow(y - rs, 2);
+ weights[y][x] = Math.exp(-dsq / rr2) / rr2pi;
+ }
+ }
+
+ for (var _y = 0; _y < this.bitmap.height; _y++) {
+ for (var _x = 0; _x < this.bitmap.width; _x++) {
+ var red = 0;
+ var green = 0;
+ var blue = 0;
+ var alpha = 0;
+ var wsum = 0;
+
+ for (var iy = 0; iy < range; iy++) {
+ for (var ix = 0; ix < range; ix++) {
+ var x1 = Math.min(this.bitmap.width - 1, Math.max(0, ix + _x - rs));
+ var y1 = Math.min(this.bitmap.height - 1, Math.max(0, iy + _y - rs));
+ var weight = weights[iy][ix];
+
+ var _idx = y1 * this.bitmap.width + x1 << 2;
+
+ red += this.bitmap.data[_idx] * weight;
+ green += this.bitmap.data[_idx + 1] * weight;
+ blue += this.bitmap.data[_idx + 2] * weight;
+ alpha += this.bitmap.data[_idx + 3] * weight;
+ wsum += weight;
+ }
+
+ var idx = _y * this.bitmap.width + _x << 2;
+ this.bitmap.data[idx] = Math.round(red / wsum);
+ this.bitmap.data[idx + 1] = Math.round(green / wsum);
+ this.bitmap.data[idx + 2] = Math.round(blue / wsum);
+ this.bitmap.data[idx + 3] = Math.round(alpha / wsum);
+ }
+ }
+ }
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 9534:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Inverts the image
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ invert: function invert(cb) {
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ this.bitmap.data[idx] = 255 - this.bitmap.data[idx];
+ this.bitmap.data[idx + 1] = 255 - this.bitmap.data[idx + 1];
+ this.bitmap.data[idx + 2] = 255 - this.bitmap.data[idx + 2];
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 497:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Masks a source image on to this image using average pixel colour. A completely black pixel on the mask will turn a pixel in the image completely transparent.
+ * @param {Jimp} src the source Jimp instance
+ * @param {number} x the horizontal position to blit the image
+ * @param {number} y the vertical position to blit the image
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ mask: function mask(src) {
+ var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
+ var y = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
+ var cb = arguments.length > 3 ? arguments[3] : undefined;
+
+ if (!(src instanceof this.constructor)) {
+ return _utils.throwError.call(this, 'The source must be a Jimp image', cb);
+ }
+
+ if (typeof x !== 'number' || typeof y !== 'number') {
+ return _utils.throwError.call(this, 'x and y must be numbers', cb);
+ } // round input
+
+
+ x = Math.round(x);
+ y = Math.round(y);
+ var w = this.bitmap.width;
+ var h = this.bitmap.height;
+ var baseImage = this;
+ src.scanQuiet(0, 0, src.bitmap.width, src.bitmap.height, function (sx, sy, idx) {
+ var destX = x + sx;
+ var destY = y + sy;
+
+ if (destX >= 0 && destY >= 0 && destX < w && destY < h) {
+ var dstIdx = baseImage.getPixelIndex(destX, destY);
+ var data = this.bitmap.data;
+ var avg = (data[idx + 0] + data[idx + 1] + data[idx + 2]) / 3;
+ baseImage.bitmap.data[dstIdx + 3] *= avg / 255;
+ }
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 7022:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Get an image's histogram
+ * @return {object} An object with an array of color occurrence counts for each channel (r,g,b)
+ */
+function histogram() {
+ var histogram = {
+ r: new Array(256).fill(0),
+ g: new Array(256).fill(0),
+ b: new Array(256).fill(0)
+ };
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, index) {
+ histogram.r[this.bitmap.data[index + 0]]++;
+ histogram.g[this.bitmap.data[index + 1]]++;
+ histogram.b[this.bitmap.data[index + 2]]++;
+ });
+ return histogram;
+}
+/**
+ * Normalize values
+ * @param {integer} value Pixel channel value.
+ * @param {integer} min Minimum value for channel
+ * @param {integer} max Maximum value for channel
+ * @return {integer} normalized values
+ */
+
+
+var _normalize = function normalize(value, min, max) {
+ return (value - min) * 255 / (max - min);
+};
+
+var getBounds = function getBounds(histogramChannel) {
+ return [histogramChannel.findIndex(function (value) {
+ return value > 0;
+ }), 255 - histogramChannel.slice().reverse().findIndex(function (value) {
+ return value > 0;
+ })];
+};
+/**
+ * Normalizes the image
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+
+
+var _default = function _default() {
+ return {
+ normalize: function normalize(cb) {
+ var h = histogram.call(this); // store bounds (minimum and maximum values)
+
+ var bounds = {
+ r: getBounds(h.r),
+ g: getBounds(h.g),
+ b: getBounds(h.b)
+ }; // apply value transformations
+
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var r = this.bitmap.data[idx + 0];
+ var g = this.bitmap.data[idx + 1];
+ var b = this.bitmap.data[idx + 2];
+ this.bitmap.data[idx + 0] = _normalize(r, bounds.r[0], bounds.r[1]);
+ this.bitmap.data[idx + 1] = _normalize(g, bounds.g[0], bounds.g[1]);
+ this.bitmap.data[idx + 2] = _normalize(b, bounds.b[0], bounds.b[1]);
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 7996:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605));
+
+var _toConsumableArray2 = _interopRequireDefault(__nccwpck_require__(3195));
+
+var _path = _interopRequireDefault(__nccwpck_require__(1017));
+
+var _loadBmfont = _interopRequireDefault(__nccwpck_require__(9919));
+
+var _utils = __nccwpck_require__(7403);
+
+var _measureText = __nccwpck_require__(4803);
+
+function xOffsetBasedOnAlignment(constants, font, line, maxWidth, alignment) {
+ if (alignment === constants.HORIZONTAL_ALIGN_LEFT) {
+ return 0;
+ }
+
+ if (alignment === constants.HORIZONTAL_ALIGN_CENTER) {
+ return (maxWidth - (0, _measureText.measureText)(font, line)) / 2;
+ }
+
+ return maxWidth - (0, _measureText.measureText)(font, line);
+}
+
+function drawCharacter(image, font, x, y, _char) {
+ if (_char.width > 0 && _char.height > 0) {
+ var characterPage = font.pages[_char.page];
+ image.blit(characterPage, x + _char.xoffset, y + _char.yoffset, _char.x, _char.y, _char.width, _char.height);
+ }
+
+ return image;
+}
+
+function printText(font, x, y, text, defaultCharWidth) {
+ for (var i = 0; i < text.length; i++) {
+ var _char2 = void 0;
+
+ if (font.chars[text[i]]) {
+ _char2 = text[i];
+ } else if (/\s/.test(text[i])) {
+ _char2 = '';
+ } else {
+ _char2 = '?';
+ }
+
+ var fontChar = font.chars[_char2] || {};
+ var fontKerning = font.kernings[_char2];
+ drawCharacter(this, font, x, y, fontChar || {});
+ var kerning = fontKerning && fontKerning[text[i + 1]] ? fontKerning[text[i + 1]] : 0;
+ x += kerning + (fontChar.xadvance || defaultCharWidth);
+ }
+}
+
+function splitLines(font, text, maxWidth) {
+ var words = text.split(' ');
+ var lines = [];
+ var currentLine = [];
+ var longestLine = 0;
+ words.forEach(function (word) {
+ var line = [].concat((0, _toConsumableArray2["default"])(currentLine), [word]).join(' ');
+ var length = (0, _measureText.measureText)(font, line);
+
+ if (length <= maxWidth) {
+ if (length > longestLine) {
+ longestLine = length;
+ }
+
+ currentLine.push(word);
+ } else {
+ lines.push(currentLine);
+ currentLine = [word];
+ }
+ });
+ lines.push(currentLine);
+ return {
+ lines: lines,
+ longestLine: longestLine
+ };
+}
+
+function loadPages(Jimp, dir, pages) {
+ var newPages = pages.map(function (page) {
+ return Jimp.read(dir + '/' + page);
+ });
+ return Promise.all(newPages);
+}
+
+var dir = process.env.DIRNAME || "".concat(__dirname, "/../");
+
+var _default = function _default() {
+ return {
+ constants: {
+ measureText: _measureText.measureText,
+ measureTextHeight: _measureText.measureTextHeight,
+ FONT_SANS_8_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-8-black/open-sans-8-black.fnt'),
+ FONT_SANS_10_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-10-black/open-sans-10-black.fnt'),
+ FONT_SANS_12_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-12-black/open-sans-12-black.fnt'),
+ FONT_SANS_14_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-14-black/open-sans-14-black.fnt'),
+ FONT_SANS_16_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-16-black/open-sans-16-black.fnt'),
+ FONT_SANS_32_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-32-black/open-sans-32-black.fnt'),
+ FONT_SANS_64_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-64-black/open-sans-64-black.fnt'),
+ FONT_SANS_128_BLACK: _path["default"].join(dir, 'fonts/open-sans/open-sans-128-black/open-sans-128-black.fnt'),
+ FONT_SANS_8_WHITE: _path["default"].join(dir, 'fonts/open-sans/open-sans-8-white/open-sans-8-white.fnt'),
+ FONT_SANS_16_WHITE: _path["default"].join(dir, 'fonts/open-sans/open-sans-16-white/open-sans-16-white.fnt'),
+ FONT_SANS_32_WHITE: _path["default"].join(dir, 'fonts/open-sans/open-sans-32-white/open-sans-32-white.fnt'),
+ FONT_SANS_64_WHITE: _path["default"].join(dir, 'fonts/open-sans/open-sans-64-white/open-sans-64-white.fnt'),
+ FONT_SANS_128_WHITE: _path["default"].join(dir, 'fonts/open-sans/open-sans-128-white/open-sans-128-white.fnt'),
+
+ /**
+ * Loads a bitmap font from a file
+ * @param {string} file the file path of a .fnt file
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the font is loaded
+ * @returns {Promise} a promise
+ */
+ loadFont: function loadFont(file, cb) {
+ var _this = this;
+
+ if (typeof file !== 'string') return _utils.throwError.call(this, 'file must be a string', cb);
+ return new Promise(function (resolve, reject) {
+ cb = cb || function (err, font) {
+ if (err) reject(err);else resolve(font);
+ };
+
+ (0, _loadBmfont["default"])(file, function (err, font) {
+ var chars = {};
+ var kernings = {};
+
+ if (err) {
+ return _utils.throwError.call(_this, err, cb);
+ }
+
+ for (var i = 0; i < font.chars.length; i++) {
+ chars[String.fromCharCode(font.chars[i].id)] = font.chars[i];
+ }
+
+ for (var _i = 0; _i < font.kernings.length; _i++) {
+ var firstString = String.fromCharCode(font.kernings[_i].first);
+ kernings[firstString] = kernings[firstString] || {};
+ kernings[firstString][String.fromCharCode(font.kernings[_i].second)] = font.kernings[_i].amount;
+ }
+
+ loadPages(_this, _path["default"].dirname(file), font.pages).then(function (pages) {
+ cb(null, {
+ chars: chars,
+ kernings: kernings,
+ pages: pages,
+ common: font.common,
+ info: font.info
+ });
+ });
+ });
+ });
+ }
+ },
+ "class": {
+ /**
+ * Draws a text on a image on a given boundary
+ * @param {Jimp} font a bitmap font loaded from `Jimp.loadFont` command
+ * @param {number} x the x position to start drawing the text
+ * @param {number} y the y position to start drawing the text
+ * @param {any} text the text to draw (string or object with `text`, `alignmentX`, and/or `alignmentY`)
+ * @param {number} maxWidth (optional) the boundary width to draw in
+ * @param {number} maxHeight (optional) the boundary height to draw in
+ * @param {function(Error, Jimp)} cb (optional) a function to call when the text is written
+ * @returns {Jimp} this for chaining of methods
+ */
+ print: function print(font, x, y, text, maxWidth, maxHeight, cb) {
+ var _this2 = this;
+
+ if (typeof maxWidth === 'function' && typeof cb === 'undefined') {
+ cb = maxWidth;
+ maxWidth = Infinity;
+ }
+
+ if (typeof maxWidth === 'undefined') {
+ maxWidth = Infinity;
+ }
+
+ if (typeof maxHeight === 'function' && typeof cb === 'undefined') {
+ cb = maxHeight;
+ maxHeight = Infinity;
+ }
+
+ if (typeof maxHeight === 'undefined') {
+ maxHeight = Infinity;
+ }
+
+ if ((0, _typeof2["default"])(font) !== 'object') {
+ return _utils.throwError.call(this, 'font must be a Jimp loadFont', cb);
+ }
+
+ if (typeof x !== 'number' || typeof y !== 'number' || typeof maxWidth !== 'number') {
+ return _utils.throwError.call(this, 'x, y and maxWidth must be numbers', cb);
+ }
+
+ if (typeof maxWidth !== 'number') {
+ return _utils.throwError.call(this, 'maxWidth must be a number', cb);
+ }
+
+ if (typeof maxHeight !== 'number') {
+ return _utils.throwError.call(this, 'maxHeight must be a number', cb);
+ }
+
+ var alignmentX;
+ var alignmentY;
+
+ if ((0, _typeof2["default"])(text) === 'object' && text.text !== null && text.text !== undefined) {
+ alignmentX = text.alignmentX || this.constructor.HORIZONTAL_ALIGN_LEFT;
+ alignmentY = text.alignmentY || this.constructor.VERTICAL_ALIGN_TOP;
+ var _text = text;
+ text = _text.text;
+ } else {
+ alignmentX = this.constructor.HORIZONTAL_ALIGN_LEFT;
+ alignmentY = this.constructor.VERTICAL_ALIGN_TOP;
+ text = text.toString();
+ }
+
+ if (maxHeight !== Infinity && alignmentY === this.constructor.VERTICAL_ALIGN_BOTTOM) {
+ y += maxHeight - (0, _measureText.measureTextHeight)(font, text, maxWidth);
+ } else if (maxHeight !== Infinity && alignmentY === this.constructor.VERTICAL_ALIGN_MIDDLE) {
+ y += maxHeight / 2 - (0, _measureText.measureTextHeight)(font, text, maxWidth) / 2;
+ }
+
+ var defaultCharWidth = Object.entries(font.chars)[0][1].xadvance;
+
+ var _splitLines = splitLines(font, text, maxWidth),
+ lines = _splitLines.lines,
+ longestLine = _splitLines.longestLine;
+
+ lines.forEach(function (line) {
+ var lineString = line.join(' ');
+ var alignmentWidth = xOffsetBasedOnAlignment(_this2.constructor, font, lineString, maxWidth, alignmentX);
+ printText.call(_this2, font, x + alignmentWidth, y, lineString, defaultCharWidth);
+ y += font.common.lineHeight;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this, {
+ x: x + longestLine,
+ y: y
+ });
+ }
+
+ return this;
+ }
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 4803:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.measureText = measureText;
+exports.measureTextHeight = measureTextHeight;
+
+function measureText(font, text) {
+ var x = 0;
+
+ for (var i = 0; i < text.length; i++) {
+ if (font.chars[text[i]]) {
+ var kerning = font.kernings[text[i]] && font.kernings[text[i]][text[i + 1]] ? font.kernings[text[i]][text[i + 1]] : 0;
+ x += (font.chars[text[i]].xadvance || 0) + kerning;
+ }
+ }
+
+ return x;
+}
+
+function measureTextHeight(font, text, maxWidth) {
+ var words = text.split(' ');
+ var line = '';
+ var textTotalHeight = font.common.lineHeight;
+
+ for (var n = 0; n < words.length; n++) {
+ var testLine = line + words[n] + ' ';
+ var testWidth = measureText(font, testLine);
+
+ if (testWidth > maxWidth && n > 0) {
+ textTotalHeight += font.common.lineHeight;
+ line = words[n] + ' ';
+ } else {
+ line = testLine;
+ }
+ }
+
+ return textTotalHeight;
+}
+//# sourceMappingURL=measure-text.js.map
+
+/***/ }),
+
+/***/ 5555:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+var _resize = _interopRequireDefault(__nccwpck_require__(391));
+
+var _resize2 = _interopRequireDefault(__nccwpck_require__(1846));
+
+var _default = function _default() {
+ return {
+ constants: {
+ RESIZE_NEAREST_NEIGHBOR: 'nearestNeighbor',
+ RESIZE_BILINEAR: 'bilinearInterpolation',
+ RESIZE_BICUBIC: 'bicubicInterpolation',
+ RESIZE_HERMITE: 'hermiteInterpolation',
+ RESIZE_BEZIER: 'bezierInterpolation'
+ },
+ "class": {
+ /**
+ * Resizes the image to a set width and height using a 2-pass bilinear algorithm
+ * @param {number} w the width to resize the image to (or Jimp.AUTO)
+ * @param {number} h the height to resize the image to (or Jimp.AUTO)
+ * @param {string} mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ resize: function resize(w, h, mode, cb) {
+ if (typeof w !== 'number' || typeof h !== 'number') {
+ return _utils.throwError.call(this, 'w and h must be numbers', cb);
+ }
+
+ if (typeof mode === 'function' && typeof cb === 'undefined') {
+ cb = mode;
+ mode = null;
+ }
+
+ if (w === this.constructor.AUTO && h === this.constructor.AUTO) {
+ return _utils.throwError.call(this, 'w and h cannot both be set to auto', cb);
+ }
+
+ if (w === this.constructor.AUTO) {
+ w = this.bitmap.width * (h / this.bitmap.height);
+ }
+
+ if (h === this.constructor.AUTO) {
+ h = this.bitmap.height * (w / this.bitmap.width);
+ }
+
+ if (w < 0 || h < 0) {
+ return _utils.throwError.call(this, 'w and h must be positive numbers', cb);
+ } // round inputs
+
+
+ w = Math.round(w);
+ h = Math.round(h);
+
+ if (typeof _resize2["default"][mode] === 'function') {
+ var dst = {
+ data: Buffer.alloc(w * h * 4),
+ width: w,
+ height: h
+ };
+
+ _resize2["default"][mode](this.bitmap, dst);
+
+ this.bitmap = dst;
+ } else {
+ var image = this;
+ var resize = new _resize["default"](this.bitmap.width, this.bitmap.height, w, h, true, true, function (buffer) {
+ image.bitmap.data = Buffer.from(buffer);
+ image.bitmap.width = w;
+ image.bitmap.height = h;
+ });
+ resize.resize(this.bitmap.data);
+ }
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 391:
+/***/ ((module) => {
+
+"use strict";
+
+
+// JavaScript Image Resizer (c) 2012 - Grant Galitz
+// Released to public domain 29 July 2013: https://github.com/grantgalitz/JS-Image-Resizer/issues/4
+function Resize(widthOriginal, heightOriginal, targetWidth, targetHeight, blendAlpha, interpolationPass, resizeCallback) {
+ this.widthOriginal = Math.abs(Math.floor(widthOriginal) || 0);
+ this.heightOriginal = Math.abs(Math.floor(heightOriginal) || 0);
+ this.targetWidth = Math.abs(Math.floor(targetWidth) || 0);
+ this.targetHeight = Math.abs(Math.floor(targetHeight) || 0);
+ this.colorChannels = blendAlpha ? 4 : 3;
+ this.interpolationPass = Boolean(interpolationPass);
+ this.resizeCallback = typeof resizeCallback === 'function' ? resizeCallback : function () {};
+ this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
+ this.originalWidthMultipliedByChannels = this.widthOriginal * this.colorChannels;
+ this.originalHeightMultipliedByChannels = this.heightOriginal * this.colorChannels;
+ this.widthPassResultSize = this.targetWidthMultipliedByChannels * this.heightOriginal;
+ this.finalResultSize = this.targetWidthMultipliedByChannels * this.targetHeight;
+ this.initialize();
+}
+
+Resize.prototype.initialize = function () {
+ // Perform some checks:
+ if (this.widthOriginal > 0 && this.heightOriginal > 0 && this.targetWidth > 0 && this.targetHeight > 0) {
+ this.configurePasses();
+ } else {
+ throw new Error('Invalid settings specified for the resizer.');
+ }
+};
+
+Resize.prototype.configurePasses = function () {
+ if (this.widthOriginal === this.targetWidth) {
+ // Bypass the width resizer pass:
+ this.resizeWidth = this.bypassResizer;
+ } else {
+ // Setup the width resizer pass:
+ this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
+
+ if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
+ this.initializeFirstPassBuffers(true);
+ this.resizeWidth = this.colorChannels === 4 ? this.resizeWidthInterpolatedRGBA : this.resizeWidthInterpolatedRGB;
+ } else {
+ this.initializeFirstPassBuffers(false);
+ this.resizeWidth = this.colorChannels === 4 ? this.resizeWidthRGBA : this.resizeWidthRGB;
+ }
+ }
+
+ if (this.heightOriginal === this.targetHeight) {
+ // Bypass the height resizer pass:
+ this.resizeHeight = this.bypassResizer;
+ } else {
+ // Setup the height resizer pass:
+ this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
+
+ if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
+ this.initializeSecondPassBuffers(true);
+ this.resizeHeight = this.resizeHeightInterpolated;
+ } else {
+ this.initializeSecondPassBuffers(false);
+ this.resizeHeight = this.colorChannels === 4 ? this.resizeHeightRGBA : this.resizeHeightRGB;
+ }
+ }
+};
+
+Resize.prototype._resizeWidthInterpolatedRGBChannels = function (buffer, fourthChannel) {
+ var channelsNum = fourthChannel ? 4 : 3;
+ var ratioWeight = this.ratioWeightWidthPass;
+ var outputBuffer = this.widthBuffer;
+ var weight = 0;
+ var finalOffset = 0;
+ var pixelOffset = 0;
+ var firstWeight = 0;
+ var secondWeight = 0;
+ var targetPosition; // Handle for only one interpolation input being valid for start calculation:
+
+ for (targetPosition = 0; weight < 1 / 3; targetPosition += channelsNum, weight += ratioWeight) {
+ for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
+ outputBuffer[finalOffset] = buffer[pixelOffset];
+ outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
+ outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
+ if (fourthChannel) outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
+ }
+ } // Adjust for overshoot of the last pass's counter:
+
+
+ weight -= 1 / 3;
+ var interpolationWidthSourceReadStop;
+
+ for (interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += channelsNum, weight += ratioWeight) {
+ // Calculate weightings:
+ secondWeight = weight % 1;
+ firstWeight = 1 - secondWeight; // Interpolate:
+
+ for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * channelsNum; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
+ outputBuffer[finalOffset + 0] = buffer[pixelOffset + 0] * firstWeight + buffer[pixelOffset + channelsNum + 0] * secondWeight;
+ outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1] * firstWeight + buffer[pixelOffset + channelsNum + 1] * secondWeight;
+ outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2] * firstWeight + buffer[pixelOffset + channelsNum + 2] * secondWeight;
+ if (fourthChannel) outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3] * firstWeight + buffer[pixelOffset + channelsNum + 3] * secondWeight;
+ }
+ } // Handle for only one interpolation input being valid for end calculation:
+
+
+ for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - channelsNum; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += channelsNum) {
+ for (finalOffset = targetPosition, pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
+ outputBuffer[finalOffset] = buffer[pixelOffset];
+ outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
+ outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
+ if (fourthChannel) outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
+ }
+ }
+
+ return outputBuffer;
+};
+
+Resize.prototype._resizeWidthRGBChannels = function (buffer, fourthChannel) {
+ var channelsNum = fourthChannel ? 4 : 3;
+ var ratioWeight = this.ratioWeightWidthPass;
+ var ratioWeightDivisor = 1 / ratioWeight;
+ var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - channelsNum + 1;
+ var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - channelsNum + 1;
+ var output = this.outputWidthWorkBench;
+ var outputBuffer = this.widthBuffer;
+ var trustworthyColorsCount = this.outputWidthWorkBenchOpaquePixelsCount;
+ var weight = 0;
+ var amountToNext = 0;
+ var actualPosition = 0;
+ var currentPosition = 0;
+ var line = 0;
+ var pixelOffset = 0;
+ var outputOffset = 0;
+ var multiplier = 1;
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ var a = 0;
+
+ do {
+ for (line = 0; line < this.originalHeightMultipliedByChannels;) {
+ output[line++] = 0;
+ output[line++] = 0;
+ output[line++] = 0;
+
+ if (fourthChannel) {
+ output[line++] = 0;
+ trustworthyColorsCount[line / channelsNum - 1] = 0;
+ }
+ }
+
+ weight = ratioWeight;
+
+ do {
+ amountToNext = 1 + actualPosition - currentPosition;
+ multiplier = Math.min(weight, amountToNext);
+
+ for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
+ r = buffer[pixelOffset];
+ g = buffer[++pixelOffset];
+ b = buffer[++pixelOffset];
+ a = fourthChannel ? buffer[++pixelOffset] : 255; // Ignore RGB values if pixel is completely transparent
+
+ output[line++] += (a ? r : 0) * multiplier;
+ output[line++] += (a ? g : 0) * multiplier;
+ output[line++] += (a ? b : 0) * multiplier;
+
+ if (fourthChannel) {
+ output[line++] += a * multiplier;
+ trustworthyColorsCount[line / channelsNum - 1] += a ? multiplier : 0;
+ }
+ }
+
+ if (weight >= amountToNext) {
+ actualPosition += channelsNum;
+ currentPosition = actualPosition;
+ weight -= amountToNext;
+ } else {
+ currentPosition += weight;
+ break;
+ }
+ } while (weight > 0 && actualPosition < this.originalWidthMultipliedByChannels);
+
+ for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
+ weight = fourthChannel ? trustworthyColorsCount[line / channelsNum] : 1;
+ multiplier = fourthChannel ? weight ? 1 / weight : 0 : ratioWeightDivisor;
+ outputBuffer[pixelOffset] = output[line++] * multiplier;
+ outputBuffer[++pixelOffset] = output[line++] * multiplier;
+ outputBuffer[++pixelOffset] = output[line++] * multiplier;
+ if (fourthChannel) outputBuffer[++pixelOffset] = output[line++] * ratioWeightDivisor;
+ }
+
+ outputOffset += channelsNum;
+ } while (outputOffset < this.targetWidthMultipliedByChannels);
+
+ return outputBuffer;
+};
+
+Resize.prototype._resizeHeightRGBChannels = function (buffer, fourthChannel) {
+ var ratioWeight = this.ratioWeightHeightPass;
+ var ratioWeightDivisor = 1 / ratioWeight;
+ var output = this.outputHeightWorkBench;
+ var outputBuffer = this.heightBuffer;
+ var trustworthyColorsCount = this.outputHeightWorkBenchOpaquePixelsCount;
+ var weight = 0;
+ var amountToNext = 0;
+ var actualPosition = 0;
+ var currentPosition = 0;
+ var pixelOffset = 0;
+ var outputOffset = 0;
+ var caret = 0;
+ var multiplier = 1;
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ var a = 0;
+
+ do {
+ for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
+ output[pixelOffset++] = 0;
+ output[pixelOffset++] = 0;
+ output[pixelOffset++] = 0;
+
+ if (fourthChannel) {
+ output[pixelOffset++] = 0;
+ trustworthyColorsCount[pixelOffset / 4 - 1] = 0;
+ }
+ }
+
+ weight = ratioWeight;
+
+ do {
+ amountToNext = 1 + actualPosition - currentPosition;
+ multiplier = Math.min(weight, amountToNext);
+ caret = actualPosition;
+
+ for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
+ r = buffer[caret++];
+ g = buffer[caret++];
+ b = buffer[caret++];
+ a = fourthChannel ? buffer[caret++] : 255; // Ignore RGB values if pixel is completely transparent
+
+ output[pixelOffset++] += (a ? r : 0) * multiplier;
+ output[pixelOffset++] += (a ? g : 0) * multiplier;
+ output[pixelOffset++] += (a ? b : 0) * multiplier;
+
+ if (fourthChannel) {
+ output[pixelOffset++] += a * multiplier;
+ trustworthyColorsCount[pixelOffset / 4 - 1] += a ? multiplier : 0;
+ }
+ }
+
+ if (weight >= amountToNext) {
+ actualPosition = caret;
+ currentPosition = actualPosition;
+ weight -= amountToNext;
+ } else {
+ currentPosition += weight;
+ break;
+ }
+ } while (weight > 0 && actualPosition < this.widthPassResultSize);
+
+ for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
+ weight = fourthChannel ? trustworthyColorsCount[pixelOffset / 4] : 1;
+ multiplier = fourthChannel ? weight ? 1 / weight : 0 : ratioWeightDivisor;
+ outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
+ outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
+ outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
+
+ if (fourthChannel) {
+ outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
+ }
+ }
+ } while (outputOffset < this.finalResultSize);
+
+ return outputBuffer;
+};
+
+Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) {
+ return this._resizeWidthInterpolatedRGBChannels(buffer, false);
+};
+
+Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) {
+ return this._resizeWidthInterpolatedRGBChannels(buffer, true);
+};
+
+Resize.prototype.resizeWidthRGB = function (buffer) {
+ return this._resizeWidthRGBChannels(buffer, false);
+};
+
+Resize.prototype.resizeWidthRGBA = function (buffer) {
+ return this._resizeWidthRGBChannels(buffer, true);
+};
+
+Resize.prototype.resizeHeightInterpolated = function (buffer) {
+ var ratioWeight = this.ratioWeightHeightPass;
+ var outputBuffer = this.heightBuffer;
+ var weight = 0;
+ var finalOffset = 0;
+ var pixelOffset = 0;
+ var pixelOffsetAccumulated = 0;
+ var pixelOffsetAccumulated2 = 0;
+ var firstWeight = 0;
+ var secondWeight = 0;
+ var interpolationHeightSourceReadStop; // Handle for only one interpolation input being valid for start calculation:
+
+ for (; weight < 1 / 3; weight += ratioWeight) {
+ for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
+ outputBuffer[finalOffset++] = Math.round(buffer[pixelOffset++]);
+ }
+ } // Adjust for overshoot of the last pass's counter:
+
+
+ weight -= 1 / 3;
+
+ for (interpolationHeightSourceReadStop = this.heightOriginal - 1; weight < interpolationHeightSourceReadStop; weight += ratioWeight) {
+ // Calculate weightings:
+ secondWeight = weight % 1;
+ firstWeight = 1 - secondWeight; // Interpolate:
+
+ pixelOffsetAccumulated = Math.floor(weight) * this.targetWidthMultipliedByChannels;
+ pixelOffsetAccumulated2 = pixelOffsetAccumulated + this.targetWidthMultipliedByChannels;
+
+ for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
+ outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++] * firstWeight + buffer[pixelOffsetAccumulated2++] * secondWeight);
+ }
+ } // Handle for only one interpolation input being valid for end calculation:
+
+
+ while (finalOffset < this.finalResultSize) {
+ for (pixelOffset = 0, pixelOffsetAccumulated = interpolationHeightSourceReadStop * this.targetWidthMultipliedByChannels; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
+ outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++]);
+ }
+ }
+
+ return outputBuffer;
+};
+
+Resize.prototype.resizeHeightRGB = function (buffer) {
+ return this._resizeHeightRGBChannels(buffer, false);
+};
+
+Resize.prototype.resizeHeightRGBA = function (buffer) {
+ return this._resizeHeightRGBChannels(buffer, true);
+};
+
+Resize.prototype.resize = function (buffer) {
+ this.resizeCallback(this.resizeHeight(this.resizeWidth(buffer)));
+};
+
+Resize.prototype.bypassResizer = function (buffer) {
+ // Just return the buffer passed:
+ return buffer;
+};
+
+Resize.prototype.initializeFirstPassBuffers = function (BILINEARAlgo) {
+ // Initialize the internal width pass buffers:
+ this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
+
+ if (!BILINEARAlgo) {
+ this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels);
+
+ if (this.colorChannels > 3) {
+ this.outputWidthWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.heightOriginal);
+ }
+ }
+};
+
+Resize.prototype.initializeSecondPassBuffers = function (BILINEARAlgo) {
+ // Initialize the internal height pass buffers:
+ this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
+
+ if (!BILINEARAlgo) {
+ this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels);
+
+ if (this.colorChannels > 3) {
+ this.outputHeightWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.targetWidth);
+ }
+ }
+};
+
+Resize.prototype.generateFloatBuffer = function (bufferLength) {
+ // Generate a float32 typed array buffer:
+ try {
+ return new Float32Array(bufferLength);
+ } catch (error) {
+ return [];
+ }
+};
+
+Resize.prototype.generateFloat64Buffer = function (bufferLength) {
+ // Generate a float64 typed array buffer:
+ try {
+ return new Float64Array(bufferLength);
+ } catch (error) {
+ return [];
+ }
+};
+
+Resize.prototype.generateUint8Buffer = function (bufferLength) {
+ // Generate a uint8 typed array buffer:
+ try {
+ return new Uint8Array(bufferLength);
+ } catch (error) {
+ return [];
+ }
+};
+
+module.exports = Resize;
+//# sourceMappingURL=resize.js.map
+
+/***/ }),
+
+/***/ 1846:
+/***/ ((module) => {
+
+"use strict";
+
+
+/**
+ * Copyright (c) 2015 Guyon Roche
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+module.exports = {
+ nearestNeighbor: function nearestNeighbor(src, dst) {
+ var wSrc = src.width;
+ var hSrc = src.height;
+ var wDst = dst.width;
+ var hDst = dst.height;
+ var bufSrc = src.data;
+ var bufDst = dst.data;
+
+ for (var i = 0; i < hDst; i++) {
+ for (var j = 0; j < wDst; j++) {
+ var posDst = (i * wDst + j) * 4;
+ var iSrc = Math.floor(i * hSrc / hDst);
+ var jSrc = Math.floor(j * wSrc / wDst);
+ var posSrc = (iSrc * wSrc + jSrc) * 4;
+ bufDst[posDst++] = bufSrc[posSrc++];
+ bufDst[posDst++] = bufSrc[posSrc++];
+ bufDst[posDst++] = bufSrc[posSrc++];
+ bufDst[posDst++] = bufSrc[posSrc++];
+ }
+ }
+ },
+ bilinearInterpolation: function bilinearInterpolation(src, dst) {
+ var wSrc = src.width;
+ var hSrc = src.height;
+ var wDst = dst.width;
+ var hDst = dst.height;
+ var bufSrc = src.data;
+ var bufDst = dst.data;
+
+ var interpolate = function interpolate(k, kMin, vMin, kMax, vMax) {
+ // special case - k is integer
+ if (kMin === kMax) {
+ return vMin;
+ }
+
+ return Math.round((k - kMin) * vMax + (kMax - k) * vMin);
+ };
+
+ var assign = function assign(pos, offset, x, xMin, xMax, y, yMin, yMax) {
+ var posMin = (yMin * wSrc + xMin) * 4 + offset;
+ var posMax = (yMin * wSrc + xMax) * 4 + offset;
+ var vMin = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]); // special case, y is integer
+
+ if (yMax === yMin) {
+ bufDst[pos + offset] = vMin;
+ } else {
+ posMin = (yMax * wSrc + xMin) * 4 + offset;
+ posMax = (yMax * wSrc + xMax) * 4 + offset;
+ var vMax = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
+ bufDst[pos + offset] = interpolate(y, yMin, vMin, yMax, vMax);
+ }
+ };
+
+ for (var i = 0; i < hDst; i++) {
+ for (var j = 0; j < wDst; j++) {
+ var posDst = (i * wDst + j) * 4; // x & y in src coordinates
+
+ var x = j * wSrc / wDst;
+ var xMin = Math.floor(x);
+ var xMax = Math.min(Math.ceil(x), wSrc - 1);
+ var y = i * hSrc / hDst;
+ var yMin = Math.floor(y);
+ var yMax = Math.min(Math.ceil(y), hSrc - 1);
+ assign(posDst, 0, x, xMin, xMax, y, yMin, yMax);
+ assign(posDst, 1, x, xMin, xMax, y, yMin, yMax);
+ assign(posDst, 2, x, xMin, xMax, y, yMin, yMax);
+ assign(posDst, 3, x, xMin, xMax, y, yMin, yMax);
+ }
+ }
+ },
+ _interpolate2D: function _interpolate2D(src, dst, options, interpolate) {
+ var bufSrc = src.data;
+ var bufDst = dst.data;
+ var wSrc = src.width;
+ var hSrc = src.height;
+ var wDst = dst.width;
+ var hDst = dst.height; // when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares
+
+ var wM = Math.max(1, Math.floor(wSrc / wDst));
+ var wDst2 = wDst * wM;
+ var hM = Math.max(1, Math.floor(hSrc / hDst));
+ var hDst2 = hDst * hM; // ===========================================================
+ // Pass 1 - interpolate rows
+ // buf1 has width of dst2 and height of src
+
+ var buf1 = Buffer.alloc(wDst2 * hSrc * 4);
+
+ for (var i = 0; i < hSrc; i++) {
+ for (var j = 0; j < wDst2; j++) {
+ // i in src coords, j in dst coords
+ // calculate x in src coords
+ // this interpolation requires 4 sample points and the two inner ones must be real
+ // the outer points can be fudged for the edges.
+ // therefore (wSrc-1)/wDst2
+ var x = j * (wSrc - 1) / wDst2;
+ var xPos = Math.floor(x);
+ var t = x - xPos;
+ var srcPos = (i * wSrc + xPos) * 4;
+ var buf1Pos = (i * wDst2 + j) * 4;
+
+ for (var k = 0; k < 4; k++) {
+ var kPos = srcPos + k;
+ var x0 = xPos > 0 ? bufSrc[kPos - 4] : 2 * bufSrc[kPos] - bufSrc[kPos + 4];
+ var x1 = bufSrc[kPos];
+ var x2 = bufSrc[kPos + 4];
+ var x3 = xPos < wSrc - 2 ? bufSrc[kPos + 8] : 2 * bufSrc[kPos + 4] - bufSrc[kPos];
+ buf1[buf1Pos + k] = interpolate(x0, x1, x2, x3, t);
+ }
+ }
+ } // this._writeFile(wDst2, hSrc, buf1, "out/buf1.jpg");
+ // ===========================================================
+ // Pass 2 - interpolate columns
+ // buf2 has width and height of dst2
+
+
+ var buf2 = Buffer.alloc(wDst2 * hDst2 * 4);
+
+ for (var _i = 0; _i < hDst2; _i++) {
+ for (var _j = 0; _j < wDst2; _j++) {
+ // i&j in dst2 coords
+ // calculate y in buf1 coords
+ // this interpolation requires 4 sample points and the two inner ones must be real
+ // the outer points can be fudged for the edges.
+ // therefore (hSrc-1)/hDst2
+ var y = _i * (hSrc - 1) / hDst2;
+ var yPos = Math.floor(y);
+
+ var _t = y - yPos;
+
+ var _buf1Pos = (yPos * wDst2 + _j) * 4;
+
+ var buf2Pos = (_i * wDst2 + _j) * 4;
+
+ for (var _k = 0; _k < 4; _k++) {
+ var _kPos = _buf1Pos + _k;
+
+ var y0 = yPos > 0 ? buf1[_kPos - wDst2 * 4] : 2 * buf1[_kPos] - buf1[_kPos + wDst2 * 4];
+ var y1 = buf1[_kPos];
+ var y2 = buf1[_kPos + wDst2 * 4];
+ var y3 = yPos < hSrc - 2 ? buf1[_kPos + wDst2 * 8] : 2 * buf1[_kPos + wDst2 * 4] - buf1[_kPos];
+ buf2[buf2Pos + _k] = interpolate(y0, y1, y2, y3, _t);
+ }
+ }
+ } // this._writeFile(wDst2, hDst2, buf2, "out/buf2.jpg");
+ // ===========================================================
+ // Pass 3 - scale to dst
+
+
+ var m = wM * hM;
+
+ if (m > 1) {
+ for (var _i2 = 0; _i2 < hDst; _i2++) {
+ for (var _j2 = 0; _j2 < wDst; _j2++) {
+ // i&j in dst bounded coords
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ var a = 0;
+ var realColors = 0;
+
+ for (var _y = 0; _y < hM; _y++) {
+ var _yPos = _i2 * hM + _y;
+
+ for (var _x = 0; _x < wM; _x++) {
+ var _xPos = _j2 * wM + _x;
+
+ var xyPos = (_yPos * wDst2 + _xPos) * 4;
+ var pixelAlpha = buf2[xyPos + 3];
+
+ if (pixelAlpha) {
+ r += buf2[xyPos];
+ g += buf2[xyPos + 1];
+ b += buf2[xyPos + 2];
+ realColors++;
+ }
+
+ a += pixelAlpha;
+ }
+ }
+
+ var pos = (_i2 * wDst + _j2) * 4;
+ bufDst[pos] = realColors ? Math.round(r / realColors) : 0;
+ bufDst[pos + 1] = realColors ? Math.round(g / realColors) : 0;
+ bufDst[pos + 2] = realColors ? Math.round(b / realColors) : 0;
+ bufDst[pos + 3] = Math.round(a / m);
+ }
+ }
+ } else {
+ // replace dst buffer with buf2
+ dst.data = buf2;
+ }
+ },
+ bicubicInterpolation: function bicubicInterpolation(src, dst, options) {
+ var interpolateCubic = function interpolateCubic(x0, x1, x2, x3, t) {
+ var a0 = x3 - x2 - x0 + x1;
+ var a1 = x0 - x1 - a0;
+ var a2 = x2 - x0;
+ var a3 = x1;
+ return Math.max(0, Math.min(255, a0 * (t * t * t) + a1 * (t * t) + a2 * t + a3));
+ };
+
+ return this._interpolate2D(src, dst, options, interpolateCubic);
+ },
+ hermiteInterpolation: function hermiteInterpolation(src, dst, options) {
+ var interpolateHermite = function interpolateHermite(x0, x1, x2, x3, t) {
+ var c0 = x1;
+ var c1 = 0.5 * (x2 - x0);
+ var c2 = x0 - 2.5 * x1 + 2 * x2 - 0.5 * x3;
+ var c3 = 0.5 * (x3 - x0) + 1.5 * (x1 - x2);
+ return Math.max(0, Math.min(255, Math.round(((c3 * t + c2) * t + c1) * t + c0)));
+ };
+
+ return this._interpolate2D(src, dst, options, interpolateHermite);
+ },
+ bezierInterpolation: function bezierInterpolation(src, dst, options) {
+ // between 2 points y(n), y(n+1), use next points out, y(n-1), y(n+2)
+ // to predict control points (a & b) to be placed at n+0.5
+ // ya(n) = y(n) + (y(n+1)-y(n-1))/4
+ // yb(n) = y(n+1) - (y(n+2)-y(n))/4
+ // then use std bezier to interpolate [n,n+1)
+ // y(n+t) = y(n)*(1-t)^3 + 3 * ya(n)*(1-t)^2*t + 3 * yb(n)*(1-t)*t^2 + y(n+1)*t^3
+ // note the 3* factor for the two control points
+ // for edge cases, can choose:
+ // y(-1) = y(0) - 2*(y(1)-y(0))
+ // y(w) = y(w-1) + 2*(y(w-1)-y(w-2))
+ // but can go with y(-1) = y(0) and y(w) = y(w-1)
+ var interpolateBezier = function interpolateBezier(x0, x1, x2, x3, t) {
+ // x1, x2 are the knots, use x0 and x3 to calculate control points
+ var cp1 = x1 + (x2 - x0) / 4;
+ var cp2 = x2 - (x3 - x1) / 4;
+ var nt = 1 - t;
+ var c0 = x1 * nt * nt * nt;
+ var c1 = 3 * cp1 * nt * nt * t;
+ var c2 = 3 * cp2 * nt * t * t;
+ var c3 = x2 * t * t * t;
+ return Math.max(0, Math.min(255, Math.round(c0 + c1 + c2 + c3)));
+ };
+
+ return this._interpolate2D(src, dst, options, interpolateBezier);
+ }
+};
+//# sourceMappingURL=resize2.js.map
+
+/***/ }),
+
+/***/ 6880:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Rotates an image clockwise by an arbitrary number of degrees. NB: 'this' must be a Jimp object.
+ * @param {number} deg the number of degrees to rotate the image by
+ * @param {string|boolean} mode (optional) resize mode or a boolean, if false then the width and height of the image will not be changed
+ */
+function advancedRotate(deg, mode) {
+ deg %= 360;
+ var rad = deg * Math.PI / 180;
+ var cosine = Math.cos(rad);
+ var sine = Math.sin(rad); // the final width and height will change if resize == true
+
+ var w = this.bitmap.width;
+ var h = this.bitmap.height;
+
+ if (mode === true || typeof mode === 'string') {
+ // resize the image to it maximum dimension and blit the existing image
+ // onto the center so that when it is rotated the image is kept in bounds
+ // http://stackoverflow.com/questions/3231176/how-to-get-size-of-a-rotated-rectangle
+ // Plus 1 border pixel to ensure to show all rotated result for some cases.
+ w = Math.ceil(Math.abs(this.bitmap.width * cosine) + Math.abs(this.bitmap.height * sine)) + 1;
+ h = Math.ceil(Math.abs(this.bitmap.width * sine) + Math.abs(this.bitmap.height * cosine)) + 1; // Ensure destination to have even size to a better result.
+
+ if (w % 2 !== 0) {
+ w++;
+ }
+
+ if (h % 2 !== 0) {
+ h++;
+ }
+
+ var c = this.cloneQuiet();
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ this.bitmap.data.writeUInt32BE(this._background, idx);
+ });
+ var max = Math.max(w, h, this.bitmap.width, this.bitmap.height);
+ this.resize(max, max, mode);
+ this.blit(c, this.bitmap.width / 2 - c.bitmap.width / 2, this.bitmap.height / 2 - c.bitmap.height / 2);
+ }
+
+ var bW = this.bitmap.width;
+ var bH = this.bitmap.height;
+ var dstBuffer = Buffer.alloc(this.bitmap.data.length);
+
+ function createTranslationFunction(deltaX, deltaY) {
+ return function (x, y) {
+ return {
+ x: x + deltaX,
+ y: y + deltaY
+ };
+ };
+ }
+
+ var translate2Cartesian = createTranslationFunction(-(bW / 2), -(bH / 2));
+ var translate2Screen = createTranslationFunction(bW / 2 + 0.5, bH / 2 + 0.5);
+
+ for (var y = 1; y <= bH; y++) {
+ for (var x = 1; x <= bW; x++) {
+ var cartesian = translate2Cartesian(x, y);
+ var source = translate2Screen(cosine * cartesian.x - sine * cartesian.y, cosine * cartesian.y + sine * cartesian.x);
+ var dstIdx = bW * (y - 1) + x - 1 << 2;
+
+ if (source.x >= 0 && source.x < bW && source.y >= 0 && source.y < bH) {
+ var srcIdx = (bW * (source.y | 0) + source.x | 0) << 2;
+ var pixelRGBA = this.bitmap.data.readUInt32BE(srcIdx);
+ dstBuffer.writeUInt32BE(pixelRGBA, dstIdx);
+ } else {
+ // reset off-image pixels
+ dstBuffer.writeUInt32BE(this._background, dstIdx);
+ }
+ }
+ }
+
+ this.bitmap.data = dstBuffer;
+
+ if (mode === true || typeof mode === 'string') {
+ // now crop the image to the final size
+ var _x = bW / 2 - w / 2;
+
+ var _y = bH / 2 - h / 2;
+
+ this.crop(_x, _y, w, h);
+ }
+}
+
+var _default = function _default() {
+ return {
+ /**
+ * Rotates the image clockwise by a number of degrees. By default the width and height of the image will be resized appropriately.
+ * @param {number} deg the number of degrees to rotate the image by
+ * @param {string|boolean} mode (optional) resize mode or a boolean, if false then the width and height of the image will not be changed
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ rotate: function rotate(deg, mode, cb) {
+ // enable overloading
+ if (typeof mode === 'undefined' || mode === null) {
+ // e.g. image.resize(120);
+ // e.g. image.resize(120, null, cb);
+ // e.g. image.resize(120, undefined, cb);
+ mode = true;
+ }
+
+ if (typeof mode === 'function' && typeof cb === 'undefined') {
+ // e.g. image.resize(120, cb);
+ cb = mode;
+ mode = true;
+ }
+
+ if (typeof deg !== 'number') {
+ return _utils.throwError.call(this, 'deg must be a number', cb);
+ }
+
+ if (typeof mode !== 'boolean' && typeof mode !== 'string') {
+ return _utils.throwError.call(this, 'mode must be a boolean or a string', cb);
+ }
+
+ advancedRotate.call(this, deg, mode, cb);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 8212:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+var _default = function _default() {
+ return {
+ /**
+ * Uniformly scales the image by a factor.
+ * @param {number} f the factor to scale the image by
+ * @param {string} mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ scale: function scale(f, mode, cb) {
+ if (typeof f !== 'number') {
+ return _utils.throwError.call(this, 'f must be a number', cb);
+ }
+
+ if (f < 0) {
+ return _utils.throwError.call(this, 'f must be a positive number', cb);
+ }
+
+ if (typeof mode === 'function' && typeof cb === 'undefined') {
+ cb = mode;
+ mode = null;
+ }
+
+ var w = this.bitmap.width * f;
+ var h = this.bitmap.height * f;
+ this.resize(w, h, mode);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Scale the image to the largest size that fits inside the rectangle that has the given width and height.
+ * @param {number} w the width to resize the image to
+ * @param {number} h the height to resize the image to
+ * @param {string} mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ scaleToFit: function scaleToFit(w, h, mode, cb) {
+ if (typeof w !== 'number' || typeof h !== 'number') {
+ return _utils.throwError.call(this, 'w and h must be numbers', cb);
+ }
+
+ if (typeof mode === 'function' && typeof cb === 'undefined') {
+ cb = mode;
+ mode = null;
+ }
+
+ var f = w / h > this.bitmap.width / this.bitmap.height ? h / this.bitmap.height : w / this.bitmap.width;
+ this.scale(f, mode);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 8178:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Creates a circle out of an image.
+ * @param {function(Error, Jimp)} options (optional)
+ * opacity - opacity of the shadow between 0 and 1
+ * size,- of the shadow
+ * blur - how blurry the shadow is
+ * x- x position of shadow
+ * y - y position of shadow
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ shadow: function shadow() {
+ var _this = this;
+
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var cb = arguments.length > 1 ? arguments[1] : undefined;
+
+ if (typeof options === 'function') {
+ cb = options;
+ options = {};
+ }
+
+ var _options = options,
+ _options$opacity = _options.opacity,
+ opacity = _options$opacity === void 0 ? 0.7 : _options$opacity,
+ _options$size = _options.size,
+ size = _options$size === void 0 ? 1.1 : _options$size,
+ _options$x = _options.x,
+ x = _options$x === void 0 ? -25 : _options$x,
+ _options$y = _options.y,
+ y = _options$y === void 0 ? 25 : _options$y,
+ _options$blur = _options.blur,
+ blur = _options$blur === void 0 ? 5 : _options$blur; // clone the image
+
+ var orig = this.clone();
+ var shadow = this.clone(); // turn all it's pixels black
+
+ shadow.scan(0, 0, shadow.bitmap.width, shadow.bitmap.height, function (x, y, idx) {
+ shadow.bitmap.data[idx] = 0x00;
+ shadow.bitmap.data[idx + 1] = 0x00;
+ shadow.bitmap.data[idx + 2] = 0x00; // up the opacity a little,
+
+ shadow.bitmap.data[idx + 3] = shadow.constructor.limit255(shadow.bitmap.data[idx + 3] * opacity);
+ _this.bitmap.data[idx] = 0x00;
+ _this.bitmap.data[idx + 1] = 0x00;
+ _this.bitmap.data[idx + 2] = 0x00;
+ _this.bitmap.data[idx + 3] = 0x00;
+ }); // enlarge it. This creates a "shadow".
+
+ shadow.resize(shadow.bitmap.width * size, shadow.bitmap.height * size).blur(blur); // Then blit the "shadow" onto the background and the image on top of that.
+
+ this.composite(shadow, x, y);
+ this.composite(orig, 0, 0);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 897:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _utils = __nccwpck_require__(7403);
+
+/**
+ * Applies a minimum color threshold to a greyscale image. Converts image to greyscale by default
+ * @param {number} options object
+ * max: A number auto limited between 0 - 255
+ * replace: (optional) A number auto limited between 0 - 255 (default 255)
+ * autoGreyscale: (optional) A boolean whether to apply greyscale beforehand (default true)
+ * @param {number} cb (optional) a callback for when complete
+ * @return {this} this for chaining of methods
+ */
+var _default = function _default() {
+ return {
+ threshold: function threshold(_ref, cb) {
+ var _this = this;
+
+ var max = _ref.max,
+ _ref$replace = _ref.replace,
+ replace = _ref$replace === void 0 ? 255 : _ref$replace,
+ _ref$autoGreyscale = _ref.autoGreyscale,
+ autoGreyscale = _ref$autoGreyscale === void 0 ? true : _ref$autoGreyscale;
+
+ if (typeof max !== 'number') {
+ return _utils.throwError.call(this, 'max must be a number', cb);
+ }
+
+ if (typeof replace !== 'number') {
+ return _utils.throwError.call(this, 'replace must be a number', cb);
+ }
+
+ if (typeof autoGreyscale !== 'boolean') {
+ return _utils.throwError.call(this, 'autoGreyscale must be a boolean', cb);
+ }
+
+ max = this.constructor.limit255(max);
+ replace = this.constructor.limit255(replace);
+
+ if (autoGreyscale) {
+ this.greyscale();
+ }
+
+ this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
+ var grey = _this.bitmap.data[idx] < max ? _this.bitmap.data[idx] : replace;
+ _this.bitmap.data[idx] = grey;
+ _this.bitmap.data[idx + 1] = grey;
+ _this.bitmap.data[idx + 2] = grey;
+ });
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 4976:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _toConsumableArray2 = _interopRequireDefault(__nccwpck_require__(3195));
+
+var _timm = __nccwpck_require__(3567);
+
+var _pluginBlit = _interopRequireDefault(__nccwpck_require__(1485));
+
+var _pluginBlur = _interopRequireDefault(__nccwpck_require__(6223));
+
+var _pluginCircle = _interopRequireDefault(__nccwpck_require__(2005));
+
+var _pluginColor = _interopRequireDefault(__nccwpck_require__(5432));
+
+var _pluginContain = _interopRequireDefault(__nccwpck_require__(7125));
+
+var _pluginCover = _interopRequireDefault(__nccwpck_require__(937));
+
+var _pluginCrop = _interopRequireDefault(__nccwpck_require__(1623));
+
+var _pluginDisplace = _interopRequireDefault(__nccwpck_require__(6096));
+
+var _pluginDither = _interopRequireDefault(__nccwpck_require__(5808));
+
+var _pluginFisheye = _interopRequireDefault(__nccwpck_require__(1885));
+
+var _pluginFlip = _interopRequireDefault(__nccwpck_require__(2818));
+
+var _pluginGaussian = _interopRequireDefault(__nccwpck_require__(2135));
+
+var _pluginInvert = _interopRequireDefault(__nccwpck_require__(9534));
+
+var _pluginMask = _interopRequireDefault(__nccwpck_require__(497));
+
+var _pluginNormalize = _interopRequireDefault(__nccwpck_require__(7022));
+
+var _pluginPrint = _interopRequireDefault(__nccwpck_require__(7996));
+
+var _pluginResize = _interopRequireDefault(__nccwpck_require__(5555));
+
+var _pluginRotate = _interopRequireDefault(__nccwpck_require__(6880));
+
+var _pluginScale = _interopRequireDefault(__nccwpck_require__(8212));
+
+var _pluginShadow = _interopRequireDefault(__nccwpck_require__(8178));
+
+var _pluginThreshold = _interopRequireDefault(__nccwpck_require__(897));
+
+var plugins = [_pluginBlit["default"], _pluginBlur["default"], _pluginCircle["default"], _pluginColor["default"], _pluginContain["default"], _pluginCover["default"], _pluginCrop["default"], _pluginDisplace["default"], _pluginDither["default"], _pluginFisheye["default"], _pluginFlip["default"], _pluginGaussian["default"], _pluginInvert["default"], _pluginMask["default"], _pluginNormalize["default"], _pluginPrint["default"], _pluginResize["default"], _pluginRotate["default"], _pluginScale["default"], _pluginShadow["default"], _pluginThreshold["default"]];
+
+var _default = function _default(jimpEvChange) {
+ var initializedPlugins = plugins.map(function (pluginModule) {
+ var plugin = pluginModule(jimpEvChange) || {};
+
+ if (!plugin["class"] && !plugin.constants) {
+ // Default to class function
+ plugin = {
+ "class": plugin
+ };
+ }
+
+ return plugin;
+ });
+ return _timm.mergeDeep.apply(void 0, (0, _toConsumableArray2["default"])(initializedPlugins));
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 7657:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _pngjs = __nccwpck_require__(6413);
+
+var _utils = __nccwpck_require__(7403);
+
+var MIME_TYPE = 'image/png'; // PNG filter types
+
+var PNG_FILTER_AUTO = -1;
+var PNG_FILTER_NONE = 0;
+var PNG_FILTER_SUB = 1;
+var PNG_FILTER_UP = 2;
+var PNG_FILTER_AVERAGE = 3;
+var PNG_FILTER_PATH = 4;
+
+var _default = function _default() {
+ return {
+ mime: (0, _defineProperty2["default"])({}, MIME_TYPE, ['png']),
+ constants: {
+ MIME_PNG: MIME_TYPE,
+ PNG_FILTER_AUTO: PNG_FILTER_AUTO,
+ PNG_FILTER_NONE: PNG_FILTER_NONE,
+ PNG_FILTER_SUB: PNG_FILTER_SUB,
+ PNG_FILTER_UP: PNG_FILTER_UP,
+ PNG_FILTER_AVERAGE: PNG_FILTER_AVERAGE,
+ PNG_FILTER_PATH: PNG_FILTER_PATH
+ },
+ hasAlpha: (0, _defineProperty2["default"])({}, MIME_TYPE, true),
+ decoders: (0, _defineProperty2["default"])({}, MIME_TYPE, _pngjs.PNG.sync.read),
+ encoders: (0, _defineProperty2["default"])({}, MIME_TYPE, function (data) {
+ var png = new _pngjs.PNG({
+ width: data.bitmap.width,
+ height: data.bitmap.height
+ });
+ png.data = data.bitmap.data;
+ return _pngjs.PNG.sync.write(png, {
+ width: data.bitmap.width,
+ height: data.bitmap.height,
+ deflateLevel: data._deflateLevel,
+ deflateStrategy: data._deflateStrategy,
+ filterType: data._filterType,
+ colorType: typeof data._colorType === 'number' ? data._colorType : data._rgba ? 6 : 2,
+ inputHasAlpha: data._rgba
+ });
+ }),
+ "class": {
+ _deflateLevel: 9,
+ _deflateStrategy: 3,
+ _filterType: PNG_FILTER_AUTO,
+ _colorType: null,
+
+ /**
+ * Sets the deflate level used when saving as PNG format (default is 9)
+ * @param {number} l Deflate level to use 0-9. 0 is no compression. 9 (default) is maximum compression.
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ deflateLevel: function deflateLevel(l, cb) {
+ if (typeof l !== 'number') {
+ return _utils.throwError.call(this, 'l must be a number', cb);
+ }
+
+ if (l < 0 || l > 9) {
+ return _utils.throwError.call(this, 'l must be a number 0 - 9', cb);
+ }
+
+ this._deflateLevel = Math.round(l);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Sets the deflate strategy used when saving as PNG format (default is 3)
+ * @param {number} s Deflate strategy to use 0-3.
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ deflateStrategy: function deflateStrategy(s, cb) {
+ if (typeof s !== 'number') {
+ return _utils.throwError.call(this, 's must be a number', cb);
+ }
+
+ if (s < 0 || s > 3) {
+ return _utils.throwError.call(this, 's must be a number 0 - 3', cb);
+ }
+
+ this._deflateStrategy = Math.round(s);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Sets the filter type used when saving as PNG format (default is automatic filters)
+ * @param {number} f The quality to use -1-4.
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ filterType: function filterType(f, cb) {
+ if (typeof f !== 'number') {
+ return _utils.throwError.call(this, 'n must be a number', cb);
+ }
+
+ if (f < -1 || f > 4) {
+ return _utils.throwError.call(this, 'n must be -1 (auto) or a number 0 - 4', cb);
+ }
+
+ this._filterType = Math.round(f);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ },
+
+ /**
+ * Sets the color type used when saving as PNG format
+ * @param {number} s color type to use 0, 2, 4, 6.
+ * @param {function(Error, Jimp)} cb (optional) a callback for when complete
+ * @returns {Jimp} this for chaining of methods
+ */
+ colorType: function colorType(s, cb) {
+ if (typeof s !== 'number') {
+ return _utils.throwError.call(this, 's must be a number', cb);
+ }
+
+ if (s !== 0 && s !== 2 && s !== 4 && s !== 6) {
+ return _utils.throwError.call(this, 's must be a number 0, 2, 4, 6.', cb);
+ }
+
+ this._colorType = Math.round(s);
+
+ if ((0, _utils.isNodePattern)(cb)) {
+ cb.call(this, null, this);
+ }
+
+ return this;
+ }
+ }
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 6447:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _defineProperty2 = _interopRequireDefault(__nccwpck_require__(1814));
+
+var _utif = _interopRequireDefault(__nccwpck_require__(6303));
+
+var MIME_TYPE = 'image/tiff';
+
+var _default = function _default() {
+ return {
+ mime: (0, _defineProperty2["default"])({}, MIME_TYPE, ['tiff', 'tif']),
+ constants: {
+ MIME_TIFF: MIME_TYPE
+ },
+ decoders: (0, _defineProperty2["default"])({}, MIME_TYPE, function (data) {
+ var ifds = _utif["default"].decode(data);
+
+ var page = ifds[0];
+
+ _utif["default"].decodeImages(data, ifds);
+
+ var rgba = _utif["default"].toRGBA8(page);
+
+ return {
+ data: Buffer.from(rgba),
+ width: page.t256[0],
+ height: page.t257[0]
+ };
+ }),
+ encoders: (0, _defineProperty2["default"])({}, MIME_TYPE, function (image) {
+ var tiff = _utif["default"].encodeImage(image.bitmap.data, image.bitmap.width, image.bitmap.height);
+
+ return Buffer.from(tiff);
+ })
+ };
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 770:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports["default"] = void 0;
+
+var _timm = __nccwpck_require__(3567);
+
+var _jpeg = _interopRequireDefault(__nccwpck_require__(5177));
+
+var _png = _interopRequireDefault(__nccwpck_require__(7657));
+
+var _bmp = _interopRequireDefault(__nccwpck_require__(4858));
+
+var _tiff = _interopRequireDefault(__nccwpck_require__(6447));
+
+var _gif = _interopRequireDefault(__nccwpck_require__(8257));
+
+var _default = function _default() {
+ return (0, _timm.mergeDeep)((0, _jpeg["default"])(), (0, _png["default"])(), (0, _bmp["default"])(), (0, _tiff["default"])(), (0, _gif["default"])());
+};
+
+exports["default"] = _default;
+module.exports = exports.default;
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 7403:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __nccwpck_require__(3286);
+
+Object.defineProperty(exports, "__esModule", ({
+ value: true
+}));
+exports.isNodePattern = isNodePattern;
+exports.throwError = throwError;
+exports.scan = scan;
+exports.scanIterator = scanIterator;
+
+var _regenerator = _interopRequireDefault(__nccwpck_require__(4210));
+
+var _marked =
+/*#__PURE__*/
+_regenerator["default"].mark(scanIterator);
+
+function isNodePattern(cb) {
+ if (typeof cb === 'undefined') {
+ return false;
+ }
+
+ if (typeof cb !== 'function') {
+ throw new TypeError('Callback must be a function');
+ }
+
+ return true;
+}
+
+function throwError(error, cb) {
+ if (typeof error === 'string') {
+ error = new Error(error);
+ }
+
+ if (typeof cb === 'function') {
+ return cb.call(this, error);
+ }
+
+ throw error;
+}
+
+function scan(image, x, y, w, h, f) {
+ // round input
+ x = Math.round(x);
+ y = Math.round(y);
+ w = Math.round(w);
+ h = Math.round(h);
+
+ for (var _y = y; _y < y + h; _y++) {
+ for (var _x = x; _x < x + w; _x++) {
+ var idx = image.bitmap.width * _y + _x << 2;
+ f.call(image, _x, _y, idx);
+ }
+ }
+
+ return image;
+}
+
+function scanIterator(image, x, y, w, h) {
+ var _y, _x, idx;
+
+ return _regenerator["default"].wrap(function scanIterator$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ // round input
+ x = Math.round(x);
+ y = Math.round(y);
+ w = Math.round(w);
+ h = Math.round(h);
+ _y = y;
+
+ case 5:
+ if (!(_y < y + h)) {
+ _context.next = 17;
+ break;
+ }
+
+ _x = x;
+
+ case 7:
+ if (!(_x < x + w)) {
+ _context.next = 14;
+ break;
+ }
+
+ idx = image.bitmap.width * _y + _x << 2;
+ _context.next = 11;
+ return {
+ x: _x,
+ y: _y,
+ idx: idx,
+ image: image
+ };
+
+ case 11:
+ _x++;
+ _context.next = 7;
+ break;
+
+ case 14:
+ _y++;
+ _context.next = 5;
+ break;
+
+ case 17:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _marked);
+}
+//# sourceMappingURL=index.js.map
+
+/***/ }),
+
+/***/ 8720:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var Converter = __nccwpck_require__(1605);
+
+/**
+ * Function get source and destination alphabet and return convert function
+ *
+ * @param {string|Array} srcAlphabet
+ * @param {string|Array} dstAlphabet
+ *
+ * @returns {function(number|Array)}
+ */
+function anyBase(srcAlphabet, dstAlphabet) {
+ var converter = new Converter(srcAlphabet, dstAlphabet);
+ /**
+ * Convert function
+ *
+ * @param {string|Array} number
+ *
+ * @return {string|Array} number
+ */
+ return function (number) {
+ return converter.convert(number);
+ }
+};
+
+anyBase.BIN = '01';
+anyBase.OCT = '01234567';
+anyBase.DEC = '0123456789';
+anyBase.HEX = '0123456789abcdef';
+
+module.exports = anyBase;
+
+/***/ }),
+
+/***/ 1605:
+/***/ ((module) => {
+
+"use strict";
+
+
+/**
+ * Converter
+ *
+ * @param {string|Array} srcAlphabet
+ * @param {string|Array} dstAlphabet
+ * @constructor
+ */
+function Converter(srcAlphabet, dstAlphabet) {
+ if (!srcAlphabet || !dstAlphabet || !srcAlphabet.length || !dstAlphabet.length) {
+ throw new Error('Bad alphabet');
+ }
+ this.srcAlphabet = srcAlphabet;
+ this.dstAlphabet = dstAlphabet;
+}
+
+/**
+ * Convert number from source alphabet to destination alphabet
+ *
+ * @param {string|Array} number - number represented as a string or array of points
+ *
+ * @returns {string|Array}
+ */
+Converter.prototype.convert = function(number) {
+ var i, divide, newlen,
+ numberMap = {},
+ fromBase = this.srcAlphabet.length,
+ toBase = this.dstAlphabet.length,
+ length = number.length,
+ result = typeof number === 'string' ? '' : [];
+
+ if (!this.isValid(number)) {
+ throw new Error('Number "' + number + '" contains of non-alphabetic digits (' + this.srcAlphabet + ')');
+ }
+
+ if (this.srcAlphabet === this.dstAlphabet) {
+ return number;
+ }
+
+ for (i = 0; i < length; i++) {
+ numberMap[i] = this.srcAlphabet.indexOf(number[i]);
+ }
+ do {
+ divide = 0;
+ newlen = 0;
+ for (i = 0; i < length; i++) {
+ divide = divide * fromBase + numberMap[i];
+ if (divide >= toBase) {
+ numberMap[newlen++] = parseInt(divide / toBase, 10);
+ divide = divide % toBase;
+ } else if (newlen > 0) {
+ numberMap[newlen++] = 0;
+ }
+ }
+ length = newlen;
+ result = this.dstAlphabet.slice(divide, divide + 1).concat(result);
+ } while (newlen !== 0);
+
+ return result;
+};
+
+/**
+ * Valid number with source alphabet
+ *
+ * @param {number} number
+ *
+ * @returns {boolean}
+ */
+Converter.prototype.isValid = function(number) {
+ var i = 0;
+ for (; i < number.length; ++i) {
+ if (this.srcAlphabet.indexOf(number[i]) === -1) {
+ return false;
+ }
+ }
+ return true;
+};
+
+module.exports = Converter;
+
+/***/ }),
+
+/***/ 7888:
+/***/ (function(__unused_webpack_module, exports) {
+
+(function (global, factory) {
+ true ? factory(exports) :
+ 0;
+}(this, (function (exports) { 'use strict';
+
+ /**
+ * Creates a continuation function with some arguments already applied.
+ *
+ * Useful as a shorthand when combined with other control flow functions. Any
+ * arguments passed to the returned function are added to the arguments
+ * originally passed to apply.
+ *
+ * @name apply
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {Function} fn - The function you want to eventually apply all
+ * arguments to. Invokes with (arguments...).
+ * @param {...*} arguments... - Any number of arguments to automatically apply
+ * when the continuation is called.
+ * @returns {Function} the partially-applied function
+ * @example
+ *
+ * // using apply
+ * async.parallel([
+ * async.apply(fs.writeFile, 'testfile1', 'test1'),
+ * async.apply(fs.writeFile, 'testfile2', 'test2')
+ * ]);
+ *
+ *
+ * // the same process without using apply
+ * async.parallel([
+ * function(callback) {
+ * fs.writeFile('testfile1', 'test1', callback);
+ * },
+ * function(callback) {
+ * fs.writeFile('testfile2', 'test2', callback);
+ * }
+ * ]);
+ *
+ * // It's possible to pass any number of additional arguments when calling the
+ * // continuation:
+ *
+ * node> var fn = async.apply(sys.puts, 'one');
+ * node> fn('two', 'three');
+ * one
+ * two
+ * three
+ */
+ function apply(fn, ...args) {
+ return (...callArgs) => fn(...args,...callArgs);
+ }
+
+ function initialParams (fn) {
+ return function (...args/*, callback*/) {
+ var callback = args.pop();
+ return fn.call(this, args, callback);
+ };
+ }
+
+ /* istanbul ignore file */
+
+ var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;
+ var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
+ var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
+
+ function fallback(fn) {
+ setTimeout(fn, 0);
+ }
+
+ function wrap(defer) {
+ return (fn, ...args) => defer(() => fn(...args));
+ }
+
+ var _defer;
+
+ if (hasQueueMicrotask) {
+ _defer = queueMicrotask;
+ } else if (hasSetImmediate) {
+ _defer = setImmediate;
+ } else if (hasNextTick) {
+ _defer = process.nextTick;
+ } else {
+ _defer = fallback;
+ }
+
+ var setImmediate$1 = wrap(_defer);
+
+ /**
+ * Take a sync function and make it async, passing its return value to a
+ * callback. This is useful for plugging sync functions into a waterfall,
+ * series, or other async functions. Any arguments passed to the generated
+ * function will be passed to the wrapped function (except for the final
+ * callback argument). Errors thrown will be passed to the callback.
+ *
+ * If the function passed to `asyncify` returns a Promise, that promises's
+ * resolved/rejected state will be used to call the callback, rather than simply
+ * the synchronous return value.
+ *
+ * This also means you can asyncify ES2017 `async` functions.
+ *
+ * @name asyncify
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @alias wrapSync
+ * @category Util
+ * @param {Function} func - The synchronous function, or Promise-returning
+ * function to convert to an {@link AsyncFunction}.
+ * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
+ * invoked with `(args..., callback)`.
+ * @example
+ *
+ * // passing a regular synchronous function
+ * async.waterfall([
+ * async.apply(fs.readFile, filename, "utf8"),
+ * async.asyncify(JSON.parse),
+ * function (data, next) {
+ * // data is the result of parsing the text.
+ * // If there was a parsing error, it would have been caught.
+ * }
+ * ], callback);
+ *
+ * // passing a function returning a promise
+ * async.waterfall([
+ * async.apply(fs.readFile, filename, "utf8"),
+ * async.asyncify(function (contents) {
+ * return db.model.create(contents);
+ * }),
+ * function (model, next) {
+ * // `model` is the instantiated model object.
+ * // If there was an error, this function would be skipped.
+ * }
+ * ], callback);
+ *
+ * // es2017 example, though `asyncify` is not needed if your JS environment
+ * // supports async functions out of the box
+ * var q = async.queue(async.asyncify(async function(file) {
+ * var intermediateStep = await processFile(file);
+ * return await somePromise(intermediateStep)
+ * }));
+ *
+ * q.push(files);
+ */
+ function asyncify(func) {
+ if (isAsync(func)) {
+ return function (...args/*, callback*/) {
+ const callback = args.pop();
+ const promise = func.apply(this, args);
+ return handlePromise(promise, callback)
+ }
+ }
+
+ return initialParams(function (args, callback) {
+ var result;
+ try {
+ result = func.apply(this, args);
+ } catch (e) {
+ return callback(e);
+ }
+ // if result is Promise object
+ if (result && typeof result.then === 'function') {
+ return handlePromise(result, callback)
+ } else {
+ callback(null, result);
+ }
+ });
+ }
+
+ function handlePromise(promise, callback) {
+ return promise.then(value => {
+ invokeCallback(callback, null, value);
+ }, err => {
+ invokeCallback(callback, err && err.message ? err : new Error(err));
+ });
+ }
+
+ function invokeCallback(callback, error, value) {
+ try {
+ callback(error, value);
+ } catch (err) {
+ setImmediate$1(e => { throw e }, err);
+ }
+ }
+
+ function isAsync(fn) {
+ return fn[Symbol.toStringTag] === 'AsyncFunction';
+ }
+
+ function isAsyncGenerator(fn) {
+ return fn[Symbol.toStringTag] === 'AsyncGenerator';
+ }
+
+ function isAsyncIterable(obj) {
+ return typeof obj[Symbol.asyncIterator] === 'function';
+ }
+
+ function wrapAsync(asyncFn) {
+ if (typeof asyncFn !== 'function') throw new Error('expected a function')
+ return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
+ }
+
+ // conditionally promisify a function.
+ // only return a promise if a callback is omitted
+ function awaitify (asyncFn, arity = asyncFn.length) {
+ if (!arity) throw new Error('arity is undefined')
+ function awaitable (...args) {
+ if (typeof args[arity - 1] === 'function') {
+ return asyncFn.apply(this, args)
+ }
+
+ return new Promise((resolve, reject) => {
+ args[arity - 1] = (err, ...cbArgs) => {
+ if (err) return reject(err)
+ resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
+ };
+ asyncFn.apply(this, args);
+ })
+ }
+
+ return awaitable
+ }
+
+ function applyEach (eachfn) {
+ return function applyEach(fns, ...callArgs) {
+ const go = awaitify(function (callback) {
+ var that = this;
+ return eachfn(fns, (fn, cb) => {
+ wrapAsync(fn).apply(that, callArgs.concat(cb));
+ }, callback);
+ });
+ return go;
+ };
+ }
+
+ function _asyncMap(eachfn, arr, iteratee, callback) {
+ arr = arr || [];
+ var results = [];
+ var counter = 0;
+ var _iteratee = wrapAsync(iteratee);
+
+ return eachfn(arr, (value, _, iterCb) => {
+ var index = counter++;
+ _iteratee(value, (err, v) => {
+ results[index] = v;
+ iterCb(err);
+ });
+ }, err => {
+ callback(err, results);
+ });
+ }
+
+ function isArrayLike(value) {
+ return value &&
+ typeof value.length === 'number' &&
+ value.length >= 0 &&
+ value.length % 1 === 0;
+ }
+
+ // A temporary value used to identify if the loop should be broken.
+ // See #1064, #1293
+ const breakLoop = {};
+
+ function once(fn) {
+ function wrapper (...args) {
+ if (fn === null) return;
+ var callFn = fn;
+ fn = null;
+ callFn.apply(this, args);
+ }
+ Object.assign(wrapper, fn);
+ return wrapper
+ }
+
+ function getIterator (coll) {
+ return coll[Symbol.iterator] && coll[Symbol.iterator]();
+ }
+
+ function createArrayIterator(coll) {
+ var i = -1;
+ var len = coll.length;
+ return function next() {
+ return ++i < len ? {value: coll[i], key: i} : null;
+ }
+ }
+
+ function createES2015Iterator(iterator) {
+ var i = -1;
+ return function next() {
+ var item = iterator.next();
+ if (item.done)
+ return null;
+ i++;
+ return {value: item.value, key: i};
+ }
+ }
+
+ function createObjectIterator(obj) {
+ var okeys = obj ? Object.keys(obj) : [];
+ var i = -1;
+ var len = okeys.length;
+ return function next() {
+ var key = okeys[++i];
+ if (key === '__proto__') {
+ return next();
+ }
+ return i < len ? {value: obj[key], key} : null;
+ };
+ }
+
+ function createIterator(coll) {
+ if (isArrayLike(coll)) {
+ return createArrayIterator(coll);
+ }
+
+ var iterator = getIterator(coll);
+ return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
+ }
+
+ function onlyOnce(fn) {
+ return function (...args) {
+ if (fn === null) throw new Error("Callback was already called.");
+ var callFn = fn;
+ fn = null;
+ callFn.apply(this, args);
+ };
+ }
+
+ // for async generators
+ function asyncEachOfLimit(generator, limit, iteratee, callback) {
+ let done = false;
+ let canceled = false;
+ let awaiting = false;
+ let running = 0;
+ let idx = 0;
+
+ function replenish() {
+ //console.log('replenish')
+ if (running >= limit || awaiting || done) return
+ //console.log('replenish awaiting')
+ awaiting = true;
+ generator.next().then(({value, done: iterDone}) => {
+ //console.log('got value', value)
+ if (canceled || done) return
+ awaiting = false;
+ if (iterDone) {
+ done = true;
+ if (running <= 0) {
+ //console.log('done nextCb')
+ callback(null);
+ }
+ return;
+ }
+ running++;
+ iteratee(value, idx, iterateeCallback);
+ idx++;
+ replenish();
+ }).catch(handleError);
+ }
+
+ function iterateeCallback(err, result) {
+ //console.log('iterateeCallback')
+ running -= 1;
+ if (canceled) return
+ if (err) return handleError(err)
+
+ if (err === false) {
+ done = true;
+ canceled = true;
+ return
+ }
+
+ if (result === breakLoop || (done && running <= 0)) {
+ done = true;
+ //console.log('done iterCb')
+ return callback(null);
+ }
+ replenish();
+ }
+
+ function handleError(err) {
+ if (canceled) return
+ awaiting = false;
+ done = true;
+ callback(err);
+ }
+
+ replenish();
+ }
+
+ var eachOfLimit = (limit) => {
+ return (obj, iteratee, callback) => {
+ callback = once(callback);
+ if (limit <= 0) {
+ throw new RangeError('concurrency limit cannot be less than 1')
+ }
+ if (!obj) {
+ return callback(null);
+ }
+ if (isAsyncGenerator(obj)) {
+ return asyncEachOfLimit(obj, limit, iteratee, callback)
+ }
+ if (isAsyncIterable(obj)) {
+ return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)
+ }
+ var nextElem = createIterator(obj);
+ var done = false;
+ var canceled = false;
+ var running = 0;
+ var looping = false;
+
+ function iterateeCallback(err, value) {
+ if (canceled) return
+ running -= 1;
+ if (err) {
+ done = true;
+ callback(err);
+ }
+ else if (err === false) {
+ done = true;
+ canceled = true;
+ }
+ else if (value === breakLoop || (done && running <= 0)) {
+ done = true;
+ return callback(null);
+ }
+ else if (!looping) {
+ replenish();
+ }
+ }
+
+ function replenish () {
+ looping = true;
+ while (running < limit && !done) {
+ var elem = nextElem();
+ if (elem === null) {
+ done = true;
+ if (running <= 0) {
+ callback(null);
+ }
+ return;
+ }
+ running += 1;
+ iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
+ }
+ looping = false;
+ }
+
+ replenish();
+ };
+ };
+
+ /**
+ * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name eachOfLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.eachOf]{@link module:Collections.eachOf}
+ * @alias forEachOfLimit
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - An async function to apply to each
+ * item in `coll`. The `key` is the item's key, or index in the case of an
+ * array.
+ * Invoked with (item, key, callback).
+ * @param {Function} [callback] - A callback which is called when all
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if a callback is omitted
+ */
+ function eachOfLimit$1(coll, limit, iteratee, callback) {
+ return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
+ }
+
+ var eachOfLimit$2 = awaitify(eachOfLimit$1, 4);
+
+ // eachOf implementation optimized for array-likes
+ function eachOfArrayLike(coll, iteratee, callback) {
+ callback = once(callback);
+ var index = 0,
+ completed = 0,
+ {length} = coll,
+ canceled = false;
+ if (length === 0) {
+ callback(null);
+ }
+
+ function iteratorCallback(err, value) {
+ if (err === false) {
+ canceled = true;
+ }
+ if (canceled === true) return
+ if (err) {
+ callback(err);
+ } else if ((++completed === length) || value === breakLoop) {
+ callback(null);
+ }
+ }
+
+ for (; index < length; index++) {
+ iteratee(coll[index], index, onlyOnce(iteratorCallback));
+ }
+ }
+
+ // a generic version of eachOf which can handle array, object, and iterator cases.
+ function eachOfGeneric (coll, iteratee, callback) {
+ return eachOfLimit$2(coll, Infinity, iteratee, callback);
+ }
+
+ /**
+ * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
+ * to the iteratee.
+ *
+ * @name eachOf
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @alias forEachOf
+ * @category Collection
+ * @see [async.each]{@link module:Collections.each}
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A function to apply to each
+ * item in `coll`.
+ * The `key` is the item's key, or index in the case of an array.
+ * Invoked with (item, key, callback).
+ * @param {Function} [callback] - A callback which is called when all
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if a callback is omitted
+ * @example
+ *
+ * // dev.json is a file containing a valid json object config for dev environment
+ * // dev.json is a file containing a valid json object config for test environment
+ * // prod.json is a file containing a valid json object config for prod environment
+ * // invalid.json is a file with a malformed json object
+ *
+ * let configs = {}; //global variable
+ * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};
+ * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};
+ *
+ * // asynchronous function that reads a json file and parses the contents as json object
+ * function parseFile(file, key, callback) {
+ * fs.readFile(file, "utf8", function(err, data) {
+ * if (err) return calback(err);
+ * try {
+ * configs[key] = JSON.parse(data);
+ * } catch (e) {
+ * return callback(e);
+ * }
+ * callback();
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.forEachOf(validConfigFileMap, parseFile, function (err) {
+ * if (err) {
+ * console.error(err);
+ * } else {
+ * console.log(configs);
+ * // configs is now a map of JSON data, e.g.
+ * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
+ * }
+ * });
+ *
+ * //Error handing
+ * async.forEachOf(invalidConfigFileMap, parseFile, function (err) {
+ * if (err) {
+ * console.error(err);
+ * // JSON parse error exception
+ * } else {
+ * console.log(configs);
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.forEachOf(validConfigFileMap, parseFile)
+ * .then( () => {
+ * console.log(configs);
+ * // configs is now a map of JSON data, e.g.
+ * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
+ * }).catch( err => {
+ * console.error(err);
+ * });
+ *
+ * //Error handing
+ * async.forEachOf(invalidConfigFileMap, parseFile)
+ * .then( () => {
+ * console.log(configs);
+ * }).catch( err => {
+ * console.error(err);
+ * // JSON parse error exception
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.forEachOf(validConfigFileMap, parseFile);
+ * console.log(configs);
+ * // configs is now a map of JSON data, e.g.
+ * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * //Error handing
+ * async () => {
+ * try {
+ * let result = await async.forEachOf(invalidConfigFileMap, parseFile);
+ * console.log(configs);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * // JSON parse error exception
+ * }
+ * }
+ *
+ */
+ function eachOf(coll, iteratee, callback) {
+ var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
+ return eachOfImplementation(coll, wrapAsync(iteratee), callback);
+ }
+
+ var eachOf$1 = awaitify(eachOf, 3);
+
+ /**
+ * Produces a new collection of values by mapping each value in `coll` through
+ * the `iteratee` function. The `iteratee` is called with an item from `coll`
+ * and a callback for when it has finished processing. Each of these callbacks
+ * takes 2 arguments: an `error`, and the transformed item from `coll`. If
+ * `iteratee` passes an error to its callback, the main `callback` (for the
+ * `map` function) is immediately called with the error.
+ *
+ * Note, that since this function applies the `iteratee` to each item in
+ * parallel, there is no guarantee that the `iteratee` functions will complete
+ * in order. However, the results array will be in the same order as the
+ * original `coll`.
+ *
+ * If `map` is passed an Object, the results will be an Array. The results
+ * will roughly be in the order of the original Objects' keys (but this can
+ * vary across JavaScript engines).
+ *
+ * @name map
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with the transformed item.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Results is an Array of the
+ * transformed items from the `coll`. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * // file1.txt is a file that is 1000 bytes in size
+ * // file2.txt is a file that is 2000 bytes in size
+ * // file3.txt is a file that is 3000 bytes in size
+ * // file4.txt does not exist
+ *
+ * const fileList = ['file1.txt','file2.txt','file3.txt'];
+ * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
+ *
+ * // asynchronous function that returns the file size in bytes
+ * function getFileSizeInBytes(file, callback) {
+ * fs.stat(file, function(err, stat) {
+ * if (err) {
+ * return callback(err);
+ * }
+ * callback(null, stat.size);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.map(fileList, getFileSizeInBytes, function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * } else {
+ * console.log(results);
+ * // results is now an array of the file size in bytes for each file, e.g.
+ * // [ 1000, 2000, 3000]
+ * }
+ * });
+ *
+ * // Error Handling
+ * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * } else {
+ * console.log(results);
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.map(fileList, getFileSizeInBytes)
+ * .then( results => {
+ * console.log(results);
+ * // results is now an array of the file size in bytes for each file, e.g.
+ * // [ 1000, 2000, 3000]
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Error Handling
+ * async.map(withMissingFileList, getFileSizeInBytes)
+ * .then( results => {
+ * console.log(results);
+ * }).catch( err => {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let results = await async.map(fileList, getFileSizeInBytes);
+ * console.log(results);
+ * // results is now an array of the file size in bytes for each file, e.g.
+ * // [ 1000, 2000, 3000]
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // Error Handling
+ * async () => {
+ * try {
+ * let results = await async.map(withMissingFileList, getFileSizeInBytes);
+ * console.log(results);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * }
+ * }
+ *
+ */
+ function map (coll, iteratee, callback) {
+ return _asyncMap(eachOf$1, coll, iteratee, callback)
+ }
+ var map$1 = awaitify(map, 3);
+
+ /**
+ * Applies the provided arguments to each function in the array, calling
+ * `callback` after all functions have completed. If you only provide the first
+ * argument, `fns`, then it will return a function which lets you pass in the
+ * arguments as if it were a single function call. If more arguments are
+ * provided, `callback` is required while `args` is still optional. The results
+ * for each of the applied async functions are passed to the final callback
+ * as an array.
+ *
+ * @name applyEach
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s
+ * to all call with the same arguments
+ * @param {...*} [args] - any number of separate arguments to pass to the
+ * function.
+ * @param {Function} [callback] - the final argument should be the callback,
+ * called when all functions have completed processing.
+ * @returns {AsyncFunction} - Returns a function that takes no args other than
+ * an optional callback, that is the result of applying the `args` to each
+ * of the functions.
+ * @example
+ *
+ * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')
+ *
+ * appliedFn((err, results) => {
+ * // results[0] is the results for `enableSearch`
+ * // results[1] is the results for `updateSchema`
+ * });
+ *
+ * // partial application example:
+ * async.each(
+ * buckets,
+ * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),
+ * callback
+ * );
+ */
+ var applyEach$1 = applyEach(map$1);
+
+ /**
+ * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
+ *
+ * @name eachOfSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.eachOf]{@link module:Collections.eachOf}
+ * @alias forEachOfSeries
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * Invoked with (item, key, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if a callback is omitted
+ */
+ function eachOfSeries(coll, iteratee, callback) {
+ return eachOfLimit$2(coll, 1, iteratee, callback)
+ }
+ var eachOfSeries$1 = awaitify(eachOfSeries, 3);
+
+ /**
+ * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
+ *
+ * @name mapSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.map]{@link module:Collections.map}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with the transformed item.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Results is an array of the
+ * transformed items from the `coll`. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function mapSeries (coll, iteratee, callback) {
+ return _asyncMap(eachOfSeries$1, coll, iteratee, callback)
+ }
+ var mapSeries$1 = awaitify(mapSeries, 3);
+
+ /**
+ * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
+ *
+ * @name applyEachSeries
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.applyEach]{@link module:ControlFlow.applyEach}
+ * @category Control Flow
+ * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all
+ * call with the same arguments
+ * @param {...*} [args] - any number of separate arguments to pass to the
+ * function.
+ * @param {Function} [callback] - the final argument should be the callback,
+ * called when all functions have completed processing.
+ * @returns {AsyncFunction} - A function, that when called, is the result of
+ * appling the `args` to the list of functions. It takes no args, other than
+ * a callback.
+ */
+ var applyEachSeries = applyEach(mapSeries$1);
+
+ const PROMISE_SYMBOL = Symbol('promiseCallback');
+
+ function promiseCallback () {
+ let resolve, reject;
+ function callback (err, ...args) {
+ if (err) return reject(err)
+ resolve(args.length > 1 ? args : args[0]);
+ }
+
+ callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
+ resolve = res,
+ reject = rej;
+ });
+
+ return callback
+ }
+
+ /**
+ * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
+ * their requirements. Each function can optionally depend on other functions
+ * being completed first, and each function is run as soon as its requirements
+ * are satisfied.
+ *
+ * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
+ * will stop. Further tasks will not execute (so any other functions depending
+ * on it will not run), and the main `callback` is immediately called with the
+ * error.
+ *
+ * {@link AsyncFunction}s also receive an object containing the results of functions which
+ * have completed so far as the first argument, if they have dependencies. If a
+ * task function has no dependencies, it will only be passed a callback.
+ *
+ * @name auto
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Object} tasks - An object. Each of its properties is either a
+ * function or an array of requirements, with the {@link AsyncFunction} itself the last item
+ * in the array. The object's key of a property serves as the name of the task
+ * defined by that property, i.e. can be used when specifying requirements for
+ * other tasks. The function receives one or two arguments:
+ * * a `results` object, containing the results of the previously executed
+ * functions, only passed if the task has any dependencies,
+ * * a `callback(err, result)` function, which must be called when finished,
+ * passing an `error` (which can be `null`) and the result of the function's
+ * execution.
+ * @param {number} [concurrency=Infinity] - An optional `integer` for
+ * determining the maximum number of tasks that can be run in parallel. By
+ * default, as many as possible.
+ * @param {Function} [callback] - An optional callback which is called when all
+ * the tasks have been completed. It receives the `err` argument if any `tasks`
+ * pass an error to their callback. Results are always returned; however, if an
+ * error occurs, no further `tasks` will be performed, and the results object
+ * will only contain partial results. Invoked with (err, results).
+ * @returns {Promise} a promise, if a callback is not passed
+ * @example
+ *
+ * //Using Callbacks
+ * async.auto({
+ * get_data: function(callback) {
+ * // async code to get some data
+ * callback(null, 'data', 'converted to array');
+ * },
+ * make_folder: function(callback) {
+ * // async code to create a directory to store a file in
+ * // this is run at the same time as getting the data
+ * callback(null, 'folder');
+ * },
+ * write_file: ['get_data', 'make_folder', function(results, callback) {
+ * // once there is some data and the directory exists,
+ * // write the data to a file in the directory
+ * callback(null, 'filename');
+ * }],
+ * email_link: ['write_file', function(results, callback) {
+ * // once the file is written let's email a link to it...
+ * callback(null, {'file':results.write_file, 'email':'user@example.com'});
+ * }]
+ * }, function(err, results) {
+ * if (err) {
+ * console.log('err = ', err);
+ * }
+ * console.log('results = ', results);
+ * // results = {
+ * // get_data: ['data', 'converted to array']
+ * // make_folder; 'folder',
+ * // write_file: 'filename'
+ * // email_link: { file: 'filename', email: 'user@example.com' }
+ * // }
+ * });
+ *
+ * //Using Promises
+ * async.auto({
+ * get_data: function(callback) {
+ * console.log('in get_data');
+ * // async code to get some data
+ * callback(null, 'data', 'converted to array');
+ * },
+ * make_folder: function(callback) {
+ * console.log('in make_folder');
+ * // async code to create a directory to store a file in
+ * // this is run at the same time as getting the data
+ * callback(null, 'folder');
+ * },
+ * write_file: ['get_data', 'make_folder', function(results, callback) {
+ * // once there is some data and the directory exists,
+ * // write the data to a file in the directory
+ * callback(null, 'filename');
+ * }],
+ * email_link: ['write_file', function(results, callback) {
+ * // once the file is written let's email a link to it...
+ * callback(null, {'file':results.write_file, 'email':'user@example.com'});
+ * }]
+ * }).then(results => {
+ * console.log('results = ', results);
+ * // results = {
+ * // get_data: ['data', 'converted to array']
+ * // make_folder; 'folder',
+ * // write_file: 'filename'
+ * // email_link: { file: 'filename', email: 'user@example.com' }
+ * // }
+ * }).catch(err => {
+ * console.log('err = ', err);
+ * });
+ *
+ * //Using async/await
+ * async () => {
+ * try {
+ * let results = await async.auto({
+ * get_data: function(callback) {
+ * // async code to get some data
+ * callback(null, 'data', 'converted to array');
+ * },
+ * make_folder: function(callback) {
+ * // async code to create a directory to store a file in
+ * // this is run at the same time as getting the data
+ * callback(null, 'folder');
+ * },
+ * write_file: ['get_data', 'make_folder', function(results, callback) {
+ * // once there is some data and the directory exists,
+ * // write the data to a file in the directory
+ * callback(null, 'filename');
+ * }],
+ * email_link: ['write_file', function(results, callback) {
+ * // once the file is written let's email a link to it...
+ * callback(null, {'file':results.write_file, 'email':'user@example.com'});
+ * }]
+ * });
+ * console.log('results = ', results);
+ * // results = {
+ * // get_data: ['data', 'converted to array']
+ * // make_folder; 'folder',
+ * // write_file: 'filename'
+ * // email_link: { file: 'filename', email: 'user@example.com' }
+ * // }
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function auto(tasks, concurrency, callback) {
+ if (typeof concurrency !== 'number') {
+ // concurrency is optional, shift the args.
+ callback = concurrency;
+ concurrency = null;
+ }
+ callback = once(callback || promiseCallback());
+ var numTasks = Object.keys(tasks).length;
+ if (!numTasks) {
+ return callback(null);
+ }
+ if (!concurrency) {
+ concurrency = numTasks;
+ }
+
+ var results = {};
+ var runningTasks = 0;
+ var canceled = false;
+ var hasError = false;
+
+ var listeners = Object.create(null);
+
+ var readyTasks = [];
+
+ // for cycle detection:
+ var readyToCheck = []; // tasks that have been identified as reachable
+ // without the possibility of returning to an ancestor task
+ var uncheckedDependencies = {};
+
+ Object.keys(tasks).forEach(key => {
+ var task = tasks[key];
+ if (!Array.isArray(task)) {
+ // no dependencies
+ enqueueTask(key, [task]);
+ readyToCheck.push(key);
+ return;
+ }
+
+ var dependencies = task.slice(0, task.length - 1);
+ var remainingDependencies = dependencies.length;
+ if (remainingDependencies === 0) {
+ enqueueTask(key, task);
+ readyToCheck.push(key);
+ return;
+ }
+ uncheckedDependencies[key] = remainingDependencies;
+
+ dependencies.forEach(dependencyName => {
+ if (!tasks[dependencyName]) {
+ throw new Error('async.auto task `' + key +
+ '` has a non-existent dependency `' +
+ dependencyName + '` in ' +
+ dependencies.join(', '));
+ }
+ addListener(dependencyName, () => {
+ remainingDependencies--;
+ if (remainingDependencies === 0) {
+ enqueueTask(key, task);
+ }
+ });
+ });
+ });
+
+ checkForDeadlocks();
+ processQueue();
+
+ function enqueueTask(key, task) {
+ readyTasks.push(() => runTask(key, task));
+ }
+
+ function processQueue() {
+ if (canceled) return
+ if (readyTasks.length === 0 && runningTasks === 0) {
+ return callback(null, results);
+ }
+ while(readyTasks.length && runningTasks < concurrency) {
+ var run = readyTasks.shift();
+ run();
+ }
+
+ }
+
+ function addListener(taskName, fn) {
+ var taskListeners = listeners[taskName];
+ if (!taskListeners) {
+ taskListeners = listeners[taskName] = [];
+ }
+
+ taskListeners.push(fn);
+ }
+
+ function taskComplete(taskName) {
+ var taskListeners = listeners[taskName] || [];
+ taskListeners.forEach(fn => fn());
+ processQueue();
+ }
+
+
+ function runTask(key, task) {
+ if (hasError) return;
+
+ var taskCallback = onlyOnce((err, ...result) => {
+ runningTasks--;
+ if (err === false) {
+ canceled = true;
+ return
+ }
+ if (result.length < 2) {
+ [result] = result;
+ }
+ if (err) {
+ var safeResults = {};
+ Object.keys(results).forEach(rkey => {
+ safeResults[rkey] = results[rkey];
+ });
+ safeResults[key] = result;
+ hasError = true;
+ listeners = Object.create(null);
+ if (canceled) return
+ callback(err, safeResults);
+ } else {
+ results[key] = result;
+ taskComplete(key);
+ }
+ });
+
+ runningTasks++;
+ var taskFn = wrapAsync(task[task.length - 1]);
+ if (task.length > 1) {
+ taskFn(results, taskCallback);
+ } else {
+ taskFn(taskCallback);
+ }
+ }
+
+ function checkForDeadlocks() {
+ // Kahn's algorithm
+ // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
+ // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
+ var currentTask;
+ var counter = 0;
+ while (readyToCheck.length) {
+ currentTask = readyToCheck.pop();
+ counter++;
+ getDependents(currentTask).forEach(dependent => {
+ if (--uncheckedDependencies[dependent] === 0) {
+ readyToCheck.push(dependent);
+ }
+ });
+ }
+
+ if (counter !== numTasks) {
+ throw new Error(
+ 'async.auto cannot execute tasks due to a recursive dependency'
+ );
+ }
+ }
+
+ function getDependents(taskName) {
+ var result = [];
+ Object.keys(tasks).forEach(key => {
+ const task = tasks[key];
+ if (Array.isArray(task) && task.indexOf(taskName) >= 0) {
+ result.push(key);
+ }
+ });
+ return result;
+ }
+
+ return callback[PROMISE_SYMBOL]
+ }
+
+ var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/;
+ var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/;
+ var FN_ARG_SPLIT = /,/;
+ var FN_ARG = /(=.+)?(\s*)$/;
+
+ function stripComments(string) {
+ let stripped = '';
+ let index = 0;
+ let endBlockComment = string.indexOf('*/');
+ while (index < string.length) {
+ if (string[index] === '/' && string[index+1] === '/') {
+ // inline comment
+ let endIndex = string.indexOf('\n', index);
+ index = (endIndex === -1) ? string.length : endIndex;
+ } else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) {
+ // block comment
+ let endIndex = string.indexOf('*/', index);
+ if (endIndex !== -1) {
+ index = endIndex + 2;
+ endBlockComment = string.indexOf('*/', index);
+ } else {
+ stripped += string[index];
+ index++;
+ }
+ } else {
+ stripped += string[index];
+ index++;
+ }
+ }
+ return stripped;
+ }
+
+ function parseParams(func) {
+ const src = stripComments(func.toString());
+ let match = src.match(FN_ARGS);
+ if (!match) {
+ match = src.match(ARROW_FN_ARGS);
+ }
+ if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src)
+ let [, args] = match;
+ return args
+ .replace(/\s/g, '')
+ .split(FN_ARG_SPLIT)
+ .map((arg) => arg.replace(FN_ARG, '').trim());
+ }
+
+ /**
+ * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
+ * tasks are specified as parameters to the function, after the usual callback
+ * parameter, with the parameter names matching the names of the tasks it
+ * depends on. This can provide even more readable task graphs which can be
+ * easier to maintain.
+ *
+ * If a final callback is specified, the task results are similarly injected,
+ * specified as named parameters after the initial error parameter.
+ *
+ * The autoInject function is purely syntactic sugar and its semantics are
+ * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
+ *
+ * @name autoInject
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.auto]{@link module:ControlFlow.auto}
+ * @category Control Flow
+ * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
+ * the form 'func([dependencies...], callback). The object's key of a property
+ * serves as the name of the task defined by that property, i.e. can be used
+ * when specifying requirements for other tasks.
+ * * The `callback` parameter is a `callback(err, result)` which must be called
+ * when finished, passing an `error` (which can be `null`) and the result of
+ * the function's execution. The remaining parameters name other tasks on
+ * which the task is dependent, and the results from those tasks are the
+ * arguments of those parameters.
+ * @param {Function} [callback] - An optional callback which is called when all
+ * the tasks have been completed. It receives the `err` argument if any `tasks`
+ * pass an error to their callback, and a `results` object with any completed
+ * task results, similar to `auto`.
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * // The example from `auto` can be rewritten as follows:
+ * async.autoInject({
+ * get_data: function(callback) {
+ * // async code to get some data
+ * callback(null, 'data', 'converted to array');
+ * },
+ * make_folder: function(callback) {
+ * // async code to create a directory to store a file in
+ * // this is run at the same time as getting the data
+ * callback(null, 'folder');
+ * },
+ * write_file: function(get_data, make_folder, callback) {
+ * // once there is some data and the directory exists,
+ * // write the data to a file in the directory
+ * callback(null, 'filename');
+ * },
+ * email_link: function(write_file, callback) {
+ * // once the file is written let's email a link to it...
+ * // write_file contains the filename returned by write_file.
+ * callback(null, {'file':write_file, 'email':'user@example.com'});
+ * }
+ * }, function(err, results) {
+ * console.log('err = ', err);
+ * console.log('email_link = ', results.email_link);
+ * });
+ *
+ * // If you are using a JS minifier that mangles parameter names, `autoInject`
+ * // will not work with plain functions, since the parameter names will be
+ * // collapsed to a single letter identifier. To work around this, you can
+ * // explicitly specify the names of the parameters your task function needs
+ * // in an array, similar to Angular.js dependency injection.
+ *
+ * // This still has an advantage over plain `auto`, since the results a task
+ * // depends on are still spread into arguments.
+ * async.autoInject({
+ * //...
+ * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
+ * callback(null, 'filename');
+ * }],
+ * email_link: ['write_file', function(write_file, callback) {
+ * callback(null, {'file':write_file, 'email':'user@example.com'});
+ * }]
+ * //...
+ * }, function(err, results) {
+ * console.log('err = ', err);
+ * console.log('email_link = ', results.email_link);
+ * });
+ */
+ function autoInject(tasks, callback) {
+ var newTasks = {};
+
+ Object.keys(tasks).forEach(key => {
+ var taskFn = tasks[key];
+ var params;
+ var fnIsAsync = isAsync(taskFn);
+ var hasNoDeps =
+ (!fnIsAsync && taskFn.length === 1) ||
+ (fnIsAsync && taskFn.length === 0);
+
+ if (Array.isArray(taskFn)) {
+ params = [...taskFn];
+ taskFn = params.pop();
+
+ newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
+ } else if (hasNoDeps) {
+ // no dependencies, use the function as-is
+ newTasks[key] = taskFn;
+ } else {
+ params = parseParams(taskFn);
+ if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {
+ throw new Error("autoInject task functions require explicit parameters.");
+ }
+
+ // remove callback param
+ if (!fnIsAsync) params.pop();
+
+ newTasks[key] = params.concat(newTask);
+ }
+
+ function newTask(results, taskCb) {
+ var newArgs = params.map(name => results[name]);
+ newArgs.push(taskCb);
+ wrapAsync(taskFn)(...newArgs);
+ }
+ });
+
+ return auto(newTasks, callback);
+ }
+
+ // Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
+ // used for queues. This implementation assumes that the node provided by the user can be modified
+ // to adjust the next and last properties. We implement only the minimal functionality
+ // for queue support.
+ class DLL {
+ constructor() {
+ this.head = this.tail = null;
+ this.length = 0;
+ }
+
+ removeLink(node) {
+ if (node.prev) node.prev.next = node.next;
+ else this.head = node.next;
+ if (node.next) node.next.prev = node.prev;
+ else this.tail = node.prev;
+
+ node.prev = node.next = null;
+ this.length -= 1;
+ return node;
+ }
+
+ empty () {
+ while(this.head) this.shift();
+ return this;
+ }
+
+ insertAfter(node, newNode) {
+ newNode.prev = node;
+ newNode.next = node.next;
+ if (node.next) node.next.prev = newNode;
+ else this.tail = newNode;
+ node.next = newNode;
+ this.length += 1;
+ }
+
+ insertBefore(node, newNode) {
+ newNode.prev = node.prev;
+ newNode.next = node;
+ if (node.prev) node.prev.next = newNode;
+ else this.head = newNode;
+ node.prev = newNode;
+ this.length += 1;
+ }
+
+ unshift(node) {
+ if (this.head) this.insertBefore(this.head, node);
+ else setInitial(this, node);
+ }
+
+ push(node) {
+ if (this.tail) this.insertAfter(this.tail, node);
+ else setInitial(this, node);
+ }
+
+ shift() {
+ return this.head && this.removeLink(this.head);
+ }
+
+ pop() {
+ return this.tail && this.removeLink(this.tail);
+ }
+
+ toArray() {
+ return [...this]
+ }
+
+ *[Symbol.iterator] () {
+ var cur = this.head;
+ while (cur) {
+ yield cur.data;
+ cur = cur.next;
+ }
+ }
+
+ remove (testFn) {
+ var curr = this.head;
+ while(curr) {
+ var {next} = curr;
+ if (testFn(curr)) {
+ this.removeLink(curr);
+ }
+ curr = next;
+ }
+ return this;
+ }
+ }
+
+ function setInitial(dll, node) {
+ dll.length = 1;
+ dll.head = dll.tail = node;
+ }
+
+ function queue(worker, concurrency, payload) {
+ if (concurrency == null) {
+ concurrency = 1;
+ }
+ else if(concurrency === 0) {
+ throw new RangeError('Concurrency must not be zero');
+ }
+
+ var _worker = wrapAsync(worker);
+ var numRunning = 0;
+ var workersList = [];
+ const events = {
+ error: [],
+ drain: [],
+ saturated: [],
+ unsaturated: [],
+ empty: []
+ };
+
+ function on (event, handler) {
+ events[event].push(handler);
+ }
+
+ function once (event, handler) {
+ const handleAndRemove = (...args) => {
+ off(event, handleAndRemove);
+ handler(...args);
+ };
+ events[event].push(handleAndRemove);
+ }
+
+ function off (event, handler) {
+ if (!event) return Object.keys(events).forEach(ev => events[ev] = [])
+ if (!handler) return events[event] = []
+ events[event] = events[event].filter(ev => ev !== handler);
+ }
+
+ function trigger (event, ...args) {
+ events[event].forEach(handler => handler(...args));
+ }
+
+ var processingScheduled = false;
+ function _insert(data, insertAtFront, rejectOnError, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+
+ var res, rej;
+ function promiseCallback (err, ...args) {
+ // we don't care about the error, let the global error handler
+ // deal with it
+ if (err) return rejectOnError ? rej(err) : res()
+ if (args.length <= 1) return res(args[0])
+ res(args);
+ }
+
+ var item = q._createTaskItem(
+ data,
+ rejectOnError ? promiseCallback :
+ (callback || promiseCallback)
+ );
+
+ if (insertAtFront) {
+ q._tasks.unshift(item);
+ } else {
+ q._tasks.push(item);
+ }
+
+ if (!processingScheduled) {
+ processingScheduled = true;
+ setImmediate$1(() => {
+ processingScheduled = false;
+ q.process();
+ });
+ }
+
+ if (rejectOnError || !callback) {
+ return new Promise((resolve, reject) => {
+ res = resolve;
+ rej = reject;
+ })
+ }
+ }
+
+ function _createCB(tasks) {
+ return function (err, ...args) {
+ numRunning -= 1;
+
+ for (var i = 0, l = tasks.length; i < l; i++) {
+ var task = tasks[i];
+
+ var index = workersList.indexOf(task);
+ if (index === 0) {
+ workersList.shift();
+ } else if (index > 0) {
+ workersList.splice(index, 1);
+ }
+
+ task.callback(err, ...args);
+
+ if (err != null) {
+ trigger('error', err, task.data);
+ }
+ }
+
+ if (numRunning <= (q.concurrency - q.buffer) ) {
+ trigger('unsaturated');
+ }
+
+ if (q.idle()) {
+ trigger('drain');
+ }
+ q.process();
+ };
+ }
+
+ function _maybeDrain(data) {
+ if (data.length === 0 && q.idle()) {
+ // call drain immediately if there are no tasks
+ setImmediate$1(() => trigger('drain'));
+ return true
+ }
+ return false
+ }
+
+ const eventMethod = (name) => (handler) => {
+ if (!handler) {
+ return new Promise((resolve, reject) => {
+ once(name, (err, data) => {
+ if (err) return reject(err)
+ resolve(data);
+ });
+ })
+ }
+ off(name);
+ on(name, handler);
+
+ };
+
+ var isProcessing = false;
+ var q = {
+ _tasks: new DLL(),
+ _createTaskItem (data, callback) {
+ return {
+ data,
+ callback
+ };
+ },
+ *[Symbol.iterator] () {
+ yield* q._tasks[Symbol.iterator]();
+ },
+ concurrency,
+ payload,
+ buffer: concurrency / 4,
+ started: false,
+ paused: false,
+ push (data, callback) {
+ if (Array.isArray(data)) {
+ if (_maybeDrain(data)) return
+ return data.map(datum => _insert(datum, false, false, callback))
+ }
+ return _insert(data, false, false, callback);
+ },
+ pushAsync (data, callback) {
+ if (Array.isArray(data)) {
+ if (_maybeDrain(data)) return
+ return data.map(datum => _insert(datum, false, true, callback))
+ }
+ return _insert(data, false, true, callback);
+ },
+ kill () {
+ off();
+ q._tasks.empty();
+ },
+ unshift (data, callback) {
+ if (Array.isArray(data)) {
+ if (_maybeDrain(data)) return
+ return data.map(datum => _insert(datum, true, false, callback))
+ }
+ return _insert(data, true, false, callback);
+ },
+ unshiftAsync (data, callback) {
+ if (Array.isArray(data)) {
+ if (_maybeDrain(data)) return
+ return data.map(datum => _insert(datum, true, true, callback))
+ }
+ return _insert(data, true, true, callback);
+ },
+ remove (testFn) {
+ q._tasks.remove(testFn);
+ },
+ process () {
+ // Avoid trying to start too many processing operations. This can occur
+ // when callbacks resolve synchronously (#1267).
+ if (isProcessing) {
+ return;
+ }
+ isProcessing = true;
+ while(!q.paused && numRunning < q.concurrency && q._tasks.length){
+ var tasks = [], data = [];
+ var l = q._tasks.length;
+ if (q.payload) l = Math.min(l, q.payload);
+ for (var i = 0; i < l; i++) {
+ var node = q._tasks.shift();
+ tasks.push(node);
+ workersList.push(node);
+ data.push(node.data);
+ }
+
+ numRunning += 1;
+
+ if (q._tasks.length === 0) {
+ trigger('empty');
+ }
+
+ if (numRunning === q.concurrency) {
+ trigger('saturated');
+ }
+
+ var cb = onlyOnce(_createCB(tasks));
+ _worker(data, cb);
+ }
+ isProcessing = false;
+ },
+ length () {
+ return q._tasks.length;
+ },
+ running () {
+ return numRunning;
+ },
+ workersList () {
+ return workersList;
+ },
+ idle() {
+ return q._tasks.length + numRunning === 0;
+ },
+ pause () {
+ q.paused = true;
+ },
+ resume () {
+ if (q.paused === false) { return; }
+ q.paused = false;
+ setImmediate$1(q.process);
+ }
+ };
+ // define these as fixed properties, so people get useful errors when updating
+ Object.defineProperties(q, {
+ saturated: {
+ writable: false,
+ value: eventMethod('saturated')
+ },
+ unsaturated: {
+ writable: false,
+ value: eventMethod('unsaturated')
+ },
+ empty: {
+ writable: false,
+ value: eventMethod('empty')
+ },
+ drain: {
+ writable: false,
+ value: eventMethod('drain')
+ },
+ error: {
+ writable: false,
+ value: eventMethod('error')
+ },
+ });
+ return q;
+ }
+
+ /**
+ * Creates a `cargo` object with the specified payload. Tasks added to the
+ * cargo will be processed altogether (up to the `payload` limit). If the
+ * `worker` is in progress, the task is queued until it becomes available. Once
+ * the `worker` has completed some tasks, each callback of those tasks is
+ * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
+ * for how `cargo` and `queue` work.
+ *
+ * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
+ * at a time, cargo passes an array of tasks to a single worker, repeating
+ * when the worker is finished.
+ *
+ * @name cargo
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.queue]{@link module:ControlFlow.queue}
+ * @category Control Flow
+ * @param {AsyncFunction} worker - An asynchronous function for processing an array
+ * of queued tasks. Invoked with `(tasks, callback)`.
+ * @param {number} [payload=Infinity] - An optional `integer` for determining
+ * how many tasks should be processed per round; if omitted, the default is
+ * unlimited.
+ * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can
+ * attached as certain properties to listen for specific events during the
+ * lifecycle of the cargo and inner queue.
+ * @example
+ *
+ * // create a cargo object with payload 2
+ * var cargo = async.cargo(function(tasks, callback) {
+ * for (var i=0; i {
+ * console.log(result);
+ * // 6000
+ * // which is the sum of the file sizes of the three files
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Error Handling
+ * async.reduce(withMissingFileList, 0, getFileSizeInBytes)
+ * .then( result => {
+ * console.log(result);
+ * }).catch( err => {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.reduce(fileList, 0, getFileSizeInBytes);
+ * console.log(result);
+ * // 6000
+ * // which is the sum of the file sizes of the three files
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // Error Handling
+ * async () => {
+ * try {
+ * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);
+ * console.log(result);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * }
+ * }
+ *
+ */
+ function reduce(coll, memo, iteratee, callback) {
+ callback = once(callback);
+ var _iteratee = wrapAsync(iteratee);
+ return eachOfSeries$1(coll, (x, i, iterCb) => {
+ _iteratee(memo, x, (err, v) => {
+ memo = v;
+ iterCb(err);
+ });
+ }, err => callback(err, memo));
+ }
+ var reduce$1 = awaitify(reduce, 4);
+
+ /**
+ * Version of the compose function that is more natural to read. Each function
+ * consumes the return value of the previous function. It is the equivalent of
+ * [compose]{@link module:ControlFlow.compose} with the arguments reversed.
+ *
+ * Each function is executed with the `this` binding of the composed function.
+ *
+ * @name seq
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.compose]{@link module:ControlFlow.compose}
+ * @category Control Flow
+ * @param {...AsyncFunction} functions - the asynchronous functions to compose
+ * @returns {Function} a function that composes the `functions` in order
+ * @example
+ *
+ * // Requires lodash (or underscore), express3 and dresende's orm2.
+ * // Part of an app, that fetches cats of the logged user.
+ * // This example uses `seq` function to avoid overnesting and error
+ * // handling clutter.
+ * app.get('/cats', function(request, response) {
+ * var User = request.models.User;
+ * async.seq(
+ * User.get.bind(User), // 'User.get' has signature (id, callback(err, data))
+ * function(user, fn) {
+ * user.getCats(fn); // 'getCats' has signature (callback(err, data))
+ * }
+ * )(req.session.user_id, function (err, cats) {
+ * if (err) {
+ * console.error(err);
+ * response.json({ status: 'error', message: err.message });
+ * } else {
+ * response.json({ status: 'ok', message: 'Cats found', data: cats });
+ * }
+ * });
+ * });
+ */
+ function seq(...functions) {
+ var _functions = functions.map(wrapAsync);
+ return function (...args) {
+ var that = this;
+
+ var cb = args[args.length - 1];
+ if (typeof cb == 'function') {
+ args.pop();
+ } else {
+ cb = promiseCallback();
+ }
+
+ reduce$1(_functions, args, (newargs, fn, iterCb) => {
+ fn.apply(that, newargs.concat((err, ...nextargs) => {
+ iterCb(err, nextargs);
+ }));
+ },
+ (err, results) => cb(err, ...results));
+
+ return cb[PROMISE_SYMBOL]
+ };
+ }
+
+ /**
+ * Creates a function which is a composition of the passed asynchronous
+ * functions. Each function consumes the return value of the function that
+ * follows. Composing functions `f()`, `g()`, and `h()` would produce the result
+ * of `f(g(h()))`, only this version uses callbacks to obtain the return values.
+ *
+ * If the last argument to the composed function is not a function, a promise
+ * is returned when you call it.
+ *
+ * Each function is executed with the `this` binding of the composed function.
+ *
+ * @name compose
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {...AsyncFunction} functions - the asynchronous functions to compose
+ * @returns {Function} an asynchronous function that is the composed
+ * asynchronous `functions`
+ * @example
+ *
+ * function add1(n, callback) {
+ * setTimeout(function () {
+ * callback(null, n + 1);
+ * }, 10);
+ * }
+ *
+ * function mul3(n, callback) {
+ * setTimeout(function () {
+ * callback(null, n * 3);
+ * }, 10);
+ * }
+ *
+ * var add1mul3 = async.compose(mul3, add1);
+ * add1mul3(4, function (err, result) {
+ * // result now equals 15
+ * });
+ */
+ function compose(...args) {
+ return seq(...args.reverse());
+ }
+
+ /**
+ * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
+ *
+ * @name mapLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.map]{@link module:Collections.map}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with the transformed item.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Results is an array of the
+ * transformed items from the `coll`. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function mapLimit (coll, limit, iteratee, callback) {
+ return _asyncMap(eachOfLimit(limit), coll, iteratee, callback)
+ }
+ var mapLimit$1 = awaitify(mapLimit, 4);
+
+ /**
+ * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
+ *
+ * @name concatLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.concat]{@link module:Collections.concat}
+ * @category Collection
+ * @alias flatMapLimit
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
+ * which should use an array as its result. Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished, or an error occurs. Results is an array
+ * containing the concatenated results of the `iteratee` function. Invoked with
+ * (err, results).
+ * @returns A Promise, if no callback is passed
+ */
+ function concatLimit(coll, limit, iteratee, callback) {
+ var _iteratee = wrapAsync(iteratee);
+ return mapLimit$1(coll, limit, (val, iterCb) => {
+ _iteratee(val, (err, ...args) => {
+ if (err) return iterCb(err);
+ return iterCb(err, args);
+ });
+ }, (err, mapResults) => {
+ var result = [];
+ for (var i = 0; i < mapResults.length; i++) {
+ if (mapResults[i]) {
+ result = result.concat(...mapResults[i]);
+ }
+ }
+
+ return callback(err, result);
+ });
+ }
+ var concatLimit$1 = awaitify(concatLimit, 4);
+
+ /**
+ * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
+ * the concatenated list. The `iteratee`s are called in parallel, and the
+ * results are concatenated as they return. The results array will be returned in
+ * the original order of `coll` passed to the `iteratee` function.
+ *
+ * @name concat
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @category Collection
+ * @alias flatMap
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
+ * which should use an array as its result. Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished, or an error occurs. Results is an array
+ * containing the concatenated results of the `iteratee` function. Invoked with
+ * (err, results).
+ * @returns A Promise, if no callback is passed
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ * // dir4 does not exist
+ *
+ * let directoryList = ['dir1','dir2','dir3'];
+ * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];
+ *
+ * // Using callbacks
+ * async.concat(directoryList, fs.readdir, function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * } else {
+ * console.log(results);
+ * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
+ * }
+ * });
+ *
+ * // Error Handling
+ * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * // since dir4 does not exist
+ * } else {
+ * console.log(results);
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.concat(directoryList, fs.readdir)
+ * .then(results => {
+ * console.log(results);
+ * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // Error Handling
+ * async.concat(withMissingDirectoryList, fs.readdir)
+ * .then(results => {
+ * console.log(results);
+ * }).catch(err => {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * // since dir4 does not exist
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let results = await async.concat(directoryList, fs.readdir);
+ * console.log(results);
+ * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
+ * } catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // Error Handling
+ * async () => {
+ * try {
+ * let results = await async.concat(withMissingDirectoryList, fs.readdir);
+ * console.log(results);
+ * } catch (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * // since dir4 does not exist
+ * }
+ * }
+ *
+ */
+ function concat(coll, iteratee, callback) {
+ return concatLimit$1(coll, Infinity, iteratee, callback)
+ }
+ var concat$1 = awaitify(concat, 3);
+
+ /**
+ * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
+ *
+ * @name concatSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.concat]{@link module:Collections.concat}
+ * @category Collection
+ * @alias flatMapSeries
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
+ * The iteratee should complete with an array an array of results.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished, or an error occurs. Results is an array
+ * containing the concatenated results of the `iteratee` function. Invoked with
+ * (err, results).
+ * @returns A Promise, if no callback is passed
+ */
+ function concatSeries(coll, iteratee, callback) {
+ return concatLimit$1(coll, 1, iteratee, callback)
+ }
+ var concatSeries$1 = awaitify(concatSeries, 3);
+
+ /**
+ * Returns a function that when called, calls-back with the values provided.
+ * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
+ * [`auto`]{@link module:ControlFlow.auto}.
+ *
+ * @name constant
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {...*} arguments... - Any number of arguments to automatically invoke
+ * callback with.
+ * @returns {AsyncFunction} Returns a function that when invoked, automatically
+ * invokes the callback with the previous given arguments.
+ * @example
+ *
+ * async.waterfall([
+ * async.constant(42),
+ * function (value, next) {
+ * // value === 42
+ * },
+ * //...
+ * ], callback);
+ *
+ * async.waterfall([
+ * async.constant(filename, "utf8"),
+ * fs.readFile,
+ * function (fileData, next) {
+ * //...
+ * }
+ * //...
+ * ], callback);
+ *
+ * async.auto({
+ * hostname: async.constant("https://server.net/"),
+ * port: findFreePort,
+ * launchServer: ["hostname", "port", function (options, cb) {
+ * startServer(options, cb);
+ * }],
+ * //...
+ * }, callback);
+ */
+ function constant(...args) {
+ return function (...ignoredArgs/*, callback*/) {
+ var callback = ignoredArgs.pop();
+ return callback(null, ...args);
+ };
+ }
+
+ function _createTester(check, getResult) {
+ return (eachfn, arr, _iteratee, cb) => {
+ var testPassed = false;
+ var testResult;
+ const iteratee = wrapAsync(_iteratee);
+ eachfn(arr, (value, _, callback) => {
+ iteratee(value, (err, result) => {
+ if (err || err === false) return callback(err);
+
+ if (check(result) && !testResult) {
+ testPassed = true;
+ testResult = getResult(true, value);
+ return callback(null, breakLoop);
+ }
+ callback();
+ });
+ }, err => {
+ if (err) return cb(err);
+ cb(null, testPassed ? testResult : getResult(false));
+ });
+ };
+ }
+
+ /**
+ * Returns the first value in `coll` that passes an async truth test. The
+ * `iteratee` is applied in parallel, meaning the first iteratee to return
+ * `true` will fire the detect `callback` with that result. That means the
+ * result might not be the first item in the original `coll` (in terms of order)
+ * that passes the test.
+
+ * If order within the original `coll` is important, then look at
+ * [`detectSeries`]{@link module:Collections.detectSeries}.
+ *
+ * @name detect
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @alias find
+ * @category Collections
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
+ * The iteratee must complete with a boolean value as its result.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called as soon as any
+ * iteratee returns `true`, or after all the `iteratee` functions have finished.
+ * Result will be the first item in the array that passes the truth test
+ * (iteratee) or the value `undefined` if none passed. Invoked with
+ * (err, result).
+ * @returns {Promise} a promise, if a callback is omitted
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ *
+ * // asynchronous function that checks if a file exists
+ * function fileExists(file, callback) {
+ * fs.access(file, fs.constants.F_OK, (err) => {
+ * callback(null, !err);
+ * });
+ * }
+ *
+ * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,
+ * function(err, result) {
+ * console.log(result);
+ * // dir1/file1.txt
+ * // result now equals the first file in the list that exists
+ * }
+ *);
+ *
+ * // Using Promises
+ * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)
+ * .then(result => {
+ * console.log(result);
+ * // dir1/file1.txt
+ * // result now equals the first file in the list that exists
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);
+ * console.log(result);
+ * // dir1/file1.txt
+ * // result now equals the file in the list that exists
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function detect(coll, iteratee, callback) {
+ return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)
+ }
+ var detect$1 = awaitify(detect, 3);
+
+ /**
+ * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name detectLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.detect]{@link module:Collections.detect}
+ * @alias findLimit
+ * @category Collections
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
+ * The iteratee must complete with a boolean value as its result.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called as soon as any
+ * iteratee returns `true`, or after all the `iteratee` functions have finished.
+ * Result will be the first item in the array that passes the truth test
+ * (iteratee) or the value `undefined` if none passed. Invoked with
+ * (err, result).
+ * @returns {Promise} a promise, if a callback is omitted
+ */
+ function detectLimit(coll, limit, iteratee, callback) {
+ return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback)
+ }
+ var detectLimit$1 = awaitify(detectLimit, 4);
+
+ /**
+ * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
+ *
+ * @name detectSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.detect]{@link module:Collections.detect}
+ * @alias findSeries
+ * @category Collections
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
+ * The iteratee must complete with a boolean value as its result.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called as soon as any
+ * iteratee returns `true`, or after all the `iteratee` functions have finished.
+ * Result will be the first item in the array that passes the truth test
+ * (iteratee) or the value `undefined` if none passed. Invoked with
+ * (err, result).
+ * @returns {Promise} a promise, if a callback is omitted
+ */
+ function detectSeries(coll, iteratee, callback) {
+ return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback)
+ }
+
+ var detectSeries$1 = awaitify(detectSeries, 3);
+
+ function consoleFunc(name) {
+ return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {
+ /* istanbul ignore else */
+ if (typeof console === 'object') {
+ /* istanbul ignore else */
+ if (err) {
+ /* istanbul ignore else */
+ if (console.error) {
+ console.error(err);
+ }
+ } else if (console[name]) { /* istanbul ignore else */
+ resultArgs.forEach(x => console[name](x));
+ }
+ }
+ })
+ }
+
+ /**
+ * Logs the result of an [`async` function]{@link AsyncFunction} to the
+ * `console` using `console.dir` to display the properties of the resulting object.
+ * Only works in Node.js or in browsers that support `console.dir` and
+ * `console.error` (such as FF and Chrome).
+ * If multiple arguments are returned from the async function,
+ * `console.dir` is called on each argument in order.
+ *
+ * @name dir
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {AsyncFunction} function - The function you want to eventually apply
+ * all arguments to.
+ * @param {...*} arguments... - Any number of arguments to apply to the function.
+ * @example
+ *
+ * // in a module
+ * var hello = function(name, callback) {
+ * setTimeout(function() {
+ * callback(null, {hello: name});
+ * }, 1000);
+ * };
+ *
+ * // in the node repl
+ * node> async.dir(hello, 'world');
+ * {hello: 'world'}
+ */
+ var dir = consoleFunc('dir');
+
+ /**
+ * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
+ * the order of operations, the arguments `test` and `iteratee` are switched.
+ *
+ * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
+ *
+ * @name doWhilst
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.whilst]{@link module:ControlFlow.whilst}
+ * @category Control Flow
+ * @param {AsyncFunction} iteratee - A function which is called each time `test`
+ * passes. Invoked with (callback).
+ * @param {AsyncFunction} test - asynchronous truth test to perform after each
+ * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
+ * non-error args from the previous callback of `iteratee`.
+ * @param {Function} [callback] - A callback which is called after the test
+ * function has failed and repeated execution of `iteratee` has stopped.
+ * `callback` will be passed an error and any arguments passed to the final
+ * `iteratee`'s callback. Invoked with (err, [results]);
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function doWhilst(iteratee, test, callback) {
+ callback = onlyOnce(callback);
+ var _fn = wrapAsync(iteratee);
+ var _test = wrapAsync(test);
+ var results;
+
+ function next(err, ...args) {
+ if (err) return callback(err);
+ if (err === false) return;
+ results = args;
+ _test(...args, check);
+ }
+
+ function check(err, truth) {
+ if (err) return callback(err);
+ if (err === false) return;
+ if (!truth) return callback(null, ...results);
+ _fn(next);
+ }
+
+ return check(null, true);
+ }
+
+ var doWhilst$1 = awaitify(doWhilst, 3);
+
+ /**
+ * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
+ * argument ordering differs from `until`.
+ *
+ * @name doUntil
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
+ * @category Control Flow
+ * @param {AsyncFunction} iteratee - An async function which is called each time
+ * `test` fails. Invoked with (callback).
+ * @param {AsyncFunction} test - asynchronous truth test to perform after each
+ * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
+ * non-error args from the previous callback of `iteratee`
+ * @param {Function} [callback] - A callback which is called after the test
+ * function has passed and repeated execution of `iteratee` has stopped. `callback`
+ * will be passed an error and any arguments passed to the final `iteratee`'s
+ * callback. Invoked with (err, [results]);
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function doUntil(iteratee, test, callback) {
+ const _test = wrapAsync(test);
+ return doWhilst$1(iteratee, (...args) => {
+ const cb = args.pop();
+ _test(...args, (err, truth) => cb (err, !truth));
+ }, callback);
+ }
+
+ function _withoutIndex(iteratee) {
+ return (value, index, callback) => iteratee(value, callback);
+ }
+
+ /**
+ * Applies the function `iteratee` to each item in `coll`, in parallel.
+ * The `iteratee` is called with an item from the list, and a callback for when
+ * it has finished. If the `iteratee` passes an error to its `callback`, the
+ * main `callback` (for the `each` function) is immediately called with the
+ * error.
+ *
+ * Note, that since this function applies `iteratee` to each item in parallel,
+ * there is no guarantee that the iteratee functions will complete in order.
+ *
+ * @name each
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @alias forEach
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to
+ * each item in `coll`. Invoked with (item, callback).
+ * The array index is not passed to the iteratee.
+ * If you need the index, use `eachOf`.
+ * @param {Function} [callback] - A callback which is called when all
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if a callback is omitted
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ * // dir4 does not exist
+ *
+ * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];
+ * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];
+ *
+ * // asynchronous function that deletes a file
+ * const deleteFile = function(file, callback) {
+ * fs.unlink(file, callback);
+ * };
+ *
+ * // Using callbacks
+ * async.each(fileList, deleteFile, function(err) {
+ * if( err ) {
+ * console.log(err);
+ * } else {
+ * console.log('All files have been deleted successfully');
+ * }
+ * });
+ *
+ * // Error Handling
+ * async.each(withMissingFileList, deleteFile, function(err){
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * // since dir4/file2.txt does not exist
+ * // dir1/file1.txt could have been deleted
+ * });
+ *
+ * // Using Promises
+ * async.each(fileList, deleteFile)
+ * .then( () => {
+ * console.log('All files have been deleted successfully');
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Error Handling
+ * async.each(fileList, deleteFile)
+ * .then( () => {
+ * console.log('All files have been deleted successfully');
+ * }).catch( err => {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * // since dir4/file2.txt does not exist
+ * // dir1/file1.txt could have been deleted
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * await async.each(files, deleteFile);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // Error Handling
+ * async () => {
+ * try {
+ * await async.each(withMissingFileList, deleteFile);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * // since dir4/file2.txt does not exist
+ * // dir1/file1.txt could have been deleted
+ * }
+ * }
+ *
+ */
+ function eachLimit(coll, iteratee, callback) {
+ return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);
+ }
+
+ var each = awaitify(eachLimit, 3);
+
+ /**
+ * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
+ *
+ * @name eachLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.each]{@link module:Collections.each}
+ * @alias forEachLimit
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The array index is not passed to the iteratee.
+ * If you need the index, use `eachOfLimit`.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called when all
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if a callback is omitted
+ */
+ function eachLimit$1(coll, limit, iteratee, callback) {
+ return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
+ }
+ var eachLimit$2 = awaitify(eachLimit$1, 4);
+
+ /**
+ * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
+ *
+ * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
+ * in series and therefore the iteratee functions will complete in order.
+
+ * @name eachSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.each]{@link module:Collections.each}
+ * @alias forEachSeries
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each
+ * item in `coll`.
+ * The array index is not passed to the iteratee.
+ * If you need the index, use `eachOfSeries`.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called when all
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if a callback is omitted
+ */
+ function eachSeries(coll, iteratee, callback) {
+ return eachLimit$2(coll, 1, iteratee, callback)
+ }
+ var eachSeries$1 = awaitify(eachSeries, 3);
+
+ /**
+ * Wrap an async function and ensure it calls its callback on a later tick of
+ * the event loop. If the function already calls its callback on a next tick,
+ * no extra deferral is added. This is useful for preventing stack overflows
+ * (`RangeError: Maximum call stack size exceeded`) and generally keeping
+ * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
+ * contained. ES2017 `async` functions are returned as-is -- they are immune
+ * to Zalgo's corrupting influences, as they always resolve on a later tick.
+ *
+ * @name ensureAsync
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {AsyncFunction} fn - an async function, one that expects a node-style
+ * callback as its last argument.
+ * @returns {AsyncFunction} Returns a wrapped function with the exact same call
+ * signature as the function passed in.
+ * @example
+ *
+ * function sometimesAsync(arg, callback) {
+ * if (cache[arg]) {
+ * return callback(null, cache[arg]); // this would be synchronous!!
+ * } else {
+ * doSomeIO(arg, callback); // this IO would be asynchronous
+ * }
+ * }
+ *
+ * // this has a risk of stack overflows if many results are cached in a row
+ * async.mapSeries(args, sometimesAsync, done);
+ *
+ * // this will defer sometimesAsync's callback if necessary,
+ * // preventing stack overflows
+ * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
+ */
+ function ensureAsync(fn) {
+ if (isAsync(fn)) return fn;
+ return function (...args/*, callback*/) {
+ var callback = args.pop();
+ var sync = true;
+ args.push((...innerArgs) => {
+ if (sync) {
+ setImmediate$1(() => callback(...innerArgs));
+ } else {
+ callback(...innerArgs);
+ }
+ });
+ fn.apply(this, args);
+ sync = false;
+ };
+ }
+
+ /**
+ * Returns `true` if every element in `coll` satisfies an async test. If any
+ * iteratee call returns `false`, the main `callback` is immediately called.
+ *
+ * @name every
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @alias all
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
+ * in the collection in parallel.
+ * The iteratee must complete with a boolean result value.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Result will be either `true` or `false`
+ * depending on the values of the async tests. Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ * // dir4 does not exist
+ *
+ * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];
+ * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
+ *
+ * // asynchronous function that checks if a file exists
+ * function fileExists(file, callback) {
+ * fs.access(file, fs.constants.F_OK, (err) => {
+ * callback(null, !err);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.every(fileList, fileExists, function(err, result) {
+ * console.log(result);
+ * // true
+ * // result is true since every file exists
+ * });
+ *
+ * async.every(withMissingFileList, fileExists, function(err, result) {
+ * console.log(result);
+ * // false
+ * // result is false since NOT every file exists
+ * });
+ *
+ * // Using Promises
+ * async.every(fileList, fileExists)
+ * .then( result => {
+ * console.log(result);
+ * // true
+ * // result is true since every file exists
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * async.every(withMissingFileList, fileExists)
+ * .then( result => {
+ * console.log(result);
+ * // false
+ * // result is false since NOT every file exists
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.every(fileList, fileExists);
+ * console.log(result);
+ * // true
+ * // result is true since every file exists
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * async () => {
+ * try {
+ * let result = await async.every(withMissingFileList, fileExists);
+ * console.log(result);
+ * // false
+ * // result is false since NOT every file exists
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function every(coll, iteratee, callback) {
+ return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)
+ }
+ var every$1 = awaitify(every, 3);
+
+ /**
+ * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
+ *
+ * @name everyLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.every]{@link module:Collections.every}
+ * @alias allLimit
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
+ * in the collection in parallel.
+ * The iteratee must complete with a boolean result value.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Result will be either `true` or `false`
+ * depending on the values of the async tests. Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ */
+ function everyLimit(coll, limit, iteratee, callback) {
+ return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback)
+ }
+ var everyLimit$1 = awaitify(everyLimit, 4);
+
+ /**
+ * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
+ *
+ * @name everySeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.every]{@link module:Collections.every}
+ * @alias allSeries
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
+ * in the collection in series.
+ * The iteratee must complete with a boolean result value.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Result will be either `true` or `false`
+ * depending on the values of the async tests. Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ */
+ function everySeries(coll, iteratee, callback) {
+ return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)
+ }
+ var everySeries$1 = awaitify(everySeries, 3);
+
+ function filterArray(eachfn, arr, iteratee, callback) {
+ var truthValues = new Array(arr.length);
+ eachfn(arr, (x, index, iterCb) => {
+ iteratee(x, (err, v) => {
+ truthValues[index] = !!v;
+ iterCb(err);
+ });
+ }, err => {
+ if (err) return callback(err);
+ var results = [];
+ for (var i = 0; i < arr.length; i++) {
+ if (truthValues[i]) results.push(arr[i]);
+ }
+ callback(null, results);
+ });
+ }
+
+ function filterGeneric(eachfn, coll, iteratee, callback) {
+ var results = [];
+ eachfn(coll, (x, index, iterCb) => {
+ iteratee(x, (err, v) => {
+ if (err) return iterCb(err);
+ if (v) {
+ results.push({index, value: x});
+ }
+ iterCb(err);
+ });
+ }, err => {
+ if (err) return callback(err);
+ callback(null, results
+ .sort((a, b) => a.index - b.index)
+ .map(v => v.value));
+ });
+ }
+
+ function _filter(eachfn, coll, iteratee, callback) {
+ var filter = isArrayLike(coll) ? filterArray : filterGeneric;
+ return filter(eachfn, coll, wrapAsync(iteratee), callback);
+ }
+
+ /**
+ * Returns a new array of all the values in `coll` which pass an async truth
+ * test. This operation is performed in parallel, but the results array will be
+ * in the same order as the original.
+ *
+ * @name filter
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @alias select
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {Function} iteratee - A truth test to apply to each item in `coll`.
+ * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
+ * with a boolean argument once it has completed. Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback provided
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ *
+ * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
+ *
+ * // asynchronous function that checks if a file exists
+ * function fileExists(file, callback) {
+ * fs.access(file, fs.constants.F_OK, (err) => {
+ * callback(null, !err);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.filter(files, fileExists, function(err, results) {
+ * if(err) {
+ * console.log(err);
+ * } else {
+ * console.log(results);
+ * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
+ * // results is now an array of the existing files
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.filter(files, fileExists)
+ * .then(results => {
+ * console.log(results);
+ * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
+ * // results is now an array of the existing files
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let results = await async.filter(files, fileExists);
+ * console.log(results);
+ * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
+ * // results is now an array of the existing files
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function filter (coll, iteratee, callback) {
+ return _filter(eachOf$1, coll, iteratee, callback)
+ }
+ var filter$1 = awaitify(filter, 3);
+
+ /**
+ * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name filterLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.filter]{@link module:Collections.filter}
+ * @alias selectLimit
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {Function} iteratee - A truth test to apply to each item in `coll`.
+ * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
+ * with a boolean argument once it has completed. Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback provided
+ */
+ function filterLimit (coll, limit, iteratee, callback) {
+ return _filter(eachOfLimit(limit), coll, iteratee, callback)
+ }
+ var filterLimit$1 = awaitify(filterLimit, 4);
+
+ /**
+ * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
+ *
+ * @name filterSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.filter]{@link module:Collections.filter}
+ * @alias selectSeries
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {Function} iteratee - A truth test to apply to each item in `coll`.
+ * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
+ * with a boolean argument once it has completed. Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Invoked with (err, results)
+ * @returns {Promise} a promise, if no callback provided
+ */
+ function filterSeries (coll, iteratee, callback) {
+ return _filter(eachOfSeries$1, coll, iteratee, callback)
+ }
+ var filterSeries$1 = awaitify(filterSeries, 3);
+
+ /**
+ * Calls the asynchronous function `fn` with a callback parameter that allows it
+ * to call itself again, in series, indefinitely.
+
+ * If an error is passed to the callback then `errback` is called with the
+ * error, and execution stops, otherwise it will never be called.
+ *
+ * @name forever
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {AsyncFunction} fn - an async function to call repeatedly.
+ * Invoked with (next).
+ * @param {Function} [errback] - when `fn` passes an error to it's callback,
+ * this function will be called, and execution stops. Invoked with (err).
+ * @returns {Promise} a promise that rejects if an error occurs and an errback
+ * is not passed
+ * @example
+ *
+ * async.forever(
+ * function(next) {
+ * // next is suitable for passing to things that need a callback(err [, whatever]);
+ * // it will result in this function being called again.
+ * },
+ * function(err) {
+ * // if next is called with a value in its first parameter, it will appear
+ * // in here as 'err', and execution will stop.
+ * }
+ * );
+ */
+ function forever(fn, errback) {
+ var done = onlyOnce(errback);
+ var task = wrapAsync(ensureAsync(fn));
+
+ function next(err) {
+ if (err) return done(err);
+ if (err === false) return;
+ task(next);
+ }
+ return next();
+ }
+ var forever$1 = awaitify(forever, 2);
+
+ /**
+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
+ *
+ * @name groupByLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.groupBy]{@link module:Collections.groupBy}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with a `key` to group the value under.
+ * Invoked with (value, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Result is an `Object` whoses
+ * properties are arrays of values which returned the corresponding key.
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function groupByLimit(coll, limit, iteratee, callback) {
+ var _iteratee = wrapAsync(iteratee);
+ return mapLimit$1(coll, limit, (val, iterCb) => {
+ _iteratee(val, (err, key) => {
+ if (err) return iterCb(err);
+ return iterCb(err, {key, val});
+ });
+ }, (err, mapResults) => {
+ var result = {};
+ // from MDN, handle object having an `hasOwnProperty` prop
+ var {hasOwnProperty} = Object.prototype;
+
+ for (var i = 0; i < mapResults.length; i++) {
+ if (mapResults[i]) {
+ var {key} = mapResults[i];
+ var {val} = mapResults[i];
+
+ if (hasOwnProperty.call(result, key)) {
+ result[key].push(val);
+ } else {
+ result[key] = [val];
+ }
+ }
+ }
+
+ return callback(err, result);
+ });
+ }
+
+ var groupByLimit$1 = awaitify(groupByLimit, 4);
+
+ /**
+ * Returns a new object, where each value corresponds to an array of items, from
+ * `coll`, that returned the corresponding key. That is, the keys of the object
+ * correspond to the values passed to the `iteratee` callback.
+ *
+ * Note: Since this function applies the `iteratee` to each item in parallel,
+ * there is no guarantee that the `iteratee` functions will complete in order.
+ * However, the values for each key in the `result` will be in the same order as
+ * the original `coll`. For Objects, the values will roughly be in the order of
+ * the original Objects' keys (but this can vary across JavaScript engines).
+ *
+ * @name groupBy
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with a `key` to group the value under.
+ * Invoked with (value, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Result is an `Object` whoses
+ * properties are arrays of values which returned the corresponding key.
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ * // dir4 does not exist
+ *
+ * const files = ['dir1/file1.txt','dir2','dir4']
+ *
+ * // asynchronous function that detects file type as none, file, or directory
+ * function detectFile(file, callback) {
+ * fs.stat(file, function(err, stat) {
+ * if (err) {
+ * return callback(null, 'none');
+ * }
+ * callback(null, stat.isDirectory() ? 'directory' : 'file');
+ * });
+ * }
+ *
+ * //Using callbacks
+ * async.groupBy(files, detectFile, function(err, result) {
+ * if(err) {
+ * console.log(err);
+ * } else {
+ * console.log(result);
+ * // {
+ * // file: [ 'dir1/file1.txt' ],
+ * // none: [ 'dir4' ],
+ * // directory: [ 'dir2']
+ * // }
+ * // result is object containing the files grouped by type
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.groupBy(files, detectFile)
+ * .then( result => {
+ * console.log(result);
+ * // {
+ * // file: [ 'dir1/file1.txt' ],
+ * // none: [ 'dir4' ],
+ * // directory: [ 'dir2']
+ * // }
+ * // result is object containing the files grouped by type
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.groupBy(files, detectFile);
+ * console.log(result);
+ * // {
+ * // file: [ 'dir1/file1.txt' ],
+ * // none: [ 'dir4' ],
+ * // directory: [ 'dir2']
+ * // }
+ * // result is object containing the files grouped by type
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function groupBy (coll, iteratee, callback) {
+ return groupByLimit$1(coll, Infinity, iteratee, callback)
+ }
+
+ /**
+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
+ *
+ * @name groupBySeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.groupBy]{@link module:Collections.groupBy}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with a `key` to group the value under.
+ * Invoked with (value, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. Result is an `Object` whose
+ * properties are arrays of values which returned the corresponding key.
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function groupBySeries (coll, iteratee, callback) {
+ return groupByLimit$1(coll, 1, iteratee, callback)
+ }
+
+ /**
+ * Logs the result of an `async` function to the `console`. Only works in
+ * Node.js or in browsers that support `console.log` and `console.error` (such
+ * as FF and Chrome). If multiple arguments are returned from the async
+ * function, `console.log` is called on each argument in order.
+ *
+ * @name log
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {AsyncFunction} function - The function you want to eventually apply
+ * all arguments to.
+ * @param {...*} arguments... - Any number of arguments to apply to the function.
+ * @example
+ *
+ * // in a module
+ * var hello = function(name, callback) {
+ * setTimeout(function() {
+ * callback(null, 'hello ' + name);
+ * }, 1000);
+ * };
+ *
+ * // in the node repl
+ * node> async.log(hello, 'world');
+ * 'hello world'
+ */
+ var log = consoleFunc('log');
+
+ /**
+ * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name mapValuesLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.mapValues]{@link module:Collections.mapValues}
+ * @category Collection
+ * @param {Object} obj - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
+ * in `coll`.
+ * The iteratee should complete with the transformed value as its result.
+ * Invoked with (value, key, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. `result` is a new object consisting
+ * of each key from `obj`, with each transformed value on the right-hand side.
+ * Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function mapValuesLimit(obj, limit, iteratee, callback) {
+ callback = once(callback);
+ var newObj = {};
+ var _iteratee = wrapAsync(iteratee);
+ return eachOfLimit(limit)(obj, (val, key, next) => {
+ _iteratee(val, key, (err, result) => {
+ if (err) return next(err);
+ newObj[key] = result;
+ next(err);
+ });
+ }, err => callback(err, newObj));
+ }
+
+ var mapValuesLimit$1 = awaitify(mapValuesLimit, 4);
+
+ /**
+ * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.
+ *
+ * Produces a new Object by mapping each value of `obj` through the `iteratee`
+ * function. The `iteratee` is called each `value` and `key` from `obj` and a
+ * callback for when it has finished processing. Each of these callbacks takes
+ * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`
+ * passes an error to its callback, the main `callback` (for the `mapValues`
+ * function) is immediately called with the error.
+ *
+ * Note, the order of the keys in the result is not guaranteed. The keys will
+ * be roughly in the order they complete, (but this is very engine-specific)
+ *
+ * @name mapValues
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @category Collection
+ * @param {Object} obj - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
+ * in `coll`.
+ * The iteratee should complete with the transformed value as its result.
+ * Invoked with (value, key, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. `result` is a new object consisting
+ * of each key from `obj`, with each transformed value on the right-hand side.
+ * Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * // file1.txt is a file that is 1000 bytes in size
+ * // file2.txt is a file that is 2000 bytes in size
+ * // file3.txt is a file that is 3000 bytes in size
+ * // file4.txt does not exist
+ *
+ * const fileMap = {
+ * f1: 'file1.txt',
+ * f2: 'file2.txt',
+ * f3: 'file3.txt'
+ * };
+ *
+ * const withMissingFileMap = {
+ * f1: 'file1.txt',
+ * f2: 'file2.txt',
+ * f3: 'file4.txt'
+ * };
+ *
+ * // asynchronous function that returns the file size in bytes
+ * function getFileSizeInBytes(file, key, callback) {
+ * fs.stat(file, function(err, stat) {
+ * if (err) {
+ * return callback(err);
+ * }
+ * callback(null, stat.size);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) {
+ * if (err) {
+ * console.log(err);
+ * } else {
+ * console.log(result);
+ * // result is now a map of file size in bytes for each file, e.g.
+ * // {
+ * // f1: 1000,
+ * // f2: 2000,
+ * // f3: 3000
+ * // }
+ * }
+ * });
+ *
+ * // Error handling
+ * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) {
+ * if (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * } else {
+ * console.log(result);
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.mapValues(fileMap, getFileSizeInBytes)
+ * .then( result => {
+ * console.log(result);
+ * // result is now a map of file size in bytes for each file, e.g.
+ * // {
+ * // f1: 1000,
+ * // f2: 2000,
+ * // f3: 3000
+ * // }
+ * }).catch (err => {
+ * console.log(err);
+ * });
+ *
+ * // Error Handling
+ * async.mapValues(withMissingFileMap, getFileSizeInBytes)
+ * .then( result => {
+ * console.log(result);
+ * }).catch (err => {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.mapValues(fileMap, getFileSizeInBytes);
+ * console.log(result);
+ * // result is now a map of file size in bytes for each file, e.g.
+ * // {
+ * // f1: 1000,
+ * // f2: 2000,
+ * // f3: 3000
+ * // }
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // Error Handling
+ * async () => {
+ * try {
+ * let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes);
+ * console.log(result);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * }
+ * }
+ *
+ */
+ function mapValues(obj, iteratee, callback) {
+ return mapValuesLimit$1(obj, Infinity, iteratee, callback)
+ }
+
+ /**
+ * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.
+ *
+ * @name mapValuesSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.mapValues]{@link module:Collections.mapValues}
+ * @category Collection
+ * @param {Object} obj - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
+ * in `coll`.
+ * The iteratee should complete with the transformed value as its result.
+ * Invoked with (value, key, callback).
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
+ * functions have finished, or an error occurs. `result` is a new object consisting
+ * of each key from `obj`, with each transformed value on the right-hand side.
+ * Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function mapValuesSeries(obj, iteratee, callback) {
+ return mapValuesLimit$1(obj, 1, iteratee, callback)
+ }
+
+ /**
+ * Caches the results of an async function. When creating a hash to store
+ * function results against, the callback is omitted from the hash and an
+ * optional hash function can be used.
+ *
+ * **Note: if the async function errs, the result will not be cached and
+ * subsequent calls will call the wrapped function.**
+ *
+ * If no hash function is specified, the first argument is used as a hash key,
+ * which may work reasonably if it is a string or a data type that converts to a
+ * distinct string. Note that objects and arrays will not behave reasonably.
+ * Neither will cases where the other arguments are significant. In such cases,
+ * specify your own hash function.
+ *
+ * The cache of results is exposed as the `memo` property of the function
+ * returned by `memoize`.
+ *
+ * @name memoize
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {AsyncFunction} fn - The async function to proxy and cache results from.
+ * @param {Function} hasher - An optional function for generating a custom hash
+ * for storing results. It has all the arguments applied to it apart from the
+ * callback, and must be synchronous.
+ * @returns {AsyncFunction} a memoized version of `fn`
+ * @example
+ *
+ * var slow_fn = function(name, callback) {
+ * // do something
+ * callback(null, result);
+ * };
+ * var fn = async.memoize(slow_fn);
+ *
+ * // fn can now be used as if it were slow_fn
+ * fn('some name', function() {
+ * // callback
+ * });
+ */
+ function memoize(fn, hasher = v => v) {
+ var memo = Object.create(null);
+ var queues = Object.create(null);
+ var _fn = wrapAsync(fn);
+ var memoized = initialParams((args, callback) => {
+ var key = hasher(...args);
+ if (key in memo) {
+ setImmediate$1(() => callback(null, ...memo[key]));
+ } else if (key in queues) {
+ queues[key].push(callback);
+ } else {
+ queues[key] = [callback];
+ _fn(...args, (err, ...resultArgs) => {
+ // #1465 don't memoize if an error occurred
+ if (!err) {
+ memo[key] = resultArgs;
+ }
+ var q = queues[key];
+ delete queues[key];
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i](err, ...resultArgs);
+ }
+ });
+ }
+ });
+ memoized.memo = memo;
+ memoized.unmemoized = fn;
+ return memoized;
+ }
+
+ /* istanbul ignore file */
+
+ /**
+ * Calls `callback` on a later loop around the event loop. In Node.js this just
+ * calls `process.nextTick`. In the browser it will use `setImmediate` if
+ * available, otherwise `setTimeout(callback, 0)`, which means other higher
+ * priority events may precede the execution of `callback`.
+ *
+ * This is used internally for browser-compatibility purposes.
+ *
+ * @name nextTick
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @see [async.setImmediate]{@link module:Utils.setImmediate}
+ * @category Util
+ * @param {Function} callback - The function to call on a later loop around
+ * the event loop. Invoked with (args...).
+ * @param {...*} args... - any number of additional arguments to pass to the
+ * callback on the next tick.
+ * @example
+ *
+ * var call_order = [];
+ * async.nextTick(function() {
+ * call_order.push('two');
+ * // call_order now equals ['one','two']
+ * });
+ * call_order.push('one');
+ *
+ * async.setImmediate(function (a, b, c) {
+ * // a, b, and c equal 1, 2, and 3
+ * }, 1, 2, 3);
+ */
+ var _defer$1;
+
+ if (hasNextTick) {
+ _defer$1 = process.nextTick;
+ } else if (hasSetImmediate) {
+ _defer$1 = setImmediate;
+ } else {
+ _defer$1 = fallback;
+ }
+
+ var nextTick = wrap(_defer$1);
+
+ var parallel = awaitify((eachfn, tasks, callback) => {
+ var results = isArrayLike(tasks) ? [] : {};
+
+ eachfn(tasks, (task, key, taskCb) => {
+ wrapAsync(task)((err, ...result) => {
+ if (result.length < 2) {
+ [result] = result;
+ }
+ results[key] = result;
+ taskCb(err);
+ });
+ }, err => callback(err, results));
+ }, 3);
+
+ /**
+ * Run the `tasks` collection of functions in parallel, without waiting until
+ * the previous function has completed. If any of the functions pass an error to
+ * its callback, the main `callback` is immediately called with the value of the
+ * error. Once the `tasks` have completed, the results are passed to the final
+ * `callback` as an array.
+ *
+ * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about
+ * parallel execution of code. If your tasks do not use any timers or perform
+ * any I/O, they will actually be executed in series. Any synchronous setup
+ * sections for each task will happen one after the other. JavaScript remains
+ * single-threaded.
+ *
+ * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
+ * execution of other tasks when a task fails.
+ *
+ * It is also possible to use an object instead of an array. Each property will
+ * be run as a function and the results will be passed to the final `callback`
+ * as an object instead of an array. This can be a more readable way of handling
+ * results from {@link async.parallel}.
+ *
+ * @name parallel
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
+ * [async functions]{@link AsyncFunction} to run.
+ * Each async function can complete with any number of optional `result` values.
+ * @param {Function} [callback] - An optional callback to run once all the
+ * functions have completed successfully. This function gets a results array
+ * (or object) containing all the result arguments passed to the task callbacks.
+ * Invoked with (err, results).
+ * @returns {Promise} a promise, if a callback is not passed
+ *
+ * @example
+ *
+ * //Using Callbacks
+ * async.parallel([
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ], function(err, results) {
+ * console.log(results);
+ * // results is equal to ['one','two'] even though
+ * // the second function had a shorter timeout.
+ * });
+ *
+ * // an example using an object instead of an array
+ * async.parallel({
+ * one: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 1);
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 2);
+ * }, 100);
+ * }
+ * }, function(err, results) {
+ * console.log(results);
+ * // results is equal to: { one: 1, two: 2 }
+ * });
+ *
+ * //Using Promises
+ * async.parallel([
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ]).then(results => {
+ * console.log(results);
+ * // results is equal to ['one','two'] even though
+ * // the second function had a shorter timeout.
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // an example using an object instead of an array
+ * async.parallel({
+ * one: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 1);
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 2);
+ * }, 100);
+ * }
+ * }).then(results => {
+ * console.log(results);
+ * // results is equal to: { one: 1, two: 2 }
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * //Using async/await
+ * async () => {
+ * try {
+ * let results = await async.parallel([
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ]);
+ * console.log(results);
+ * // results is equal to ['one','two'] even though
+ * // the second function had a shorter timeout.
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // an example using an object instead of an array
+ * async () => {
+ * try {
+ * let results = await async.parallel({
+ * one: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 1);
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 2);
+ * }, 100);
+ * }
+ * });
+ * console.log(results);
+ * // results is equal to: { one: 1, two: 2 }
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function parallel$1(tasks, callback) {
+ return parallel(eachOf$1, tasks, callback);
+ }
+
+ /**
+ * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name parallelLimit
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.parallel]{@link module:ControlFlow.parallel}
+ * @category Control Flow
+ * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
+ * [async functions]{@link AsyncFunction} to run.
+ * Each async function can complete with any number of optional `result` values.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {Function} [callback] - An optional callback to run once all the
+ * functions have completed successfully. This function gets a results array
+ * (or object) containing all the result arguments passed to the task callbacks.
+ * Invoked with (err, results).
+ * @returns {Promise} a promise, if a callback is not passed
+ */
+ function parallelLimit(tasks, limit, callback) {
+ return parallel(eachOfLimit(limit), tasks, callback);
+ }
+
+ /**
+ * A queue of tasks for the worker function to complete.
+ * @typedef {Iterable} QueueObject
+ * @memberOf module:ControlFlow
+ * @property {Function} length - a function returning the number of items
+ * waiting to be processed. Invoke with `queue.length()`.
+ * @property {boolean} started - a boolean indicating whether or not any
+ * items have been pushed and processed by the queue.
+ * @property {Function} running - a function returning the number of items
+ * currently being processed. Invoke with `queue.running()`.
+ * @property {Function} workersList - a function returning the array of items
+ * currently being processed. Invoke with `queue.workersList()`.
+ * @property {Function} idle - a function returning false if there are items
+ * waiting or being processed, or true if not. Invoke with `queue.idle()`.
+ * @property {number} concurrency - an integer for determining how many `worker`
+ * functions should be run in parallel. This property can be changed after a
+ * `queue` is created to alter the concurrency on-the-fly.
+ * @property {number} payload - an integer that specifies how many items are
+ * passed to the worker function at a time. only applies if this is a
+ * [cargo]{@link module:ControlFlow.cargo} object
+ * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`
+ * once the `worker` has finished processing the task. Instead of a single task,
+ * a `tasks` array can be submitted. The respective callback is used for every
+ * task in the list. Invoke with `queue.push(task, [callback])`,
+ * @property {AsyncFunction} unshift - add a new task to the front of the `queue`.
+ * Invoke with `queue.unshift(task, [callback])`.
+ * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns
+ * a promise that rejects if an error occurs.
+ * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns
+ * a promise that rejects if an error occurs.
+ * @property {Function} remove - remove items from the queue that match a test
+ * function. The test function will be passed an object with a `data` property,
+ * and a `priority` property, if this is a
+ * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
+ * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
+ * `function ({data, priority}) {}` and returns a Boolean.
+ * @property {Function} saturated - a function that sets a callback that is
+ * called when the number of running workers hits the `concurrency` limit, and
+ * further tasks will be queued. If the callback is omitted, `q.saturated()`
+ * returns a promise for the next occurrence.
+ * @property {Function} unsaturated - a function that sets a callback that is
+ * called when the number of running workers is less than the `concurrency` &
+ * `buffer` limits, and further tasks will not be queued. If the callback is
+ * omitted, `q.unsaturated()` returns a promise for the next occurrence.
+ * @property {number} buffer - A minimum threshold buffer in order to say that
+ * the `queue` is `unsaturated`.
+ * @property {Function} empty - a function that sets a callback that is called
+ * when the last item from the `queue` is given to a `worker`. If the callback
+ * is omitted, `q.empty()` returns a promise for the next occurrence.
+ * @property {Function} drain - a function that sets a callback that is called
+ * when the last item from the `queue` has returned from the `worker`. If the
+ * callback is omitted, `q.drain()` returns a promise for the next occurrence.
+ * @property {Function} error - a function that sets a callback that is called
+ * when a task errors. Has the signature `function(error, task)`. If the
+ * callback is omitted, `error()` returns a promise that rejects on the next
+ * error.
+ * @property {boolean} paused - a boolean for determining whether the queue is
+ * in a paused state.
+ * @property {Function} pause - a function that pauses the processing of tasks
+ * until `resume()` is called. Invoke with `queue.pause()`.
+ * @property {Function} resume - a function that resumes the processing of
+ * queued tasks when the queue is paused. Invoke with `queue.resume()`.
+ * @property {Function} kill - a function that removes the `drain` callback and
+ * empties remaining tasks from the queue forcing it to go idle. No more tasks
+ * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.
+ *
+ * @example
+ * const q = async.queue(worker, 2)
+ * q.push(item1)
+ * q.push(item2)
+ * q.push(item3)
+ * // queues are iterable, spread into an array to inspect
+ * const items = [...q] // [item1, item2, item3]
+ * // or use for of
+ * for (let item of q) {
+ * console.log(item)
+ * }
+ *
+ * q.drain(() => {
+ * console.log('all done')
+ * })
+ * // or
+ * await q.drain()
+ */
+
+ /**
+ * Creates a `queue` object with the specified `concurrency`. Tasks added to the
+ * `queue` are processed in parallel (up to the `concurrency` limit). If all
+ * `worker`s are in progress, the task is queued until one becomes available.
+ * Once a `worker` completes a `task`, that `task`'s callback is called.
+ *
+ * @name queue
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {AsyncFunction} worker - An async function for processing a queued task.
+ * If you want to handle errors from an individual task, pass a callback to
+ * `q.push()`. Invoked with (task, callback).
+ * @param {number} [concurrency=1] - An `integer` for determining how many
+ * `worker` functions should be run in parallel. If omitted, the concurrency
+ * defaults to `1`. If the concurrency is `0`, an error is thrown.
+ * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be
+ * attached as certain properties to listen for specific events during the
+ * lifecycle of the queue.
+ * @example
+ *
+ * // create a queue object with concurrency 2
+ * var q = async.queue(function(task, callback) {
+ * console.log('hello ' + task.name);
+ * callback();
+ * }, 2);
+ *
+ * // assign a callback
+ * q.drain(function() {
+ * console.log('all items have been processed');
+ * });
+ * // or await the end
+ * await q.drain()
+ *
+ * // assign an error callback
+ * q.error(function(err, task) {
+ * console.error('task experienced an error');
+ * });
+ *
+ * // add some items to the queue
+ * q.push({name: 'foo'}, function(err) {
+ * console.log('finished processing foo');
+ * });
+ * // callback is optional
+ * q.push({name: 'bar'});
+ *
+ * // add some items to the queue (batch-wise)
+ * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
+ * console.log('finished processing item');
+ * });
+ *
+ * // add some items to the front of the queue
+ * q.unshift({name: 'bar'}, function (err) {
+ * console.log('finished processing bar');
+ * });
+ */
+ function queue$1 (worker, concurrency) {
+ var _worker = wrapAsync(worker);
+ return queue((items, cb) => {
+ _worker(items[0], cb);
+ }, concurrency, 1);
+ }
+
+ // Binary min-heap implementation used for priority queue.
+ // Implementation is stable, i.e. push time is considered for equal priorities
+ class Heap {
+ constructor() {
+ this.heap = [];
+ this.pushCount = Number.MIN_SAFE_INTEGER;
+ }
+
+ get length() {
+ return this.heap.length;
+ }
+
+ empty () {
+ this.heap = [];
+ return this;
+ }
+
+ percUp(index) {
+ let p;
+
+ while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {
+ let t = this.heap[index];
+ this.heap[index] = this.heap[p];
+ this.heap[p] = t;
+
+ index = p;
+ }
+ }
+
+ percDown(index) {
+ let l;
+
+ while ((l=leftChi(index)) < this.heap.length) {
+ if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {
+ l = l+1;
+ }
+
+ if (smaller(this.heap[index], this.heap[l])) {
+ break;
+ }
+
+ let t = this.heap[index];
+ this.heap[index] = this.heap[l];
+ this.heap[l] = t;
+
+ index = l;
+ }
+ }
+
+ push(node) {
+ node.pushCount = ++this.pushCount;
+ this.heap.push(node);
+ this.percUp(this.heap.length-1);
+ }
+
+ unshift(node) {
+ return this.heap.push(node);
+ }
+
+ shift() {
+ let [top] = this.heap;
+
+ this.heap[0] = this.heap[this.heap.length-1];
+ this.heap.pop();
+ this.percDown(0);
+
+ return top;
+ }
+
+ toArray() {
+ return [...this];
+ }
+
+ *[Symbol.iterator] () {
+ for (let i = 0; i < this.heap.length; i++) {
+ yield this.heap[i].data;
+ }
+ }
+
+ remove (testFn) {
+ let j = 0;
+ for (let i = 0; i < this.heap.length; i++) {
+ if (!testFn(this.heap[i])) {
+ this.heap[j] = this.heap[i];
+ j++;
+ }
+ }
+
+ this.heap.splice(j);
+
+ for (let i = parent(this.heap.length-1); i >= 0; i--) {
+ this.percDown(i);
+ }
+
+ return this;
+ }
+ }
+
+ function leftChi(i) {
+ return (i<<1)+1;
+ }
+
+ function parent(i) {
+ return ((i+1)>>1)-1;
+ }
+
+ function smaller(x, y) {
+ if (x.priority !== y.priority) {
+ return x.priority < y.priority;
+ }
+ else {
+ return x.pushCount < y.pushCount;
+ }
+ }
+
+ /**
+ * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and
+ * completed in ascending priority order.
+ *
+ * @name priorityQueue
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.queue]{@link module:ControlFlow.queue}
+ * @category Control Flow
+ * @param {AsyncFunction} worker - An async function for processing a queued task.
+ * If you want to handle errors from an individual task, pass a callback to
+ * `q.push()`.
+ * Invoked with (task, callback).
+ * @param {number} concurrency - An `integer` for determining how many `worker`
+ * functions should be run in parallel. If omitted, the concurrency defaults to
+ * `1`. If the concurrency is `0`, an error is thrown.
+ * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are three
+ * differences between `queue` and `priorityQueue` objects:
+ * * `push(task, priority, [callback])` - `priority` should be a number. If an
+ * array of `tasks` is given, all tasks will be assigned the same priority.
+ * * `pushAsync(task, priority, [callback])` - the same as `priorityQueue.push`,
+ * except this returns a promise that rejects if an error occurs.
+ * * The `unshift` and `unshiftAsync` methods were removed.
+ */
+ function priorityQueue(worker, concurrency) {
+ // Start with a normal queue
+ var q = queue$1(worker, concurrency);
+
+ var {
+ push,
+ pushAsync
+ } = q;
+
+ q._tasks = new Heap();
+ q._createTaskItem = ({data, priority}, callback) => {
+ return {
+ data,
+ priority,
+ callback
+ };
+ };
+
+ function createDataItems(tasks, priority) {
+ if (!Array.isArray(tasks)) {
+ return {data: tasks, priority};
+ }
+ return tasks.map(data => { return {data, priority}; });
+ }
+
+ // Override push to accept second parameter representing priority
+ q.push = function(data, priority = 0, callback) {
+ return push(createDataItems(data, priority), callback);
+ };
+
+ q.pushAsync = function(data, priority = 0, callback) {
+ return pushAsync(createDataItems(data, priority), callback);
+ };
+
+ // Remove unshift functions
+ delete q.unshift;
+ delete q.unshiftAsync;
+
+ return q;
+ }
+
+ /**
+ * Runs the `tasks` array of functions in parallel, without waiting until the
+ * previous function has completed. Once any of the `tasks` complete or pass an
+ * error to its callback, the main `callback` is immediately called. It's
+ * equivalent to `Promise.race()`.
+ *
+ * @name race
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
+ * to run. Each function can complete with an optional `result` value.
+ * @param {Function} callback - A callback to run once any of the functions have
+ * completed. This function gets an error or result from the first function that
+ * completed. Invoked with (err, result).
+ * @returns {Promise} a promise, if a callback is omitted
+ * @example
+ *
+ * async.race([
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ],
+ * // main callback
+ * function(err, result) {
+ * // the result will be equal to 'two' as it finishes earlier
+ * });
+ */
+ function race(tasks, callback) {
+ callback = once(callback);
+ if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
+ if (!tasks.length) return callback();
+ for (var i = 0, l = tasks.length; i < l; i++) {
+ wrapAsync(tasks[i])(callback);
+ }
+ }
+
+ var race$1 = awaitify(race, 2);
+
+ /**
+ * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
+ *
+ * @name reduceRight
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.reduce]{@link module:Collections.reduce}
+ * @alias foldr
+ * @category Collection
+ * @param {Array} array - A collection to iterate over.
+ * @param {*} memo - The initial state of the reduction.
+ * @param {AsyncFunction} iteratee - A function applied to each item in the
+ * array to produce the next step in the reduction.
+ * The `iteratee` should complete with the next state of the reduction.
+ * If the iteratee completes with an error, the reduction is stopped and the
+ * main `callback` is immediately called with the error.
+ * Invoked with (memo, item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Result is the reduced value. Invoked with
+ * (err, result).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function reduceRight (array, memo, iteratee, callback) {
+ var reversed = [...array].reverse();
+ return reduce$1(reversed, memo, iteratee, callback);
+ }
+
+ /**
+ * Wraps the async function in another function that always completes with a
+ * result object, even when it errors.
+ *
+ * The result object has either the property `error` or `value`.
+ *
+ * @name reflect
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {AsyncFunction} fn - The async function you want to wrap
+ * @returns {Function} - A function that always passes null to it's callback as
+ * the error. The second argument to the callback will be an `object` with
+ * either an `error` or a `value` property.
+ * @example
+ *
+ * async.parallel([
+ * async.reflect(function(callback) {
+ * // do some stuff ...
+ * callback(null, 'one');
+ * }),
+ * async.reflect(function(callback) {
+ * // do some more stuff but error ...
+ * callback('bad stuff happened');
+ * }),
+ * async.reflect(function(callback) {
+ * // do some more stuff ...
+ * callback(null, 'two');
+ * })
+ * ],
+ * // optional callback
+ * function(err, results) {
+ * // values
+ * // results[0].value = 'one'
+ * // results[1].error = 'bad stuff happened'
+ * // results[2].value = 'two'
+ * });
+ */
+ function reflect(fn) {
+ var _fn = wrapAsync(fn);
+ return initialParams(function reflectOn(args, reflectCallback) {
+ args.push((error, ...cbArgs) => {
+ let retVal = {};
+ if (error) {
+ retVal.error = error;
+ }
+ if (cbArgs.length > 0){
+ var value = cbArgs;
+ if (cbArgs.length <= 1) {
+ [value] = cbArgs;
+ }
+ retVal.value = value;
+ }
+ reflectCallback(null, retVal);
+ });
+
+ return _fn.apply(this, args);
+ });
+ }
+
+ /**
+ * A helper function that wraps an array or an object of functions with `reflect`.
+ *
+ * @name reflectAll
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @see [async.reflect]{@link module:Utils.reflect}
+ * @category Util
+ * @param {Array|Object|Iterable} tasks - The collection of
+ * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
+ * @returns {Array} Returns an array of async functions, each wrapped in
+ * `async.reflect`
+ * @example
+ *
+ * let tasks = [
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * // do some more stuff but error ...
+ * callback(new Error('bad stuff happened'));
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ];
+ *
+ * async.parallel(async.reflectAll(tasks),
+ * // optional callback
+ * function(err, results) {
+ * // values
+ * // results[0].value = 'one'
+ * // results[1].error = Error('bad stuff happened')
+ * // results[2].value = 'two'
+ * });
+ *
+ * // an example using an object instead of an array
+ * let tasks = {
+ * one: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * callback('two');
+ * },
+ * three: function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'three');
+ * }, 100);
+ * }
+ * };
+ *
+ * async.parallel(async.reflectAll(tasks),
+ * // optional callback
+ * function(err, results) {
+ * // values
+ * // results.one.value = 'one'
+ * // results.two.error = 'two'
+ * // results.three.value = 'three'
+ * });
+ */
+ function reflectAll(tasks) {
+ var results;
+ if (Array.isArray(tasks)) {
+ results = tasks.map(reflect);
+ } else {
+ results = {};
+ Object.keys(tasks).forEach(key => {
+ results[key] = reflect.call(this, tasks[key]);
+ });
+ }
+ return results;
+ }
+
+ function reject(eachfn, arr, _iteratee, callback) {
+ const iteratee = wrapAsync(_iteratee);
+ return _filter(eachfn, arr, (value, cb) => {
+ iteratee(value, (err, v) => {
+ cb(err, !v);
+ });
+ }, callback);
+ }
+
+ /**
+ * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
+ *
+ * @name reject
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.filter]{@link module:Collections.filter}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {Function} iteratee - An async truth test to apply to each item in
+ * `coll`.
+ * The should complete with a boolean value as its `result`.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ *
+ * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
+ *
+ * // asynchronous function that checks if a file exists
+ * function fileExists(file, callback) {
+ * fs.access(file, fs.constants.F_OK, (err) => {
+ * callback(null, !err);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.reject(fileList, fileExists, function(err, results) {
+ * // [ 'dir3/file6.txt' ]
+ * // results now equals an array of the non-existing files
+ * });
+ *
+ * // Using Promises
+ * async.reject(fileList, fileExists)
+ * .then( results => {
+ * console.log(results);
+ * // [ 'dir3/file6.txt' ]
+ * // results now equals an array of the non-existing files
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let results = await async.reject(fileList, fileExists);
+ * console.log(results);
+ * // [ 'dir3/file6.txt' ]
+ * // results now equals an array of the non-existing files
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function reject$1 (coll, iteratee, callback) {
+ return reject(eachOf$1, coll, iteratee, callback)
+ }
+ var reject$2 = awaitify(reject$1, 3);
+
+ /**
+ * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name rejectLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.reject]{@link module:Collections.reject}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {Function} iteratee - An async truth test to apply to each item in
+ * `coll`.
+ * The should complete with a boolean value as its `result`.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function rejectLimit (coll, limit, iteratee, callback) {
+ return reject(eachOfLimit(limit), coll, iteratee, callback)
+ }
+ var rejectLimit$1 = awaitify(rejectLimit, 4);
+
+ /**
+ * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
+ *
+ * @name rejectSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.reject]{@link module:Collections.reject}
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {Function} iteratee - An async truth test to apply to each item in
+ * `coll`.
+ * The should complete with a boolean value as its `result`.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ */
+ function rejectSeries (coll, iteratee, callback) {
+ return reject(eachOfSeries$1, coll, iteratee, callback)
+ }
+ var rejectSeries$1 = awaitify(rejectSeries, 3);
+
+ function constant$1(value) {
+ return function () {
+ return value;
+ }
+ }
+
+ /**
+ * Attempts to get a successful response from `task` no more than `times` times
+ * before returning an error. If the task is successful, the `callback` will be
+ * passed the result of the successful task. If all attempts fail, the callback
+ * will be passed the error and result (if any) of the final attempt.
+ *
+ * @name retry
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @see [async.retryable]{@link module:ControlFlow.retryable}
+ * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
+ * object with `times` and `interval` or a number.
+ * * `times` - The number of attempts to make before giving up. The default
+ * is `5`.
+ * * `interval` - The time to wait between retries, in milliseconds. The
+ * default is `0`. The interval may also be specified as a function of the
+ * retry count (see example).
+ * * `errorFilter` - An optional synchronous function that is invoked on
+ * erroneous result. If it returns `true` the retry attempts will continue;
+ * if the function returns `false` the retry flow is aborted with the current
+ * attempt's error and result being returned to the final callback.
+ * Invoked with (err).
+ * * If `opts` is a number, the number specifies the number of times to retry,
+ * with the default interval of `0`.
+ * @param {AsyncFunction} task - An async function to retry.
+ * Invoked with (callback).
+ * @param {Function} [callback] - An optional callback which is called when the
+ * task has succeeded, or after the final failed attempt. It receives the `err`
+ * and `result` arguments of the last attempt at completing the `task`. Invoked
+ * with (err, results).
+ * @returns {Promise} a promise if no callback provided
+ *
+ * @example
+ *
+ * // The `retry` function can be used as a stand-alone control flow by passing
+ * // a callback, as shown below:
+ *
+ * // try calling apiMethod 3 times
+ * async.retry(3, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // try calling apiMethod 3 times, waiting 200 ms between each retry
+ * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // try calling apiMethod 10 times with exponential backoff
+ * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
+ * async.retry({
+ * times: 10,
+ * interval: function(retryCount) {
+ * return 50 * Math.pow(2, retryCount);
+ * }
+ * }, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // try calling apiMethod the default 5 times no delay between each retry
+ * async.retry(apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // try calling apiMethod only when error condition satisfies, all other
+ * // errors will abort the retry control flow and return to final callback
+ * async.retry({
+ * errorFilter: function(err) {
+ * return err.message === 'Temporary error'; // only retry on a specific error
+ * }
+ * }, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // to retry individual methods that are not as reliable within other
+ * // control flow functions, use the `retryable` wrapper:
+ * async.auto({
+ * users: api.getUsers.bind(api),
+ * payments: async.retryable(3, api.getPayments.bind(api))
+ * }, function(err, results) {
+ * // do something with the results
+ * });
+ *
+ */
+ const DEFAULT_TIMES = 5;
+ const DEFAULT_INTERVAL = 0;
+
+ function retry(opts, task, callback) {
+ var options = {
+ times: DEFAULT_TIMES,
+ intervalFunc: constant$1(DEFAULT_INTERVAL)
+ };
+
+ if (arguments.length < 3 && typeof opts === 'function') {
+ callback = task || promiseCallback();
+ task = opts;
+ } else {
+ parseTimes(options, opts);
+ callback = callback || promiseCallback();
+ }
+
+ if (typeof task !== 'function') {
+ throw new Error("Invalid arguments for async.retry");
+ }
+
+ var _task = wrapAsync(task);
+
+ var attempt = 1;
+ function retryAttempt() {
+ _task((err, ...args) => {
+ if (err === false) return
+ if (err && attempt++ < options.times &&
+ (typeof options.errorFilter != 'function' ||
+ options.errorFilter(err))) {
+ setTimeout(retryAttempt, options.intervalFunc(attempt - 1));
+ } else {
+ callback(err, ...args);
+ }
+ });
+ }
+
+ retryAttempt();
+ return callback[PROMISE_SYMBOL]
+ }
+
+ function parseTimes(acc, t) {
+ if (typeof t === 'object') {
+ acc.times = +t.times || DEFAULT_TIMES;
+
+ acc.intervalFunc = typeof t.interval === 'function' ?
+ t.interval :
+ constant$1(+t.interval || DEFAULT_INTERVAL);
+
+ acc.errorFilter = t.errorFilter;
+ } else if (typeof t === 'number' || typeof t === 'string') {
+ acc.times = +t || DEFAULT_TIMES;
+ } else {
+ throw new Error("Invalid arguments for async.retry");
+ }
+ }
+
+ /**
+ * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method
+ * wraps a task and makes it retryable, rather than immediately calling it
+ * with retries.
+ *
+ * @name retryable
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.retry]{@link module:ControlFlow.retry}
+ * @category Control Flow
+ * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
+ * options, exactly the same as from `retry`, except for a `opts.arity` that
+ * is the arity of the `task` function, defaulting to `task.length`
+ * @param {AsyncFunction} task - the asynchronous function to wrap.
+ * This function will be passed any arguments passed to the returned wrapper.
+ * Invoked with (...args, callback).
+ * @returns {AsyncFunction} The wrapped function, which when invoked, will
+ * retry on an error, based on the parameters specified in `opts`.
+ * This function will accept the same parameters as `task`.
+ * @example
+ *
+ * async.auto({
+ * dep1: async.retryable(3, getFromFlakyService),
+ * process: ["dep1", async.retryable(3, function (results, cb) {
+ * maybeProcessData(results.dep1, cb);
+ * })]
+ * }, callback);
+ */
+ function retryable (opts, task) {
+ if (!task) {
+ task = opts;
+ opts = null;
+ }
+ let arity = (opts && opts.arity) || task.length;
+ if (isAsync(task)) {
+ arity += 1;
+ }
+ var _task = wrapAsync(task);
+ return initialParams((args, callback) => {
+ if (args.length < arity - 1 || callback == null) {
+ args.push(callback);
+ callback = promiseCallback();
+ }
+ function taskFn(cb) {
+ _task(...args, cb);
+ }
+
+ if (opts) retry(opts, taskFn, callback);
+ else retry(taskFn, callback);
+
+ return callback[PROMISE_SYMBOL]
+ });
+ }
+
+ /**
+ * Run the functions in the `tasks` collection in series, each one running once
+ * the previous function has completed. If any functions in the series pass an
+ * error to its callback, no more functions are run, and `callback` is
+ * immediately called with the value of the error. Otherwise, `callback`
+ * receives an array of results when `tasks` have completed.
+ *
+ * It is also possible to use an object instead of an array. Each property will
+ * be run as a function, and the results will be passed to the final `callback`
+ * as an object instead of an array. This can be a more readable way of handling
+ * results from {@link async.series}.
+ *
+ * **Note** that while many implementations preserve the order of object
+ * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
+ * explicitly states that
+ *
+ * > The mechanics and order of enumerating the properties is not specified.
+ *
+ * So if you rely on the order in which your series of functions are executed,
+ * and want this to work on all platforms, consider using an array.
+ *
+ * @name series
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing
+ * [async functions]{@link AsyncFunction} to run in series.
+ * Each function can complete with any number of optional `result` values.
+ * @param {Function} [callback] - An optional callback to run once all the
+ * functions have completed. This function gets a results array (or object)
+ * containing all the result arguments passed to the `task` callbacks. Invoked
+ * with (err, result).
+ * @return {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * //Using Callbacks
+ * async.series([
+ * function(callback) {
+ * setTimeout(function() {
+ * // do some async task
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * // then do another async task
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ], function(err, results) {
+ * console.log(results);
+ * // results is equal to ['one','two']
+ * });
+ *
+ * // an example using objects instead of arrays
+ * async.series({
+ * one: function(callback) {
+ * setTimeout(function() {
+ * // do some async task
+ * callback(null, 1);
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * setTimeout(function() {
+ * // then do another async task
+ * callback(null, 2);
+ * }, 100);
+ * }
+ * }, function(err, results) {
+ * console.log(results);
+ * // results is equal to: { one: 1, two: 2 }
+ * });
+ *
+ * //Using Promises
+ * async.series([
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ]).then(results => {
+ * console.log(results);
+ * // results is equal to ['one','two']
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // an example using an object instead of an array
+ * async.series({
+ * one: function(callback) {
+ * setTimeout(function() {
+ * // do some async task
+ * callback(null, 1);
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * setTimeout(function() {
+ * // then do another async task
+ * callback(null, 2);
+ * }, 100);
+ * }
+ * }).then(results => {
+ * console.log(results);
+ * // results is equal to: { one: 1, two: 2 }
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * //Using async/await
+ * async () => {
+ * try {
+ * let results = await async.series([
+ * function(callback) {
+ * setTimeout(function() {
+ * // do some async task
+ * callback(null, 'one');
+ * }, 200);
+ * },
+ * function(callback) {
+ * setTimeout(function() {
+ * // then do another async task
+ * callback(null, 'two');
+ * }, 100);
+ * }
+ * ]);
+ * console.log(results);
+ * // results is equal to ['one','two']
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * // an example using an object instead of an array
+ * async () => {
+ * try {
+ * let results = await async.parallel({
+ * one: function(callback) {
+ * setTimeout(function() {
+ * // do some async task
+ * callback(null, 1);
+ * }, 200);
+ * },
+ * two: function(callback) {
+ * setTimeout(function() {
+ * // then do another async task
+ * callback(null, 2);
+ * }, 100);
+ * }
+ * });
+ * console.log(results);
+ * // results is equal to: { one: 1, two: 2 }
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function series(tasks, callback) {
+ return parallel(eachOfSeries$1, tasks, callback);
+ }
+
+ /**
+ * Returns `true` if at least one element in the `coll` satisfies an async test.
+ * If any iteratee call returns `true`, the main `callback` is immediately
+ * called.
+ *
+ * @name some
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @alias any
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
+ * in the collections in parallel.
+ * The iteratee should complete with a boolean `result` value.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called as soon as any
+ * iteratee returns `true`, or after all the iteratee functions have finished.
+ * Result will be either `true` or `false` depending on the values of the async
+ * tests. Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ * @example
+ *
+ * // dir1 is a directory that contains file1.txt, file2.txt
+ * // dir2 is a directory that contains file3.txt, file4.txt
+ * // dir3 is a directory that contains file5.txt
+ * // dir4 does not exist
+ *
+ * // asynchronous function that checks if a file exists
+ * function fileExists(file, callback) {
+ * fs.access(file, fs.constants.F_OK, (err) => {
+ * callback(null, !err);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,
+ * function(err, result) {
+ * console.log(result);
+ * // true
+ * // result is true since some file in the list exists
+ * }
+ *);
+ *
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,
+ * function(err, result) {
+ * console.log(result);
+ * // false
+ * // result is false since none of the files exists
+ * }
+ *);
+ *
+ * // Using Promises
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)
+ * .then( result => {
+ * console.log(result);
+ * // true
+ * // result is true since some file in the list exists
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)
+ * .then( result => {
+ * console.log(result);
+ * // false
+ * // result is false since none of the files exists
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);
+ * console.log(result);
+ * // true
+ * // result is true since some file in the list exists
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ * async () => {
+ * try {
+ * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);
+ * console.log(result);
+ * // false
+ * // result is false since none of the files exists
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function some(coll, iteratee, callback) {
+ return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)
+ }
+ var some$1 = awaitify(some, 3);
+
+ /**
+ * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
+ *
+ * @name someLimit
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.some]{@link module:Collections.some}
+ * @alias anyLimit
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
+ * in the collections in parallel.
+ * The iteratee should complete with a boolean `result` value.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called as soon as any
+ * iteratee returns `true`, or after all the iteratee functions have finished.
+ * Result will be either `true` or `false` depending on the values of the async
+ * tests. Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ */
+ function someLimit(coll, limit, iteratee, callback) {
+ return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback)
+ }
+ var someLimit$1 = awaitify(someLimit, 4);
+
+ /**
+ * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
+ *
+ * @name someSeries
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @see [async.some]{@link module:Collections.some}
+ * @alias anySeries
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
+ * in the collections in series.
+ * The iteratee should complete with a boolean `result` value.
+ * Invoked with (item, callback).
+ * @param {Function} [callback] - A callback which is called as soon as any
+ * iteratee returns `true`, or after all the iteratee functions have finished.
+ * Result will be either `true` or `false` depending on the values of the async
+ * tests. Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ */
+ function someSeries(coll, iteratee, callback) {
+ return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)
+ }
+ var someSeries$1 = awaitify(someSeries, 3);
+
+ /**
+ * Sorts a list by the results of running each `coll` value through an async
+ * `iteratee`.
+ *
+ * @name sortBy
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
+ * `coll`.
+ * The iteratee should complete with a value to use as the sort criteria as
+ * its `result`.
+ * Invoked with (item, callback).
+ * @param {Function} callback - A callback which is called after all the
+ * `iteratee` functions have finished, or an error occurs. Results is the items
+ * from the original `coll` sorted by the values returned by the `iteratee`
+ * calls. Invoked with (err, results).
+ * @returns {Promise} a promise, if no callback passed
+ * @example
+ *
+ * // bigfile.txt is a file that is 251100 bytes in size
+ * // mediumfile.txt is a file that is 11000 bytes in size
+ * // smallfile.txt is a file that is 121 bytes in size
+ *
+ * // asynchronous function that returns the file size in bytes
+ * function getFileSizeInBytes(file, callback) {
+ * fs.stat(file, function(err, stat) {
+ * if (err) {
+ * return callback(err);
+ * }
+ * callback(null, stat.size);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,
+ * function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * } else {
+ * console.log(results);
+ * // results is now the original array of files sorted by
+ * // file size (ascending by default), e.g.
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
+ * }
+ * }
+ * );
+ *
+ * // By modifying the callback parameter the
+ * // sorting order can be influenced:
+ *
+ * // ascending order
+ * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {
+ * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
+ * if (getFileSizeErr) return callback(getFileSizeErr);
+ * callback(null, fileSize);
+ * });
+ * }, function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * } else {
+ * console.log(results);
+ * // results is now the original array of files sorted by
+ * // file size (ascending by default), e.g.
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
+ * }
+ * }
+ * );
+ *
+ * // descending order
+ * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {
+ * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
+ * if (getFileSizeErr) {
+ * return callback(getFileSizeErr);
+ * }
+ * callback(null, fileSize * -1);
+ * });
+ * }, function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * } else {
+ * console.log(results);
+ * // results is now the original array of files sorted by
+ * // file size (ascending by default), e.g.
+ * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']
+ * }
+ * }
+ * );
+ *
+ * // Error handling
+ * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,
+ * function(err, results) {
+ * if (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * } else {
+ * console.log(results);
+ * }
+ * }
+ * );
+ *
+ * // Using Promises
+ * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)
+ * .then( results => {
+ * console.log(results);
+ * // results is now the original array of files sorted by
+ * // file size (ascending by default), e.g.
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
+ * }).catch( err => {
+ * console.log(err);
+ * });
+ *
+ * // Error handling
+ * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)
+ * .then( results => {
+ * console.log(results);
+ * }).catch( err => {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * });
+ *
+ * // Using async/await
+ * (async () => {
+ * try {
+ * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
+ * console.log(results);
+ * // results is now the original array of files sorted by
+ * // file size (ascending by default), e.g.
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * })();
+ *
+ * // Error handling
+ * async () => {
+ * try {
+ * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
+ * console.log(results);
+ * }
+ * catch (err) {
+ * console.log(err);
+ * // [ Error: ENOENT: no such file or directory ]
+ * }
+ * }
+ *
+ */
+ function sortBy (coll, iteratee, callback) {
+ var _iteratee = wrapAsync(iteratee);
+ return map$1(coll, (x, iterCb) => {
+ _iteratee(x, (err, criteria) => {
+ if (err) return iterCb(err);
+ iterCb(err, {value: x, criteria});
+ });
+ }, (err, results) => {
+ if (err) return callback(err);
+ callback(null, results.sort(comparator).map(v => v.value));
+ });
+
+ function comparator(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }
+ }
+ var sortBy$1 = awaitify(sortBy, 3);
+
+ /**
+ * Sets a time limit on an asynchronous function. If the function does not call
+ * its callback within the specified milliseconds, it will be called with a
+ * timeout error. The code property for the error object will be `'ETIMEDOUT'`.
+ *
+ * @name timeout
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @category Util
+ * @param {AsyncFunction} asyncFn - The async function to limit in time.
+ * @param {number} milliseconds - The specified time limit.
+ * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
+ * to timeout Error for more information..
+ * @returns {AsyncFunction} Returns a wrapped function that can be used with any
+ * of the control flow functions.
+ * Invoke this function with the same parameters as you would `asyncFunc`.
+ * @example
+ *
+ * function myFunction(foo, callback) {
+ * doAsyncTask(foo, function(err, data) {
+ * // handle errors
+ * if (err) return callback(err);
+ *
+ * // do some stuff ...
+ *
+ * // return processed data
+ * return callback(null, data);
+ * });
+ * }
+ *
+ * var wrapped = async.timeout(myFunction, 1000);
+ *
+ * // call `wrapped` as you would `myFunction`
+ * wrapped({ bar: 'bar' }, function(err, data) {
+ * // if `myFunction` takes < 1000 ms to execute, `err`
+ * // and `data` will have their expected values
+ *
+ * // else `err` will be an Error with the code 'ETIMEDOUT'
+ * });
+ */
+ function timeout(asyncFn, milliseconds, info) {
+ var fn = wrapAsync(asyncFn);
+
+ return initialParams((args, callback) => {
+ var timedOut = false;
+ var timer;
+
+ function timeoutCallback() {
+ var name = asyncFn.name || 'anonymous';
+ var error = new Error('Callback function "' + name + '" timed out.');
+ error.code = 'ETIMEDOUT';
+ if (info) {
+ error.info = info;
+ }
+ timedOut = true;
+ callback(error);
+ }
+
+ args.push((...cbArgs) => {
+ if (!timedOut) {
+ callback(...cbArgs);
+ clearTimeout(timer);
+ }
+ });
+
+ // setup timer and call original function
+ timer = setTimeout(timeoutCallback, milliseconds);
+ fn(...args);
+ });
+ }
+
+ function range(size) {
+ var result = Array(size);
+ while (size--) {
+ result[size] = size;
+ }
+ return result;
+ }
+
+ /**
+ * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
+ * time.
+ *
+ * @name timesLimit
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.times]{@link module:ControlFlow.times}
+ * @category Control Flow
+ * @param {number} count - The number of times to run the function.
+ * @param {number} limit - The maximum number of async operations at a time.
+ * @param {AsyncFunction} iteratee - The async function to call `n` times.
+ * Invoked with the iteration index and a callback: (n, next).
+ * @param {Function} callback - see [async.map]{@link module:Collections.map}.
+ * @returns {Promise} a promise, if no callback is provided
+ */
+ function timesLimit(count, limit, iteratee, callback) {
+ var _iteratee = wrapAsync(iteratee);
+ return mapLimit$1(range(count), limit, _iteratee, callback);
+ }
+
+ /**
+ * Calls the `iteratee` function `n` times, and accumulates results in the same
+ * manner you would use with [map]{@link module:Collections.map}.
+ *
+ * @name times
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.map]{@link module:Collections.map}
+ * @category Control Flow
+ * @param {number} n - The number of times to run the function.
+ * @param {AsyncFunction} iteratee - The async function to call `n` times.
+ * Invoked with the iteration index and a callback: (n, next).
+ * @param {Function} callback - see {@link module:Collections.map}.
+ * @returns {Promise} a promise, if no callback is provided
+ * @example
+ *
+ * // Pretend this is some complicated async factory
+ * var createUser = function(id, callback) {
+ * callback(null, {
+ * id: 'user' + id
+ * });
+ * };
+ *
+ * // generate 5 users
+ * async.times(5, function(n, next) {
+ * createUser(n, function(err, user) {
+ * next(err, user);
+ * });
+ * }, function(err, users) {
+ * // we should now have 5 users
+ * });
+ */
+ function times (n, iteratee, callback) {
+ return timesLimit(n, Infinity, iteratee, callback)
+ }
+
+ /**
+ * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.
+ *
+ * @name timesSeries
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.times]{@link module:ControlFlow.times}
+ * @category Control Flow
+ * @param {number} n - The number of times to run the function.
+ * @param {AsyncFunction} iteratee - The async function to call `n` times.
+ * Invoked with the iteration index and a callback: (n, next).
+ * @param {Function} callback - see {@link module:Collections.map}.
+ * @returns {Promise} a promise, if no callback is provided
+ */
+ function timesSeries (n, iteratee, callback) {
+ return timesLimit(n, 1, iteratee, callback)
+ }
+
+ /**
+ * A relative of `reduce`. Takes an Object or Array, and iterates over each
+ * element in parallel, each step potentially mutating an `accumulator` value.
+ * The type of the accumulator defaults to the type of collection passed in.
+ *
+ * @name transform
+ * @static
+ * @memberOf module:Collections
+ * @method
+ * @category Collection
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
+ * @param {*} [accumulator] - The initial state of the transform. If omitted,
+ * it will default to an empty Object or Array, depending on the type of `coll`
+ * @param {AsyncFunction} iteratee - A function applied to each item in the
+ * collection that potentially modifies the accumulator.
+ * Invoked with (accumulator, item, key, callback).
+ * @param {Function} [callback] - A callback which is called after all the
+ * `iteratee` functions have finished. Result is the transformed accumulator.
+ * Invoked with (err, result).
+ * @returns {Promise} a promise, if no callback provided
+ * @example
+ *
+ * // file1.txt is a file that is 1000 bytes in size
+ * // file2.txt is a file that is 2000 bytes in size
+ * // file3.txt is a file that is 3000 bytes in size
+ *
+ * // helper function that returns human-readable size format from bytes
+ * function formatBytes(bytes, decimals = 2) {
+ * // implementation not included for brevity
+ * return humanReadbleFilesize;
+ * }
+ *
+ * const fileList = ['file1.txt','file2.txt','file3.txt'];
+ *
+ * // asynchronous function that returns the file size, transformed to human-readable format
+ * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.
+ * function transformFileSize(acc, value, key, callback) {
+ * fs.stat(value, function(err, stat) {
+ * if (err) {
+ * return callback(err);
+ * }
+ * acc[key] = formatBytes(stat.size);
+ * callback(null);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.transform(fileList, transformFileSize, function(err, result) {
+ * if(err) {
+ * console.log(err);
+ * } else {
+ * console.log(result);
+ * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.transform(fileList, transformFileSize)
+ * .then(result => {
+ * console.log(result);
+ * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * (async () => {
+ * try {
+ * let result = await async.transform(fileList, transformFileSize);
+ * console.log(result);
+ * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * })();
+ *
+ * @example
+ *
+ * // file1.txt is a file that is 1000 bytes in size
+ * // file2.txt is a file that is 2000 bytes in size
+ * // file3.txt is a file that is 3000 bytes in size
+ *
+ * // helper function that returns human-readable size format from bytes
+ * function formatBytes(bytes, decimals = 2) {
+ * // implementation not included for brevity
+ * return humanReadbleFilesize;
+ * }
+ *
+ * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' };
+ *
+ * // asynchronous function that returns the file size, transformed to human-readable format
+ * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.
+ * function transformFileSize(acc, value, key, callback) {
+ * fs.stat(value, function(err, stat) {
+ * if (err) {
+ * return callback(err);
+ * }
+ * acc[key] = formatBytes(stat.size);
+ * callback(null);
+ * });
+ * }
+ *
+ * // Using callbacks
+ * async.transform(fileMap, transformFileSize, function(err, result) {
+ * if(err) {
+ * console.log(err);
+ * } else {
+ * console.log(result);
+ * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
+ * }
+ * });
+ *
+ * // Using Promises
+ * async.transform(fileMap, transformFileSize)
+ * .then(result => {
+ * console.log(result);
+ * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
+ * }).catch(err => {
+ * console.log(err);
+ * });
+ *
+ * // Using async/await
+ * async () => {
+ * try {
+ * let result = await async.transform(fileMap, transformFileSize);
+ * console.log(result);
+ * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
+ * }
+ * catch (err) {
+ * console.log(err);
+ * }
+ * }
+ *
+ */
+ function transform (coll, accumulator, iteratee, callback) {
+ if (arguments.length <= 3 && typeof accumulator === 'function') {
+ callback = iteratee;
+ iteratee = accumulator;
+ accumulator = Array.isArray(coll) ? [] : {};
+ }
+ callback = once(callback || promiseCallback());
+ var _iteratee = wrapAsync(iteratee);
+
+ eachOf$1(coll, (v, k, cb) => {
+ _iteratee(accumulator, v, k, cb);
+ }, err => callback(err, accumulator));
+ return callback[PROMISE_SYMBOL]
+ }
+
+ /**
+ * It runs each task in series but stops whenever any of the functions were
+ * successful. If one of the tasks were successful, the `callback` will be
+ * passed the result of the successful task. If all tasks fail, the callback
+ * will be passed the error and result (if any) of the final attempt.
+ *
+ * @name tryEach
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to
+ * run, each function is passed a `callback(err, result)` it must call on
+ * completion with an error `err` (which can be `null`) and an optional `result`
+ * value.
+ * @param {Function} [callback] - An optional callback which is called when one
+ * of the tasks has succeeded, or all have failed. It receives the `err` and
+ * `result` arguments of the last attempt at completing the `task`. Invoked with
+ * (err, results).
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ * async.tryEach([
+ * function getDataFromFirstWebsite(callback) {
+ * // Try getting the data from the first website
+ * callback(err, data);
+ * },
+ * function getDataFromSecondWebsite(callback) {
+ * // First website failed,
+ * // Try getting the data from the backup website
+ * callback(err, data);
+ * }
+ * ],
+ * // optional callback
+ * function(err, results) {
+ * Now do something with the data.
+ * });
+ *
+ */
+ function tryEach(tasks, callback) {
+ var error = null;
+ var result;
+ return eachSeries$1(tasks, (task, taskCb) => {
+ wrapAsync(task)((err, ...args) => {
+ if (err === false) return taskCb(err);
+
+ if (args.length < 2) {
+ [result] = args;
+ } else {
+ result = args;
+ }
+ error = err;
+ taskCb(err ? null : {});
+ });
+ }, () => callback(error, result));
+ }
+
+ var tryEach$1 = awaitify(tryEach);
+
+ /**
+ * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,
+ * unmemoized form. Handy for testing.
+ *
+ * @name unmemoize
+ * @static
+ * @memberOf module:Utils
+ * @method
+ * @see [async.memoize]{@link module:Utils.memoize}
+ * @category Util
+ * @param {AsyncFunction} fn - the memoized function
+ * @returns {AsyncFunction} a function that calls the original unmemoized function
+ */
+ function unmemoize(fn) {
+ return (...args) => {
+ return (fn.unmemoized || fn)(...args);
+ };
+ }
+
+ /**
+ * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
+ * stopped, or an error occurs.
+ *
+ * @name whilst
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {AsyncFunction} test - asynchronous truth test to perform before each
+ * execution of `iteratee`. Invoked with ().
+ * @param {AsyncFunction} iteratee - An async function which is called each time
+ * `test` passes. Invoked with (callback).
+ * @param {Function} [callback] - A callback which is called after the test
+ * function has failed and repeated execution of `iteratee` has stopped. `callback`
+ * will be passed an error and any arguments passed to the final `iteratee`'s
+ * callback. Invoked with (err, [results]);
+ * @returns {Promise} a promise, if no callback is passed
+ * @example
+ *
+ * var count = 0;
+ * async.whilst(
+ * function test(cb) { cb(null, count < 5); },
+ * function iter(callback) {
+ * count++;
+ * setTimeout(function() {
+ * callback(null, count);
+ * }, 1000);
+ * },
+ * function (err, n) {
+ * // 5 seconds have passed, n = 5
+ * }
+ * );
+ */
+ function whilst(test, iteratee, callback) {
+ callback = onlyOnce(callback);
+ var _fn = wrapAsync(iteratee);
+ var _test = wrapAsync(test);
+ var results = [];
+
+ function next(err, ...rest) {
+ if (err) return callback(err);
+ results = rest;
+ if (err === false) return;
+ _test(check);
+ }
+
+ function check(err, truth) {
+ if (err) return callback(err);
+ if (err === false) return;
+ if (!truth) return callback(null, ...results);
+ _fn(next);
+ }
+
+ return _test(check);
+ }
+ var whilst$1 = awaitify(whilst, 3);
+
+ /**
+ * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
+ * stopped, or an error occurs. `callback` will be passed an error and any
+ * arguments passed to the final `iteratee`'s callback.
+ *
+ * The inverse of [whilst]{@link module:ControlFlow.whilst}.
+ *
+ * @name until
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @see [async.whilst]{@link module:ControlFlow.whilst}
+ * @category Control Flow
+ * @param {AsyncFunction} test - asynchronous truth test to perform before each
+ * execution of `iteratee`. Invoked with (callback).
+ * @param {AsyncFunction} iteratee - An async function which is called each time
+ * `test` fails. Invoked with (callback).
+ * @param {Function} [callback] - A callback which is called after the test
+ * function has passed and repeated execution of `iteratee` has stopped. `callback`
+ * will be passed an error and any arguments passed to the final `iteratee`'s
+ * callback. Invoked with (err, [results]);
+ * @returns {Promise} a promise, if a callback is not passed
+ *
+ * @example
+ * const results = []
+ * let finished = false
+ * async.until(function test(cb) {
+ * cb(null, finished)
+ * }, function iter(next) {
+ * fetchPage(url, (err, body) => {
+ * if (err) return next(err)
+ * results = results.concat(body.objects)
+ * finished = !!body.next
+ * next(err)
+ * })
+ * }, function done (err) {
+ * // all pages have been fetched
+ * })
+ */
+ function until(test, iteratee, callback) {
+ const _test = wrapAsync(test);
+ return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);
+ }
+
+ /**
+ * Runs the `tasks` array of functions in series, each passing their results to
+ * the next in the array. However, if any of the `tasks` pass an error to their
+ * own callback, the next function is not executed, and the main `callback` is
+ * immediately called with the error.
+ *
+ * @name waterfall
+ * @static
+ * @memberOf module:ControlFlow
+ * @method
+ * @category Control Flow
+ * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
+ * to run.
+ * Each function should complete with any number of `result` values.
+ * The `result` values will be passed as arguments, in order, to the next task.
+ * @param {Function} [callback] - An optional callback to run once all the
+ * functions have completed. This will be passed the results of the last task's
+ * callback. Invoked with (err, [results]).
+ * @returns {Promise} a promise, if a callback is omitted
+ * @example
+ *
+ * async.waterfall([
+ * function(callback) {
+ * callback(null, 'one', 'two');
+ * },
+ * function(arg1, arg2, callback) {
+ * // arg1 now equals 'one' and arg2 now equals 'two'
+ * callback(null, 'three');
+ * },
+ * function(arg1, callback) {
+ * // arg1 now equals 'three'
+ * callback(null, 'done');
+ * }
+ * ], function (err, result) {
+ * // result now equals 'done'
+ * });
+ *
+ * // Or, with named functions:
+ * async.waterfall([
+ * myFirstFunction,
+ * mySecondFunction,
+ * myLastFunction,
+ * ], function (err, result) {
+ * // result now equals 'done'
+ * });
+ * function myFirstFunction(callback) {
+ * callback(null, 'one', 'two');
+ * }
+ * function mySecondFunction(arg1, arg2, callback) {
+ * // arg1 now equals 'one' and arg2 now equals 'two'
+ * callback(null, 'three');
+ * }
+ * function myLastFunction(arg1, callback) {
+ * // arg1 now equals 'three'
+ * callback(null, 'done');
+ * }
+ */
+ function waterfall (tasks, callback) {
+ callback = once(callback);
+ if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
+ if (!tasks.length) return callback();
+ var taskIndex = 0;
+
+ function nextTask(args) {
+ var task = wrapAsync(tasks[taskIndex++]);
+ task(...args, onlyOnce(next));
+ }
+
+ function next(err, ...args) {
+ if (err === false) return
+ if (err || taskIndex === tasks.length) {
+ return callback(err, ...args);
+ }
+ nextTask(args);
+ }
+
+ nextTask([]);
+ }
+
+ var waterfall$1 = awaitify(waterfall);
+
+ /**
+ * An "async function" in the context of Async is an asynchronous function with
+ * a variable number of parameters, with the final parameter being a callback.
+ * (`function (arg1, arg2, ..., callback) {}`)
+ * The final callback is of the form `callback(err, results...)`, which must be
+ * called once the function is completed. The callback should be called with a
+ * Error as its first argument to signal that an error occurred.
+ * Otherwise, if no error occurred, it should be called with `null` as the first
+ * argument, and any additional `result` arguments that may apply, to signal
+ * successful completion.
+ * The callback must be called exactly once, ideally on a later tick of the
+ * JavaScript event loop.
+ *
+ * This type of function is also referred to as a "Node-style async function",
+ * or a "continuation passing-style function" (CPS). Most of the methods of this
+ * library are themselves CPS/Node-style async functions, or functions that
+ * return CPS/Node-style async functions.
+ *
+ * Wherever we accept a Node-style async function, we also directly accept an
+ * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
+ * In this case, the `async` function will not be passed a final callback
+ * argument, and any thrown error will be used as the `err` argument of the
+ * implicit callback, and the return value will be used as the `result` value.
+ * (i.e. a `rejected` of the returned Promise becomes the `err` callback
+ * argument, and a `resolved` value becomes the `result`.)
+ *
+ * Note, due to JavaScript limitations, we can only detect native `async`
+ * functions and not transpilied implementations.
+ * Your environment must have `async`/`await` support for this to work.
+ * (e.g. Node > v7.6, or a recent version of a modern browser).
+ * If you are using `async` functions through a transpiler (e.g. Babel), you
+ * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
+ * because the `async function` will be compiled to an ordinary function that
+ * returns a promise.
+ *
+ * @typedef {Function} AsyncFunction
+ * @static
+ */
+
+ var index = {
+ apply,
+ applyEach: applyEach$1,
+ applyEachSeries,
+ asyncify,
+ auto,
+ autoInject,
+ cargo,
+ cargoQueue: cargo$1,
+ compose,
+ concat: concat$1,
+ concatLimit: concatLimit$1,
+ concatSeries: concatSeries$1,
+ constant,
+ detect: detect$1,
+ detectLimit: detectLimit$1,
+ detectSeries: detectSeries$1,
+ dir,
+ doUntil,
+ doWhilst: doWhilst$1,
+ each,
+ eachLimit: eachLimit$2,
+ eachOf: eachOf$1,
+ eachOfLimit: eachOfLimit$2,
+ eachOfSeries: eachOfSeries$1,
+ eachSeries: eachSeries$1,
+ ensureAsync,
+ every: every$1,
+ everyLimit: everyLimit$1,
+ everySeries: everySeries$1,
+ filter: filter$1,
+ filterLimit: filterLimit$1,
+ filterSeries: filterSeries$1,
+ forever: forever$1,
+ groupBy,
+ groupByLimit: groupByLimit$1,
+ groupBySeries,
+ log,
+ map: map$1,
+ mapLimit: mapLimit$1,
+ mapSeries: mapSeries$1,
+ mapValues,
+ mapValuesLimit: mapValuesLimit$1,
+ mapValuesSeries,
+ memoize,
+ nextTick,
+ parallel: parallel$1,
+ parallelLimit,
+ priorityQueue,
+ queue: queue$1,
+ race: race$1,
+ reduce: reduce$1,
+ reduceRight,
+ reflect,
+ reflectAll,
+ reject: reject$2,
+ rejectLimit: rejectLimit$1,
+ rejectSeries: rejectSeries$1,
+ retry,
+ retryable,
+ seq,
+ series,
+ setImmediate: setImmediate$1,
+ some: some$1,
+ someLimit: someLimit$1,
+ someSeries: someSeries$1,
+ sortBy: sortBy$1,
+ timeout,
+ times,
+ timesLimit,
+ timesSeries,
+ transform,
+ tryEach: tryEach$1,
+ unmemoize,
+ until,
+ waterfall: waterfall$1,
+ whilst: whilst$1,
+
+ // aliases
+ all: every$1,
+ allLimit: everyLimit$1,
+ allSeries: everySeries$1,
+ any: some$1,
+ anyLimit: someLimit$1,
+ anySeries: someSeries$1,
+ find: detect$1,
+ findLimit: detectLimit$1,
+ findSeries: detectSeries$1,
+ flatMap: concat$1,
+ flatMapLimit: concatLimit$1,
+ flatMapSeries: concatSeries$1,
+ forEach: each,
+ forEachSeries: eachSeries$1,
+ forEachLimit: eachLimit$2,
+ forEachOf: eachOf$1,
+ forEachOfSeries: eachOfSeries$1,
+ forEachOfLimit: eachOfLimit$2,
+ inject: reduce$1,
+ foldl: reduce$1,
+ foldr: reduceRight,
+ select: filter$1,
+ selectLimit: filterLimit$1,
+ selectSeries: filterSeries$1,
+ wrapSync: asyncify,
+ during: whilst$1,
+ doDuring: doWhilst$1
+ };
+
+ exports.default = index;
+ exports.apply = apply;
+ exports.applyEach = applyEach$1;
+ exports.applyEachSeries = applyEachSeries;
+ exports.asyncify = asyncify;
+ exports.auto = auto;
+ exports.autoInject = autoInject;
+ exports.cargo = cargo;
+ exports.cargoQueue = cargo$1;
+ exports.compose = compose;
+ exports.concat = concat$1;
+ exports.concatLimit = concatLimit$1;
+ exports.concatSeries = concatSeries$1;
+ exports.constant = constant;
+ exports.detect = detect$1;
+ exports.detectLimit = detectLimit$1;
+ exports.detectSeries = detectSeries$1;
+ exports.dir = dir;
+ exports.doUntil = doUntil;
+ exports.doWhilst = doWhilst$1;
+ exports.each = each;
+ exports.eachLimit = eachLimit$2;
+ exports.eachOf = eachOf$1;
+ exports.eachOfLimit = eachOfLimit$2;
+ exports.eachOfSeries = eachOfSeries$1;
+ exports.eachSeries = eachSeries$1;
+ exports.ensureAsync = ensureAsync;
+ exports.every = every$1;
+ exports.everyLimit = everyLimit$1;
+ exports.everySeries = everySeries$1;
+ exports.filter = filter$1;
+ exports.filterLimit = filterLimit$1;
+ exports.filterSeries = filterSeries$1;
+ exports.forever = forever$1;
+ exports.groupBy = groupBy;
+ exports.groupByLimit = groupByLimit$1;
+ exports.groupBySeries = groupBySeries;
+ exports.log = log;
+ exports.map = map$1;
+ exports.mapLimit = mapLimit$1;
+ exports.mapSeries = mapSeries$1;
+ exports.mapValues = mapValues;
+ exports.mapValuesLimit = mapValuesLimit$1;
+ exports.mapValuesSeries = mapValuesSeries;
+ exports.memoize = memoize;
+ exports.nextTick = nextTick;
+ exports.parallel = parallel$1;
+ exports.parallelLimit = parallelLimit;
+ exports.priorityQueue = priorityQueue;
+ exports.queue = queue$1;
+ exports.race = race$1;
+ exports.reduce = reduce$1;
+ exports.reduceRight = reduceRight;
+ exports.reflect = reflect;
+ exports.reflectAll = reflectAll;
+ exports.reject = reject$2;
+ exports.rejectLimit = rejectLimit$1;
+ exports.rejectSeries = rejectSeries$1;
+ exports.retry = retry;
+ exports.retryable = retryable;
+ exports.seq = seq;
+ exports.series = series;
+ exports.setImmediate = setImmediate$1;
+ exports.some = some$1;
+ exports.someLimit = someLimit$1;
+ exports.someSeries = someSeries$1;
+ exports.sortBy = sortBy$1;
+ exports.timeout = timeout;
+ exports.times = times;
+ exports.timesLimit = timesLimit;
+ exports.timesSeries = timesSeries;
+ exports.transform = transform;
+ exports.tryEach = tryEach$1;
+ exports.unmemoize = unmemoize;
+ exports.until = until;
+ exports.waterfall = waterfall$1;
+ exports.whilst = whilst$1;
+ exports.all = every$1;
+ exports.allLimit = everyLimit$1;
+ exports.allSeries = everySeries$1;
+ exports.any = some$1;
+ exports.anyLimit = someLimit$1;
+ exports.anySeries = someSeries$1;
+ exports.find = detect$1;
+ exports.findLimit = detectLimit$1;
+ exports.findSeries = detectSeries$1;
+ exports.flatMap = concat$1;
+ exports.flatMapLimit = concatLimit$1;
+ exports.flatMapSeries = concatSeries$1;
+ exports.forEach = each;
+ exports.forEachSeries = eachSeries$1;
+ exports.forEachLimit = eachLimit$2;
+ exports.forEachOf = eachOf$1;
+ exports.forEachOfSeries = eachOfSeries$1;
+ exports.forEachOfLimit = eachOfLimit$2;
+ exports.inject = reduce$1;
+ exports.foldl = reduce$1;
+ exports.foldr = reduceRight;
+ exports.select = filter$1;
+ exports.selectLimit = filterLimit$1;
+ exports.selectSeries = filterSeries$1;
+ exports.wrapSync = asyncify;
+ exports.during = whilst$1;
+ exports.doDuring = doWhilst$1;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
+
+
+/***/ }),
+
+/***/ 9165:
+/***/ ((module, exports, __nccwpck_require__) => {
+
+var merge = __nccwpck_require__(6247)
+var ffmpeg = __nccwpck_require__(1859)
+var version = (__nccwpck_require__(1439)/* .version */ .i8)
+
+module.exports = exports = function (inputs, opts) {
+ return new Audioconcat(inputs, opts)
+}
+
+exports.VERSION = version
+exports.ffmpeg = ffmpeg
+
+function Audioconcat(inputs, opts) {
+ this.inputs = inputs || []
+ this.opts = opts || {}
+}
+
+Audioconcat.prototype.options = function (opts) {
+ merge(this.opts, opts)
+ return this
+}
+
+Audioconcat.prototype.concat = function (file) {
+ if (file) {
+ this.opts.output = file
+ }
+ return concat(this.inputs, this.opts)
+}
+
+function concat(inputs, opts) {
+ var filter = 'concat:' + inputs.join('|')
+
+ var renderer = ffmpeg()
+ .input(filter)
+ .outputOptions('-acodec copy')
+
+ var output = opts.output
+ if (output) {
+ return renderer.save(output)
+ }
+
+ return renderer
+}
+
+
+/***/ }),
+
+/***/ 9417:
+/***/ ((module) => {
+
+"use strict";
+
+module.exports = balanced;
+function balanced(a, b, str) {
+ if (a instanceof RegExp) a = maybeMatch(a, str);
+ if (b instanceof RegExp) b = maybeMatch(b, str);
+
+ var r = range(a, b, str);
+
+ return r && {
+ start: r[0],
+ end: r[1],
+ pre: str.slice(0, r[0]),
+ body: str.slice(r[0] + a.length, r[1]),
+ post: str.slice(r[1] + b.length)
+ };
+}
+
+function maybeMatch(reg, str) {
+ var m = str.match(reg);
+ return m ? m[0] : null;
+}
+
+balanced.range = range;
+function range(a, b, str) {
+ var begs, beg, left, right, result;
+ var ai = str.indexOf(a);
+ var bi = str.indexOf(b, ai + 1);
+ var i = ai;
+
+ if (ai >= 0 && bi > 0) {
+ if(a===b) {
+ return [ai, bi];
+ }
+ begs = [];
+ left = str.length;
+
+ while (i >= 0 && !result) {
+ if (i == ai) {
+ begs.push(i);
+ ai = str.indexOf(a, i + 1);
+ } else if (begs.length == 1) {
+ result = [ begs.pop(), bi ];
+ } else {
+ beg = begs.pop();
+ if (beg < left) {
+ left = beg;
+ right = bi;
+ }
+
+ bi = str.indexOf(b, i + 1);
+ }
+
+ i = ai < bi && ai >= 0 ? ai : bi;
+ }
+
+ if (begs.length) {
+ result = [ left, right ];
+ }
+ }
+
+ return result;
+}
+
+
+/***/ }),
+
+/***/ 9030:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/**
+ * @author shaozilee
+ *
+ * support 1bit 4bit 8bit 24bit decode
+ * encode with 24bit
+ *
+ */
+
+var encode = __nccwpck_require__(4551),
+ decode = __nccwpck_require__(2767);
+
+module.exports = {
+ encode: encode,
+ decode: decode
+};
+
+
+/***/ }),
+
+/***/ 2767:
+/***/ ((module) => {
+
+/**
+ * @author shaozilee
+ *
+ * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
+ *
+ */
+
+function BmpDecoder(buffer,is_with_alpha) {
+ this.pos = 0;
+ this.buffer = buffer;
+ this.is_with_alpha = !!is_with_alpha;
+ this.bottom_up = true;
+ this.flag = this.buffer.toString("utf-8", 0, this.pos += 2);
+ if (this.flag != "BM") throw new Error("Invalid BMP File");
+ this.parseHeader();
+ this.parseRGBA();
+}
+
+BmpDecoder.prototype.parseHeader = function() {
+ this.fileSize = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.reserved = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.offset = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.headerSize = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.width = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.height = this.buffer.readInt32LE(this.pos);
+ this.pos += 4;
+ this.planes = this.buffer.readUInt16LE(this.pos);
+ this.pos += 2;
+ this.bitPP = this.buffer.readUInt16LE(this.pos);
+ this.pos += 2;
+ this.compress = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.rawSize = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.hr = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.vr = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.colors = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+ this.importantColors = this.buffer.readUInt32LE(this.pos);
+ this.pos += 4;
+
+ if(this.bitPP === 16 && this.is_with_alpha){
+ this.bitPP = 15
+ }
+ if (this.bitPP < 15) {
+ var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
+ this.palette = new Array(len);
+ for (var i = 0; i < len; i++) {
+ var blue = this.buffer.readUInt8(this.pos++);
+ var green = this.buffer.readUInt8(this.pos++);
+ var red = this.buffer.readUInt8(this.pos++);
+ var quad = this.buffer.readUInt8(this.pos++);
+ this.palette[i] = {
+ red: red,
+ green: green,
+ blue: blue,
+ quad: quad
+ };
+ }
+ }
+ if(this.height < 0) {
+ this.height *= -1;
+ this.bottom_up = false;
+ }
+
+}
+
+BmpDecoder.prototype.parseRGBA = function() {
+ var bitn = "bit" + this.bitPP;
+ var len = this.width * this.height * 4;
+ this.data = new Buffer(len);
+ this[bitn]();
+};
+
+BmpDecoder.prototype.bit1 = function() {
+ var xlen = Math.ceil(this.width / 8);
+ var mode = xlen%4;
+ var y = this.height >= 0 ? this.height - 1 : -this.height
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y
+ for (var x = 0; x < xlen; x++) {
+ var b = this.buffer.readUInt8(this.pos++);
+ var location = line * this.width * 4 + x*8*4;
+ for (var i = 0; i < 8; i++) {
+ if(x*8+i>(7-i))&0x1)];
+
+ this.data[location+i*4] = 0;
+ this.data[location+i*4 + 1] = rgb.blue;
+ this.data[location+i*4 + 2] = rgb.green;
+ this.data[location+i*4 + 3] = rgb.red;
+
+ }else{
+ break;
+ }
+ }
+ }
+
+ if (mode != 0){
+ this.pos+=(4 - mode);
+ }
+ }
+};
+
+BmpDecoder.prototype.bit4 = function() {
+ //RLE-4
+ if(this.compress == 2){
+ this.data.fill(0xff);
+
+ var location = 0;
+ var lines = this.bottom_up?this.height-1:0;
+ var low_nibble = false;//for all count of pixel
+
+ while(location>4);
+ }
+
+ if ((i & 1) && (i+1 < b)){
+ c = this.buffer.readUInt8(this.pos++);
+ }
+
+ low_nibble = !low_nibble;
+ }
+
+ if ((((b+1) >> 1) & 1 ) == 1){
+ this.pos++
+ }
+ }
+
+ }else{//encoded mode
+ for (var i = 0; i < a; i++) {
+ if (low_nibble) {
+ setPixelData.call(this, (b & 0x0f));
+ } else {
+ setPixelData.call(this, (b & 0xf0)>>4);
+ }
+ low_nibble = !low_nibble;
+ }
+ }
+
+ }
+
+
+
+
+ function setPixelData(rgbIndex){
+ var rgb = this.palette[rgbIndex];
+ this.data[location] = 0;
+ this.data[location + 1] = rgb.blue;
+ this.data[location + 2] = rgb.green;
+ this.data[location + 3] = rgb.red;
+ location+=4;
+ }
+ }else{
+
+ var xlen = Math.ceil(this.width/2);
+ var mode = xlen%4;
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y
+ for (var x = 0; x < xlen; x++) {
+ var b = this.buffer.readUInt8(this.pos++);
+ var location = line * this.width * 4 + x*2*4;
+
+ var before = b>>4;
+ var after = b&0x0F;
+
+ var rgb = this.palette[before];
+ this.data[location] = 0;
+ this.data[location + 1] = rgb.blue;
+ this.data[location + 2] = rgb.green;
+ this.data[location + 3] = rgb.red;
+
+
+ if(x*2+1>=this.width)break;
+
+ rgb = this.palette[after];
+
+ this.data[location+4] = 0;
+ this.data[location+4 + 1] = rgb.blue;
+ this.data[location+4 + 2] = rgb.green;
+ this.data[location+4 + 3] = rgb.red;
+
+ }
+
+ if (mode != 0){
+ this.pos+=(4 - mode);
+ }
+ }
+
+ }
+
+};
+
+BmpDecoder.prototype.bit8 = function() {
+ //RLE-8
+ if(this.compress == 1){
+ this.data.fill(0xff);
+
+ var location = 0;
+ var lines = this.bottom_up?this.height-1:0;
+
+ while(location= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y
+ for (var x = 0; x < this.width; x++) {
+ var b = this.buffer.readUInt8(this.pos++);
+ var location = line * this.width * 4 + x * 4;
+ if (b < this.palette.length) {
+ var rgb = this.palette[b];
+
+ this.data[location] = 0;
+ this.data[location + 1] = rgb.blue;
+ this.data[location + 2] = rgb.green;
+ this.data[location + 3] = rgb.red;
+
+ } else {
+ this.data[location] = 0;
+ this.data[location + 1] = 0xFF;
+ this.data[location + 2] = 0xFF;
+ this.data[location + 3] = 0xFF;
+ }
+ }
+ if (mode != 0) {
+ this.pos += (4 - mode);
+ }
+ }
+ }
+};
+
+BmpDecoder.prototype.bit15 = function() {
+ var dif_w =this.width % 3;
+ var _11111 = parseInt("11111", 2),_1_5 = _11111;
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y
+ for (var x = 0; x < this.width; x++) {
+
+ var B = this.buffer.readUInt16LE(this.pos);
+ this.pos+=2;
+ var blue = (B & _1_5) / _1_5 * 255 | 0;
+ var green = (B >> 5 & _1_5 ) / _1_5 * 255 | 0;
+ var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;
+ var alpha = (B>>15)?0xFF:0x00;
+
+ var location = line * this.width * 4 + x * 4;
+
+ this.data[location] = alpha;
+ this.data[location + 1] = blue;
+ this.data[location + 2] = green;
+ this.data[location + 3] = red;
+ }
+ //skip extra bytes
+ this.pos += dif_w;
+ }
+};
+
+BmpDecoder.prototype.bit16 = function() {
+ var dif_w =(this.width % 2)*2;
+ //default xrgb555
+ this.maskRed = 0x7C00;
+ this.maskGreen = 0x3E0;
+ this.maskBlue =0x1F;
+ this.mask0 = 0;
+
+ if(this.compress == 3){
+ this.maskRed = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ this.maskGreen = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ this.maskBlue = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ this.mask0 = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ }
+
+
+ var ns=[0,0,0];
+ for (var i=0;i<16;i++){
+ if ((this.maskRed>>i)&0x01) ns[0]++;
+ if ((this.maskGreen>>i)&0x01) ns[1]++;
+ if ((this.maskBlue>>i)&0x01) ns[2]++;
+ }
+ ns[1]+=ns[0]; ns[2]+=ns[1]; ns[0]=8-ns[0]; ns[1]-=8; ns[2]-=8;
+
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y;
+ for (var x = 0; x < this.width; x++) {
+
+ var B = this.buffer.readUInt16LE(this.pos);
+ this.pos+=2;
+
+ var blue = (B&this.maskBlue)<>ns[1];
+ var red = (B&this.maskRed)>>ns[2];
+
+ var location = line * this.width * 4 + x * 4;
+
+ this.data[location] = 0;
+ this.data[location + 1] = blue;
+ this.data[location + 2] = green;
+ this.data[location + 3] = red;
+ }
+ //skip extra bytes
+ this.pos += dif_w;
+ }
+};
+
+BmpDecoder.prototype.bit24 = function() {
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y
+ for (var x = 0; x < this.width; x++) {
+ //Little Endian rgb
+ var blue = this.buffer.readUInt8(this.pos++);
+ var green = this.buffer.readUInt8(this.pos++);
+ var red = this.buffer.readUInt8(this.pos++);
+ var location = line * this.width * 4 + x * 4;
+ this.data[location] = 0;
+ this.data[location + 1] = blue;
+ this.data[location + 2] = green;
+ this.data[location + 3] = red;
+ }
+ //skip extra bytes
+ this.pos += (this.width % 4);
+ }
+
+};
+
+/**
+ * add 32bit decode func
+ * @author soubok
+ */
+BmpDecoder.prototype.bit32 = function() {
+ //BI_BITFIELDS
+ if(this.compress == 3){
+ this.maskRed = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ this.maskGreen = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ this.maskBlue = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ this.mask0 = this.buffer.readUInt32LE(this.pos);
+ this.pos+=4;
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y;
+ for (var x = 0; x < this.width; x++) {
+ //Little Endian rgba
+ var alpha = this.buffer.readUInt8(this.pos++);
+ var blue = this.buffer.readUInt8(this.pos++);
+ var green = this.buffer.readUInt8(this.pos++);
+ var red = this.buffer.readUInt8(this.pos++);
+ var location = line * this.width * 4 + x * 4;
+ this.data[location] = alpha;
+ this.data[location + 1] = blue;
+ this.data[location + 2] = green;
+ this.data[location + 3] = red;
+ }
+ }
+
+ }else{
+ for (var y = this.height - 1; y >= 0; y--) {
+ var line = this.bottom_up ? y : this.height - 1 - y;
+ for (var x = 0; x < this.width; x++) {
+ //Little Endian argb
+ var blue = this.buffer.readUInt8(this.pos++);
+ var green = this.buffer.readUInt8(this.pos++);
+ var red = this.buffer.readUInt8(this.pos++);
+ var alpha = this.buffer.readUInt8(this.pos++);
+ var location = line * this.width * 4 + x * 4;
+ this.data[location] = alpha;
+ this.data[location + 1] = blue;
+ this.data[location + 2] = green;
+ this.data[location + 3] = red;
+ }
+ }
+
+ }
+
+
+
+
+};
+
+BmpDecoder.prototype.getData = function() {
+ return this.data;
+};
+
+module.exports = function(bmpData) {
+ var decoder = new BmpDecoder(bmpData);
+ return decoder;
+};
+
+
+/***/ }),
+
+/***/ 4551:
+/***/ ((module) => {
+
+/**
+ * @author shaozilee
+ *
+ * BMP format encoder,encode 24bit BMP
+ * Not support quality compression
+ *
+ */
+
+function BmpEncoder(imgData){
+ this.buffer = imgData.data;
+ this.width = imgData.width;
+ this.height = imgData.height;
+ this.extraBytes = this.width%4;
+ this.rgbSize = this.height*(3*this.width+this.extraBytes);
+ this.headerInfoSize = 40;
+
+ this.data = [];
+ /******************header***********************/
+ this.flag = "BM";
+ this.reserved = 0;
+ this.offset = 54;
+ this.fileSize = this.rgbSize+this.offset;
+ this.planes = 1;
+ this.bitPP = 24;
+ this.compress = 0;
+ this.hr = 0;
+ this.vr = 0;
+ this.colors = 0;
+ this.importantColors = 0;
+}
+
+BmpEncoder.prototype.encode = function() {
+ var tempBuffer = new Buffer(this.offset+this.rgbSize);
+ this.pos = 0;
+ tempBuffer.write(this.flag,this.pos,2);this.pos+=2;
+ tempBuffer.writeUInt32LE(this.fileSize,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.reserved,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.offset,this.pos);this.pos+=4;
+
+ tempBuffer.writeUInt32LE(this.headerInfoSize,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.width,this.pos);this.pos+=4;
+ tempBuffer.writeInt32LE(-this.height,this.pos);this.pos+=4;
+ tempBuffer.writeUInt16LE(this.planes,this.pos);this.pos+=2;
+ tempBuffer.writeUInt16LE(this.bitPP,this.pos);this.pos+=2;
+ tempBuffer.writeUInt32LE(this.compress,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.rgbSize,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.hr,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.vr,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.colors,this.pos);this.pos+=4;
+ tempBuffer.writeUInt32LE(this.importantColors,this.pos);this.pos+=4;
+
+ var i=0;
+ var rowBytes = 3*this.width+this.extraBytes;
+
+ for (var y = 0; y 0){
+ var fillOffset = this.pos+y*rowBytes+this.width*3;
+ tempBuffer.fill(0,fillOffset,fillOffset+this.extraBytes);
+ }
+ }
+
+ return tempBuffer;
+};
+
+module.exports = function(imgData, quality) {
+ if (typeof quality === 'undefined') quality = 100;
+ var encoder = new BmpEncoder(imgData);
+ var data = encoder.encode();
+ return {
+ data: data,
+ width: imgData.width,
+ height: imgData.height
+ };
+};
+
+
+/***/ }),
+
+/***/ 4664:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var Buffer = (__nccwpck_require__(4300).Buffer); // for use with browserify
+
+module.exports = function (a, b) {
+ if (!Buffer.isBuffer(a)) return undefined;
+ if (!Buffer.isBuffer(b)) return undefined;
+ if (typeof a.equals === 'function') return a.equals(b);
+ if (a.length !== b.length) return false;
+
+ for (var i = 0; i < a.length; i++) {
+ if (a[i] !== b[i]) return false;
+ }
+
+ return true;
+};
+
+
+/***/ }),
+
+/***/ 6621:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var Parser = __nccwpck_require__(4898);
+
+function getGlobal() {
+ return (1,eval)('this');
+}
+
+module.exports = {
+ create: function(buffer, global) {
+ global = global || getGlobal();
+ if(buffer instanceof global.ArrayBuffer) {
+ var DOMBufferStream = __nccwpck_require__(4674);
+ return new Parser(new DOMBufferStream(buffer, 0, buffer.byteLength, true, global));
+ } else {
+ var NodeBufferStream = __nccwpck_require__(7525);
+ return new Parser(new NodeBufferStream(buffer, 0, buffer.length, true));
+ }
+ }
+};
+
+
+/***/ }),
+
+/***/ 7525:
+/***/ ((module) => {
+
+function BufferStream(buffer, offset, length, bigEndian) {
+ this.buffer = buffer;
+ this.offset = offset || 0;
+ length = typeof length === 'number' ? length : buffer.length;
+ this.endPosition = this.offset + length;
+ this.setBigEndian(bigEndian);
+}
+
+BufferStream.prototype = {
+ setBigEndian: function(bigEndian) {
+ this.bigEndian = !!bigEndian;
+ },
+ nextUInt8: function() {
+ var value = this.buffer.readUInt8(this.offset);
+ this.offset += 1;
+ return value;
+ },
+ nextInt8: function() {
+ var value = this.buffer.readInt8(this.offset);
+ this.offset += 1;
+ return value;
+ },
+ nextUInt16: function() {
+ var value = this.bigEndian ? this.buffer.readUInt16BE(this.offset) : this.buffer.readUInt16LE(this.offset);
+ this.offset += 2;
+ return value;
+ },
+ nextUInt32: function() {
+ var value = this.bigEndian ? this.buffer.readUInt32BE(this.offset) : this.buffer.readUInt32LE(this.offset);
+ this.offset += 4;
+ return value;
+ },
+ nextInt16: function() {
+ var value = this.bigEndian ? this.buffer.readInt16BE(this.offset) : this.buffer.readInt16LE(this.offset);
+ this.offset += 2;
+ return value;
+ },
+ nextInt32: function() {
+ var value = this.bigEndian ? this.buffer.readInt32BE(this.offset) : this.buffer.readInt32LE(this.offset);
+ this.offset += 4;
+ return value;
+ },
+ nextFloat: function() {
+ var value = this.bigEndian ? this.buffer.readFloatBE(this.offset) : this.buffer.readFloatLE(this.offset);
+ this.offset += 4;
+ return value;
+ },
+ nextDouble: function() {
+ var value = this.bigEndian ? this.buffer.readDoubleBE(this.offset) : this.buffer.readDoubleLE(this.offset);
+ this.offset += 8;
+ return value;
+ },
+ nextBuffer: function(length) {
+ var value = this.buffer.slice(this.offset, this.offset + length);
+ this.offset += length;
+ return value;
+ },
+ remainingLength: function() {
+ return this.endPosition - this.offset;
+ },
+ nextString: function(length) {
+ var value = this.buffer.toString('utf8', this.offset, this.offset + length);
+ this.offset += length;
+ return value;
+ },
+ mark: function() {
+ var self = this;
+ return {
+ openWithOffset: function(offset) {
+ offset = (offset || 0) + this.offset;
+ return new BufferStream(self.buffer, offset, self.endPosition - offset, self.bigEndian);
+ },
+ offset: this.offset
+ };
+ },
+ offsetFrom: function(marker) {
+ return this.offset - marker.offset;
+ },
+ skip: function(amount) {
+ this.offset += amount;
+ },
+ branch: function(offset, length) {
+ length = typeof length === 'number' ? length : this.endPosition - (this.offset + offset);
+ return new BufferStream(this.buffer, this.offset + offset, length, this.bigEndian);
+ }
+};
+
+module.exports = BufferStream;
+
+
+/***/ }),
+
+/***/ 610:
+/***/ ((module) => {
+
+function parseNumber(s) {
+ return parseInt(s, 10);
+}
+
+//in seconds
+var hours = 3600;
+var minutes = 60;
+
+//take date (year, month, day) and time (hour, minutes, seconds) digits in UTC
+//and return a timestamp in seconds
+function parseDateTimeParts(dateParts, timeParts) {
+ dateParts = dateParts.map(parseNumber);
+ timeParts = timeParts.map(parseNumber);
+ var year = dateParts[0];
+ var month = dateParts[1] - 1;
+ var day = dateParts[2];
+ var hours = timeParts[0];
+ var minutes = timeParts[1];
+ var seconds = timeParts[2];
+ var date = Date.UTC(year, month, day, hours, minutes, seconds, 0);
+ var timestamp = date / 1000;
+ return timestamp;
+}
+
+//parse date with "2004-09-04T23:39:06-08:00" format,
+//one of the formats supported by ISO 8601, and
+//convert to utc timestamp in seconds
+function parseDateWithTimezoneFormat(dateTimeStr) {
+
+ var dateParts = dateTimeStr.substr(0, 10).split('-');
+ var timeParts = dateTimeStr.substr(11, 8).split(':');
+ var timezoneStr = dateTimeStr.substr(19, 6);
+ var timezoneParts = timezoneStr.split(':').map(parseNumber);
+ var timezoneOffset = (timezoneParts[0] * hours) +
+ (timezoneParts[1] * minutes);
+
+ var timestamp = parseDateTimeParts(dateParts, timeParts);
+ //minus because the timezoneOffset describes
+ //how much the described time is ahead of UTC
+ timestamp -= timezoneOffset;
+
+ if(typeof timestamp === 'number' && !isNaN(timestamp)) {
+ return timestamp;
+ }
+}
+
+//parse date with "YYYY:MM:DD hh:mm:ss" format, convert to utc timestamp in seconds
+function parseDateWithSpecFormat(dateTimeStr) {
+ var parts = dateTimeStr.split(' '),
+ dateParts = parts[0].split(':'),
+ timeParts = parts[1].split(':');
+
+ var timestamp = parseDateTimeParts(dateParts, timeParts);
+
+ if(typeof timestamp === 'number' && !isNaN(timestamp)) {
+ return timestamp;
+ }
+}
+
+function parseExifDate(dateTimeStr) {
+ //some easy checks to determine two common date formats
+
+ //is the date in the standard "YYYY:MM:DD hh:mm:ss" format?
+ var isSpecFormat = dateTimeStr.length === 19 &&
+ dateTimeStr.charAt(4) === ':';
+ //is the date in the non-standard format,
+ //"2004-09-04T23:39:06-08:00" to include a timezone?
+ var isTimezoneFormat = dateTimeStr.length === 25 &&
+ dateTimeStr.charAt(10) === 'T';
+ var timestamp;
+
+ if(isTimezoneFormat) {
+ return parseDateWithTimezoneFormat(dateTimeStr);
+ }
+ else if(isSpecFormat) {
+ return parseDateWithSpecFormat(dateTimeStr);
+ }
+}
+
+module.exports = {
+ parseDateWithSpecFormat: parseDateWithSpecFormat,
+ parseDateWithTimezoneFormat: parseDateWithTimezoneFormat,
+ parseExifDate: parseExifDate
+};
+
+
+/***/ }),
+
+/***/ 4674:
+/***/ ((module) => {
+
+/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
+
+function DOMBufferStream(arrayBuffer, offset, length, bigEndian, global, parentOffset) {
+ this.global = global;
+ offset = offset || 0;
+ length = length || (arrayBuffer.byteLength - offset);
+ this.arrayBuffer = arrayBuffer.slice(offset, offset + length);
+ this.view = new global.DataView(this.arrayBuffer, 0, this.arrayBuffer.byteLength);
+ this.setBigEndian(bigEndian);
+ this.offset = 0;
+ this.parentOffset = (parentOffset || 0) + offset;
+}
+
+DOMBufferStream.prototype = {
+ setBigEndian: function(bigEndian) {
+ this.littleEndian = !bigEndian;
+ },
+ nextUInt8: function() {
+ var value = this.view.getUint8(this.offset);
+ this.offset += 1;
+ return value;
+ },
+ nextInt8: function() {
+ var value = this.view.getInt8(this.offset);
+ this.offset += 1;
+ return value;
+ },
+ nextUInt16: function() {
+ var value = this.view.getUint16(this.offset, this.littleEndian);
+ this.offset += 2;
+ return value;
+ },
+ nextUInt32: function() {
+ var value = this.view.getUint32(this.offset, this.littleEndian);
+ this.offset += 4;
+ return value;
+ },
+ nextInt16: function() {
+ var value = this.view.getInt16(this.offset, this.littleEndian);
+ this.offset += 2;
+ return value;
+ },
+ nextInt32: function() {
+ var value = this.view.getInt32(this.offset, this.littleEndian);
+ this.offset += 4;
+ return value;
+ },
+ nextFloat: function() {
+ var value = this.view.getFloat32(this.offset, this.littleEndian);
+ this.offset += 4;
+ return value;
+ },
+ nextDouble: function() {
+ var value = this.view.getFloat64(this.offset, this.littleEndian);
+ this.offset += 8;
+ return value;
+ },
+ nextBuffer: function(length) {
+ //this won't work in IE10
+ var value = this.arrayBuffer.slice(this.offset, this.offset + length);
+ this.offset += length;
+ return value;
+ },
+ remainingLength: function() {
+ return this.arrayBuffer.byteLength - this.offset;
+ },
+ nextString: function(length) {
+ var value = this.arrayBuffer.slice(this.offset, this.offset + length);
+ value = String.fromCharCode.apply(null, new this.global.Uint8Array(value));
+ this.offset += length;
+ return value;
+ },
+ mark: function() {
+ var self = this;
+ return {
+ openWithOffset: function(offset) {
+ offset = (offset || 0) + this.offset;
+ return new DOMBufferStream(self.arrayBuffer, offset, self.arrayBuffer.byteLength - offset, !self.littleEndian, self.global, self.parentOffset);
+ },
+ offset: this.offset,
+ getParentOffset: function() {
+ return self.parentOffset;
+ }
+ };
+ },
+ offsetFrom: function(marker) {
+ return this.parentOffset + this.offset - (marker.offset + marker.getParentOffset());
+ },
+ skip: function(amount) {
+ this.offset += amount;
+ },
+ branch: function(offset, length) {
+ length = typeof length === 'number' ? length : this.arrayBuffer.byteLength - (this.offset + offset);
+ return new DOMBufferStream(this.arrayBuffer, this.offset + offset, length, !this.littleEndian, this.global, this.parentOffset);
+ }
+};
+
+module.exports = DOMBufferStream;
+
+
+/***/ }),
+
+/***/ 1494:
+/***/ ((module) => {
+
+module.exports = {
+ exif : {
+ 0x0001 : "InteropIndex",
+ 0x0002 : "InteropVersion",
+ 0x000B : "ProcessingSoftware",
+ 0x00FE : "SubfileType",
+ 0x00FF : "OldSubfileType",
+ 0x0100 : "ImageWidth",
+ 0x0101 : "ImageHeight",
+ 0x0102 : "BitsPerSample",
+ 0x0103 : "Compression",
+ 0x0106 : "PhotometricInterpretation",
+ 0x0107 : "Thresholding",
+ 0x0108 : "CellWidth",
+ 0x0109 : "CellLength",
+ 0x010A : "FillOrder",
+ 0x010D : "DocumentName",
+ 0x010E : "ImageDescription",
+ 0x010F : "Make",
+ 0x0110 : "Model",
+ 0x0111 : "StripOffsets",
+ 0x0112 : "Orientation",
+ 0x0115 : "SamplesPerPixel",
+ 0x0116 : "RowsPerStrip",
+ 0x0117 : "StripByteCounts",
+ 0x0118 : "MinSampleValue",
+ 0x0119 : "MaxSampleValue",
+ 0x011A : "XResolution",
+ 0x011B : "YResolution",
+ 0x011C : "PlanarConfiguration",
+ 0x011D : "PageName",
+ 0x011E : "XPosition",
+ 0x011F : "YPosition",
+ 0x0120 : "FreeOffsets",
+ 0x0121 : "FreeByteCounts",
+ 0x0122 : "GrayResponseUnit",
+ 0x0123 : "GrayResponseCurve",
+ 0x0124 : "T4Options",
+ 0x0125 : "T6Options",
+ 0x0128 : "ResolutionUnit",
+ 0x0129 : "PageNumber",
+ 0x012C : "ColorResponseUnit",
+ 0x012D : "TransferFunction",
+ 0x0131 : "Software",
+ 0x0132 : "ModifyDate",
+ 0x013B : "Artist",
+ 0x013C : "HostComputer",
+ 0x013D : "Predictor",
+ 0x013E : "WhitePoint",
+ 0x013F : "PrimaryChromaticities",
+ 0x0140 : "ColorMap",
+ 0x0141 : "HalftoneHints",
+ 0x0142 : "TileWidth",
+ 0x0143 : "TileLength",
+ 0x0144 : "TileOffsets",
+ 0x0145 : "TileByteCounts",
+ 0x0146 : "BadFaxLines",
+ 0x0147 : "CleanFaxData",
+ 0x0148 : "ConsecutiveBadFaxLines",
+ 0x014A : "SubIFD",
+ 0x014C : "InkSet",
+ 0x014D : "InkNames",
+ 0x014E : "NumberofInks",
+ 0x0150 : "DotRange",
+ 0x0151 : "TargetPrinter",
+ 0x0152 : "ExtraSamples",
+ 0x0153 : "SampleFormat",
+ 0x0154 : "SMinSampleValue",
+ 0x0155 : "SMaxSampleValue",
+ 0x0156 : "TransferRange",
+ 0x0157 : "ClipPath",
+ 0x0158 : "XClipPathUnits",
+ 0x0159 : "YClipPathUnits",
+ 0x015A : "Indexed",
+ 0x015B : "JPEGTables",
+ 0x015F : "OPIProxy",
+ 0x0190 : "GlobalParametersIFD",
+ 0x0191 : "ProfileType",
+ 0x0192 : "FaxProfile",
+ 0x0193 : "CodingMethods",
+ 0x0194 : "VersionYear",
+ 0x0195 : "ModeNumber",
+ 0x01B1 : "Decode",
+ 0x01B2 : "DefaultImageColor",
+ 0x01B3 : "T82Options",
+ 0x01B5 : "JPEGTables",
+ 0x0200 : "JPEGProc",
+ 0x0201 : "ThumbnailOffset",
+ 0x0202 : "ThumbnailLength",
+ 0x0203 : "JPEGRestartInterval",
+ 0x0205 : "JPEGLosslessPredictors",
+ 0x0206 : "JPEGPointTransforms",
+ 0x0207 : "JPEGQTables",
+ 0x0208 : "JPEGDCTables",
+ 0x0209 : "JPEGACTables",
+ 0x0211 : "YCbCrCoefficients",
+ 0x0212 : "YCbCrSubSampling",
+ 0x0213 : "YCbCrPositioning",
+ 0x0214 : "ReferenceBlackWhite",
+ 0x022F : "StripRowCounts",
+ 0x02BC : "ApplicationNotes",
+ 0x03E7 : "USPTOMiscellaneous",
+ 0x1000 : "RelatedImageFileFormat",
+ 0x1001 : "RelatedImageWidth",
+ 0x1002 : "RelatedImageHeight",
+ 0x4746 : "Rating",
+ 0x4747 : "XP_DIP_XML",
+ 0x4748 : "StitchInfo",
+ 0x4749 : "RatingPercent",
+ 0x800D : "ImageID",
+ 0x80A3 : "WangTag1",
+ 0x80A4 : "WangAnnotation",
+ 0x80A5 : "WangTag3",
+ 0x80A6 : "WangTag4",
+ 0x80E3 : "Matteing",
+ 0x80E4 : "DataType",
+ 0x80E5 : "ImageDepth",
+ 0x80E6 : "TileDepth",
+ 0x827D : "Model2",
+ 0x828D : "CFARepeatPatternDim",
+ 0x828E : "CFAPattern2",
+ 0x828F : "BatteryLevel",
+ 0x8290 : "KodakIFD",
+ 0x8298 : "Copyright",
+ 0x829A : "ExposureTime",
+ 0x829D : "FNumber",
+ 0x82A5 : "MDFileTag",
+ 0x82A6 : "MDScalePixel",
+ 0x82A7 : "MDColorTable",
+ 0x82A8 : "MDLabName",
+ 0x82A9 : "MDSampleInfo",
+ 0x82AA : "MDPrepDate",
+ 0x82AB : "MDPrepTime",
+ 0x82AC : "MDFileUnits",
+ 0x830E : "PixelScale",
+ 0x8335 : "AdventScale",
+ 0x8336 : "AdventRevision",
+ 0x835C : "UIC1Tag",
+ 0x835D : "UIC2Tag",
+ 0x835E : "UIC3Tag",
+ 0x835F : "UIC4Tag",
+ 0x83BB : "IPTC-NAA",
+ 0x847E : "IntergraphPacketData",
+ 0x847F : "IntergraphFlagRegisters",
+ 0x8480 : "IntergraphMatrix",
+ 0x8481 : "INGRReserved",
+ 0x8482 : "ModelTiePoint",
+ 0x84E0 : "Site",
+ 0x84E1 : "ColorSequence",
+ 0x84E2 : "IT8Header",
+ 0x84E3 : "RasterPadding",
+ 0x84E4 : "BitsPerRunLength",
+ 0x84E5 : "BitsPerExtendedRunLength",
+ 0x84E6 : "ColorTable",
+ 0x84E7 : "ImageColorIndicator",
+ 0x84E8 : "BackgroundColorIndicator",
+ 0x84E9 : "ImageColorValue",
+ 0x84EA : "BackgroundColorValue",
+ 0x84EB : "PixelIntensityRange",
+ 0x84EC : "TransparencyIndicator",
+ 0x84ED : "ColorCharacterization",
+ 0x84EE : "HCUsage",
+ 0x84EF : "TrapIndicator",
+ 0x84F0 : "CMYKEquivalent",
+ 0x8546 : "SEMInfo",
+ 0x8568 : "AFCP_IPTC",
+ 0x85B8 : "PixelMagicJBIGOptions",
+ 0x85D8 : "ModelTransform",
+ 0x8602 : "WB_GRGBLevels",
+ 0x8606 : "LeafData",
+ 0x8649 : "PhotoshopSettings",
+ 0x8769 : "ExifOffset",
+ 0x8773 : "ICC_Profile",
+ 0x877F : "TIFF_FXExtensions",
+ 0x8780 : "MultiProfiles",
+ 0x8781 : "SharedData",
+ 0x8782 : "T88Options",
+ 0x87AC : "ImageLayer",
+ 0x87AF : "GeoTiffDirectory",
+ 0x87B0 : "GeoTiffDoubleParams",
+ 0x87B1 : "GeoTiffAsciiParams",
+ 0x8822 : "ExposureProgram",
+ 0x8824 : "SpectralSensitivity",
+ 0x8825 : "GPSInfo",
+ 0x8827 : "ISO",
+ 0x8828 : "Opto-ElectricConvFactor",
+ 0x8829 : "Interlace",
+ 0x882A : "TimeZoneOffset",
+ 0x882B : "SelfTimerMode",
+ 0x8830 : "SensitivityType",
+ 0x8831 : "StandardOutputSensitivity",
+ 0x8832 : "RecommendedExposureIndex",
+ 0x8833 : "ISOSpeed",
+ 0x8834 : "ISOSpeedLatitudeyyy",
+ 0x8835 : "ISOSpeedLatitudezzz",
+ 0x885C : "FaxRecvParams",
+ 0x885D : "FaxSubAddress",
+ 0x885E : "FaxRecvTime",
+ 0x888A : "LeafSubIFD",
+ 0x9000 : "ExifVersion",
+ 0x9003 : "DateTimeOriginal",
+ 0x9004 : "CreateDate",
+ 0x9101 : "ComponentsConfiguration",
+ 0x9102 : "CompressedBitsPerPixel",
+ 0x9201 : "ShutterSpeedValue",
+ 0x9202 : "ApertureValue",
+ 0x9203 : "BrightnessValue",
+ 0x9204 : "ExposureCompensation",
+ 0x9205 : "MaxApertureValue",
+ 0x9206 : "SubjectDistance",
+ 0x9207 : "MeteringMode",
+ 0x9208 : "LightSource",
+ 0x9209 : "Flash",
+ 0x920A : "FocalLength",
+ 0x920B : "FlashEnergy",
+ 0x920C : "SpatialFrequencyResponse",
+ 0x920D : "Noise",
+ 0x920E : "FocalPlaneXResolution",
+ 0x920F : "FocalPlaneYResolution",
+ 0x9210 : "FocalPlaneResolutionUnit",
+ 0x9211 : "ImageNumber",
+ 0x9212 : "SecurityClassification",
+ 0x9213 : "ImageHistory",
+ 0x9214 : "SubjectArea",
+ 0x9215 : "ExposureIndex",
+ 0x9216 : "TIFF-EPStandardID",
+ 0x9217 : "SensingMethod",
+ 0x923A : "CIP3DataFile",
+ 0x923B : "CIP3Sheet",
+ 0x923C : "CIP3Side",
+ 0x923F : "StoNits",
+ 0x927C : "MakerNote",
+ 0x9286 : "UserComment",
+ 0x9290 : "SubSecTime",
+ 0x9291 : "SubSecTimeOriginal",
+ 0x9292 : "SubSecTimeDigitized",
+ 0x932F : "MSDocumentText",
+ 0x9330 : "MSPropertySetStorage",
+ 0x9331 : "MSDocumentTextPosition",
+ 0x935C : "ImageSourceData",
+ 0x9C9B : "XPTitle",
+ 0x9C9C : "XPComment",
+ 0x9C9D : "XPAuthor",
+ 0x9C9E : "XPKeywords",
+ 0x9C9F : "XPSubject",
+ 0xA000 : "FlashpixVersion",
+ 0xA001 : "ColorSpace",
+ 0xA002 : "ExifImageWidth",
+ 0xA003 : "ExifImageHeight",
+ 0xA004 : "RelatedSoundFile",
+ 0xA005 : "InteropOffset",
+ 0xA20B : "FlashEnergy",
+ 0xA20C : "SpatialFrequencyResponse",
+ 0xA20D : "Noise",
+ 0xA20E : "FocalPlaneXResolution",
+ 0xA20F : "FocalPlaneYResolution",
+ 0xA210 : "FocalPlaneResolutionUnit",
+ 0xA211 : "ImageNumber",
+ 0xA212 : "SecurityClassification",
+ 0xA213 : "ImageHistory",
+ 0xA214 : "SubjectLocation",
+ 0xA215 : "ExposureIndex",
+ 0xA216 : "TIFF-EPStandardID",
+ 0xA217 : "SensingMethod",
+ 0xA300 : "FileSource",
+ 0xA301 : "SceneType",
+ 0xA302 : "CFAPattern",
+ 0xA401 : "CustomRendered",
+ 0xA402 : "ExposureMode",
+ 0xA403 : "WhiteBalance",
+ 0xA404 : "DigitalZoomRatio",
+ 0xA405 : "FocalLengthIn35mmFormat",
+ 0xA406 : "SceneCaptureType",
+ 0xA407 : "GainControl",
+ 0xA408 : "Contrast",
+ 0xA409 : "Saturation",
+ 0xA40A : "Sharpness",
+ 0xA40B : "DeviceSettingDescription",
+ 0xA40C : "SubjectDistanceRange",
+ 0xA420 : "ImageUniqueID",
+ 0xA430 : "OwnerName",
+ 0xA431 : "SerialNumber",
+ 0xA432 : "LensInfo",
+ 0xA433 : "LensMake",
+ 0xA434 : "LensModel",
+ 0xA435 : "LensSerialNumber",
+ 0xA480 : "GDALMetadata",
+ 0xA481 : "GDALNoData",
+ 0xA500 : "Gamma",
+ 0xAFC0 : "ExpandSoftware",
+ 0xAFC1 : "ExpandLens",
+ 0xAFC2 : "ExpandFilm",
+ 0xAFC3 : "ExpandFilterLens",
+ 0xAFC4 : "ExpandScanner",
+ 0xAFC5 : "ExpandFlashLamp",
+ 0xBC01 : "PixelFormat",
+ 0xBC02 : "Transformation",
+ 0xBC03 : "Uncompressed",
+ 0xBC04 : "ImageType",
+ 0xBC80 : "ImageWidth",
+ 0xBC81 : "ImageHeight",
+ 0xBC82 : "WidthResolution",
+ 0xBC83 : "HeightResolution",
+ 0xBCC0 : "ImageOffset",
+ 0xBCC1 : "ImageByteCount",
+ 0xBCC2 : "AlphaOffset",
+ 0xBCC3 : "AlphaByteCount",
+ 0xBCC4 : "ImageDataDiscard",
+ 0xBCC5 : "AlphaDataDiscard",
+ 0xC427 : "OceScanjobDesc",
+ 0xC428 : "OceApplicationSelector",
+ 0xC429 : "OceIDNumber",
+ 0xC42A : "OceImageLogic",
+ 0xC44F : "Annotations",
+ 0xC4A5 : "PrintIM",
+ 0xC580 : "USPTOOriginalContentType",
+ 0xC612 : "DNGVersion",
+ 0xC613 : "DNGBackwardVersion",
+ 0xC614 : "UniqueCameraModel",
+ 0xC615 : "LocalizedCameraModel",
+ 0xC616 : "CFAPlaneColor",
+ 0xC617 : "CFALayout",
+ 0xC618 : "LinearizationTable",
+ 0xC619 : "BlackLevelRepeatDim",
+ 0xC61A : "BlackLevel",
+ 0xC61B : "BlackLevelDeltaH",
+ 0xC61C : "BlackLevelDeltaV",
+ 0xC61D : "WhiteLevel",
+ 0xC61E : "DefaultScale",
+ 0xC61F : "DefaultCropOrigin",
+ 0xC620 : "DefaultCropSize",
+ 0xC621 : "ColorMatrix1",
+ 0xC622 : "ColorMatrix2",
+ 0xC623 : "CameraCalibration1",
+ 0xC624 : "CameraCalibration2",
+ 0xC625 : "ReductionMatrix1",
+ 0xC626 : "ReductionMatrix2",
+ 0xC627 : "AnalogBalance",
+ 0xC628 : "AsShotNeutral",
+ 0xC629 : "AsShotWhiteXY",
+ 0xC62A : "BaselineExposure",
+ 0xC62B : "BaselineNoise",
+ 0xC62C : "BaselineSharpness",
+ 0xC62D : "BayerGreenSplit",
+ 0xC62E : "LinearResponseLimit",
+ 0xC62F : "CameraSerialNumber",
+ 0xC630 : "DNGLensInfo",
+ 0xC631 : "ChromaBlurRadius",
+ 0xC632 : "AntiAliasStrength",
+ 0xC633 : "ShadowScale",
+ 0xC634 : "DNGPrivateData",
+ 0xC635 : "MakerNoteSafety",
+ 0xC640 : "RawImageSegmentation",
+ 0xC65A : "CalibrationIlluminant1",
+ 0xC65B : "CalibrationIlluminant2",
+ 0xC65C : "BestQualityScale",
+ 0xC65D : "RawDataUniqueID",
+ 0xC660 : "AliasLayerMetadata",
+ 0xC68B : "OriginalRawFileName",
+ 0xC68C : "OriginalRawFileData",
+ 0xC68D : "ActiveArea",
+ 0xC68E : "MaskedAreas",
+ 0xC68F : "AsShotICCProfile",
+ 0xC690 : "AsShotPreProfileMatrix",
+ 0xC691 : "CurrentICCProfile",
+ 0xC692 : "CurrentPreProfileMatrix",
+ 0xC6BF : "ColorimetricReference",
+ 0xC6D2 : "PanasonicTitle",
+ 0xC6D3 : "PanasonicTitle2",
+ 0xC6F3 : "CameraCalibrationSig",
+ 0xC6F4 : "ProfileCalibrationSig",
+ 0xC6F5 : "ProfileIFD",
+ 0xC6F6 : "AsShotProfileName",
+ 0xC6F7 : "NoiseReductionApplied",
+ 0xC6F8 : "ProfileName",
+ 0xC6F9 : "ProfileHueSatMapDims",
+ 0xC6FA : "ProfileHueSatMapData1",
+ 0xC6FB : "ProfileHueSatMapData2",
+ 0xC6FC : "ProfileToneCurve",
+ 0xC6FD : "ProfileEmbedPolicy",
+ 0xC6FE : "ProfileCopyright",
+ 0xC714 : "ForwardMatrix1",
+ 0xC715 : "ForwardMatrix2",
+ 0xC716 : "PreviewApplicationName",
+ 0xC717 : "PreviewApplicationVersion",
+ 0xC718 : "PreviewSettingsName",
+ 0xC719 : "PreviewSettingsDigest",
+ 0xC71A : "PreviewColorSpace",
+ 0xC71B : "PreviewDateTime",
+ 0xC71C : "RawImageDigest",
+ 0xC71D : "OriginalRawFileDigest",
+ 0xC71E : "SubTileBlockSize",
+ 0xC71F : "RowInterleaveFactor",
+ 0xC725 : "ProfileLookTableDims",
+ 0xC726 : "ProfileLookTableData",
+ 0xC740 : "OpcodeList1",
+ 0xC741 : "OpcodeList2",
+ 0xC74E : "OpcodeList3",
+ 0xC761 : "NoiseProfile",
+ 0xC763 : "TimeCodes",
+ 0xC764 : "FrameRate",
+ 0xC772 : "TStop",
+ 0xC789 : "ReelName",
+ 0xC791 : "OriginalDefaultFinalSize",
+ 0xC792 : "OriginalBestQualitySize",
+ 0xC793 : "OriginalDefaultCropSize",
+ 0xC7A1 : "CameraLabel",
+ 0xC7A3 : "ProfileHueSatMapEncoding",
+ 0xC7A4 : "ProfileLookTableEncoding",
+ 0xC7A5 : "BaselineExposureOffset",
+ 0xC7A6 : "DefaultBlackRender",
+ 0xC7A7 : "NewRawImageDigest",
+ 0xC7A8 : "RawToPreviewGain",
+ 0xC7B5 : "DefaultUserCrop",
+ 0xEA1C : "Padding",
+ 0xEA1D : "OffsetSchema",
+ 0xFDE8 : "OwnerName",
+ 0xFDE9 : "SerialNumber",
+ 0xFDEA : "Lens",
+ 0xFE00 : "KDC_IFD",
+ 0xFE4C : "RawFile",
+ 0xFE4D : "Converter",
+ 0xFE4E : "WhiteBalance",
+ 0xFE51 : "Exposure",
+ 0xFE52 : "Shadows",
+ 0xFE53 : "Brightness",
+ 0xFE54 : "Contrast",
+ 0xFE55 : "Saturation",
+ 0xFE56 : "Sharpness",
+ 0xFE57 : "Smoothness",
+ 0xFE58 : "MoireFilter"
+
+ },
+ gps : {
+ 0x0000 : 'GPSVersionID',
+ 0x0001 : 'GPSLatitudeRef',
+ 0x0002 : 'GPSLatitude',
+ 0x0003 : 'GPSLongitudeRef',
+ 0x0004 : 'GPSLongitude',
+ 0x0005 : 'GPSAltitudeRef',
+ 0x0006 : 'GPSAltitude',
+ 0x0007 : 'GPSTimeStamp',
+ 0x0008 : 'GPSSatellites',
+ 0x0009 : 'GPSStatus',
+ 0x000A : 'GPSMeasureMode',
+ 0x000B : 'GPSDOP',
+ 0x000C : 'GPSSpeedRef',
+ 0x000D : 'GPSSpeed',
+ 0x000E : 'GPSTrackRef',
+ 0x000F : 'GPSTrack',
+ 0x0010 : 'GPSImgDirectionRef',
+ 0x0011 : 'GPSImgDirection',
+ 0x0012 : 'GPSMapDatum',
+ 0x0013 : 'GPSDestLatitudeRef',
+ 0x0014 : 'GPSDestLatitude',
+ 0x0015 : 'GPSDestLongitudeRef',
+ 0x0016 : 'GPSDestLongitude',
+ 0x0017 : 'GPSDestBearingRef',
+ 0x0018 : 'GPSDestBearing',
+ 0x0019 : 'GPSDestDistanceRef',
+ 0x001A : 'GPSDestDistance',
+ 0x001B : 'GPSProcessingMethod',
+ 0x001C : 'GPSAreaInformation',
+ 0x001D : 'GPSDateStamp',
+ 0x001E : 'GPSDifferential',
+ 0x001F : 'GPSHPositioningError'
+ }
+};
+
+/***/ }),
+
+/***/ 5506:
+/***/ ((module) => {
+
+/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
+
+function readExifValue(format, stream) {
+ switch(format) {
+ case 1: return stream.nextUInt8();
+ case 3: return stream.nextUInt16();
+ case 4: return stream.nextUInt32();
+ case 5: return [stream.nextUInt32(), stream.nextUInt32()];
+ case 6: return stream.nextInt8();
+ case 8: return stream.nextUInt16();
+ case 9: return stream.nextUInt32();
+ case 10: return [stream.nextInt32(), stream.nextInt32()];
+ case 11: return stream.nextFloat();
+ case 12: return stream.nextDouble();
+ default: throw new Error('Invalid format while decoding: ' + format);
+ }
+}
+
+function getBytesPerComponent(format) {
+ switch(format) {
+ case 1:
+ case 2:
+ case 6:
+ case 7:
+ return 1;
+ case 3:
+ case 8:
+ return 2;
+ case 4:
+ case 9:
+ case 11:
+ return 4;
+ case 5:
+ case 10:
+ case 12:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+function readExifTag(tiffMarker, stream) {
+ var tagType = stream.nextUInt16(),
+ format = stream.nextUInt16(),
+ bytesPerComponent = getBytesPerComponent(format),
+ components = stream.nextUInt32(),
+ valueBytes = bytesPerComponent * components,
+ values,
+ value,
+ c;
+
+ /* if the value is bigger then 4 bytes, the value is in the data section of the IFD
+ and the value present in the tag is the offset starting from the tiff header. So we replace the stream
+ with a stream that is located at the given offset in the data section. s*/
+ if(valueBytes > 4) {
+ stream = tiffMarker.openWithOffset(stream.nextUInt32());
+ }
+ //we don't want to read strings as arrays
+ if(format === 2) {
+ values = stream.nextString(components);
+ //cut off \0 characters
+ var lastNull = values.indexOf('\0');
+ if(lastNull !== -1) {
+ values = values.substr(0, lastNull);
+ }
+ }
+ else if(format === 7) {
+ values = stream.nextBuffer(components);
+ }
+ else if(format !== 0) {
+ values = [];
+ for(c = 0; c < components; ++c) {
+ values.push(readExifValue(format, stream));
+ }
+ }
+ //since our stream is a stateful object, we need to skip remaining bytes
+ //so our offset stays correct
+ if(valueBytes < 4) {
+ stream.skip(4 - valueBytes);
+ }
+
+ return [tagType, values, format];
+}
+
+function readIFDSection(tiffMarker, stream, iterator) {
+ var numberOfEntries = stream.nextUInt16(), tag, i;
+ for(i = 0; i < numberOfEntries; ++i) {
+ tag = readExifTag(tiffMarker, stream);
+ iterator(tag[0], tag[1], tag[2]);
+ }
+}
+
+function readHeader(stream) {
+ var exifHeader = stream.nextString(6);
+ if(exifHeader !== 'Exif\0\0') {
+ throw new Error('Invalid EXIF header');
+ }
+
+ var tiffMarker = stream.mark();
+ var tiffHeader = stream.nextUInt16();
+ if(tiffHeader === 0x4949) {
+ stream.setBigEndian(false);
+ } else if(tiffHeader === 0x4D4D) {
+ stream.setBigEndian(true);
+ } else {
+ throw new Error('Invalid TIFF header');
+ }
+ if(stream.nextUInt16() !== 0x002A) {
+ throw new Error('Invalid TIFF data');
+ }
+ return tiffMarker;
+}
+
+module.exports = {
+ IFD0: 1,
+ IFD1: 2,
+ GPSIFD: 3,
+ SubIFD: 4,
+ InteropIFD: 5,
+ parseTags: function(stream, iterator) {
+ var tiffMarker;
+ try {
+ tiffMarker = readHeader(stream);
+ } catch(e) {
+ return false; //ignore APP1 sections with invalid headers
+ }
+ var subIfdOffset, gpsOffset, interopOffset;
+ var ifd0Stream = tiffMarker.openWithOffset(stream.nextUInt32()),
+ IFD0 = this.IFD0;
+ readIFDSection(tiffMarker, ifd0Stream, function(tagType, value, format) {
+ switch(tagType) {
+ case 0x8825: gpsOffset = value[0]; break;
+ case 0x8769: subIfdOffset = value[0]; break;
+ default: iterator(IFD0, tagType, value, format); break;
+ }
+ });
+ var ifd1Offset = ifd0Stream.nextUInt32();
+ if(ifd1Offset !== 0) {
+ var ifd1Stream = tiffMarker.openWithOffset(ifd1Offset);
+ readIFDSection(tiffMarker, ifd1Stream, iterator.bind(null, this.IFD1));
+ }
+
+ if(gpsOffset) {
+ var gpsStream = tiffMarker.openWithOffset(gpsOffset);
+ readIFDSection(tiffMarker, gpsStream, iterator.bind(null, this.GPSIFD));
+ }
+
+ if(subIfdOffset) {
+ var subIfdStream = tiffMarker.openWithOffset(subIfdOffset), InteropIFD = this.InteropIFD;
+ readIFDSection(tiffMarker, subIfdStream, function(tagType, value, format) {
+ if(tagType === 0xA005) {
+ interopOffset = value[0];
+ } else {
+ iterator(InteropIFD, tagType, value, format);
+ }
+ });
+ }
+
+ if(interopOffset) {
+ var interopStream = tiffMarker.openWithOffset(interopOffset);
+ readIFDSection(tiffMarker, interopStream, iterator.bind(null, this.InteropIFD));
+ }
+ return true;
+ }
+};
+
+/***/ }),
+
+/***/ 1659:
+/***/ ((module) => {
+
+/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
+
+module.exports = {
+ parseSections: function(stream, iterator) {
+ var len, markerType;
+ stream.setBigEndian(true);
+ //stop reading the stream at the SOS (Start of Stream) marker,
+ //because its length is not stored in the header so we can't
+ //know where to jump to. The only marker after that is just EOI (End Of Image) anyway
+ while(stream.remainingLength() > 0 && markerType !== 0xDA) {
+ if(stream.nextUInt8() !== 0xFF) {
+ throw new Error('Invalid JPEG section offset');
+ }
+ markerType = stream.nextUInt8();
+ //don't read size from markers that have no datas
+ if((markerType >= 0xD0 && markerType <= 0xD9) || markerType === 0xDA) {
+ len = 0;
+ } else {
+ len = stream.nextUInt16() - 2;
+ }
+ iterator(markerType, stream.branch(0, len));
+ stream.skip(len);
+ }
+ },
+ //stream should be located after SOF section size and in big endian mode, like passed to parseSections iterator
+ getSizeFromSOFSection: function(stream) {
+ stream.skip(1);
+ return {
+ height: stream.nextUInt16(),
+ width: stream.nextUInt16()
+ };
+ },
+ getSectionName: function(markerType) {
+ var name, index;
+ switch(markerType) {
+ case 0xD8: name = 'SOI'; break;
+ case 0xC4: name = 'DHT'; break;
+ case 0xDB: name = 'DQT'; break;
+ case 0xDD: name = 'DRI'; break;
+ case 0xDA: name = 'SOS'; break;
+ case 0xFE: name = 'COM'; break;
+ case 0xD9: name = 'EOI'; break;
+ default:
+ if(markerType >= 0xE0 && markerType <= 0xEF) {
+ name = 'APP';
+ index = markerType - 0xE0;
+ }
+ else if(markerType >= 0xC0 && markerType <= 0xCF && markerType !== 0xC4 && markerType !== 0xC8 && markerType !== 0xCC) {
+ name = 'SOF';
+ index = markerType - 0xC0;
+ }
+ else if(markerType >= 0xD0 && markerType <= 0xD7) {
+ name = 'RST';
+ index = markerType - 0xD0;
+ }
+ break;
+ }
+ var nameStruct = {
+ name: name
+ };
+ if(typeof index === 'number') {
+ nameStruct.index = index;
+ }
+ return nameStruct;
+ }
+};
+
+/***/ }),
+
+/***/ 4898:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
+
+var jpeg = __nccwpck_require__(1659),
+ exif = __nccwpck_require__(5506),
+ simplify = __nccwpck_require__(8062);
+
+function ExifResult(startMarker, tags, imageSize, thumbnailOffset, thumbnailLength, thumbnailType, app1Offset) {
+ this.startMarker = startMarker;
+ this.tags = tags;
+ this.imageSize = imageSize;
+ this.thumbnailOffset = thumbnailOffset;
+ this.thumbnailLength = thumbnailLength;
+ this.thumbnailType = thumbnailType;
+ this.app1Offset = app1Offset;
+}
+
+ExifResult.prototype = {
+ hasThumbnail: function(mime) {
+ if(!this.thumbnailOffset || !this.thumbnailLength) {
+ return false;
+ }
+ if(typeof mime !== 'string') {
+ return true;
+ }
+ if(mime.toLowerCase().trim() === 'image/jpeg') {
+ return this.thumbnailType === 6;
+ }
+ if(mime.toLowerCase().trim() === 'image/tiff') {
+ return this.thumbnailType === 1;
+ }
+ return false;
+ },
+ getThumbnailOffset: function() {
+ return this.app1Offset + 6 + this.thumbnailOffset;
+ },
+ getThumbnailLength: function() {
+ return this.thumbnailLength;
+ },
+ getThumbnailBuffer: function() {
+ return this._getThumbnailStream().nextBuffer(this.thumbnailLength);
+ },
+ _getThumbnailStream: function() {
+ return this.startMarker.openWithOffset(this.getThumbnailOffset());
+ },
+ getImageSize: function() {
+ return this.imageSize;
+ },
+ getThumbnailSize: function() {
+ var stream = this._getThumbnailStream(), size;
+ jpeg.parseSections(stream, function(sectionType, sectionStream) {
+ if(jpeg.getSectionName(sectionType).name === 'SOF') {
+ size = jpeg.getSizeFromSOFSection(sectionStream);
+ }
+ });
+ return size;
+ }
+};
+
+function Parser(stream) {
+ this.stream = stream;
+ this.flags = {
+ readBinaryTags: false,
+ resolveTagNames: true,
+ simplifyValues: true,
+ imageSize: true,
+ hidePointers: true,
+ returnTags: true
+ };
+}
+
+Parser.prototype = {
+ enableBinaryFields: function(enable) {
+ this.flags.readBinaryTags = !!enable;
+ return this;
+ },
+ enablePointers: function(enable) {
+ this.flags.hidePointers = !enable;
+ return this;
+ },
+ enableTagNames: function(enable) {
+ this.flags.resolveTagNames = !!enable;
+ return this;
+ },
+ enableImageSize: function(enable) {
+ this.flags.imageSize = !!enable;
+ return this;
+ },
+ enableReturnTags: function(enable) {
+ this.flags.returnTags = !!enable;
+ return this;
+ },
+ enableSimpleValues: function(enable) {
+ this.flags.simplifyValues = !!enable;
+ return this;
+ },
+ parse: function() {
+ var start = this.stream.mark(),
+ stream = start.openWithOffset(0),
+ flags = this.flags,
+ tags,
+ imageSize,
+ thumbnailOffset,
+ thumbnailLength,
+ thumbnailType,
+ app1Offset,
+ tagNames,
+ getTagValue, setTagValue;
+ if(flags.resolveTagNames) {
+ tagNames = __nccwpck_require__(1494);
+ }
+ if(flags.resolveTagNames) {
+ tags = {};
+ getTagValue = function(t) {
+ return tags[t.name];
+ };
+ setTagValue = function(t, value) {
+ tags[t.name] = value;
+ };
+ } else {
+ tags = [];
+ getTagValue = function(t) {
+ var i;
+ for(i = 0; i < tags.length; ++i) {
+ if(tags[i].type === t.type && tags[i].section === t.section) {
+ return tags.value;
+ }
+ }
+ };
+ setTagValue = function(t, value) {
+ var i;
+ for(i = 0; i < tags.length; ++i) {
+ if(tags[i].type === t.type && tags[i].section === t.section) {
+ tags.value = value;
+ return;
+ }
+ }
+ };
+ }
+
+ jpeg.parseSections(stream, function(sectionType, sectionStream) {
+ var validExifHeaders, sectionOffset = sectionStream.offsetFrom(start);
+ if(sectionType === 0xE1) {
+ validExifHeaders = exif.parseTags(sectionStream, function(ifdSection, tagType, value, format) {
+ //ignore binary fields if disabled
+ if(!flags.readBinaryTags && format === 7) {
+ return;
+ }
+
+ if(tagType === 0x0201) {
+ thumbnailOffset = value[0];
+ if(flags.hidePointers) {return;}
+ } else if(tagType === 0x0202) {
+ thumbnailLength = value[0];
+ if(flags.hidePointers) {return;}
+ } else if(tagType === 0x0103) {
+ thumbnailType = value[0];
+ if(flags.hidePointers) {return;}
+ }
+ //if flag is set to not store tags, return here after storing pointers
+ if(!flags.returnTags) {
+ return;
+ }
+
+ if(flags.simplifyValues) {
+ value = simplify.simplifyValue(value, format);
+ }
+ if(flags.resolveTagNames) {
+ var sectionTagNames = ifdSection === exif.GPSIFD ? tagNames.gps : tagNames.exif;
+ var name = sectionTagNames[tagType];
+ if(!name) {
+ name = tagNames.exif[tagType];
+ }
+ if (!tags.hasOwnProperty(name)) {
+ tags[name] = value;
+ }
+ } else {
+ tags.push({
+ section: ifdSection,
+ type: tagType,
+ value: value
+ });
+ }
+ });
+ if(validExifHeaders) {
+ app1Offset = sectionOffset;
+ }
+ }
+ else if(flags.imageSize && jpeg.getSectionName(sectionType).name === 'SOF') {
+ imageSize = jpeg.getSizeFromSOFSection(sectionStream);
+ }
+ });
+
+ if(flags.simplifyValues) {
+ simplify.castDegreeValues(getTagValue, setTagValue);
+ simplify.castDateValues(getTagValue, setTagValue);
+ }
+
+ return new ExifResult(start, tags, imageSize, thumbnailOffset, thumbnailLength, thumbnailType, app1Offset);
+ }
+};
+
+
+
+module.exports = Parser;
+
+
+/***/ }),
+
+/***/ 8062:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+var exif = __nccwpck_require__(5506);
+var date = __nccwpck_require__(610);
+
+var degreeTags = [{
+ section: exif.GPSIFD,
+ type: 0x0002,
+ name: 'GPSLatitude',
+ refType: 0x0001,
+ refName: 'GPSLatitudeRef',
+ posVal: 'N'
+},
+{
+ section: exif.GPSIFD,
+ type: 0x0004,
+ name: 'GPSLongitude',
+ refType: 0x0003,
+ refName: 'GPSLongitudeRef',
+ posVal: 'E'
+}];
+var dateTags = [{
+ section: exif.SubIFD,
+ type: 0x0132,
+ name: 'ModifyDate'
+},
+{
+ section: exif.SubIFD,
+ type: 0x9003,
+ name: 'DateTimeOriginal'
+},
+{
+ section: exif.SubIFD,
+ type: 0x9004,
+ name: 'CreateDate'
+},
+{
+ section: exif.SubIFD,
+ type: 0x0132,
+ name : 'ModifyDate',
+}];
+
+module.exports = {
+ castDegreeValues: function(getTagValue, setTagValue) {
+ degreeTags.forEach(function(t) {
+ var degreeVal = getTagValue(t);
+ if(degreeVal) {
+ var degreeRef = getTagValue({section: t.section, type: t.refType, name: t.refName});
+ var degreeNumRef = degreeRef === t.posVal ? 1 : -1;
+ var degree = (degreeVal[0] + (degreeVal[1] / 60) + (degreeVal[2] / 3600)) * degreeNumRef;
+ setTagValue(t, degree);
+ }
+ });
+ },
+ castDateValues: function(getTagValue, setTagValue) {
+ dateTags.forEach(function(t) {
+ var dateStrVal = getTagValue(t);
+ if(dateStrVal) {
+ //some easy checks to determine two common date formats
+ var timestamp = date.parseExifDate(dateStrVal);
+ if(typeof timestamp !== 'undefined') {
+ setTagValue(t, timestamp);
+ }
+ }
+ });
+ },
+ simplifyValue: function(values, format) {
+ if(Array.isArray(values)) {
+ values = values.map(function(value) {
+ if(format === 10 || format === 5) {
+ return value[0] / value[1];
+ }
+ return value;
+ });
+ if(values.length === 1) {
+ values = values[0];
+ }
+ }
+ return values;
+ }
+};
+
+
+/***/ }),
+
+/***/ 4930:
+/***/ ((module) => {
+
+"use strict";
+
+const toBytes = s => [...s].map(c => c.charCodeAt(0));
+const xpiZipFilename = toBytes('META-INF/mozilla.rsa');
+const oxmlContentTypes = toBytes('[Content_Types].xml');
+const oxmlRels = toBytes('_rels/.rels');
+
+module.exports = input => {
+ const buf = input instanceof Uint8Array ? input : new Uint8Array(input);
+
+ if (!(buf && buf.length > 1)) {
+ return null;
+ }
+
+ const check = (header, options) => {
+ options = Object.assign({
+ offset: 0
+ }, options);
+
+ for (let i = 0; i < header.length; i++) {
+ // If a bitmask is set
+ if (options.mask) {
+ // If header doesn't equal `buf` with bits masked off
+ if (header[i] !== (options.mask[i] & buf[i + options.offset])) {
+ return false;
+ }
+ } else if (header[i] !== buf[i + options.offset]) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ const checkString = (header, options) => check(toBytes(header), options);
+
+ if (check([0xFF, 0xD8, 0xFF])) {
+ return {
+ ext: 'jpg',
+ mime: 'image/jpeg'
+ };
+ }
+
+ if (check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {
+ return {
+ ext: 'png',
+ mime: 'image/png'
+ };
+ }
+
+ if (check([0x47, 0x49, 0x46])) {
+ return {
+ ext: 'gif',
+ mime: 'image/gif'
+ };
+ }
+
+ if (check([0x57, 0x45, 0x42, 0x50], {offset: 8})) {
+ return {
+ ext: 'webp',
+ mime: 'image/webp'
+ };
+ }
+
+ if (check([0x46, 0x4C, 0x49, 0x46])) {
+ return {
+ ext: 'flif',
+ mime: 'image/flif'
+ };
+ }
+
+ // Needs to be before `tif` check
+ if (
+ (check([0x49, 0x49, 0x2A, 0x0]) || check([0x4D, 0x4D, 0x0, 0x2A])) &&
+ check([0x43, 0x52], {offset: 8})
+ ) {
+ return {
+ ext: 'cr2',
+ mime: 'image/x-canon-cr2'
+ };
+ }
+
+ if (
+ check([0x49, 0x49, 0x2A, 0x0]) ||
+ check([0x4D, 0x4D, 0x0, 0x2A])
+ ) {
+ return {
+ ext: 'tif',
+ mime: 'image/tiff'
+ };
+ }
+
+ if (check([0x42, 0x4D])) {
+ return {
+ ext: 'bmp',
+ mime: 'image/bmp'
+ };
+ }
+
+ if (check([0x49, 0x49, 0xBC])) {
+ return {
+ ext: 'jxr',
+ mime: 'image/vnd.ms-photo'
+ };
+ }
+
+ if (check([0x38, 0x42, 0x50, 0x53])) {
+ return {
+ ext: 'psd',
+ mime: 'image/vnd.adobe.photoshop'
+ };
+ }
+
+ // Zip-based file formats
+ // Need to be before the `zip` check
+ if (check([0x50, 0x4B, 0x3, 0x4])) {
+ if (
+ check([0x6D, 0x69, 0x6D, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x65, 0x70, 0x75, 0x62, 0x2B, 0x7A, 0x69, 0x70], {offset: 30})
+ ) {
+ return {
+ ext: 'epub',
+ mime: 'application/epub+zip'
+ };
+ }
+
+ // Assumes signed `.xpi` from addons.mozilla.org
+ if (check(xpiZipFilename, {offset: 30})) {
+ return {
+ ext: 'xpi',
+ mime: 'application/x-xpinstall'
+ };
+ }
+
+ if (checkString('mimetypeapplication/vnd.oasis.opendocument.text', {offset: 30})) {
+ return {
+ ext: 'odt',
+ mime: 'application/vnd.oasis.opendocument.text'
+ };
+ }
+
+ if (checkString('mimetypeapplication/vnd.oasis.opendocument.spreadsheet', {offset: 30})) {
+ return {
+ ext: 'ods',
+ mime: 'application/vnd.oasis.opendocument.spreadsheet'
+ };
+ }
+
+ if (checkString('mimetypeapplication/vnd.oasis.opendocument.presentation', {offset: 30})) {
+ return {
+ ext: 'odp',
+ mime: 'application/vnd.oasis.opendocument.presentation'
+ };
+ }
+
+ // The docx, xlsx and pptx file types extend the Office Open XML file format:
+ // https://en.wikipedia.org/wiki/Office_Open_XML_file_formats
+ // We look for:
+ // - one entry named '[Content_Types].xml' or '_rels/.rels',
+ // - one entry indicating specific type of file.
+ // MS Office, OpenOffice and LibreOffice may put the parts in different order, so the check should not rely on it.
+ const findNextZipHeaderIndex = (arr, startAt = 0) => arr.findIndex((el, i, arr) => i >= startAt && arr[i] === 0x50 && arr[i + 1] === 0x4B && arr[i + 2] === 0x3 && arr[i + 3] === 0x4);
+
+ let zipHeaderIndex = 0; // The first zip header was already found at index 0
+ let oxmlFound = false;
+ let type = null;
+
+ do {
+ const offset = zipHeaderIndex + 30;
+
+ if (!oxmlFound) {
+ oxmlFound = (check(oxmlContentTypes, {offset}) || check(oxmlRels, {offset}));
+ }
+
+ if (!type) {
+ if (checkString('word/', {offset})) {
+ type = {
+ ext: 'docx',
+ mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
+ };
+ } else if (checkString('ppt/', {offset})) {
+ type = {
+ ext: 'pptx',
+ mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
+ };
+ } else if (checkString('xl/', {offset})) {
+ type = {
+ ext: 'xlsx',
+ mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+ };
+ }
+ }
+
+ if (oxmlFound && type) {
+ return type;
+ }
+
+ zipHeaderIndex = findNextZipHeaderIndex(buf, offset);
+ } while (zipHeaderIndex >= 0);
+
+ // No more zip parts available in the buffer, but maybe we are almost certain about the type?
+ if (type) {
+ return type;
+ }
+ }
+
+ if (
+ check([0x50, 0x4B]) &&
+ (buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) &&
+ (buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8)
+ ) {
+ return {
+ ext: 'zip',
+ mime: 'application/zip'
+ };
+ }
+
+ if (check([0x75, 0x73, 0x74, 0x61, 0x72], {offset: 257})) {
+ return {
+ ext: 'tar',
+ mime: 'application/x-tar'
+ };
+ }
+
+ if (
+ check([0x52, 0x61, 0x72, 0x21, 0x1A, 0x7]) &&
+ (buf[6] === 0x0 || buf[6] === 0x1)
+ ) {
+ return {
+ ext: 'rar',
+ mime: 'application/x-rar-compressed'
+ };
+ }
+
+ if (check([0x1F, 0x8B, 0x8])) {
+ return {
+ ext: 'gz',
+ mime: 'application/gzip'
+ };
+ }
+
+ if (check([0x42, 0x5A, 0x68])) {
+ return {
+ ext: 'bz2',
+ mime: 'application/x-bzip2'
+ };
+ }
+
+ if (check([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) {
+ return {
+ ext: '7z',
+ mime: 'application/x-7z-compressed'
+ };
+ }
+
+ if (check([0x78, 0x01])) {
+ return {
+ ext: 'dmg',
+ mime: 'application/x-apple-diskimage'
+ };
+ }
+
+ if (check([0x33, 0x67, 0x70, 0x35]) || // 3gp5
+ (
+ check([0x0, 0x0, 0x0]) && check([0x66, 0x74, 0x79, 0x70], {offset: 4}) &&
+ (
+ check([0x6D, 0x70, 0x34, 0x31], {offset: 8}) || // MP41
+ check([0x6D, 0x70, 0x34, 0x32], {offset: 8}) || // MP42
+ check([0x69, 0x73, 0x6F, 0x6D], {offset: 8}) || // ISOM
+ check([0x69, 0x73, 0x6F, 0x32], {offset: 8}) || // ISO2
+ check([0x6D, 0x6D, 0x70, 0x34], {offset: 8}) || // MMP4
+ check([0x4D, 0x34, 0x56], {offset: 8}) || // M4V
+ check([0x64, 0x61, 0x73, 0x68], {offset: 8}) // DASH
+ )
+ )) {
+ return {
+ ext: 'mp4',
+ mime: 'video/mp4'
+ };
+ }
+
+ if (check([0x4D, 0x54, 0x68, 0x64])) {
+ return {
+ ext: 'mid',
+ mime: 'audio/midi'
+ };
+ }
+
+ // https://github.com/threatstack/libmagic/blob/master/magic/Magdir/matroska
+ if (check([0x1A, 0x45, 0xDF, 0xA3])) {
+ const sliced = buf.subarray(4, 4 + 4096);
+ const idPos = sliced.findIndex((el, i, arr) => arr[i] === 0x42 && arr[i + 1] === 0x82);
+
+ if (idPos !== -1) {
+ const docTypePos = idPos + 3;
+ const findDocType = type => [...type].every((c, i) => sliced[docTypePos + i] === c.charCodeAt(0));
+
+ if (findDocType('matroska')) {
+ return {
+ ext: 'mkv',
+ mime: 'video/x-matroska'
+ };
+ }
+
+ if (findDocType('webm')) {
+ return {
+ ext: 'webm',
+ mime: 'video/webm'
+ };
+ }
+ }
+ }
+
+ if (check([0x0, 0x0, 0x0, 0x14, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20]) ||
+ check([0x66, 0x72, 0x65, 0x65], {offset: 4}) ||
+ check([0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20], {offset: 4}) ||
+ check([0x6D, 0x64, 0x61, 0x74], {offset: 4}) || // MJPEG
+ check([0x77, 0x69, 0x64, 0x65], {offset: 4})) {
+ return {
+ ext: 'mov',
+ mime: 'video/quicktime'
+ };
+ }
+
+ // RIFF file format which might be AVI, WAV, QCP, etc
+ if (check([0x52, 0x49, 0x46, 0x46])) {
+ if (check([0x41, 0x56, 0x49], {offset: 8})) {
+ return {
+ ext: 'avi',
+ mime: 'video/vnd.avi'
+ };
+ }
+ if (check([0x57, 0x41, 0x56, 0x45], {offset: 8})) {
+ return {
+ ext: 'wav',
+ mime: 'audio/vnd.wave'
+ };
+ }
+ // QLCM, QCP file
+ if (check([0x51, 0x4C, 0x43, 0x4D], {offset: 8})) {
+ return {
+ ext: 'qcp',
+ mime: 'audio/qcelp'
+ };
+ }
+ }
+
+ if (check([0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9])) {
+ return {
+ ext: 'wmv',
+ mime: 'video/x-ms-wmv'
+ };
+ }
+
+ if (
+ check([0x0, 0x0, 0x1, 0xBA]) ||
+ check([0x0, 0x0, 0x1, 0xB3])
+ ) {
+ return {
+ ext: 'mpg',
+ mime: 'video/mpeg'
+ };
+ }
+
+ if (check([0x66, 0x74, 0x79, 0x70, 0x33, 0x67], {offset: 4})) {
+ return {
+ ext: '3gp',
+ mime: 'video/3gpp'
+ };
+ }
+
+ // Check for MPEG header at different starting offsets
+ for (let start = 0; start < 2 && start < (buf.length - 16); start++) {
+ if (
+ check([0x49, 0x44, 0x33], {offset: start}) || // ID3 header
+ check([0xFF, 0xE2], {offset: start, mask: [0xFF, 0xE2]}) // MPEG 1 or 2 Layer 3 header
+ ) {
+ return {
+ ext: 'mp3',
+ mime: 'audio/mpeg'
+ };
+ }
+
+ if (
+ check([0xFF, 0xE4], {offset: start, mask: [0xFF, 0xE4]}) // MPEG 1 or 2 Layer 2 header
+ ) {
+ return {
+ ext: 'mp2',
+ mime: 'audio/mpeg'
+ };
+ }
+
+ if (
+ check([0xFF, 0xF8], {offset: start, mask: [0xFF, 0xFC]}) // MPEG 2 layer 0 using ADTS
+ ) {
+ return {
+ ext: 'mp2',
+ mime: 'audio/mpeg'
+ };
+ }
+
+ if (
+ check([0xFF, 0xF0], {offset: start, mask: [0xFF, 0xFC]}) // MPEG 4 layer 0 using ADTS
+ ) {
+ return {
+ ext: 'mp4',
+ mime: 'audio/mpeg'
+ };
+ }
+ }
+
+ if (
+ check([0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41], {offset: 4}) ||
+ check([0x4D, 0x34, 0x41, 0x20])
+ ) {
+ return { // MPEG-4 layer 3 (audio)
+ ext: 'm4a',
+ mime: 'audio/mp4' // RFC 4337
+ };
+ }
+
+ // Needs to be before `ogg` check
+ if (check([0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64], {offset: 28})) {
+ return {
+ ext: 'opus',
+ mime: 'audio/opus'
+ };
+ }
+
+ // If 'OggS' in first bytes, then OGG container
+ if (check([0x4F, 0x67, 0x67, 0x53])) {
+ // This is a OGG container
+
+ // If ' theora' in header.
+ if (check([0x80, 0x74, 0x68, 0x65, 0x6F, 0x72, 0x61], {offset: 28})) {
+ return {
+ ext: 'ogv',
+ mime: 'video/ogg'
+ };
+ }
+ // If '\x01video' in header.
+ if (check([0x01, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00], {offset: 28})) {
+ return {
+ ext: 'ogm',
+ mime: 'video/ogg'
+ };
+ }
+ // If ' FLAC' in header https://xiph.org/flac/faq.html
+ if (check([0x7F, 0x46, 0x4C, 0x41, 0x43], {offset: 28})) {
+ return {
+ ext: 'oga',
+ mime: 'audio/ogg'
+ };
+ }
+
+ // 'Speex ' in header https://en.wikipedia.org/wiki/Speex
+ if (check([0x53, 0x70, 0x65, 0x65, 0x78, 0x20, 0x20], {offset: 28})) {
+ return {
+ ext: 'spx',
+ mime: 'audio/ogg'
+ };
+ }
+
+ // If '\x01vorbis' in header
+ if (check([0x01, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73], {offset: 28})) {
+ return {
+ ext: 'ogg',
+ mime: 'audio/ogg'
+ };
+ }
+
+ // Default OGG container https://www.iana.org/assignments/media-types/application/ogg
+ return {
+ ext: 'ogx',
+ mime: 'application/ogg'
+ };
+ }
+
+ if (check([0x66, 0x4C, 0x61, 0x43])) {
+ return {
+ ext: 'flac',
+ mime: 'audio/x-flac'
+ };
+ }
+
+ if (check([0x4D, 0x41, 0x43, 0x20])) { // 'MAC '
+ return {
+ ext: 'ape',
+ mime: 'audio/ape'
+ };
+ }
+
+ if (check([0x77, 0x76, 0x70, 0x6B])) { // 'wvpk'
+ return {
+ ext: 'wv',
+ mime: 'audio/wavpack'
+ };
+ }
+
+ if (check([0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A])) {
+ return {
+ ext: 'amr',
+ mime: 'audio/amr'
+ };
+ }
+
+ if (check([0x25, 0x50, 0x44, 0x46])) {
+ return {
+ ext: 'pdf',
+ mime: 'application/pdf'
+ };
+ }
+
+ if (check([0x4D, 0x5A])) {
+ return {
+ ext: 'exe',
+ mime: 'application/x-msdownload'
+ };
+ }
+
+ if (
+ (buf[0] === 0x43 || buf[0] === 0x46) &&
+ check([0x57, 0x53], {offset: 1})
+ ) {
+ return {
+ ext: 'swf',
+ mime: 'application/x-shockwave-flash'
+ };
+ }
+
+ if (check([0x7B, 0x5C, 0x72, 0x74, 0x66])) {
+ return {
+ ext: 'rtf',
+ mime: 'application/rtf'
+ };
+ }
+
+ if (check([0x00, 0x61, 0x73, 0x6D])) {
+ return {
+ ext: 'wasm',
+ mime: 'application/wasm'
+ };
+ }
+
+ if (
+ check([0x77, 0x4F, 0x46, 0x46]) &&
+ (
+ check([0x00, 0x01, 0x00, 0x00], {offset: 4}) ||
+ check([0x4F, 0x54, 0x54, 0x4F], {offset: 4})
+ )
+ ) {
+ return {
+ ext: 'woff',
+ mime: 'font/woff'
+ };
+ }
+
+ if (
+ check([0x77, 0x4F, 0x46, 0x32]) &&
+ (
+ check([0x00, 0x01, 0x00, 0x00], {offset: 4}) ||
+ check([0x4F, 0x54, 0x54, 0x4F], {offset: 4})
+ )
+ ) {
+ return {
+ ext: 'woff2',
+ mime: 'font/woff2'
+ };
+ }
+
+ if (
+ check([0x4C, 0x50], {offset: 34}) &&
+ (
+ check([0x00, 0x00, 0x01], {offset: 8}) ||
+ check([0x01, 0x00, 0x02], {offset: 8}) ||
+ check([0x02, 0x00, 0x02], {offset: 8})
+ )
+ ) {
+ return {
+ ext: 'eot',
+ mime: 'application/vnd.ms-fontobject'
+ };
+ }
+
+ if (check([0x00, 0x01, 0x00, 0x00, 0x00])) {
+ return {
+ ext: 'ttf',
+ mime: 'font/ttf'
+ };
+ }
+
+ if (check([0x4F, 0x54, 0x54, 0x4F, 0x00])) {
+ return {
+ ext: 'otf',
+ mime: 'font/otf'
+ };
+ }
+
+ if (check([0x00, 0x00, 0x01, 0x00])) {
+ return {
+ ext: 'ico',
+ mime: 'image/x-icon'
+ };
+ }
+
+ if (check([0x00, 0x00, 0x02, 0x00])) {
+ return {
+ ext: 'cur',
+ mime: 'image/x-icon'
+ };
+ }
+
+ if (check([0x46, 0x4C, 0x56, 0x01])) {
+ return {
+ ext: 'flv',
+ mime: 'video/x-flv'
+ };
+ }
+
+ if (check([0x25, 0x21])) {
+ return {
+ ext: 'ps',
+ mime: 'application/postscript'
+ };
+ }
+
+ if (check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) {
+ return {
+ ext: 'xz',
+ mime: 'application/x-xz'
+ };
+ }
+
+ if (check([0x53, 0x51, 0x4C, 0x69])) {
+ return {
+ ext: 'sqlite',
+ mime: 'application/x-sqlite3'
+ };
+ }
+
+ if (check([0x4E, 0x45, 0x53, 0x1A])) {
+ return {
+ ext: 'nes',
+ mime: 'application/x-nintendo-nes-rom'
+ };
+ }
+
+ if (check([0x43, 0x72, 0x32, 0x34])) {
+ return {
+ ext: 'crx',
+ mime: 'application/x-google-chrome-extension'
+ };
+ }
+
+ if (
+ check([0x4D, 0x53, 0x43, 0x46]) ||
+ check([0x49, 0x53, 0x63, 0x28])
+ ) {
+ return {
+ ext: 'cab',
+ mime: 'application/vnd.ms-cab-compressed'
+ };
+ }
+
+ // Needs to be before `ar` check
+ if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A, 0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79])) {
+ return {
+ ext: 'deb',
+ mime: 'application/x-deb'
+ };
+ }
+
+ if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E])) {
+ return {
+ ext: 'ar',
+ mime: 'application/x-unix-archive'
+ };
+ }
+
+ if (check([0xED, 0xAB, 0xEE, 0xDB])) {
+ return {
+ ext: 'rpm',
+ mime: 'application/x-rpm'
+ };
+ }
+
+ if (
+ check([0x1F, 0xA0]) ||
+ check([0x1F, 0x9D])
+ ) {
+ return {
+ ext: 'Z',
+ mime: 'application/x-compress'
+ };
+ }
+
+ if (check([0x4C, 0x5A, 0x49, 0x50])) {
+ return {
+ ext: 'lz',
+ mime: 'application/x-lzip'
+ };
+ }
+
+ if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) {
+ return {
+ ext: 'msi',
+ mime: 'application/x-msi'
+ };
+ }
+
+ if (check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) {
+ return {
+ ext: 'mxf',
+ mime: 'application/mxf'
+ };
+ }
+
+ if (check([0x47], {offset: 4}) && (check([0x47], {offset: 192}) || check([0x47], {offset: 196}))) {
+ return {
+ ext: 'mts',
+ mime: 'video/mp2t'
+ };
+ }
+
+ if (check([0x42, 0x4C, 0x45, 0x4E, 0x44, 0x45, 0x52])) {
+ return {
+ ext: 'blend',
+ mime: 'application/x-blender'
+ };
+ }
+
+ if (check([0x42, 0x50, 0x47, 0xFB])) {
+ return {
+ ext: 'bpg',
+ mime: 'image/bpg'
+ };
+ }
+
+ if (check([0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A])) {
+ // JPEG-2000 family
+
+ if (check([0x6A, 0x70, 0x32, 0x20], {offset: 20})) {
+ return {
+ ext: 'jp2',
+ mime: 'image/jp2'
+ };
+ }
+
+ if (check([0x6A, 0x70, 0x78, 0x20], {offset: 20})) {
+ return {
+ ext: 'jpx',
+ mime: 'image/jpx'
+ };
+ }
+
+ if (check([0x6A, 0x70, 0x6D, 0x20], {offset: 20})) {
+ return {
+ ext: 'jpm',
+ mime: 'image/jpm'
+ };
+ }
+
+ if (check([0x6D, 0x6A, 0x70, 0x32], {offset: 20})) {
+ return {
+ ext: 'mj2',
+ mime: 'image/mj2'
+ };
+ }
+ }
+
+ if (check([0x46, 0x4F, 0x52, 0x4D, 0x00])) {
+ return {
+ ext: 'aif',
+ mime: 'audio/aiff'
+ };
+ }
+
+ if (checkString(' {
+
+module.exports = process.env.FLUENTFFMPEG_COV ? __nccwpck_require__(5607) : __nccwpck_require__(1376);
+
+
+/***/ }),
+
+/***/ 2832:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var fs = __nccwpck_require__(7147);
+var path = __nccwpck_require__(1017);
+var async = __nccwpck_require__(7888);
+var utils = __nccwpck_require__(7166);
+
+/*
+ *! Capability helpers
+ */
+
+var avCodecRegexp = /^\s*([D ])([E ])([VAS])([S ])([D ])([T ]) ([^ ]+) +(.*)$/;
+var ffCodecRegexp = /^\s*([D\.])([E\.])([VAS])([I\.])([L\.])([S\.]) ([^ ]+) +(.*)$/;
+var ffEncodersRegexp = /\(encoders:([^\)]+)\)/;
+var ffDecodersRegexp = /\(decoders:([^\)]+)\)/;
+var encodersRegexp = /^\s*([VAS\.])([F\.])([S\.])([X\.])([B\.])([D\.]) ([^ ]+) +(.*)$/;
+var formatRegexp = /^\s*([D ])([E ]) ([^ ]+) +(.*)$/;
+var lineBreakRegexp = /\r\n|\r|\n/;
+var filterRegexp = /^(?: [T\.][S\.][C\.] )?([^ ]+) +(AA?|VV?|\|)->(AA?|VV?|\|) +(.*)$/;
+
+var cache = {};
+
+module.exports = function(proto) {
+ /**
+ * Manually define the ffmpeg binary full path.
+ *
+ * @method FfmpegCommand#setFfmpegPath
+ *
+ * @param {String} ffmpegPath The full path to the ffmpeg binary.
+ * @return FfmpegCommand
+ */
+ proto.setFfmpegPath = function(ffmpegPath) {
+ cache.ffmpegPath = ffmpegPath;
+ return this;
+ };
+
+ /**
+ * Manually define the ffprobe binary full path.
+ *
+ * @method FfmpegCommand#setFfprobePath
+ *
+ * @param {String} ffprobePath The full path to the ffprobe binary.
+ * @return FfmpegCommand
+ */
+ proto.setFfprobePath = function(ffprobePath) {
+ cache.ffprobePath = ffprobePath;
+ return this;
+ };
+
+ /**
+ * Manually define the flvtool2/flvmeta binary full path.
+ *
+ * @method FfmpegCommand#setFlvtoolPath
+ *
+ * @param {String} flvtool The full path to the flvtool2 or flvmeta binary.
+ * @return FfmpegCommand
+ */
+ proto.setFlvtoolPath = function(flvtool) {
+ cache.flvtoolPath = flvtool;
+ return this;
+ };
+
+ /**
+ * Forget executable paths
+ *
+ * (only used for testing purposes)
+ *
+ * @method FfmpegCommand#_forgetPaths
+ * @private
+ */
+ proto._forgetPaths = function() {
+ delete cache.ffmpegPath;
+ delete cache.ffprobePath;
+ delete cache.flvtoolPath;
+ };
+
+ /**
+ * Check for ffmpeg availability
+ *
+ * If the FFMPEG_PATH environment variable is set, try to use it.
+ * If it is unset or incorrect, try to find ffmpeg in the PATH instead.
+ *
+ * @method FfmpegCommand#_getFfmpegPath
+ * @param {Function} callback callback with signature (err, path)
+ * @private
+ */
+ proto._getFfmpegPath = function(callback) {
+ if ('ffmpegPath' in cache) {
+ return callback(null, cache.ffmpegPath);
+ }
+
+ async.waterfall([
+ // Try FFMPEG_PATH
+ function(cb) {
+ if (process.env.FFMPEG_PATH) {
+ fs.exists(process.env.FFMPEG_PATH, function(exists) {
+ if (exists) {
+ cb(null, process.env.FFMPEG_PATH);
+ } else {
+ cb(null, '');
+ }
+ });
+ } else {
+ cb(null, '');
+ }
+ },
+
+ // Search in the PATH
+ function(ffmpeg, cb) {
+ if (ffmpeg.length) {
+ return cb(null, ffmpeg);
+ }
+
+ utils.which('ffmpeg', function(err, ffmpeg) {
+ cb(err, ffmpeg);
+ });
+ }
+ ], function(err, ffmpeg) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, cache.ffmpegPath = (ffmpeg || ''));
+ }
+ });
+ };
+
+
+ /**
+ * Check for ffprobe availability
+ *
+ * If the FFPROBE_PATH environment variable is set, try to use it.
+ * If it is unset or incorrect, try to find ffprobe in the PATH instead.
+ * If this still fails, try to find ffprobe in the same directory as ffmpeg.
+ *
+ * @method FfmpegCommand#_getFfprobePath
+ * @param {Function} callback callback with signature (err, path)
+ * @private
+ */
+ proto._getFfprobePath = function(callback) {
+ var self = this;
+
+ if ('ffprobePath' in cache) {
+ return callback(null, cache.ffprobePath);
+ }
+
+ async.waterfall([
+ // Try FFPROBE_PATH
+ function(cb) {
+ if (process.env.FFPROBE_PATH) {
+ fs.exists(process.env.FFPROBE_PATH, function(exists) {
+ cb(null, exists ? process.env.FFPROBE_PATH : '');
+ });
+ } else {
+ cb(null, '');
+ }
+ },
+
+ // Search in the PATH
+ function(ffprobe, cb) {
+ if (ffprobe.length) {
+ return cb(null, ffprobe);
+ }
+
+ utils.which('ffprobe', function(err, ffprobe) {
+ cb(err, ffprobe);
+ });
+ },
+
+ // Search in the same directory as ffmpeg
+ function(ffprobe, cb) {
+ if (ffprobe.length) {
+ return cb(null, ffprobe);
+ }
+
+ self._getFfmpegPath(function(err, ffmpeg) {
+ if (err) {
+ cb(err);
+ } else if (ffmpeg.length) {
+ var name = utils.isWindows ? 'ffprobe.exe' : 'ffprobe';
+ var ffprobe = path.join(path.dirname(ffmpeg), name);
+ fs.exists(ffprobe, function(exists) {
+ cb(null, exists ? ffprobe : '');
+ });
+ } else {
+ cb(null, '');
+ }
+ });
+ }
+ ], function(err, ffprobe) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, cache.ffprobePath = (ffprobe || ''));
+ }
+ });
+ };
+
+
+ /**
+ * Check for flvtool2/flvmeta availability
+ *
+ * If the FLVTOOL2_PATH or FLVMETA_PATH environment variable are set, try to use them.
+ * If both are either unset or incorrect, try to find flvtool2 or flvmeta in the PATH instead.
+ *
+ * @method FfmpegCommand#_getFlvtoolPath
+ * @param {Function} callback callback with signature (err, path)
+ * @private
+ */
+ proto._getFlvtoolPath = function(callback) {
+ if ('flvtoolPath' in cache) {
+ return callback(null, cache.flvtoolPath);
+ }
+
+ async.waterfall([
+ // Try FLVMETA_PATH
+ function(cb) {
+ if (process.env.FLVMETA_PATH) {
+ fs.exists(process.env.FLVMETA_PATH, function(exists) {
+ cb(null, exists ? process.env.FLVMETA_PATH : '');
+ });
+ } else {
+ cb(null, '');
+ }
+ },
+
+ // Try FLVTOOL2_PATH
+ function(flvtool, cb) {
+ if (flvtool.length) {
+ return cb(null, flvtool);
+ }
+
+ if (process.env.FLVTOOL2_PATH) {
+ fs.exists(process.env.FLVTOOL2_PATH, function(exists) {
+ cb(null, exists ? process.env.FLVTOOL2_PATH : '');
+ });
+ } else {
+ cb(null, '');
+ }
+ },
+
+ // Search for flvmeta in the PATH
+ function(flvtool, cb) {
+ if (flvtool.length) {
+ return cb(null, flvtool);
+ }
+
+ utils.which('flvmeta', function(err, flvmeta) {
+ cb(err, flvmeta);
+ });
+ },
+
+ // Search for flvtool2 in the PATH
+ function(flvtool, cb) {
+ if (flvtool.length) {
+ return cb(null, flvtool);
+ }
+
+ utils.which('flvtool2', function(err, flvtool2) {
+ cb(err, flvtool2);
+ });
+ },
+ ], function(err, flvtool) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, cache.flvtoolPath = (flvtool || ''));
+ }
+ });
+ };
+
+
+ /**
+ * A callback passed to {@link FfmpegCommand#availableFilters}.
+ *
+ * @callback FfmpegCommand~filterCallback
+ * @param {Error|null} err error object or null if no error happened
+ * @param {Object} filters filter object with filter names as keys and the following
+ * properties for each filter:
+ * @param {String} filters.description filter description
+ * @param {String} filters.input input type, one of 'audio', 'video' and 'none'
+ * @param {Boolean} filters.multipleInputs whether the filter supports multiple inputs
+ * @param {String} filters.output output type, one of 'audio', 'video' and 'none'
+ * @param {Boolean} filters.multipleOutputs whether the filter supports multiple outputs
+ */
+
+ /**
+ * Query ffmpeg for available filters
+ *
+ * @method FfmpegCommand#availableFilters
+ * @category Capabilities
+ * @aliases getAvailableFilters
+ *
+ * @param {FfmpegCommand~filterCallback} callback callback function
+ */
+ proto.availableFilters =
+ proto.getAvailableFilters = function(callback) {
+ if ('filters' in cache) {
+ return callback(null, cache.filters);
+ }
+
+ this._spawnFfmpeg(['-filters'], { captureStdout: true, stdoutLines: 0 }, function (err, stdoutRing) {
+ if (err) {
+ return callback(err);
+ }
+
+ var stdout = stdoutRing.get();
+ var lines = stdout.split('\n');
+ var data = {};
+ var types = { A: 'audio', V: 'video', '|': 'none' };
+
+ lines.forEach(function(line) {
+ var match = line.match(filterRegexp);
+ if (match) {
+ data[match[1]] = {
+ description: match[4],
+ input: types[match[2].charAt(0)],
+ multipleInputs: match[2].length > 1,
+ output: types[match[3].charAt(0)],
+ multipleOutputs: match[3].length > 1
+ };
+ }
+ });
+
+ callback(null, cache.filters = data);
+ });
+ };
+
+
+ /**
+ * A callback passed to {@link FfmpegCommand#availableCodecs}.
+ *
+ * @callback FfmpegCommand~codecCallback
+ * @param {Error|null} err error object or null if no error happened
+ * @param {Object} codecs codec object with codec names as keys and the following
+ * properties for each codec (more properties may be available depending on the
+ * ffmpeg version used):
+ * @param {String} codecs.description codec description
+ * @param {Boolean} codecs.canDecode whether the codec is able to decode streams
+ * @param {Boolean} codecs.canEncode whether the codec is able to encode streams
+ */
+
+ /**
+ * Query ffmpeg for available codecs
+ *
+ * @method FfmpegCommand#availableCodecs
+ * @category Capabilities
+ * @aliases getAvailableCodecs
+ *
+ * @param {FfmpegCommand~codecCallback} callback callback function
+ */
+ proto.availableCodecs =
+ proto.getAvailableCodecs = function(callback) {
+ if ('codecs' in cache) {
+ return callback(null, cache.codecs);
+ }
+
+ this._spawnFfmpeg(['-codecs'], { captureStdout: true, stdoutLines: 0 }, function(err, stdoutRing) {
+ if (err) {
+ return callback(err);
+ }
+
+ var stdout = stdoutRing.get();
+ var lines = stdout.split(lineBreakRegexp);
+ var data = {};
+
+ lines.forEach(function(line) {
+ var match = line.match(avCodecRegexp);
+ if (match && match[7] !== '=') {
+ data[match[7]] = {
+ type: { 'V': 'video', 'A': 'audio', 'S': 'subtitle' }[match[3]],
+ description: match[8],
+ canDecode: match[1] === 'D',
+ canEncode: match[2] === 'E',
+ drawHorizBand: match[4] === 'S',
+ directRendering: match[5] === 'D',
+ weirdFrameTruncation: match[6] === 'T'
+ };
+ }
+
+ match = line.match(ffCodecRegexp);
+ if (match && match[7] !== '=') {
+ var codecData = data[match[7]] = {
+ type: { 'V': 'video', 'A': 'audio', 'S': 'subtitle' }[match[3]],
+ description: match[8],
+ canDecode: match[1] === 'D',
+ canEncode: match[2] === 'E',
+ intraFrameOnly: match[4] === 'I',
+ isLossy: match[5] === 'L',
+ isLossless: match[6] === 'S'
+ };
+
+ var encoders = codecData.description.match(ffEncodersRegexp);
+ encoders = encoders ? encoders[1].trim().split(' ') : [];
+
+ var decoders = codecData.description.match(ffDecodersRegexp);
+ decoders = decoders ? decoders[1].trim().split(' ') : [];
+
+ if (encoders.length || decoders.length) {
+ var coderData = {};
+ utils.copy(codecData, coderData);
+ delete coderData.canEncode;
+ delete coderData.canDecode;
+
+ encoders.forEach(function(name) {
+ data[name] = {};
+ utils.copy(coderData, data[name]);
+ data[name].canEncode = true;
+ });
+
+ decoders.forEach(function(name) {
+ if (name in data) {
+ data[name].canDecode = true;
+ } else {
+ data[name] = {};
+ utils.copy(coderData, data[name]);
+ data[name].canDecode = true;
+ }
+ });
+ }
+ }
+ });
+
+ callback(null, cache.codecs = data);
+ });
+ };
+
+
+ /**
+ * A callback passed to {@link FfmpegCommand#availableEncoders}.
+ *
+ * @callback FfmpegCommand~encodersCallback
+ * @param {Error|null} err error object or null if no error happened
+ * @param {Object} encoders encoders object with encoder names as keys and the following
+ * properties for each encoder:
+ * @param {String} encoders.description codec description
+ * @param {Boolean} encoders.type "audio", "video" or "subtitle"
+ * @param {Boolean} encoders.frameMT whether the encoder is able to do frame-level multithreading
+ * @param {Boolean} encoders.sliceMT whether the encoder is able to do slice-level multithreading
+ * @param {Boolean} encoders.experimental whether the encoder is experimental
+ * @param {Boolean} encoders.drawHorizBand whether the encoder supports draw_horiz_band
+ * @param {Boolean} encoders.directRendering whether the encoder supports direct encoding method 1
+ */
+
+ /**
+ * Query ffmpeg for available encoders
+ *
+ * @method FfmpegCommand#availableEncoders
+ * @category Capabilities
+ * @aliases getAvailableEncoders
+ *
+ * @param {FfmpegCommand~encodersCallback} callback callback function
+ */
+ proto.availableEncoders =
+ proto.getAvailableEncoders = function(callback) {
+ if ('encoders' in cache) {
+ return callback(null, cache.encoders);
+ }
+
+ this._spawnFfmpeg(['-encoders'], { captureStdout: true, stdoutLines: 0 }, function(err, stdoutRing) {
+ if (err) {
+ return callback(err);
+ }
+
+ var stdout = stdoutRing.get();
+ var lines = stdout.split(lineBreakRegexp);
+ var data = {};
+
+ lines.forEach(function(line) {
+ var match = line.match(encodersRegexp);
+ if (match && match[7] !== '=') {
+ data[match[7]] = {
+ type: { 'V': 'video', 'A': 'audio', 'S': 'subtitle' }[match[1]],
+ description: match[8],
+ frameMT: match[2] === 'F',
+ sliceMT: match[3] === 'S',
+ experimental: match[4] === 'X',
+ drawHorizBand: match[5] === 'B',
+ directRendering: match[6] === 'D'
+ };
+ }
+ });
+
+ callback(null, cache.encoders = data);
+ });
+ };
+
+
+ /**
+ * A callback passed to {@link FfmpegCommand#availableFormats}.
+ *
+ * @callback FfmpegCommand~formatCallback
+ * @param {Error|null} err error object or null if no error happened
+ * @param {Object} formats format object with format names as keys and the following
+ * properties for each format:
+ * @param {String} formats.description format description
+ * @param {Boolean} formats.canDemux whether the format is able to demux streams from an input file
+ * @param {Boolean} formats.canMux whether the format is able to mux streams into an output file
+ */
+
+ /**
+ * Query ffmpeg for available formats
+ *
+ * @method FfmpegCommand#availableFormats
+ * @category Capabilities
+ * @aliases getAvailableFormats
+ *
+ * @param {FfmpegCommand~formatCallback} callback callback function
+ */
+ proto.availableFormats =
+ proto.getAvailableFormats = function(callback) {
+ if ('formats' in cache) {
+ return callback(null, cache.formats);
+ }
+
+ // Run ffmpeg -formats
+ this._spawnFfmpeg(['-formats'], { captureStdout: true, stdoutLines: 0 }, function (err, stdoutRing) {
+ if (err) {
+ return callback(err);
+ }
+
+ // Parse output
+ var stdout = stdoutRing.get();
+ var lines = stdout.split(lineBreakRegexp);
+ var data = {};
+
+ lines.forEach(function(line) {
+ var match = line.match(formatRegexp);
+ if (match) {
+ match[3].split(',').forEach(function(format) {
+ if (!(format in data)) {
+ data[format] = {
+ description: match[4],
+ canDemux: false,
+ canMux: false
+ };
+ }
+
+ if (match[1] === 'D') {
+ data[format].canDemux = true;
+ }
+ if (match[2] === 'E') {
+ data[format].canMux = true;
+ }
+ });
+ }
+ });
+
+ callback(null, cache.formats = data);
+ });
+ };
+
+
+ /**
+ * Check capabilities before executing a command
+ *
+ * Checks whether all used codecs and formats are indeed available
+ *
+ * @method FfmpegCommand#_checkCapabilities
+ * @param {Function} callback callback with signature (err)
+ * @private
+ */
+ proto._checkCapabilities = function(callback) {
+ var self = this;
+ async.waterfall([
+ // Get available formats
+ function(cb) {
+ self.availableFormats(cb);
+ },
+
+ // Check whether specified formats are available
+ function(formats, cb) {
+ var unavailable;
+
+ // Output format(s)
+ unavailable = self._outputs
+ .reduce(function(fmts, output) {
+ var format = output.options.find('-f', 1);
+ if (format) {
+ if (!(format[0] in formats) || !(formats[format[0]].canMux)) {
+ fmts.push(format);
+ }
+ }
+
+ return fmts;
+ }, []);
+
+ if (unavailable.length === 1) {
+ return cb(new Error('Output format ' + unavailable[0] + ' is not available'));
+ } else if (unavailable.length > 1) {
+ return cb(new Error('Output formats ' + unavailable.join(', ') + ' are not available'));
+ }
+
+ // Input format(s)
+ unavailable = self._inputs
+ .reduce(function(fmts, input) {
+ var format = input.options.find('-f', 1);
+ if (format) {
+ if (!(format[0] in formats) || !(formats[format[0]].canDemux)) {
+ fmts.push(format[0]);
+ }
+ }
+
+ return fmts;
+ }, []);
+
+ if (unavailable.length === 1) {
+ return cb(new Error('Input format ' + unavailable[0] + ' is not available'));
+ } else if (unavailable.length > 1) {
+ return cb(new Error('Input formats ' + unavailable.join(', ') + ' are not available'));
+ }
+
+ cb();
+ },
+
+ // Get available codecs
+ function(cb) {
+ self.availableEncoders(cb);
+ },
+
+ // Check whether specified codecs are available and add strict experimental options if needed
+ function(encoders, cb) {
+ var unavailable;
+
+ // Audio codec(s)
+ unavailable = self._outputs.reduce(function(cdcs, output) {
+ var acodec = output.audio.find('-acodec', 1);
+ if (acodec && acodec[0] !== 'copy') {
+ if (!(acodec[0] in encoders) || encoders[acodec[0]].type !== 'audio') {
+ cdcs.push(acodec[0]);
+ }
+ }
+
+ return cdcs;
+ }, []);
+
+ if (unavailable.length === 1) {
+ return cb(new Error('Audio codec ' + unavailable[0] + ' is not available'));
+ } else if (unavailable.length > 1) {
+ return cb(new Error('Audio codecs ' + unavailable.join(', ') + ' are not available'));
+ }
+
+ // Video codec(s)
+ unavailable = self._outputs.reduce(function(cdcs, output) {
+ var vcodec = output.video.find('-vcodec', 1);
+ if (vcodec && vcodec[0] !== 'copy') {
+ if (!(vcodec[0] in encoders) || encoders[vcodec[0]].type !== 'video') {
+ cdcs.push(vcodec[0]);
+ }
+ }
+
+ return cdcs;
+ }, []);
+
+ if (unavailable.length === 1) {
+ return cb(new Error('Video codec ' + unavailable[0] + ' is not available'));
+ } else if (unavailable.length > 1) {
+ return cb(new Error('Video codecs ' + unavailable.join(', ') + ' are not available'));
+ }
+
+ cb();
+ }
+ ], callback);
+ };
+};
+
+
+/***/ }),
+
+/***/ 960:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true, laxcomma:true*/
+
+
+var spawn = (__nccwpck_require__(2081).spawn);
+
+
+function legacyTag(key) { return key.match(/^TAG:/); }
+function legacyDisposition(key) { return key.match(/^DISPOSITION:/); }
+
+function parseFfprobeOutput(out) {
+ var lines = out.split(/\r\n|\r|\n/);
+
+ lines = lines.filter(function (line) {
+ return line.length > 0;
+ });
+
+ var data = {
+ streams: [],
+ format: {},
+ chapters: []
+ };
+
+ function parseBlock(name) {
+ var data = {};
+
+ var line = lines.shift();
+ while (typeof line !== 'undefined') {
+ if (line.toLowerCase() == '[/'+name+']') {
+ return data;
+ } else if (line.match(/^\[/)) {
+ line = lines.shift();
+ continue;
+ }
+
+ var kv = line.match(/^([^=]+)=(.*)$/);
+ if (kv) {
+ if (!(kv[1].match(/^TAG:/)) && kv[2].match(/^[0-9]+(\.[0-9]+)?$/)) {
+ data[kv[1]] = Number(kv[2]);
+ } else {
+ data[kv[1]] = kv[2];
+ }
+ }
+
+ line = lines.shift();
+ }
+
+ return data;
+ }
+
+ var line = lines.shift();
+ while (typeof line !== 'undefined') {
+ if (line.match(/^\[stream/i)) {
+ var stream = parseBlock('stream');
+ data.streams.push(stream);
+ } else if (line.match(/^\[chapter/i)) {
+ var chapter = parseBlock('chapter');
+ data.chapters.push(chapter);
+ } else if (line.toLowerCase() === '[format]') {
+ data.format = parseBlock('format');
+ }
+
+ line = lines.shift();
+ }
+
+ return data;
+}
+
+
+
+module.exports = function(proto) {
+ /**
+ * A callback passed to the {@link FfmpegCommand#ffprobe} method.
+ *
+ * @callback FfmpegCommand~ffprobeCallback
+ *
+ * @param {Error|null} err error object or null if no error happened
+ * @param {Object} ffprobeData ffprobe output data; this object
+ * has the same format as what the following command returns:
+ *
+ * `ffprobe -print_format json -show_streams -show_format INPUTFILE`
+ * @param {Array} ffprobeData.streams stream information
+ * @param {Object} ffprobeData.format format information
+ */
+
+ /**
+ * Run ffprobe on last specified input
+ *
+ * @method FfmpegCommand#ffprobe
+ * @category Metadata
+ *
+ * @param {?Number} [index] 0-based index of input to probe (defaults to last input)
+ * @param {?String[]} [options] array of output options to return
+ * @param {FfmpegCommand~ffprobeCallback} callback callback function
+ *
+ */
+ proto.ffprobe = function() {
+ var input, index = null, options = [], callback;
+
+ // the last argument should be the callback
+ var callback = arguments[arguments.length - 1];
+
+ var ended = false
+ function handleCallback(err, data) {
+ if (!ended) {
+ ended = true;
+ callback(err, data);
+ }
+ };
+
+ // map the arguments to the correct variable names
+ switch (arguments.length) {
+ case 3:
+ index = arguments[0];
+ options = arguments[1];
+ break;
+ case 2:
+ if (typeof arguments[0] === 'number') {
+ index = arguments[0];
+ } else if (Array.isArray(arguments[0])) {
+ options = arguments[0];
+ }
+ break;
+ }
+
+
+ if (index === null) {
+ if (!this._currentInput) {
+ return handleCallback(new Error('No input specified'));
+ }
+
+ input = this._currentInput;
+ } else {
+ input = this._inputs[index];
+
+ if (!input) {
+ return handleCallback(new Error('Invalid input index'));
+ }
+ }
+
+ // Find ffprobe
+ this._getFfprobePath(function(err, path) {
+ if (err) {
+ return handleCallback(err);
+ } else if (!path) {
+ return handleCallback(new Error('Cannot find ffprobe'));
+ }
+
+ var stdout = '';
+ var stdoutClosed = false;
+ var stderr = '';
+ var stderrClosed = false;
+
+ // Spawn ffprobe
+ var src = input.isStream ? 'pipe:0' : input.source;
+ var ffprobe = spawn(path, ['-show_streams', '-show_format'].concat(options, src));
+
+ if (input.isStream) {
+ // Skip errors on stdin. These get thrown when ffprobe is complete and
+ // there seems to be no way hook in and close stdin before it throws.
+ ffprobe.stdin.on('error', function(err) {
+ if (['ECONNRESET', 'EPIPE'].indexOf(err.code) >= 0) { return; }
+ handleCallback(err);
+ });
+
+ // Once ffprobe's input stream closes, we need no more data from the
+ // input
+ ffprobe.stdin.on('close', function() {
+ input.source.pause();
+ input.source.unpipe(ffprobe.stdin);
+ });
+
+ input.source.pipe(ffprobe.stdin);
+ }
+
+ ffprobe.on('error', callback);
+
+ // Ensure we wait for captured streams to end before calling callback
+ var exitError = null;
+ function handleExit(err) {
+ if (err) {
+ exitError = err;
+ }
+
+ if (processExited && stdoutClosed && stderrClosed) {
+ if (exitError) {
+ if (stderr) {
+ exitError.message += '\n' + stderr;
+ }
+
+ return handleCallback(exitError);
+ }
+
+ // Process output
+ var data = parseFfprobeOutput(stdout);
+
+ // Handle legacy output with "TAG:x" and "DISPOSITION:x" keys
+ [data.format].concat(data.streams).forEach(function(target) {
+ if (target) {
+ var legacyTagKeys = Object.keys(target).filter(legacyTag);
+
+ if (legacyTagKeys.length) {
+ target.tags = target.tags || {};
+
+ legacyTagKeys.forEach(function(tagKey) {
+ target.tags[tagKey.substr(4)] = target[tagKey];
+ delete target[tagKey];
+ });
+ }
+
+ var legacyDispositionKeys = Object.keys(target).filter(legacyDisposition);
+
+ if (legacyDispositionKeys.length) {
+ target.disposition = target.disposition || {};
+
+ legacyDispositionKeys.forEach(function(dispositionKey) {
+ target.disposition[dispositionKey.substr(12)] = target[dispositionKey];
+ delete target[dispositionKey];
+ });
+ }
+ }
+ });
+
+ handleCallback(null, data);
+ }
+ }
+
+ // Handle ffprobe exit
+ var processExited = false;
+ ffprobe.on('exit', function(code, signal) {
+ processExited = true;
+
+ if (code) {
+ handleExit(new Error('ffprobe exited with code ' + code));
+ } else if (signal) {
+ handleExit(new Error('ffprobe was killed with signal ' + signal));
+ } else {
+ handleExit();
+ }
+ });
+
+ // Handle stdout/stderr streams
+ ffprobe.stdout.on('data', function(data) {
+ stdout += data;
+ });
+
+ ffprobe.stdout.on('close', function() {
+ stdoutClosed = true;
+ handleExit();
+ });
+
+ ffprobe.stderr.on('data', function(data) {
+ stderr += data;
+ });
+
+ ffprobe.stderr.on('close', function() {
+ stderrClosed = true;
+ handleExit();
+ });
+ });
+ };
+};
+
+
+/***/ }),
+
+/***/ 1376:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var path = __nccwpck_require__(1017);
+var util = __nccwpck_require__(3837);
+var EventEmitter = (__nccwpck_require__(2361).EventEmitter);
+
+var utils = __nccwpck_require__(7166);
+var ARGLISTS = (/* unused pure expression or super */ null && (['_global', '_audio', '_audioFilters', '_video', '_videoFilters', '_sizeFilters', '_complexFilters']));
+
+
+/**
+ * Create an ffmpeg command
+ *
+ * Can be called with or without the 'new' operator, and the 'input' parameter
+ * may be specified as 'options.source' instead (or passed later with the
+ * addInput method).
+ *
+ * @constructor
+ * @param {String|ReadableStream} [input] input file path or readable stream
+ * @param {Object} [options] command options
+ * @param {Object} [options.logger=] logger object with 'error', 'warning', 'info' and 'debug' methods
+ * @param {Number} [options.niceness=0] ffmpeg process niceness, ignored on Windows
+ * @param {Number} [options.priority=0] alias for `niceness`
+ * @param {String} [options.presets="fluent-ffmpeg/lib/presets"] directory to load presets from
+ * @param {String} [options.preset="fluent-ffmpeg/lib/presets"] alias for `presets`
+ * @param {String} [options.stdoutLines=100] maximum lines of ffmpeg output to keep in memory, use 0 for unlimited
+ * @param {Number} [options.timeout=] ffmpeg processing timeout in seconds
+ * @param {String|ReadableStream} [options.source=] alias for the `input` parameter
+ */
+function FfmpegCommand(input, options) {
+ // Make 'new' optional
+ if (!(this instanceof FfmpegCommand)) {
+ return new FfmpegCommand(input, options);
+ }
+
+ EventEmitter.call(this);
+
+ if (typeof input === 'object' && !('readable' in input)) {
+ // Options object passed directly
+ options = input;
+ } else {
+ // Input passed first
+ options = options || {};
+ options.source = input;
+ }
+
+ // Add input if present
+ this._inputs = [];
+ if (options.source) {
+ this.input(options.source);
+ }
+
+ // Add target-less output for backwards compatibility
+ this._outputs = [];
+ this.output();
+
+ // Create argument lists
+ var self = this;
+ ['_global', '_complexFilters'].forEach(function(prop) {
+ self[prop] = utils.args();
+ });
+
+ // Set default option values
+ options.stdoutLines = 'stdoutLines' in options ? options.stdoutLines : 100;
+ options.presets = options.presets || options.preset || __nccwpck_require__.ab + "presets";
+ options.niceness = options.niceness || options.priority || 0;
+
+ // Save options
+ this.options = options;
+
+ // Setup logger
+ this.logger = options.logger || {
+ debug: function() {},
+ info: function() {},
+ warn: function() {},
+ error: function() {}
+ };
+}
+util.inherits(FfmpegCommand, EventEmitter);
+module.exports = FfmpegCommand;
+
+
+/**
+ * Clone an ffmpeg command
+ *
+ * This method is useful when you want to process the same input multiple times.
+ * It returns a new FfmpegCommand instance with the exact same options.
+ *
+ * All options set _after_ the clone() call will only be applied to the instance
+ * it has been called on.
+ *
+ * @example
+ * var command = ffmpeg('/path/to/source.avi')
+ * .audioCodec('libfaac')
+ * .videoCodec('libx264')
+ * .format('mp4');
+ *
+ * command.clone()
+ * .size('320x200')
+ * .save('/path/to/output-small.mp4');
+ *
+ * command.clone()
+ * .size('640x400')
+ * .save('/path/to/output-medium.mp4');
+ *
+ * command.save('/path/to/output-original-size.mp4');
+ *
+ * @method FfmpegCommand#clone
+ * @return FfmpegCommand
+ */
+FfmpegCommand.prototype.clone = function() {
+ var clone = new FfmpegCommand();
+ var self = this;
+
+ // Clone options and logger
+ clone.options = this.options;
+ clone.logger = this.logger;
+
+ // Clone inputs
+ clone._inputs = this._inputs.map(function(input) {
+ return {
+ source: input.source,
+ options: input.options.clone()
+ };
+ });
+
+ // Create first output
+ if ('target' in this._outputs[0]) {
+ // We have outputs set, don't clone them and create first output
+ clone._outputs = [];
+ clone.output();
+ } else {
+ // No outputs set, clone first output options
+ clone._outputs = [
+ clone._currentOutput = {
+ flags: {}
+ }
+ ];
+
+ ['audio', 'audioFilters', 'video', 'videoFilters', 'sizeFilters', 'options'].forEach(function(key) {
+ clone._currentOutput[key] = self._currentOutput[key].clone();
+ });
+
+ if (this._currentOutput.sizeData) {
+ clone._currentOutput.sizeData = {};
+ utils.copy(this._currentOutput.sizeData, clone._currentOutput.sizeData);
+ }
+
+ utils.copy(this._currentOutput.flags, clone._currentOutput.flags);
+ }
+
+ // Clone argument lists
+ ['_global', '_complexFilters'].forEach(function(prop) {
+ clone[prop] = self[prop].clone();
+ });
+
+ return clone;
+};
+
+
+/* Add methods from options submodules */
+
+__nccwpck_require__(8781)(FfmpegCommand.prototype);
+__nccwpck_require__(8117)(FfmpegCommand.prototype);
+__nccwpck_require__(7215)(FfmpegCommand.prototype);
+__nccwpck_require__(4773)(FfmpegCommand.prototype);
+__nccwpck_require__(6488)(FfmpegCommand.prototype);
+__nccwpck_require__(1117)(FfmpegCommand.prototype);
+__nccwpck_require__(81)(FfmpegCommand.prototype);
+
+
+/* Add processor methods */
+
+__nccwpck_require__(981)(FfmpegCommand.prototype);
+
+
+/* Add capabilities methods */
+
+__nccwpck_require__(2832)(FfmpegCommand.prototype);
+
+FfmpegCommand.setFfmpegPath = function(path) {
+ (new FfmpegCommand()).setFfmpegPath(path);
+};
+
+FfmpegCommand.setFfprobePath = function(path) {
+ (new FfmpegCommand()).setFfprobePath(path);
+};
+
+FfmpegCommand.setFlvtoolPath = function(path) {
+ (new FfmpegCommand()).setFlvtoolPath(path);
+};
+
+FfmpegCommand.availableFilters =
+FfmpegCommand.getAvailableFilters = function(callback) {
+ (new FfmpegCommand()).availableFilters(callback);
+};
+
+FfmpegCommand.availableCodecs =
+FfmpegCommand.getAvailableCodecs = function(callback) {
+ (new FfmpegCommand()).availableCodecs(callback);
+};
+
+FfmpegCommand.availableFormats =
+FfmpegCommand.getAvailableFormats = function(callback) {
+ (new FfmpegCommand()).availableFormats(callback);
+};
+
+FfmpegCommand.availableEncoders =
+FfmpegCommand.getAvailableEncoders = function(callback) {
+ (new FfmpegCommand()).availableEncoders(callback);
+};
+
+
+/* Add ffprobe methods */
+
+__nccwpck_require__(960)(FfmpegCommand.prototype);
+
+FfmpegCommand.ffprobe = function(file) {
+ var instance = new FfmpegCommand(file);
+ instance.ffprobe.apply(instance, Array.prototype.slice.call(arguments, 1));
+};
+
+/* Add processing recipes */
+
+__nccwpck_require__(9341)(FfmpegCommand.prototype);
+
+
+/***/ }),
+
+/***/ 8117:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var utils = __nccwpck_require__(7166);
+
+
+/*
+ *! Audio-related methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Disable audio in the output
+ *
+ * @method FfmpegCommand#noAudio
+ * @category Audio
+ * @aliases withNoAudio
+ * @return FfmpegCommand
+ */
+ proto.withNoAudio =
+ proto.noAudio = function() {
+ this._currentOutput.audio.clear();
+ this._currentOutput.audioFilters.clear();
+ this._currentOutput.audio('-an');
+
+ return this;
+ };
+
+
+ /**
+ * Specify audio codec
+ *
+ * @method FfmpegCommand#audioCodec
+ * @category Audio
+ * @aliases withAudioCodec
+ *
+ * @param {String} codec audio codec name
+ * @return FfmpegCommand
+ */
+ proto.withAudioCodec =
+ proto.audioCodec = function(codec) {
+ this._currentOutput.audio('-acodec', codec);
+
+ return this;
+ };
+
+
+ /**
+ * Specify audio bitrate
+ *
+ * @method FfmpegCommand#audioBitrate
+ * @category Audio
+ * @aliases withAudioBitrate
+ *
+ * @param {String|Number} bitrate audio bitrate in kbps (with an optional 'k' suffix)
+ * @return FfmpegCommand
+ */
+ proto.withAudioBitrate =
+ proto.audioBitrate = function(bitrate) {
+ this._currentOutput.audio('-b:a', ('' + bitrate).replace(/k?$/, 'k'));
+ return this;
+ };
+
+
+ /**
+ * Specify audio channel count
+ *
+ * @method FfmpegCommand#audioChannels
+ * @category Audio
+ * @aliases withAudioChannels
+ *
+ * @param {Number} channels channel count
+ * @return FfmpegCommand
+ */
+ proto.withAudioChannels =
+ proto.audioChannels = function(channels) {
+ this._currentOutput.audio('-ac', channels);
+ return this;
+ };
+
+
+ /**
+ * Specify audio frequency
+ *
+ * @method FfmpegCommand#audioFrequency
+ * @category Audio
+ * @aliases withAudioFrequency
+ *
+ * @param {Number} freq audio frequency in Hz
+ * @return FfmpegCommand
+ */
+ proto.withAudioFrequency =
+ proto.audioFrequency = function(freq) {
+ this._currentOutput.audio('-ar', freq);
+ return this;
+ };
+
+
+ /**
+ * Specify audio quality
+ *
+ * @method FfmpegCommand#audioQuality
+ * @category Audio
+ * @aliases withAudioQuality
+ *
+ * @param {Number} quality audio quality factor
+ * @return FfmpegCommand
+ */
+ proto.withAudioQuality =
+ proto.audioQuality = function(quality) {
+ this._currentOutput.audio('-aq', quality);
+ return this;
+ };
+
+
+ /**
+ * Specify custom audio filter(s)
+ *
+ * Can be called both with one or many filters, or a filter array.
+ *
+ * @example
+ * command.audioFilters('filter1');
+ *
+ * @example
+ * command.audioFilters('filter1', 'filter2=param1=value1:param2=value2');
+ *
+ * @example
+ * command.audioFilters(['filter1', 'filter2']);
+ *
+ * @example
+ * command.audioFilters([
+ * {
+ * filter: 'filter1'
+ * },
+ * {
+ * filter: 'filter2',
+ * options: 'param=value:param=value'
+ * }
+ * ]);
+ *
+ * @example
+ * command.audioFilters(
+ * {
+ * filter: 'filter1',
+ * options: ['value1', 'value2']
+ * },
+ * {
+ * filter: 'filter2',
+ * options: { param1: 'value1', param2: 'value2' }
+ * }
+ * );
+ *
+ * @method FfmpegCommand#audioFilters
+ * @aliases withAudioFilter,withAudioFilters,audioFilter
+ * @category Audio
+ *
+ * @param {...String|String[]|Object[]} filters audio filter strings, string array or
+ * filter specification array, each with the following properties:
+ * @param {String} filters.filter filter name
+ * @param {String|String[]|Object} [filters.options] filter option string, array, or object
+ * @return FfmpegCommand
+ */
+ proto.withAudioFilter =
+ proto.withAudioFilters =
+ proto.audioFilter =
+ proto.audioFilters = function(filters) {
+ if (arguments.length > 1) {
+ filters = [].slice.call(arguments);
+ }
+
+ if (!Array.isArray(filters)) {
+ filters = [filters];
+ }
+
+ this._currentOutput.audioFilters(utils.makeFilterStrings(filters));
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 1117:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var utils = __nccwpck_require__(7166);
+
+
+/*
+ *! Custom options methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Add custom input option(s)
+ *
+ * When passing a single string or an array, each string containing two
+ * words is split (eg. inputOptions('-option value') is supported) for
+ * compatibility reasons. This is not the case when passing more than
+ * one argument.
+ *
+ * @example
+ * command.inputOptions('option1');
+ *
+ * @example
+ * command.inputOptions('option1', 'option2');
+ *
+ * @example
+ * command.inputOptions(['option1', 'option2']);
+ *
+ * @method FfmpegCommand#inputOptions
+ * @category Custom options
+ * @aliases addInputOption,addInputOptions,withInputOption,withInputOptions,inputOption
+ *
+ * @param {...String} options option string(s) or string array
+ * @return FfmpegCommand
+ */
+ proto.addInputOption =
+ proto.addInputOptions =
+ proto.withInputOption =
+ proto.withInputOptions =
+ proto.inputOption =
+ proto.inputOptions = function(options) {
+ if (!this._currentInput) {
+ throw new Error('No input specified');
+ }
+
+ var doSplit = true;
+
+ if (arguments.length > 1) {
+ options = [].slice.call(arguments);
+ doSplit = false;
+ }
+
+ if (!Array.isArray(options)) {
+ options = [options];
+ }
+
+ this._currentInput.options(options.reduce(function(options, option) {
+ var split = String(option).split(' ');
+
+ if (doSplit && split.length === 2) {
+ options.push(split[0], split[1]);
+ } else {
+ options.push(option);
+ }
+
+ return options;
+ }, []));
+ return this;
+ };
+
+
+ /**
+ * Add custom output option(s)
+ *
+ * @example
+ * command.outputOptions('option1');
+ *
+ * @example
+ * command.outputOptions('option1', 'option2');
+ *
+ * @example
+ * command.outputOptions(['option1', 'option2']);
+ *
+ * @method FfmpegCommand#outputOptions
+ * @category Custom options
+ * @aliases addOutputOption,addOutputOptions,addOption,addOptions,withOutputOption,withOutputOptions,withOption,withOptions,outputOption
+ *
+ * @param {...String} options option string(s) or string array
+ * @return FfmpegCommand
+ */
+ proto.addOutputOption =
+ proto.addOutputOptions =
+ proto.addOption =
+ proto.addOptions =
+ proto.withOutputOption =
+ proto.withOutputOptions =
+ proto.withOption =
+ proto.withOptions =
+ proto.outputOption =
+ proto.outputOptions = function(options) {
+ var doSplit = true;
+
+ if (arguments.length > 1) {
+ options = [].slice.call(arguments);
+ doSplit = false;
+ }
+
+ if (!Array.isArray(options)) {
+ options = [options];
+ }
+
+ this._currentOutput.options(options.reduce(function(options, option) {
+ var split = String(option).split(' ');
+
+ if (doSplit && split.length === 2) {
+ options.push(split[0], split[1]);
+ } else {
+ options.push(option);
+ }
+
+ return options;
+ }, []));
+ return this;
+ };
+
+
+ /**
+ * Specify a complex filtergraph
+ *
+ * Calling this method will override any previously set filtergraph, but you can set
+ * as many filters as needed in one call.
+ *
+ * @example Overlay an image over a video (using a filtergraph string)
+ * ffmpeg()
+ * .input('video.avi')
+ * .input('image.png')
+ * .complexFilter('[0:v][1:v]overlay[out]', ['out']);
+ *
+ * @example Overlay an image over a video (using a filter array)
+ * ffmpeg()
+ * .input('video.avi')
+ * .input('image.png')
+ * .complexFilter([{
+ * filter: 'overlay',
+ * inputs: ['0:v', '1:v'],
+ * outputs: ['out']
+ * }], ['out']);
+ *
+ * @example Split video into RGB channels and output a 3x1 video with channels side to side
+ * ffmpeg()
+ * .input('video.avi')
+ * .complexFilter([
+ * // Duplicate video stream 3 times into streams a, b, and c
+ * { filter: 'split', options: '3', outputs: ['a', 'b', 'c'] },
+ *
+ * // Create stream 'red' by cancelling green and blue channels from stream 'a'
+ * { filter: 'lutrgb', options: { g: 0, b: 0 }, inputs: 'a', outputs: 'red' },
+ *
+ * // Create stream 'green' by cancelling red and blue channels from stream 'b'
+ * { filter: 'lutrgb', options: { r: 0, b: 0 }, inputs: 'b', outputs: 'green' },
+ *
+ * // Create stream 'blue' by cancelling red and green channels from stream 'c'
+ * { filter: 'lutrgb', options: { r: 0, g: 0 }, inputs: 'c', outputs: 'blue' },
+ *
+ * // Pad stream 'red' to 3x width, keeping the video on the left, and name output 'padded'
+ * { filter: 'pad', options: { w: 'iw*3', h: 'ih' }, inputs: 'red', outputs: 'padded' },
+ *
+ * // Overlay 'green' onto 'padded', moving it to the center, and name output 'redgreen'
+ * { filter: 'overlay', options: { x: 'w', y: 0 }, inputs: ['padded', 'green'], outputs: 'redgreen'},
+ *
+ * // Overlay 'blue' onto 'redgreen', moving it to the right
+ * { filter: 'overlay', options: { x: '2*w', y: 0 }, inputs: ['redgreen', 'blue']},
+ * ]);
+ *
+ * @method FfmpegCommand#complexFilter
+ * @category Custom options
+ * @aliases filterGraph
+ *
+ * @param {String|Array} spec filtergraph string or array of filter specification
+ * objects, each having the following properties:
+ * @param {String} spec.filter filter name
+ * @param {String|Array} [spec.inputs] (array of) input stream specifier(s) for the filter,
+ * defaults to ffmpeg automatically choosing the first unused matching streams
+ * @param {String|Array} [spec.outputs] (array of) output stream specifier(s) for the filter,
+ * defaults to ffmpeg automatically assigning the output to the output file
+ * @param {Object|String|Array} [spec.options] filter options, can be omitted to not set any options
+ * @param {Array} [map] (array of) stream specifier(s) from the graph to include in
+ * ffmpeg output, defaults to ffmpeg automatically choosing the first matching streams.
+ * @return FfmpegCommand
+ */
+ proto.filterGraph =
+ proto.complexFilter = function(spec, map) {
+ this._complexFilters.clear();
+
+ if (!Array.isArray(spec)) {
+ spec = [spec];
+ }
+
+ this._complexFilters('-filter_complex', utils.makeFilterStrings(spec).join(';'));
+
+ if (Array.isArray(map)) {
+ var self = this;
+ map.forEach(function(streamSpec) {
+ self._complexFilters('-map', streamSpec.replace(utils.streamRegexp, '[$1]'));
+ });
+ } else if (typeof map === 'string') {
+ this._complexFilters('-map', map.replace(utils.streamRegexp, '[$1]'));
+ }
+
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 8781:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var utils = __nccwpck_require__(7166);
+
+/*
+ *! Input-related methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Add an input to command
+ *
+ * Also switches "current input", that is the input that will be affected
+ * by subsequent input-related methods.
+ *
+ * Note: only one stream input is supported for now.
+ *
+ * @method FfmpegCommand#input
+ * @category Input
+ * @aliases mergeAdd,addInput
+ *
+ * @param {String|Readable} source input file path or readable stream
+ * @return FfmpegCommand
+ */
+ proto.mergeAdd =
+ proto.addInput =
+ proto.input = function(source) {
+ var isFile = false;
+ var isStream = false;
+
+ if (typeof source !== 'string') {
+ if (!('readable' in source) || !(source.readable)) {
+ throw new Error('Invalid input');
+ }
+
+ var hasInputStream = this._inputs.some(function(input) {
+ return input.isStream;
+ });
+
+ if (hasInputStream) {
+ throw new Error('Only one input stream is supported');
+ }
+
+ isStream = true;
+ source.pause();
+ } else {
+ var protocol = source.match(/^([a-z]{2,}):/i);
+ isFile = !protocol || protocol[0] === 'file';
+ }
+
+ this._inputs.push(this._currentInput = {
+ source: source,
+ isFile: isFile,
+ isStream: isStream,
+ options: utils.args()
+ });
+
+ return this;
+ };
+
+
+ /**
+ * Specify input format for the last specified input
+ *
+ * @method FfmpegCommand#inputFormat
+ * @category Input
+ * @aliases withInputFormat,fromFormat
+ *
+ * @param {String} format input format
+ * @return FfmpegCommand
+ */
+ proto.withInputFormat =
+ proto.inputFormat =
+ proto.fromFormat = function(format) {
+ if (!this._currentInput) {
+ throw new Error('No input specified');
+ }
+
+ this._currentInput.options('-f', format);
+ return this;
+ };
+
+
+ /**
+ * Specify input FPS for the last specified input
+ * (only valid for raw video formats)
+ *
+ * @method FfmpegCommand#inputFps
+ * @category Input
+ * @aliases withInputFps,withInputFPS,withFpsInput,withFPSInput,inputFPS,inputFps,fpsInput
+ *
+ * @param {Number} fps input FPS
+ * @return FfmpegCommand
+ */
+ proto.withInputFps =
+ proto.withInputFPS =
+ proto.withFpsInput =
+ proto.withFPSInput =
+ proto.inputFPS =
+ proto.inputFps =
+ proto.fpsInput =
+ proto.FPSInput = function(fps) {
+ if (!this._currentInput) {
+ throw new Error('No input specified');
+ }
+
+ this._currentInput.options('-r', fps);
+ return this;
+ };
+
+
+ /**
+ * Use native framerate for the last specified input
+ *
+ * @method FfmpegCommand#native
+ * @category Input
+ * @aliases nativeFramerate,withNativeFramerate
+ *
+ * @return FfmmegCommand
+ */
+ proto.nativeFramerate =
+ proto.withNativeFramerate =
+ proto.native = function() {
+ if (!this._currentInput) {
+ throw new Error('No input specified');
+ }
+
+ this._currentInput.options('-re');
+ return this;
+ };
+
+
+ /**
+ * Specify input seek time for the last specified input
+ *
+ * @method FfmpegCommand#seekInput
+ * @category Input
+ * @aliases setStartTime,seekTo
+ *
+ * @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
+ * @return FfmpegCommand
+ */
+ proto.setStartTime =
+ proto.seekInput = function(seek) {
+ if (!this._currentInput) {
+ throw new Error('No input specified');
+ }
+
+ this._currentInput.options('-ss', seek);
+
+ return this;
+ };
+
+
+ /**
+ * Loop over the last specified input
+ *
+ * @method FfmpegCommand#loop
+ * @category Input
+ *
+ * @param {String|Number} [duration] loop duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
+ * @return FfmpegCommand
+ */
+ proto.loop = function(duration) {
+ if (!this._currentInput) {
+ throw new Error('No input specified');
+ }
+
+ this._currentInput.options('-loop', '1');
+
+ if (typeof duration !== 'undefined') {
+ this.duration(duration);
+ }
+
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 81:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var path = __nccwpck_require__(1017);
+
+/*
+ *! Miscellaneous methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Use preset
+ *
+ * @method FfmpegCommand#preset
+ * @category Miscellaneous
+ * @aliases usingPreset
+ *
+ * @param {String|Function} preset preset name or preset function
+ */
+ proto.usingPreset =
+ proto.preset = function(preset) {
+ if (typeof preset === 'function') {
+ preset(this);
+ } else {
+ try {
+ var modulePath = path.join(this.options.presets, preset);
+ var module = require(modulePath);
+
+ if (typeof module.load === 'function') {
+ module.load(this);
+ } else {
+ throw new Error('preset ' + modulePath + ' has no load() function');
+ }
+ } catch (err) {
+ throw new Error('preset ' + modulePath + ' could not be loaded: ' + err.message);
+ }
+ }
+
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 6488:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var utils = __nccwpck_require__(7166);
+
+
+/*
+ *! Output-related methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Add output
+ *
+ * @method FfmpegCommand#output
+ * @category Output
+ * @aliases addOutput
+ *
+ * @param {String|Writable} target target file path or writable stream
+ * @param {Object} [pipeopts={}] pipe options (only applies to streams)
+ * @return FfmpegCommand
+ */
+ proto.addOutput =
+ proto.output = function(target, pipeopts) {
+ var isFile = false;
+
+ if (!target && this._currentOutput) {
+ // No target is only allowed when called from constructor
+ throw new Error('Invalid output');
+ }
+
+ if (target && typeof target !== 'string') {
+ if (!('writable' in target) || !(target.writable)) {
+ throw new Error('Invalid output');
+ }
+ } else if (typeof target === 'string') {
+ var protocol = target.match(/^([a-z]{2,}):/i);
+ isFile = !protocol || protocol[0] === 'file';
+ }
+
+ if (target && !('target' in this._currentOutput)) {
+ // For backwards compatibility, set target for first output
+ this._currentOutput.target = target;
+ this._currentOutput.isFile = isFile;
+ this._currentOutput.pipeopts = pipeopts || {};
+ } else {
+ if (target && typeof target !== 'string') {
+ var hasOutputStream = this._outputs.some(function(output) {
+ return typeof output.target !== 'string';
+ });
+
+ if (hasOutputStream) {
+ throw new Error('Only one output stream is supported');
+ }
+ }
+
+ this._outputs.push(this._currentOutput = {
+ target: target,
+ isFile: isFile,
+ flags: {},
+ pipeopts: pipeopts || {}
+ });
+
+ var self = this;
+ ['audio', 'audioFilters', 'video', 'videoFilters', 'sizeFilters', 'options'].forEach(function(key) {
+ self._currentOutput[key] = utils.args();
+ });
+
+ if (!target) {
+ // Call from constructor: remove target key
+ delete this._currentOutput.target;
+ }
+ }
+
+ return this;
+ };
+
+
+ /**
+ * Specify output seek time
+ *
+ * @method FfmpegCommand#seek
+ * @category Input
+ * @aliases seekOutput
+ *
+ * @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
+ * @return FfmpegCommand
+ */
+ proto.seekOutput =
+ proto.seek = function(seek) {
+ this._currentOutput.options('-ss', seek);
+ return this;
+ };
+
+
+ /**
+ * Set output duration
+ *
+ * @method FfmpegCommand#duration
+ * @category Output
+ * @aliases withDuration,setDuration
+ *
+ * @param {String|Number} duration duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
+ * @return FfmpegCommand
+ */
+ proto.withDuration =
+ proto.setDuration =
+ proto.duration = function(duration) {
+ this._currentOutput.options('-t', duration);
+ return this;
+ };
+
+
+ /**
+ * Set output format
+ *
+ * @method FfmpegCommand#format
+ * @category Output
+ * @aliases toFormat,withOutputFormat,outputFormat
+ *
+ * @param {String} format output format name
+ * @return FfmpegCommand
+ */
+ proto.toFormat =
+ proto.withOutputFormat =
+ proto.outputFormat =
+ proto.format = function(format) {
+ this._currentOutput.options('-f', format);
+ return this;
+ };
+
+
+ /**
+ * Add stream mapping to output
+ *
+ * @method FfmpegCommand#map
+ * @category Output
+ *
+ * @param {String} spec stream specification string, with optional square brackets
+ * @return FfmpegCommand
+ */
+ proto.map = function(spec) {
+ this._currentOutput.options('-map', spec.replace(utils.streamRegexp, '[$1]'));
+ return this;
+ };
+
+
+ /**
+ * Run flvtool2/flvmeta on output
+ *
+ * @method FfmpegCommand#flvmeta
+ * @category Output
+ * @aliases updateFlvMetadata
+ *
+ * @return FfmpegCommand
+ */
+ proto.updateFlvMetadata =
+ proto.flvmeta = function() {
+ this._currentOutput.flags.flvmeta = true;
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 7215:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var utils = __nccwpck_require__(7166);
+
+
+/*
+ *! Video-related methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Disable video in the output
+ *
+ * @method FfmpegCommand#noVideo
+ * @category Video
+ * @aliases withNoVideo
+ *
+ * @return FfmpegCommand
+ */
+ proto.withNoVideo =
+ proto.noVideo = function() {
+ this._currentOutput.video.clear();
+ this._currentOutput.videoFilters.clear();
+ this._currentOutput.video('-vn');
+
+ return this;
+ };
+
+
+ /**
+ * Specify video codec
+ *
+ * @method FfmpegCommand#videoCodec
+ * @category Video
+ * @aliases withVideoCodec
+ *
+ * @param {String} codec video codec name
+ * @return FfmpegCommand
+ */
+ proto.withVideoCodec =
+ proto.videoCodec = function(codec) {
+ this._currentOutput.video('-vcodec', codec);
+ return this;
+ };
+
+
+ /**
+ * Specify video bitrate
+ *
+ * @method FfmpegCommand#videoBitrate
+ * @category Video
+ * @aliases withVideoBitrate
+ *
+ * @param {String|Number} bitrate video bitrate in kbps (with an optional 'k' suffix)
+ * @param {Boolean} [constant=false] enforce constant bitrate
+ * @return FfmpegCommand
+ */
+ proto.withVideoBitrate =
+ proto.videoBitrate = function(bitrate, constant) {
+ bitrate = ('' + bitrate).replace(/k?$/, 'k');
+
+ this._currentOutput.video('-b:v', bitrate);
+ if (constant) {
+ this._currentOutput.video(
+ '-maxrate', bitrate,
+ '-minrate', bitrate,
+ '-bufsize', '3M'
+ );
+ }
+
+ return this;
+ };
+
+
+ /**
+ * Specify custom video filter(s)
+ *
+ * Can be called both with one or many filters, or a filter array.
+ *
+ * @example
+ * command.videoFilters('filter1');
+ *
+ * @example
+ * command.videoFilters('filter1', 'filter2=param1=value1:param2=value2');
+ *
+ * @example
+ * command.videoFilters(['filter1', 'filter2']);
+ *
+ * @example
+ * command.videoFilters([
+ * {
+ * filter: 'filter1'
+ * },
+ * {
+ * filter: 'filter2',
+ * options: 'param=value:param=value'
+ * }
+ * ]);
+ *
+ * @example
+ * command.videoFilters(
+ * {
+ * filter: 'filter1',
+ * options: ['value1', 'value2']
+ * },
+ * {
+ * filter: 'filter2',
+ * options: { param1: 'value1', param2: 'value2' }
+ * }
+ * );
+ *
+ * @method FfmpegCommand#videoFilters
+ * @category Video
+ * @aliases withVideoFilter,withVideoFilters,videoFilter
+ *
+ * @param {...String|String[]|Object[]} filters video filter strings, string array or
+ * filter specification array, each with the following properties:
+ * @param {String} filters.filter filter name
+ * @param {String|String[]|Object} [filters.options] filter option string, array, or object
+ * @return FfmpegCommand
+ */
+ proto.withVideoFilter =
+ proto.withVideoFilters =
+ proto.videoFilter =
+ proto.videoFilters = function(filters) {
+ if (arguments.length > 1) {
+ filters = [].slice.call(arguments);
+ }
+
+ if (!Array.isArray(filters)) {
+ filters = [filters];
+ }
+
+ this._currentOutput.videoFilters(utils.makeFilterStrings(filters));
+
+ return this;
+ };
+
+
+ /**
+ * Specify output FPS
+ *
+ * @method FfmpegCommand#fps
+ * @category Video
+ * @aliases withOutputFps,withOutputFPS,withFpsOutput,withFPSOutput,withFps,withFPS,outputFPS,outputFps,fpsOutput,FPSOutput,FPS
+ *
+ * @param {Number} fps output FPS
+ * @return FfmpegCommand
+ */
+ proto.withOutputFps =
+ proto.withOutputFPS =
+ proto.withFpsOutput =
+ proto.withFPSOutput =
+ proto.withFps =
+ proto.withFPS =
+ proto.outputFPS =
+ proto.outputFps =
+ proto.fpsOutput =
+ proto.FPSOutput =
+ proto.fps =
+ proto.FPS = function(fps) {
+ this._currentOutput.video('-r', fps);
+ return this;
+ };
+
+
+ /**
+ * Only transcode a certain number of frames
+ *
+ * @method FfmpegCommand#frames
+ * @category Video
+ * @aliases takeFrames,withFrames
+ *
+ * @param {Number} frames frame count
+ * @return FfmpegCommand
+ */
+ proto.takeFrames =
+ proto.withFrames =
+ proto.frames = function(frames) {
+ this._currentOutput.video('-vframes', frames);
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 4773:
+/***/ ((module) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+/*
+ *! Size helpers
+ */
+
+
+/**
+ * Return filters to pad video to width*height,
+ *
+ * @param {Number} width output width
+ * @param {Number} height output height
+ * @param {Number} aspect video aspect ratio (without padding)
+ * @param {Number} color padding color
+ * @return scale/pad filters
+ * @private
+ */
+function getScalePadFilters(width, height, aspect, color) {
+ /*
+ let a be the input aspect ratio, A be the requested aspect ratio
+
+ if a > A, padding is done on top and bottom
+ if a < A, padding is done on left and right
+ */
+
+ return [
+ /*
+ In both cases, we first have to scale the input to match the requested size.
+ When using computed width/height, we truncate them to multiples of 2
+ */
+ {
+ filter: 'scale',
+ options: {
+ w: 'if(gt(a,' + aspect + '),' + width + ',trunc(' + height + '*a/2)*2)',
+ h: 'if(lt(a,' + aspect + '),' + height + ',trunc(' + width + '/a/2)*2)'
+ }
+ },
+
+ /*
+ Then we pad the scaled input to match the target size
+ (here iw and ih refer to the padding input, i.e the scaled output)
+ */
+
+ {
+ filter: 'pad',
+ options: {
+ w: width,
+ h: height,
+ x: 'if(gt(a,' + aspect + '),0,(' + width + '-iw)/2)',
+ y: 'if(lt(a,' + aspect + '),0,(' + height + '-ih)/2)',
+ color: color
+ }
+ }
+ ];
+}
+
+
+/**
+ * Recompute size filters
+ *
+ * @param {Object} output
+ * @param {String} key newly-added parameter name ('size', 'aspect' or 'pad')
+ * @param {String} value newly-added parameter value
+ * @return filter string array
+ * @private
+ */
+function createSizeFilters(output, key, value) {
+ // Store parameters
+ var data = output.sizeData = output.sizeData || {};
+ data[key] = value;
+
+ if (!('size' in data)) {
+ // No size requested, keep original size
+ return [];
+ }
+
+ // Try to match the different size string formats
+ var fixedSize = data.size.match(/([0-9]+)x([0-9]+)/);
+ var fixedWidth = data.size.match(/([0-9]+)x\?/);
+ var fixedHeight = data.size.match(/\?x([0-9]+)/);
+ var percentRatio = data.size.match(/\b([0-9]{1,3})%/);
+ var width, height, aspect;
+
+ if (percentRatio) {
+ var ratio = Number(percentRatio[1]) / 100;
+ return [{
+ filter: 'scale',
+ options: {
+ w: 'trunc(iw*' + ratio + '/2)*2',
+ h: 'trunc(ih*' + ratio + '/2)*2'
+ }
+ }];
+ } else if (fixedSize) {
+ // Round target size to multiples of 2
+ width = Math.round(Number(fixedSize[1]) / 2) * 2;
+ height = Math.round(Number(fixedSize[2]) / 2) * 2;
+
+ aspect = width / height;
+
+ if (data.pad) {
+ return getScalePadFilters(width, height, aspect, data.pad);
+ } else {
+ // No autopad requested, rescale to target size
+ return [{ filter: 'scale', options: { w: width, h: height }}];
+ }
+ } else if (fixedWidth || fixedHeight) {
+ if ('aspect' in data) {
+ // Specified aspect ratio
+ width = fixedWidth ? fixedWidth[1] : Math.round(Number(fixedHeight[1]) * data.aspect);
+ height = fixedHeight ? fixedHeight[1] : Math.round(Number(fixedWidth[1]) / data.aspect);
+
+ // Round to multiples of 2
+ width = Math.round(width / 2) * 2;
+ height = Math.round(height / 2) * 2;
+
+ if (data.pad) {
+ return getScalePadFilters(width, height, data.aspect, data.pad);
+ } else {
+ // No autopad requested, rescale to target size
+ return [{ filter: 'scale', options: { w: width, h: height }}];
+ }
+ } else {
+ // Keep input aspect ratio
+
+ if (fixedWidth) {
+ return [{
+ filter: 'scale',
+ options: {
+ w: Math.round(Number(fixedWidth[1]) / 2) * 2,
+ h: 'trunc(ow/a/2)*2'
+ }
+ }];
+ } else {
+ return [{
+ filter: 'scale',
+ options: {
+ w: 'trunc(oh*a/2)*2',
+ h: Math.round(Number(fixedHeight[1]) / 2) * 2
+ }
+ }];
+ }
+ }
+ } else {
+ throw new Error('Invalid size specified: ' + data.size);
+ }
+}
+
+
+/*
+ *! Video size-related methods
+ */
+
+module.exports = function(proto) {
+ /**
+ * Keep display aspect ratio
+ *
+ * This method is useful when converting an input with non-square pixels to an output format
+ * that does not support non-square pixels. It rescales the input so that the display aspect
+ * ratio is the same.
+ *
+ * @method FfmpegCommand#keepDAR
+ * @category Video size
+ * @aliases keepPixelAspect,keepDisplayAspect,keepDisplayAspectRatio
+ *
+ * @return FfmpegCommand
+ */
+ proto.keepPixelAspect = // Only for compatibility, this is not about keeping _pixel_ aspect ratio
+ proto.keepDisplayAspect =
+ proto.keepDisplayAspectRatio =
+ proto.keepDAR = function() {
+ return this.videoFilters([
+ {
+ filter: 'scale',
+ options: {
+ w: 'if(gt(sar,1),iw*sar,iw)',
+ h: 'if(lt(sar,1),ih/sar,ih)'
+ }
+ },
+ {
+ filter: 'setsar',
+ options: '1'
+ }
+ ]);
+ };
+
+
+ /**
+ * Set output size
+ *
+ * The 'size' parameter can have one of 4 forms:
+ * - 'X%': rescale to xx % of the original size
+ * - 'WxH': specify width and height
+ * - 'Wx?': specify width and compute height from input aspect ratio
+ * - '?xH': specify height and compute width from input aspect ratio
+ *
+ * Note: both dimensions will be truncated to multiples of 2.
+ *
+ * @method FfmpegCommand#size
+ * @category Video size
+ * @aliases withSize,setSize
+ *
+ * @param {String} size size string, eg. '33%', '320x240', '320x?', '?x240'
+ * @return FfmpegCommand
+ */
+ proto.withSize =
+ proto.setSize =
+ proto.size = function(size) {
+ var filters = createSizeFilters(this._currentOutput, 'size', size);
+
+ this._currentOutput.sizeFilters.clear();
+ this._currentOutput.sizeFilters(filters);
+
+ return this;
+ };
+
+
+ /**
+ * Set output aspect ratio
+ *
+ * @method FfmpegCommand#aspect
+ * @category Video size
+ * @aliases withAspect,withAspectRatio,setAspect,setAspectRatio,aspectRatio
+ *
+ * @param {String|Number} aspect aspect ratio (number or 'X:Y' string)
+ * @return FfmpegCommand
+ */
+ proto.withAspect =
+ proto.withAspectRatio =
+ proto.setAspect =
+ proto.setAspectRatio =
+ proto.aspect =
+ proto.aspectRatio = function(aspect) {
+ var a = Number(aspect);
+ if (isNaN(a)) {
+ var match = aspect.match(/^(\d+):(\d+)$/);
+ if (match) {
+ a = Number(match[1]) / Number(match[2]);
+ } else {
+ throw new Error('Invalid aspect ratio: ' + aspect);
+ }
+ }
+
+ var filters = createSizeFilters(this._currentOutput, 'aspect', a);
+
+ this._currentOutput.sizeFilters.clear();
+ this._currentOutput.sizeFilters(filters);
+
+ return this;
+ };
+
+
+ /**
+ * Enable auto-padding the output
+ *
+ * @method FfmpegCommand#autopad
+ * @category Video size
+ * @aliases applyAutopadding,applyAutoPadding,applyAutopad,applyAutoPad,withAutopadding,withAutoPadding,withAutopad,withAutoPad,autoPad
+ *
+ * @param {Boolean} [pad=true] enable/disable auto-padding
+ * @param {String} [color='black'] pad color
+ */
+ proto.applyAutopadding =
+ proto.applyAutoPadding =
+ proto.applyAutopad =
+ proto.applyAutoPad =
+ proto.withAutopadding =
+ proto.withAutoPadding =
+ proto.withAutopad =
+ proto.withAutoPad =
+ proto.autoPad =
+ proto.autopad = function(pad, color) {
+ // Allow autopad(color)
+ if (typeof pad === 'string') {
+ color = pad;
+ pad = true;
+ }
+
+ // Allow autopad() and autopad(undefined, color)
+ if (typeof pad === 'undefined') {
+ pad = true;
+ }
+
+ var filters = createSizeFilters(this._currentOutput, 'pad', pad ? color || 'black' : false);
+
+ this._currentOutput.sizeFilters.clear();
+ this._currentOutput.sizeFilters(filters);
+
+ return this;
+ };
+};
+
+
+/***/ }),
+
+/***/ 981:
+/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
+
+"use strict";
+/*jshint node:true*/
+
+
+var spawn = (__nccwpck_require__(2081).spawn);
+var path = __nccwpck_require__(1017);
+var fs = __nccwpck_require__(7147);
+var async = __nccwpck_require__(7888);
+var utils = __nccwpck_require__(7166);
+
+var nlRegexp = /\r\n|\r|\n/g;
+
+/*
+ *! Processor methods
+ */
+
+
+/**
+ * Run ffprobe asynchronously and store data in command
+ *
+ * @param {FfmpegCommand} command
+ * @private
+ */
+function runFfprobe(command) {
+ const inputProbeIndex = 0;
+ if (command._inputs[inputProbeIndex].isStream) {
+ // Don't probe input streams as this will consume them
+ return;
+ }
+ command.ffprobe(inputProbeIndex, function(err, data) {
+ command._ffprobeData = data;
+ });
+}
+
+
+module.exports = function(proto) {
+ /**
+ * Emitted just after ffmpeg has been spawned.
+ *
+ * @event FfmpegCommand#start
+ * @param {String} command ffmpeg command line
+ */
+
+ /**
+ * Emitted when ffmpeg reports progress information
+ *
+ * @event FfmpegCommand#progress
+ * @param {Object} progress progress object
+ * @param {Number} progress.frames number of frames transcoded
+ * @param {Number} progress.currentFps current processing speed in frames per second
+ * @param {Number} progress.currentKbps current output generation speed in kilobytes per second
+ * @param {Number} progress.targetSize current output file size
+ * @param {String} progress.timemark current video timemark
+ * @param {Number} [progress.percent] processing progress (may not be available depending on input)
+ */
+
+ /**
+ * Emitted when ffmpeg outputs to stderr
+ *
+ * @event FfmpegCommand#stderr
+ * @param {String} line stderr output line
+ */
+
+ /**
+ * Emitted when ffmpeg reports input codec data
+ *
+ * @event FfmpegCommand#codecData
+ * @param {Object} codecData codec data object
+ * @param {String} codecData.format input format name
+ * @param {String} codecData.audio input audio codec name
+ * @param {String} codecData.audio_details input audio codec parameters
+ * @param {String} codecData.video input video codec name
+ * @param {String} codecData.video_details input video codec parameters
+ */
+
+ /**
+ * Emitted when an error happens when preparing or running a command
+ *
+ * @event FfmpegCommand#error
+ * @param {Error} error error object, with optional properties 'inputStreamError' / 'outputStreamError' for errors on their respective streams
+ * @param {String|null} stdout ffmpeg stdout, unless outputting to a stream
+ * @param {String|null} stderr ffmpeg stderr
+ */
+
+ /**
+ * Emitted when a command finishes processing
+ *
+ * @event FfmpegCommand#end
+ * @param {Array|String|null} [filenames|stdout] generated filenames when taking screenshots, ffmpeg stdout when not outputting to a stream, null otherwise
+ * @param {String|null} stderr ffmpeg stderr
+ */
+
+
+ /**
+ * Spawn an ffmpeg process
+ *
+ * The 'options' argument may contain the following keys:
+ * - 'niceness': specify process niceness, ignored on Windows (default: 0)
+ * - `cwd`: change working directory
+ * - 'captureStdout': capture stdout and pass it to 'endCB' as its 2nd argument (default: false)
+ * - 'stdoutLines': override command limit (default: use command limit)
+ *
+ * The 'processCB' callback, if present, is called as soon as the process is created and
+ * receives a nodejs ChildProcess object. It may not be called at all if an error happens
+ * before spawning the process.
+ *
+ * The 'endCB' callback is called either when an error occurs or when the ffmpeg process finishes.
+ *
+ * @method FfmpegCommand#_spawnFfmpeg
+ * @param {Array} args ffmpeg command line argument list
+ * @param {Object} [options] spawn options (see above)
+ * @param {Function} [processCB] callback called with process object and stdout/stderr ring buffers when process has been created
+ * @param {Function} endCB callback called with error (if applicable) and stdout/stderr ring buffers when process finished
+ * @private
+ */
+ proto._spawnFfmpeg = function(args, options, processCB, endCB) {
+ // Enable omitting options
+ if (typeof options === 'function') {
+ endCB = processCB;
+ processCB = options;
+ options = {};
+ }
+
+ // Enable omitting processCB
+ if (typeof endCB === 'undefined') {
+ endCB = processCB;
+ processCB = function() {};
+ }
+
+ var maxLines = 'stdoutLines' in options ? options.stdoutLines : this.options.stdoutLines;
+
+ // Find ffmpeg
+ this._getFfmpegPath(function(err, command) {
+ if (err) {
+ return endCB(err);
+ } else if (!command || command.length === 0) {
+ return endCB(new Error('Cannot find ffmpeg'));
+ }
+
+ // Apply niceness
+ if (options.niceness && options.niceness !== 0 && !utils.isWindows) {
+ args.unshift('-n', options.niceness, command);
+ command = 'nice';
+ }
+
+ var stdoutRing = utils.linesRing(maxLines);
+ var stdoutClosed = false;
+
+ var stderrRing = utils.linesRing(maxLines);
+ var stderrClosed = false;
+
+ // Spawn process
+ var ffmpegProc = spawn(command, args, options);
+
+ if (ffmpegProc.stderr) {
+ ffmpegProc.stderr.setEncoding('utf8');
+ }
+
+ ffmpegProc.on('error', function(err) {
+ endCB(err);
+ });
+
+ // Ensure we wait for captured streams to end before calling endCB
+ var exitError = null;
+ function handleExit(err) {
+ if (err) {
+ exitError = err;
+ }
+
+ if (processExited && (stdoutClosed || !options.captureStdout) && stderrClosed) {
+ endCB(exitError, stdoutRing, stderrRing);
+ }
+ }
+
+ // Handle process exit
+ var processExited = false;
+ ffmpegProc.on('exit', function(code, signal) {
+ processExited = true;
+
+ if (signal) {
+ handleExit(new Error('ffmpeg was killed with signal ' + signal));
+ } else if (code) {
+ handleExit(new Error('ffmpeg exited with code ' + code));
+ } else {
+ handleExit();
+ }
+ });
+
+ // Capture stdout if specified
+ if (options.captureStdout) {
+ ffmpegProc.stdout.on('data', function(data) {
+ stdoutRing.append(data);
+ });
+
+ ffmpegProc.stdout.on('close', function() {
+ stdoutRing.close();
+ stdoutClosed = true;
+ handleExit();
+ });
+ }
+
+ // Capture stderr if specified
+ ffmpegProc.stderr.on('data', function(data) {
+ stderrRing.append(data);
+ });
+
+ ffmpegProc.stderr.on('close', function() {
+ stderrRing.close();
+ stderrClosed = true;
+ handleExit();
+ });
+
+ // Call process callback
+ processCB(ffmpegProc, stdoutRing, stderrRing);
+ });
+ };
+
+
+ /**
+ * Build the argument list for an ffmpeg command
+ *
+ * @method FfmpegCommand#_getArguments
+ * @return argument list
+ * @private
+ */
+ proto._getArguments = function() {
+ var complexFilters = this._complexFilters.get();
+
+ var fileOutput = this._outputs.some(function(output) {
+ return output.isFile;
+ });
+
+ return [].concat(
+ // Inputs and input options
+ this._inputs.reduce(function(args, input) {
+ var source = (typeof input.source === 'string') ? input.source : 'pipe:0';
+
+ // For each input, add input options, then '-i