webdriverio-automation
Version:
WebdriverIO-Automation android ios project
235 lines (184 loc) • 26 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.uploadFile = uploadFile;
exports.downloadFile = downloadFile;
require("source-map-support/register");
var _lodash = _interopRequireDefault(require("lodash"));
var _fs = _interopRequireDefault(require("./fs"));
var _url = _interopRequireDefault(require("url"));
var _bluebird = _interopRequireDefault(require("bluebird"));
var _util = require("./util");
var _logger = _interopRequireDefault(require("./logger"));
var _jsftp = _interopRequireDefault(require("jsftp"));
var _timing = _interopRequireDefault(require("./timing"));
var _axios = _interopRequireDefault(require("axios"));
var _formData = _interopRequireDefault(require("form-data"));
function toAxiosAuth(auth) {
if (!_lodash.default.isPlainObject(auth)) {
return null;
}
const axiosAuth = {
username: auth.username || auth.user,
password: auth.password || auth.pass
};
return axiosAuth.username && axiosAuth.password ? axiosAuth : null;
}
async function uploadFileToHttp(localFileStream, parsedUri, uploadOptions = {}) {
const {
method = 'POST',
timeout = 5000,
headers,
auth,
fileFieldName = 'file',
formFields
} = uploadOptions;
const {
protocol,
href
} = parsedUri;
const requestOpts = {
url: href,
method,
timeout
};
const axiosAuth = toAxiosAuth(auth);
if (axiosAuth) {
requestOpts.auth = axiosAuth;
}
const form = new _formData.default();
form.append(fileFieldName, localFileStream);
if (formFields) {
let pairs = [];
if (_lodash.default.isArray(formFields)) {
pairs = formFields;
} else if (_lodash.default.isPlainObject(formFields)) {
pairs = _lodash.default.toPairs(formFields);
}
for (const [key, value] of pairs) {
if (_lodash.default.toLower(key) !== _lodash.default.toLower(fileFieldName)) {
form.append(key, value);
}
}
}
requestOpts.headers = Object.assign({}, _lodash.default.isPlainObject(headers) ? headers : {}, form.getHeaders());
_logger.default.debug(`${protocol} upload options (ex. form data): ${JSON.stringify(requestOpts)}`);
requestOpts.data = form;
await (0, _axios.default)(requestOpts);
}
async function uploadFileToFtp(localFileStream, parsedUri, uploadOptions = {}) {
const {
auth,
user,
pass
} = uploadOptions;
const {
hostname,
port,
protocol,
pathname
} = parsedUri;
const ftpOpts = {
host: hostname,
port: port || 21
};
if ((auth === null || auth === void 0 ? void 0 : auth.user) && (auth === null || auth === void 0 ? void 0 : auth.pass) || user && pass) {
ftpOpts.user = (auth === null || auth === void 0 ? void 0 : auth.user) || user;
ftpOpts.pass = (auth === null || auth === void 0 ? void 0 : auth.pass) || pass;
}
_logger.default.debug(`${protocol} upload options: ${JSON.stringify(ftpOpts)}`);
return await new _bluebird.default((resolve, reject) => {
new _jsftp.default(ftpOpts).put(localFileStream, pathname, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
async function uploadFile(localPath, remoteUri, uploadOptions = {}) {
if (!(await _fs.default.exists(localPath))) {
throw new Error(`'${localPath}' does not exists or is not accessible`);
}
const {
isMetered = true
} = uploadOptions;
const parsedUri = _url.default.parse(remoteUri);
const {
size
} = await _fs.default.stat(localPath);
if (isMetered) {
_logger.default.info(`Uploading '${localPath}' of ${(0, _util.toReadableSizeString)(size)} size to '${remoteUri}'...`);
}
const timer = new _timing.default().start();
if (['http:', 'https:'].includes(parsedUri.protocol)) {
await uploadFileToHttp(_fs.default.createReadStream(localPath), parsedUri, uploadOptions);
} else if (parsedUri.protocol === 'ftp:') {
await uploadFileToFtp(_fs.default.createReadStream(localPath), parsedUri, uploadOptions);
} else {
throw new Error(`Cannot upload the file at '${localPath}' to '${remoteUri}'. ` + `Unsupported remote protocol '${parsedUri.protocol}'. ` + `Only http/https and ftp/ftps protocols are supported.`);
}
if (isMetered) {
_logger.default.info(`Uploaded '${localPath}' of ${(0, _util.toReadableSizeString)(size)} size in ${timer.getDuration().asSeconds.toFixed(3)}s`);
}
}
async function downloadFile(remoteUrl, dstPath, downloadOptions = {}) {
const {
isMetered = true,
auth,
timeout = 5000,
headers
} = downloadOptions;
const requestOpts = {
url: remoteUrl,
responseType: 'stream',
timeout
};
const axiosAuth = toAxiosAuth(auth);
if (axiosAuth) {
requestOpts.auth = axiosAuth;
}
if (_lodash.default.isPlainObject(headers)) {
requestOpts.headers = headers;
}
const timer = new _timing.default().start();
let responseLength;
try {
const writer = _fs.default.createWriteStream(dstPath);
const {
data: responseStream,
headers: responseHeaders
} = await (0, _axios.default)(requestOpts);
responseLength = parseInt(responseHeaders['content-length'], 10);
responseStream.pipe(writer);
await new _bluebird.default((resolve, reject) => {
responseStream.once('error', reject);
writer.once('finish', resolve);
writer.once('error', e => {
responseStream.unpipe(writer);
reject(e);
});
});
} catch (err) {
throw new Error(`Cannot download the file from ${remoteUrl}: ${err.message}`);
}
const {
size
} = await _fs.default.stat(dstPath);
if (responseLength && size !== responseLength) {
await _fs.default.rimraf(dstPath);
throw new Error(`The size of the file downloaded from ${remoteUrl} (${size} bytes) ` + `differs from the one in Content-Length response header (${responseLength} bytes)`);
}
if (isMetered) {
const secondsElapsed = timer.getDuration().asSeconds;
_logger.default.debug(`${remoteUrl} (${(0, _util.toReadableSizeString)(size)}) ` + `has been downloaded to '${dstPath}' in ${secondsElapsed.toFixed(3)}s`);
if (secondsElapsed >= 2) {
const bytesPerSec = Math.floor(size / secondsElapsed);
_logger.default.debug(`Approximate download speed: ${(0, _util.toReadableSizeString)(bytesPerSec)}/s`);
}
}
}require('source-map-support').install();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9uZXQuanMiXSwibmFtZXMiOlsidG9BeGlvc0F1dGgiLCJhdXRoIiwiXyIsImlzUGxhaW5PYmplY3QiLCJheGlvc0F1dGgiLCJ1c2VybmFtZSIsInVzZXIiLCJwYXNzd29yZCIsInBhc3MiLCJ1cGxvYWRGaWxlVG9IdHRwIiwibG9jYWxGaWxlU3RyZWFtIiwicGFyc2VkVXJpIiwidXBsb2FkT3B0aW9ucyIsIm1ldGhvZCIsInRpbWVvdXQiLCJoZWFkZXJzIiwiZmlsZUZpZWxkTmFtZSIsImZvcm1GaWVsZHMiLCJwcm90b2NvbCIsImhyZWYiLCJyZXF1ZXN0T3B0cyIsInVybCIsImZvcm0iLCJGb3JtRGF0YSIsImFwcGVuZCIsInBhaXJzIiwiaXNBcnJheSIsInRvUGFpcnMiLCJrZXkiLCJ2YWx1ZSIsInRvTG93ZXIiLCJPYmplY3QiLCJhc3NpZ24iLCJnZXRIZWFkZXJzIiwibG9nIiwiZGVidWciLCJKU09OIiwic3RyaW5naWZ5IiwiZGF0YSIsInVwbG9hZEZpbGVUb0Z0cCIsImhvc3RuYW1lIiwicG9ydCIsInBhdGhuYW1lIiwiZnRwT3B0cyIsImhvc3QiLCJCIiwicmVzb2x2ZSIsInJlamVjdCIsIkZ0cCIsInB1dCIsImVyciIsInVwbG9hZEZpbGUiLCJsb2NhbFBhdGgiLCJyZW1vdGVVcmkiLCJmcyIsImV4aXN0cyIsIkVycm9yIiwiaXNNZXRlcmVkIiwicGFyc2UiLCJzaXplIiwic3RhdCIsImluZm8iLCJ0aW1lciIsIlRpbWVyIiwic3RhcnQiLCJpbmNsdWRlcyIsImNyZWF0ZVJlYWRTdHJlYW0iLCJnZXREdXJhdGlvbiIsImFzU2Vjb25kcyIsInRvRml4ZWQiLCJkb3dubG9hZEZpbGUiLCJyZW1vdGVVcmwiLCJkc3RQYXRoIiwiZG93bmxvYWRPcHRpb25zIiwicmVzcG9uc2VUeXBlIiwicmVzcG9uc2VMZW5ndGgiLCJ3cml0ZXIiLCJjcmVhdGVXcml0ZVN0cmVhbSIsInJlc3BvbnNlU3RyZWFtIiwicmVzcG9uc2VIZWFkZXJzIiwicGFyc2VJbnQiLCJwaXBlIiwib25jZSIsImUiLCJ1bnBpcGUiLCJtZXNzYWdlIiwicmltcmFmIiwic2Vjb25kc0VsYXBzZWQiLCJieXRlc1BlclNlYyIsIk1hdGgiLCJmbG9vciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsU0FBU0EsV0FBVCxDQUFzQkMsSUFBdEIsRUFBNEI7QUFDMUIsTUFBSSxDQUFDQyxnQkFBRUMsYUFBRixDQUFnQkYsSUFBaEIsQ0FBTCxFQUE0QjtBQUMxQixXQUFPLElBQVA7QUFDRDs7QUFFRCxRQUFNRyxTQUFTLEdBQUc7QUFDaEJDLElBQUFBLFFBQVEsRUFBRUosSUFBSSxDQUFDSSxRQUFMLElBQWlCSixJQUFJLENBQUNLLElBRGhCO0FBRWhCQyxJQUFBQSxRQUFRLEVBQUVOLElBQUksQ0FBQ00sUUFBTCxJQUFpQk4sSUFBSSxDQUFDTztBQUZoQixHQUFsQjtBQUlBLFNBQVFKLFNBQVMsQ0FBQ0MsUUFBVixJQUFzQkQsU0FBUyxDQUFDRyxRQUFqQyxHQUE2Q0gsU0FBN0MsR0FBeUQsSUFBaEU7QUFDRDs7QUFFRCxlQUFlSyxnQkFBZixDQUFpQ0MsZUFBakMsRUFBa0RDLFNBQWxELEVBQTZEQyxhQUFhLEdBQUcsRUFBN0UsRUFBaUY7QUFDL0UsUUFBTTtBQUNKQyxJQUFBQSxNQUFNLEdBQUcsTUFETDtBQUVKQyxJQUFBQSxPQUFPLEdBQUcsSUFGTjtBQUdKQyxJQUFBQSxPQUhJO0FBSUpkLElBQUFBLElBSkk7QUFLSmUsSUFBQUEsYUFBYSxHQUFHLE1BTFo7QUFNSkMsSUFBQUE7QUFOSSxNQU9GTCxhQVBKO0FBUUEsUUFBTTtBQUNKTSxJQUFBQSxRQURJO0FBRUpDLElBQUFBO0FBRkksTUFHRlIsU0FISjtBQUtBLFFBQU1TLFdBQVcsR0FBRztBQUNsQkMsSUFBQUEsR0FBRyxFQUFFRixJQURhO0FBRWxCTixJQUFBQSxNQUZrQjtBQUdsQkMsSUFBQUE7QUFIa0IsR0FB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QUlHLGNBQWMsSUFBSWhCLElBQUksS0FBS2dCLGNBQS9CLEVBQStDO0FBQzdDLFVBQU1yQixZQUFHZ0MsTUFBSCxDQUFVZCxPQUFWLENBQU47QUFDQSxVQUFNLElBQUloQixLQUFKLENBQVcsd0NBQXVDZSxTQUFVLEtBQUlaLElBQUssVUFBM0QsR0FDYiwyREFBMERnQixjQUFlLFNBRHRFLENBQU47QUFFRDs7QUFDRCxNQUFJbEIsU0FBSixFQUFlO0FBQ2IsVUFBTThCLGNBQWMsR0FBR3pCLEtBQUssQ0FBQ0ssV0FBTixHQUFvQkMsU0FBM0M7O0FBQ0FsQyxvQkFBSUMsS0FBSixDQUFXLEdBQUVvQyxTQUFVLEtBQUksZ0NBQXFCWixJQUFyQixDQUEyQixJQUE1QyxHQUNQLDJCQUEwQmEsT0FBUSxRQUFPZSxjQUFjLENBQUNsQixPQUFmLENBQXVCLENBQXZCLENBQTBCLEdBRHRFOztBQUVBLFFBQUlrQixjQUFjLElBQUksQ0FBdEIsRUFBeUI7QUFDdkIsWUFBTUMsV0FBVyxHQUFHQyxJQUFJLENBQUNDLEtBQUwsQ0FBVy9CLElBQUksR0FBRzRCLGNBQWxCLENBQXBCOztBQUNBckQsc0JBQUlDLEtBQUosQ0FBVywrQkFBOEIsZ0NBQXFCcUQsV0FBckIsQ0FBa0MsSUFBM0U7QUFDRDtBQUNGO0FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGZzIGZyb20gJy4vZnMnO1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgdG9SZWFkYWJsZVNpemVTdHJpbmcgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgRnRwIGZyb20gJ2pzZnRwJztcbmltcG9ydCBUaW1lciBmcm9tICcuL3RpbWluZyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IEZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5cblxuZnVuY3Rpb24gdG9BeGlvc0F1dGggKGF1dGgpIHtcbiAgaWYgKCFfLmlzUGxhaW5PYmplY3QoYXV0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGF4aW9zQXV0aCA9IHtcbiAgICB1c2VybmFtZTogYXV0aC51c2VybmFtZSB8fCBhdXRoLnVzZXIsXG4gICAgcGFzc3dvcmQ6IGF1dGgucGFzc3dvcmQgfHwgYXV0aC5wYXNzLFxuICB9O1xuICByZXR1cm4gKGF4aW9zQXV0aC51c2VybmFtZSAmJiBheGlvc0F1dGgucGFzc3dvcmQpID8gYXhpb3NBdXRoIDogbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBsb2FkRmlsZVRvSHR0cCAobG9jYWxGaWxlU3RyZWFtLCBwYXJzZWRVcmksIHVwbG9hZE9wdGlvbnMgPSB7fSkge1xuICBjb25zdCB7XG4gICAgbWV0aG9kID0gJ1BPU1QnLFxuICAgIHRpbWVvdXQgPSA1MDAwLFxuICAgIGhlYWRlcnMsXG4gICAgYXV0aCxcbiAgICBmaWxlRmllbGROYW1lID0gJ2ZpbGUnLFxuICAgIGZvcm1GaWVsZHMsXG4gIH0gPSB1cGxvYWRPcHRpb25zO1xuICBjb25zdCB7XG4gICAgcHJvdG9jb2wsXG4gICAgaHJlZixcbiAgfSA9IHBhcnNlZFVyaTtcblxuICBjb25zdCByZXF1ZXN0T3B0cyA9IHtcbiAgICB1cmw6IGhyZWYsXG4gICAgbWV0aG9kLFxuICAgIHRpbWVvdXQsXG4gIH07XG4gIGNvbnN0IGF4aW9zQXV0aCA9IHRvQXhpb3NBdXRoKGF1dGgpO1xuICBpZiAoYXhpb3NBdXRoKSB7XG4gICAgcmVxdWVzdE9wdHMuYXV0aCA9IGF4aW9zQXV0aDtcbiAgfVxuICBjb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKCk7XG4gIGZvcm0uYXBwZW5kKGZpbGVGaWVsZE5hbWUsIGxvY2FsRmlsZVN0cmVhbSk7XG4gIGlmIChmb3JtRmllbGRzKSB7XG4gICAgbGV0IHBhaXJzID0gW107XG4gICAgaWYgKF8uaXNBcnJheShmb3JtRmllbGRzKSkge1xuICAgICAgcGFpcnMgPSBmb3JtRmllbGRzO1xuICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KGZvcm1GaWVsZHMpKSB7XG4gICAgICBwYWlycyA9IF8udG9QYWlycyhmb3JtRmllbGRzKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgcGFpcnMpIHtcbiAgICAgIGlmIChfLnRvTG93ZXIoa2V5KSAhPT0gXy50b0xvd2VyKGZpbGVGaWVsZE5hbWUpKSB7XG4gICAgICAgIGZvcm0uYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXF1ZXN0T3B0cy5oZWFkZXJzID0gT2JqZWN0LmFzc2lnbih7fSwgXy5pc1BsYWluT2JqZWN0KGhlYWRlcnMpID8gaGVhZGVycyA6IHt9LCBmb3JtLmdldEhlYWRlcnMoKSk7XG5cbiAgLy8gZXhjbHVkZSBmb3JtIGRhdGEgZnJvbSB0aGUgbG9nIHNpbmNlIGl0J2xsIGNvbnRhaW4gdGhlIGVudGlyZSByZWNvcmRlZCB2aWRlb1xuICBsb2cuZGVidWcoYCR7cHJvdG9jb2x9IHVwbG9hZCBvcHRpb25zIChleC4gZm9ybSBkYXRhKTogJHtKU09OLnN0cmluZ2lmeShyZXF1ZXN0T3B0cyl9YCk7XG4gIHJlcXVlc3RPcHRzLmRhdGEgPSBmb3JtO1xuXG4gIGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBsb2FkRmlsZVRvRnRwIChsb2NhbEZpbGVTdHJlYW0sIHBhcnNlZFVyaSwgdXBsb2FkT3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHtcbiAgICBhdXRoLFxuICAgIHVzZXIsXG4gICAgcGFzcyxcbiAgfSA9IHVwbG9hZE9wdGlvbnM7XG4gIGNvbnN0IHtcbiAgICBob3N0bmFtZSxcbiAgICBwb3J0LFxuICAgIHByb3RvY29sLFxuICAgIHBhdGhuYW1lLFxuICB9ID0gcGFyc2VkVXJpO1xuXG4gIGNvbnN0IGZ0cE9wdHMgPSB7XG4gICAgaG9zdDogaG9zdG5hbWUsXG4gICAgcG9ydDogcG9ydCB8fCAyMSxcbiAgfTtcbiAgaWYgKChhdXRoPy51c2VyICYmIGF1dGg/LnBhc3MpIHx8ICh1c2VyICYmIHBhc3MpKSB7XG4gICAgZnRwT3B0cy51c2VyID0gYXV0aD8udXNlciB8fCB1c2VyO1xuICAgIGZ0cE9wdHMucGFzcyA9IGF1dGg/LnBhc3MgfHwgcGFzcztcbiAgfVxuICBsb2cuZGVidWcoYCR7cHJvdG9jb2x9IHVwbG9hZCBvcHRpb25zOiAke0pTT04uc3RyaW5naWZ5KGZ0cE9wdHMpfWApO1xuICByZXR1cm4gYXdhaXQgbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIG5ldyBGdHAoZnRwT3B0cykucHV0KGxvY2FsRmlsZVN0cmVhbSwgcGF0aG5hbWUsIChlcnIpID0+IHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEF1dGhDcmVkZW50aWFsc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHVzZXIgLSBOb24tZW1wdHkgdXNlciBuYW1lXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcGFzcyAtIE5vbi1lbXB0eSBwYXNzd29yZFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRnRwVXBsb2FkT3B0aW9uc1xuICogQHByb3BlcnR5IHtib29sZWFufSBpc01ldGVyZWQgW3RydWVdIC0gV2hldGhlciB0byBsb2cgdGhlIGFjdHVhbCB1cGxvYWQgcGVyZm9ybWFuY2VcbiAqIChlLmcuIHRpbWluZ3MgYW5kIHNwZWVkKVxuICogQHByb3BlcnR5IHtBdXRoQ3JlZGVudGlhbHN9IGF1dGhcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEh0dHBVcGxvYWRPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGlzTWV0ZXJlZCBbdHJ1ZV0gLSBXaGV0aGVyIHRvIGxvZyB0aGUgYWN0dWFsIHVwbG9hZCBwZXJmb3JtYW5jZVxuICogKGUuZy4gdGltaW5ncyBhbmQgc3BlZWQpXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbWV0aG9kIFtQT1NUXSAtIFRoZSBIVFRQIG1ldGhvZCB1c2VkIGZvciBmaWxlIHVwbG9hZFxuICogQHByb3BlcnR5IHtBdXRoQ3JlZGVudGlhbHN9IGF1dGhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0aW1lb3V0IFs1MDAwXSAtIFRoZSBhY3R1YWwgcmVxdWVzdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kc1xuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgLSBBZGRpdGlvbmFsIHJlcXVlc3QgaGVhZGVycyBtYXBwaW5nXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZmlsZUZpZWxkTmFtZSBbZmlsZV0gLSBUaGUgbmFtZSBvZiB0aGUgZm9ybSBmaWVsZCBjb250YWluaW5nIHRoZSBmaWxlXG4gKiBjb250ZW50IHRvIGJlIHVwbG9hZGVkXG4gKiBAcHJvcGVydHkge0FycmF5PFBhaXI+fE9iamVjdH0gZm9ybUZpZWxkcyAtIFRoZSBhZGRpdGlvbmFsIGZvcm0gZmllbGRzXG4gKiB0byBiZSBpbmNsdWRlZCBpbnRvIHRoZSB1cGxvYWQgcmVxdWVzdC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGNvbnNpZGVyZWQgaWZcbiAqIGBmaWxlRmllbGROYW1lYCBpcyBzZXRcbiAqL1xuXG4vKipcbiAqIFVwbG9hZHMgdGhlIGdpdmVuIGZpbGUgdG8gYSByZW1vdGUgbG9jYXRpb24uIEhUVFAoUykgYW5kIEZUUFxuICogcHJvdG9jb2xzIGFyZSBzdXBwb3J0ZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsUGF0aCAtIFRoZSBwYXRoIHRvIGEgZmlsZSBvbiB0aGUgbG9jYWwgc3RvcmFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSByZW1vdGVVcmkgLSBUaGUgcmVtb3RlIFVSSSB0byB1cGxvYWQgdGhlIGZpbGUgdG8uXG4gKiBAcGFyYW0gez9GdHBVcGxvYWRPcHRpb25zfEh0dHBVcGxvYWRPcHRpb25zfSB1cGxvYWRPcHRpb25zXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVwbG9hZEZpbGUgKGxvY2FsUGF0aCwgcmVtb3RlVXJpLCB1cGxvYWRPcHRpb25zID0ge30pIHtcbiAgaWYgKCFhd2FpdCBmcy5leGlzdHMobG9jYWxQYXRoKSkge1xuICAgIHRocm93IG5ldyBFcnJvciAoYCcke2xvY2FsUGF0aH0nIGRvZXMgbm90IGV4aXN0cyBvciBpcyBub3QgYWNjZXNzaWJsZWApO1xuICB9XG5cbiAgY29uc3Qge1xuICAgIGlzTWV0ZXJlZCA9IHRydWUsXG4gIH0gPSB1cGxvYWRPcHRpb25zO1xuXG4gIGNvbnN0IHBhcnNlZFVyaSA9IHVybC5wYXJzZShyZW1vdGVVcmkpO1xuICBjb25zdCB7c2l6ZX0gPSBhd2FpdCBmcy5zdGF0KGxvY2FsUGF0aCk7XG4gIGlmIChpc01ldGVyZWQpIHtcbiAgICBsb2cuaW5mbyhgVXBsb2FkaW5nICcke2xvY2FsUGF0aH0nIG9mICR7dG9SZWFkYWJsZVNpemVTdHJpbmcoc2l6ZSl9IHNpemUgdG8gJyR7cmVtb3RlVXJpfScuLi5gKTtcbiAgfVxuICBjb25zdCB0aW1lciA9IG5ldyBUaW1lcigpLnN0YXJ0KCk7XG4gIGlmIChbJ2h0dHA6JywgJ2h0dHBzOiddLmluY2x1ZGVzKHBhcnNlZFVyaS5wcm90b2NvbCkpIHtcbiAgICBhd2FpdCB1cGxvYWRGaWxlVG9IdHRwKGZzLmNyZWF0ZVJlYWRTdHJlYW0obG9jYWxQYXRoKSwgcGFyc2VkVXJpLCB1cGxvYWRPcHRpb25zKTtcbiAgfSBlbHNlIGlmIChwYXJzZWRVcmkucHJvdG9jb2wgPT09ICdmdHA6Jykge1xuICAgIGF3YWl0IHVwbG9hZEZpbGVUb0Z0cChmcy5jcmVhdGVSZWFkU3RyZWFtKGxvY2FsUGF0aCksIHBhcnNlZFVyaSwgdXBsb2FkT3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgdXBsb2FkIHRoZSBmaWxlIGF0ICcke2xvY2FsUGF0aH0nIHRvICcke3JlbW90ZVVyaX0nLiBgICtcbiAgICAgIGBVbnN1cHBvcnRlZCByZW1vdGUgcHJvdG9jb2wgJyR7cGFyc2VkVXJpLnByb3RvY29sfScuIGAgK1xuICAgICAgYE9ubHkgaHR0cC9odHRwcyBhbmQgZnRwL2Z0cHMgcHJvdG9jb2xzIGFyZSBzdXBwb3J0ZWQuYCk7XG4gIH1cbiAgaWYgKGlzTWV0ZXJlZCkge1xuICAgIGxvZy5pbmZvKGBVcGxvYWRlZCAnJHtsb2NhbFBhdGh9JyBvZiAke3RvUmVhZGFibGVTaXplU3RyaW5nKHNpemUpfSBzaXplIGluICR7dGltZXIuZ2V0RHVyYXRpb24oKS5hc1NlY29uZHMudG9GaXhlZCgzKX1zYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEb3dubG9hZE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaXNNZXRlcmVkIFt0cnVlXSAtIFdoZXRoZXIgdG8gbG9nIHRoZSBhY3R1YWwgZG93bmxvYWQgcGVyZm9ybWFuY2VcbiAqIChlLmcuIHRpbWluZ3MgYW5kIHNwZWVkKVxuICogQHByb3BlcnR5IHtBdXRoQ3JlZGVudGlhbHN9IGF1dGhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0aW1lb3V0IFs1MDAwXSAtIFRoZSBhY3R1YWwgcmVxdWVzdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kc1xuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgLSBSZXF1ZXN0IGhlYWRlcnMgbWFwcGluZ1xuICovXG5cbi8qKlxuICogRG93bmxvYWRzIHRoZSBnaXZlbiBmaWxlIHZpYSBIVFRQKFMpXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHJlbW90ZVVybCAtIFRoZSByZW1vdGUgdXJsXG4gKiBAcGFyYW0ge3N0cmluZ30gZHN0UGF0aCAtIFRoZSBsb2NhbCBwYXRoIHRvIGRvd25sb2FkIHRoZSBmaWxlIHRvXG4gKiBAcGFyYW0gez9Eb3dubG9hZE9wdGlvbnN9IGRvd25sb2FkT3B0aW9uc1xuICogQHRocm93cyB7RXJyb3J9IElmIGRvd25sb2FkIG9wZXJhdGlvbiBmYWlsc1xuICovXG5hc3luYyBmdW5jdGlvbiBkb3dubG9hZEZpbGUgKHJlbW90ZVVybCwgZHN0UGF0aCwgZG93bmxvYWRPcHRpb25zID0ge30pIHtcbiAgY29uc3Qge1xuICAgIGlzTWV0ZXJlZCA9IHRydWUsXG4gICAgYXV0aCxcbiAgICB0aW1lb3V0ID0gNTAwMCxcbiAgICBoZWFkZXJzLFxuICB9ID0gZG93bmxvYWRPcHRpb25zO1xuXG4gIGNvbnN0IHJlcXVlc3RPcHRzID0ge1xuICAgIHVybDogcmVtb3RlVXJsLFxuICAgIHJlc3BvbnNlVHlwZTogJ3N0cmVhbScsXG4gICAgdGltZW91dCxcbiAgfTtcbiAgY29uc3QgYXhpb3NBdXRoID0gdG9BeGlvc0F1dGgoYXV0aCk7XG4gIGlmIChheGlvc0F1dGgpIHtcbiAgICByZXF1ZXN0T3B0cy5hdXRoID0gYXhpb3NBdXRoO1xuICB9XG4gIGlmIChfLmlzUGxhaW5PYmplY3QoaGVhZGVycykpIHtcbiAgICByZXF1ZXN0T3B0cy5oZWFkZXJzID0gaGVhZGVycztcbiAgfVxuXG4gIGNvbnN0IHRpbWVyID0gbmV3IFRpbWVyKCkuc3RhcnQoKTtcbiAgbGV0IHJlc3BvbnNlTGVuZ3RoO1xuICB0cnkge1xuICAgIGNvbnN0IHdyaXRlciA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKGRzdFBhdGgpO1xuICAgIGNvbnN0IHtcbiAgICAgIGRhdGE6IHJlc3BvbnNlU3RyZWFtLFxuICAgICAgaGVhZGVyczogcmVzcG9uc2VIZWFkZXJzLFxuICAgIH0gPSBhd2FpdCBheGlvcyhyZXF1ZXN0T3B0cyk7XG4gICAgcmVzcG9uc2VMZW5ndGggPSBwYXJzZUludChyZXNwb25zZUhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ10sIDEwKTtcbiAgICByZXNwb25zZVN0cmVhbS5waXBlKHdyaXRlcik7XG5cbiAgICBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICByZXNwb25zZVN0cmVhbS5vbmNlKCdlcnJvcicsIHJlamVjdCk7XG4gICAgICB3cml0ZXIub25jZSgnZmluaXNoJywgcmVzb2x2ZSk7XG4gICAgICB3cml0ZXIub25jZSgnZXJyb3InLCAoZSkgPT4ge1xuICAgICAgICByZXNwb25zZVN0cmVhbS51bnBpcGUod3JpdGVyKTtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGRvd25sb2FkIHRoZSBmaWxlIGZyb20gJHtyZW1vdGVVcmx9OiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG5cbiAgY29uc3Qge3NpemV9ID0gYXdhaXQgZnMuc3RhdChkc3RQYXRoKTtcbiAgaWYgKHJlc3BvbnNlTGVuZ3RoICYmIHNpemUgIT09IHJlc3BvbnNlTGVuZ3RoKSB7XG4gICAgYXdhaXQgZnMucmltcmFmKGRzdFBhdGgpO1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHNpemUgb2YgdGhlIGZpbGUgZG93bmxvYWRlZCBmcm9tICR7cmVtb3RlVXJsfSAoJHtzaXplfSBieXRlcykgYCArXG4gICAgICBgZGlmZmVycyBmcm9tIHRoZSBvbmUgaW4gQ29udGVudC1MZW5ndGggcmVzcG9uc2UgaGVhZGVyICgke3Jlc3BvbnNlTGVuZ3RofSBieXRlcylgKTtcbiAgfVxuICBpZiAoaXNNZXRlcmVkKSB7XG4gICAgY29uc3Qgc2Vjb25kc0VsYXBzZWQgPSB0aW1lci5nZXREdXJhdGlvbigpLmFzU2Vjb25kcztcbiAgICBsb2cuZGVidWcoYCR7cmVtb3RlVXJsfSAoJHt0b1JlYWRhYmxlU2l6ZVN0cmluZyhzaXplKX0pIGAgK1xuICAgICAgYGhhcyBiZWVuIGRvd25sb2FkZWQgdG8gJyR7ZHN0UGF0aH0nIGluICR7c2Vjb25kc0VsYXBzZWQudG9GaXhlZCgzKX1zYCk7XG4gICAgaWYgKHNlY29uZHNFbGFwc2VkID49IDIpIHtcbiAgICAgIGNvbnN0IGJ5dGVzUGVyU2VjID0gTWF0aC5mbG9vcihzaXplIC8gc2Vjb25kc0VsYXBzZWQpO1xuICAgICAgbG9nLmRlYnVnKGBBcHByb3hpbWF0ZSBkb3dubG9hZCBzcGVlZDogJHt0b1JlYWRhYmxlU2l6ZVN0cmluZyhieXRlc1BlclNlYyl9L3NgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHsgdXBsb2FkRmlsZSwgZG93bmxvYWRGaWxlIH07XG4iXSwiZmlsZSI6ImxpYi9uZXQuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==