antfarm
Version:
File automation framework for ants.
246 lines (244 loc) • 32.1 kB
JavaScript
;
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var fileJob_1 = require("./fileJob");
var folderJob_1 = require("./folderJob");
var jobProperty_1 = require("./jobProperty");
var tmp = require("tmp"), fs = require("fs"), path = require("path"), JSZip = require("jszip"), _ = require("lodash"), Reflect = require("reflect-metadata");
var PackedJob = (function (_super) {
__extends(PackedJob, _super);
function PackedJob(e, job) {
// let job_name = job.name;
_super.call(this, e, job.name);
var pj = this;
pj.e = e;
pj.job = job;
}
Object.defineProperty(PackedJob.prototype, "job", {
get: function () {
return this._job;
},
set: function (job) {
this._job = job;
},
enumerable: true,
configurable: true
});
/**
* Makes job ticket and returns the _path to the temporary file.
* @param job
* @returns {string}
*/
PackedJob.prototype.getJobTicket = function (job) {
var pj = this;
// Make job ticket
var json = job.getJSON();
var tmpobj = tmp.dirSync();
var dir = tmpobj.name;
var file_name = dir + path.sep + "ticket.json";
try {
fs.writeFileSync(file_name, json, "utf8");
}
catch (err) {
pj.e.log(3, "Error writing job ticket to temporary file", pj);
}
return file_name;
};
PackedJob.prototype.buildZip = function (zip, callback) {
// Save out zip
var pj = this;
var job = this.job;
var tmpobj = tmp.dirSync();
var dir = tmpobj.name;
var file_name = job.name + ".antpack.zip";
var file_path = dir + path.sep + file_name;
zip
.generateNodeStream({ type: "nodebuffer", streamFiles: true })
.pipe(fs.createWriteStream(file_path))
.on("finish", function () {
// JSZip generates a readable stream with a "end" event,
// but is piped here in a writable stream which emits a "_finish" event.
pj.path = file_path;
pj.name = file_name;
callback();
});
};
/**
* Packs the related job on construction.
*/
PackedJob.prototype.execPack = function (done) {
var pj = this;
var job = pj.job;
var ticketPath = pj.getJobTicket(job);
var zip = new JSZip();
// Add ticket to zip
fs.readFile(ticketPath, function (err, data) {
if (err)
throw err;
zip.file("_ticket/ticket.json", data);
if (job.isFile()) {
fs.readFile(job.path, function (err, data) {
if (err)
throw err;
zip.file("_asset/" + job.name, data);
pj.buildZip(zip, function () {
done();
});
});
}
else if (job.isFolder()) {
job.files.forEach(function (file) {
fs.readFile(file.path, function (err, data) {
if (err)
throw err;
zip.file("_asset" + path.sep + job.nameProper + path.sep + file.name, data);
pj.buildZip(zip, function () {
done();
});
});
});
}
else {
pj.buildZip(zip, function () {
done();
});
}
});
};
PackedJob.prototype.restoreJobTicket = function (jsonTicket) {
var pj = this;
var jobObject, job;
try {
jobObject = JSON.parse(jsonTicket);
if (jobObject._type === "file") {
job = new fileJob_1.FileJob(pj.e, jobObject._id);
}
else if (jobObject._type === "folder") {
job = new folderJob_1.FolderJob(pj.e, jobObject._id);
}
else {
pj.e.log(3, "Cannot unpack this type of job: " + jobObject._type, pj);
}
}
catch (err) {
pj.e.log(3, "Unpack ticket parse error: " + err + ".", pj);
pj.e.log(3, "Unparsable ticket: " + jsonTicket + ".", pj);
}
// Restore property values
var props = {};
_.each(jobObject._properties, function (prop) {
props[prop._key] = new jobProperty_1.JobProperty(prop._key, prop._value);
});
job.propertyValues = props;
// Restore lifecycle
job.lifeCycle = jobObject._lifeCycle;
return job;
};
PackedJob.prototype.execUnpack = function (done) {
// console.log("unpacking");
var pj = this;
var job = pj.job;
// Read the zip to a buffer
fs.readFile(job.path, function (err, data) {
if (err) {
pj.e.log(3, "Unpacking readFile error: " + err, pj);
}
// Open the zip in JSZip
JSZip.loadAsync(data).then(function (zip) {
// Restore job ticket and create job
zip.folder("_ticket").forEach(function (relativePath, file) {
zip.file("_ticket" + path.sep + relativePath).async("string")
.then(function (content) {
// Restore old job ticket
job = pj.restoreJobTicket(content);
// Restore _files
pj.restoreFiles(job, zip, function (unpackedJob) {
done(unpackedJob);
});
});
});
});
});
};
PackedJob.prototype.restoreFiles = function (job, zip, callback) {
var pj = this;
// Check for valid pack format
if (zip.folder("_asset").length > 1) {
pj.e.log(2, "Restored job did not contain any file assets.", pj, [job]);
}
if (job.isFolder()) {
pj.extractFiles(zip, false, "_asset/", function (folderPath, folderName) {
job.path = folderPath;
job.rename(folderName);
callback(job);
});
}
else if (job.isFile()) {
pj.extractFiles(zip, true, "_asset/", function (filePath, fileName) {
job.path = filePath;
job.rename(fileName);
callback(job);
});
}
};
PackedJob.prototype.extractFiles = function (zip, single, zipPath, callback, totalFiles) {
var pj = this;
var tmpobj = tmp.dirSync();
var tempPath = tmpobj.name;
var fileNumber = 1;
if (!totalFiles) {
totalFiles = 0;
zip.folder(zipPath).forEach(function (asset) { return totalFiles++; });
}
if (single === true) {
zip.folder(zipPath).forEach(function (relativePath, asset) {
if (fileNumber > 1) {
pj.e.log(3, "More than 1 files found when extracting a file job.", pj);
}
else {
var newRelPath = zipPath + relativePath;
if (asset.dir === "true") {
totalFiles--;
pj.extractFiles(zip, single, newRelPath, callback, totalFiles);
}
else {
zip.file(newRelPath).async("nodebuffer")
.then(function (content) {
fileNumber++;
var filePath = tempPath + path.sep + relativePath;
fs.writeFileSync(filePath, content);
callback(filePath, relativePath);
});
}
}
});
}
else {
zip.folder(zipPath).forEach(function (relativePath, asset) {
var newRelPath = zipPath + relativePath;
if (asset.dir === true) {
totalFiles--;
pj.extractFiles(zip, single, newRelPath, callback, totalFiles);
}
else {
zip.file(newRelPath).async("nodebuffer")
.then(function (content) {
var filePath = tempPath + path.sep + relativePath;
fs.writeFileSync(filePath, content);
if (totalFiles === fileNumber) {
var rootFolderName = newRelPath.split(path.sep)[1];
callback(tempPath, rootFolderName);
}
fileNumber++;
});
}
});
}
};
return PackedJob;
}(fileJob_1.FileJob));
exports.PackedJob = PackedJob;
//# sourceMappingURL=data:application/json;charset=utf8;base64,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Q0FBQyxDQUFDO3dCQUN2QyxDQUFDO3dCQUNELFVBQVUsRUFBRSxDQUFDO29CQUVqQixDQUFDLENBQUMsQ0FBQztnQkFDUCxDQUFDO1lBRUwsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDO0lBRUwsQ0FBQztJQUVMLGdCQUFDO0FBQUQsQ0F4UUEsQUF3UUMsQ0F4UThCLGlCQUFPLEdBd1FyQztBQXhRWSxpQkFBUyxZQXdRckIsQ0FBQSIsImZpbGUiOiJsaWIvam9iL3BhY2tlZEpvYi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RW52aXJvbm1lbnR9IGZyb20gXCIuLi9lbnZpcm9ubWVudC9lbnZpcm9ubWVudFwiO1xuaW1wb3J0IHtGaWxlSm9ifSBmcm9tIFwiLi9maWxlSm9iXCI7XG5pbXBvcnQge0pvYn0gZnJvbSBcIi4vam9iXCI7XG5pbXBvcnQge0ZvbGRlckpvYn0gZnJvbSBcIi4vZm9sZGVySm9iXCI7XG5pbXBvcnQge0pvYlByb3BlcnR5fSBmcm9tIFwiLi9qb2JQcm9wZXJ0eVwiO1xuXG5jb25zdCAgIHRtcCA9IHJlcXVpcmUoXCJ0bXBcIiksXG4gICAgICAgIGZzID0gcmVxdWlyZShcImZzXCIpLFxuICAgICAgICBwYXRoID0gcmVxdWlyZShcInBhdGhcIiksXG4gICAgICAgIEpTWmlwID0gcmVxdWlyZShcImpzemlwXCIpLFxuICAgICAgICBfID0gcmVxdWlyZShcImxvZGFzaFwiKSxcbiAgICAgICAgUmVmbGVjdCA9IHJlcXVpcmUoXCJyZWZsZWN0LW1ldGFkYXRhXCIpO1xuXG5leHBvcnQgY2xhc3MgUGFja2VkSm9iIGV4dGVuZHMgRmlsZUpvYiB7XG5cbiAgICBwcm90ZWN0ZWQgZTogRW52aXJvbm1lbnQ7XG4gICAgcHJvdGVjdGVkIF9qb2I6IEpvYjtcblxuICAgIGNvbnN0cnVjdG9yKGU6IEVudmlyb25tZW50LCBqb2I6IEpvYikge1xuICAgICAgICAvLyBsZXQgam9iX25hbWUgPSBqb2IubmFtZTtcbiAgICAgICAgc3VwZXIoZSwgam9iLm5hbWUpO1xuICAgICAgICBsZXQgcGogPSB0aGlzO1xuICAgICAgICBwai5lID0gZTtcbiAgICAgICAgcGouam9iID0gam9iO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgam9iKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fam9iO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzZXQgam9iKGpvYjogSm9iKSB7XG4gICAgICAgIHRoaXMuX2pvYiA9IGpvYjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBqb2IgdGlja2V0IGFuZCByZXR1cm5zIHRoZSBfcGF0aCB0byB0aGUgdGVtcG9yYXJ5IGZpbGUuXG4gICAgICogQHBhcmFtIGpvYlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGdldEpvYlRpY2tldChqb2I6IEpvYikge1xuICAgICAgICBsZXQgcGogPSB0aGlzO1xuICAgICAgICAvLyBNYWtlIGpvYiB0aWNrZXRcbiAgICAgICAgbGV0IGpzb24gPSBqb2IuZ2V0SlNPTigpO1xuICAgICAgICBsZXQgdG1wb2JqID0gdG1wLmRpclN5bmMoKTtcbiAgICAgICAgbGV0IGRpciA9IHRtcG9iai5uYW1lO1xuICAgICAgICBsZXQgZmlsZV9uYW1lID0gZGlyICsgcGF0aC5zZXAgKyBcInRpY2tldC5qc29uXCI7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZV9uYW1lLCBqc29uLCBcInV0ZjhcIik7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcGouZS5sb2coMywgYEVycm9yIHdyaXRpbmcgam9iIHRpY2tldCB0byB0ZW1wb3JhcnkgZmlsZWAsIHBqKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsZV9uYW1lO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBidWlsZFppcCh6aXA6IGFueSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gU2F2ZSBvdXQgemlwXG4gICAgICAgIGxldCBwaiA9IHRoaXM7XG4gICAgICAgIGxldCBqb2IgPSB0aGlzLmpvYjtcbiAgICAgICAgbGV0IHRtcG9iaiA9IHRtcC5kaXJTeW5jKCk7XG4gICAgICAgIGxldCBkaXIgPSB0bXBvYmoubmFtZTtcbiAgICAgICAgbGV0IGZpbGVfbmFtZSA9IGpvYi5uYW1lICsgXCIuYW50cGFjay56aXBcIjtcbiAgICAgICAgbGV0IGZpbGVfcGF0aCA9IGRpciArIHBhdGguc2VwICsgZmlsZV9uYW1lO1xuICAgICAgICB6aXBcbiAgICAgICAgICAgIC5nZW5lcmF0ZU5vZGVTdHJlYW0oe3R5cGU6IFwibm9kZWJ1ZmZlclwiLCBzdHJlYW1GaWxlczogdHJ1ZX0pXG4gICAgICAgICAgICAucGlwZShmcy5jcmVhdGVXcml0ZVN0cmVhbShmaWxlX3BhdGgpKVxuICAgICAgICAgICAgLm9uKFwiZmluaXNoXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAvLyBKU1ppcCBnZW5lcmF0ZXMgYSByZWFkYWJsZSBzdHJlYW0gd2l0aCBhIFwiZW5kXCIgZXZlbnQsXG4gICAgICAgICAgICAgICAgLy8gYnV0IGlzIHBpcGVkIGhlcmUgaW4gYSB3cml0YWJsZSBzdHJlYW0gd2hpY2ggZW1pdHMgYSBcIl9maW5pc2hcIiBldmVudC5cbiAgICAgICAgICAgICAgICBwai5wYXRoID0gZmlsZV9wYXRoO1xuICAgICAgICAgICAgICAgIHBqLm5hbWUgPSBmaWxlX25hbWU7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhY2tzIHRoZSByZWxhdGVkIGpvYiBvbiBjb25zdHJ1Y3Rpb24uXG4gICAgICovXG4gICAgcHVibGljIGV4ZWNQYWNrKGRvbmUpIHtcbiAgICAgICAgbGV0IHBqID0gdGhpcztcbiAgICAgICAgbGV0IGpvYiA9IHBqLmpvYjtcblxuICAgICAgICBsZXQgdGlja2V0UGF0aCA9IHBqLmdldEpvYlRpY2tldChqb2IpO1xuXG4gICAgICAgIGxldCB6aXAgPSBuZXcgSlNaaXAoKTtcblxuICAgICAgICAvLyBBZGQgdGlja2V0IHRvIHppcFxuICAgICAgICBmcy5yZWFkRmlsZSh0aWNrZXRQYXRoLCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChlcnIpIHRocm93IGVycjtcbiAgICAgICAgICAgIHppcC5maWxlKFwiX3RpY2tldC90aWNrZXQuanNvblwiLCBkYXRhKTtcblxuICAgICAgICAgICAgaWYgKGpvYi5pc0ZpbGUoKSkge1xuXG4gICAgICAgICAgICAgICAgZnMucmVhZEZpbGUoam9iLnBhdGgsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycikgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICB6aXAuZmlsZShcIl9hc3NldC9cIiArIGpvYi5uYW1lLCBkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcGouYnVpbGRaaXAoemlwLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChqb2IuaXNGb2xkZXIoKSkge1xuICAgICAgICAgICAgICAgIGpvYi5maWxlcy5mb3JFYWNoKGZpbGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBmcy5yZWFkRmlsZShmaWxlLnBhdGgsIGZ1bmN0aW9uKGVyciwgZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycikgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgemlwLmZpbGUoXCJfYXNzZXRcIiArIHBhdGguc2VwICsgam9iLm5hbWVQcm9wZXIgKyBwYXRoLnNlcCArIGZpbGUubmFtZSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwai5idWlsZFppcCh6aXAsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBqLmJ1aWxkWmlwKHppcCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVzdG9yZUpvYlRpY2tldChqc29uVGlja2V0KSB7XG4gICAgICAgIGxldCBwaiA9IHRoaXM7XG4gICAgICAgIGxldCBqb2JPYmplY3QsIGpvYjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGpvYk9iamVjdCA9IEpTT04ucGFyc2UoanNvblRpY2tldCk7XG5cbiAgICAgICAgICAgIGlmIChqb2JPYmplY3QuX3R5cGUgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgam9iID0gbmV3IEZpbGVKb2IocGouZSwgam9iT2JqZWN0Ll9pZCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGpvYk9iamVjdC5fdHlwZSA9PT0gXCJmb2xkZXJcIikge1xuICAgICAgICAgICAgICAgIGpvYiA9IG5ldyBGb2xkZXJKb2IocGouZSwgam9iT2JqZWN0Ll9pZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBqLmUubG9nKDMsIGBDYW5ub3QgdW5wYWNrIHRoaXMgdHlwZSBvZiBqb2I6ICR7am9iT2JqZWN0Ll90eXBlfWAsIHBqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBwai5lLmxvZygzLCBgVW5wYWNrIHRpY2tldCBwYXJzZSBlcnJvcjogJHtlcnJ9LmAsIHBqKTtcbiAgICAgICAgICAgIHBqLmUubG9nKDMsIGBVbnBhcnNhYmxlIHRpY2tldDogJHtqc29uVGlja2V0fS5gLCBwaik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXN0b3JlIHByb3BlcnR5IHZhbHVlc1xuICAgICAgICBsZXQgcHJvcHMgPSB7fTtcblxuICAgICAgICBfLmVhY2goam9iT2JqZWN0Ll9wcm9wZXJ0aWVzLCBwcm9wID0+IHtcbiAgICAgICAgICAgIHByb3BzW3Byb3AuX2tleV0gPSBuZXcgSm9iUHJvcGVydHkocHJvcC5fa2V5LCBwcm9wLl92YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBqb2IucHJvcGVydHlWYWx1ZXMgPSBwcm9wcztcblxuICAgICAgICAvLyBSZXN0b3JlIGxpZmVjeWNsZVxuICAgICAgICBqb2IubGlmZUN5Y2xlID0gam9iT2JqZWN0Ll9saWZlQ3ljbGU7XG5cbiAgICAgICAgcmV0dXJuIGpvYjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZXhlY1VucGFjayhkb25lKSB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwidW5wYWNraW5nXCIpO1xuXG4gICAgICAgIGxldCBwaiA9IHRoaXM7XG4gICAgICAgIGxldCBqb2IgPSBwai5qb2I7XG5cbiAgICAgICAgLy8gUmVhZCB0aGUgemlwIHRvIGEgYnVmZmVyXG4gICAgICAgIGZzLnJlYWRGaWxlKGpvYi5wYXRoLCAoZXJyLCBkYXRhKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcGouZS5sb2coMywgYFVucGFja2luZyByZWFkRmlsZSBlcnJvcjogJHtlcnJ9YCwgcGopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gT3BlbiB0aGUgemlwIGluIEpTWmlwXG4gICAgICAgICAgICBKU1ppcC5sb2FkQXN5bmMoZGF0YSkudGhlbigoemlwKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBqb2IgdGlja2V0IGFuZCBjcmVhdGUgam9iXG4gICAgICAgICAgICAgICAgemlwLmZvbGRlcihcIl90aWNrZXRcIikuZm9yRWFjaCgocmVsYXRpdmVQYXRoLCBmaWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHppcC5maWxlKGBfdGlja2V0JHtwYXRoLnNlcH0ke3JlbGF0aXZlUGF0aH1gKS5hc3luYyhcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoY29udGVudCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIG9sZCBqb2IgdGlja2V0XG4gICAgICAgICAgICAgICAgICAgICAgICBqb2IgPSBwai5yZXN0b3JlSm9iVGlja2V0KGNvbnRlbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIF9maWxlc1xuICAgICAgICAgICAgICAgICAgICAgICAgcGoucmVzdG9yZUZpbGVzKGpvYiwgemlwLCAodW5wYWNrZWRKb2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lKHVucGFja2VkSm9iKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZXN0b3JlRmlsZXMoam9iOiBKb2IsIHppcDogYW55LCBjYWxsYmFjaykge1xuXG4gICAgICAgIGxldCBwaiA9IHRoaXM7XG5cblxuICAgICAgICAvLyBDaGVjayBmb3IgdmFsaWQgcGFjayBmb3JtYXRcbiAgICAgICAgaWYgKHppcC5mb2xkZXIoXCJfYXNzZXRcIikubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgcGouZS5sb2coMiwgYFJlc3RvcmVkIGpvYiBkaWQgbm90IGNvbnRhaW4gYW55IGZpbGUgYXNzZXRzLmAsIHBqLCBbam9iXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoam9iLmlzRm9sZGVyKCkpIHtcbiAgICAgICAgICAgIHBqLmV4dHJhY3RGaWxlcyh6aXAsIGZhbHNlLCBcIl9hc3NldC9cIiwgKGZvbGRlclBhdGgsIGZvbGRlck5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBqb2IucGF0aCA9IGZvbGRlclBhdGg7XG4gICAgICAgICAgICAgICAgam9iLnJlbmFtZShmb2xkZXJOYW1lKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhqb2IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoam9iLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICBwai5leHRyYWN0RmlsZXMoemlwLCB0cnVlLCBcIl9hc3NldC9cIiwgKGZpbGVQYXRoLCBmaWxlTmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIGpvYi5wYXRoID0gZmlsZVBhdGg7XG4gICAgICAgICAgICAgICAgam9iLnJlbmFtZShmaWxlTmFtZSk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soam9iKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGV4dHJhY3RGaWxlcyh6aXA6IGFueSwgc2luZ2xlOiBib29sZWFuLCB6aXBQYXRoOiBzdHJpbmcsIGNhbGxiYWNrOiBhbnksIHRvdGFsRmlsZXM/OiBudW1iZXIpIHtcbiAgICAgICAgbGV0IHBqID0gdGhpcztcblxuICAgICAgICBsZXQgdG1wb2JqID0gdG1wLmRpclN5bmMoKTtcbiAgICAgICAgbGV0IHRlbXBQYXRoID0gdG1wb2JqLm5hbWU7XG5cbiAgICAgICAgbGV0IGZpbGVOdW1iZXIgPSAxO1xuXG4gICAgICAgIGlmICghdG90YWxGaWxlcykge1xuICAgICAgICAgICAgdG90YWxGaWxlcyA9IDA7XG4gICAgICAgICAgICB6aXAuZm9sZGVyKHppcFBhdGgpLmZvckVhY2goKGFzc2V0KSA9PiB0b3RhbEZpbGVzKysgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzaW5nbGUgPT09IHRydWUpIHtcblxuICAgICAgICAgICAgemlwLmZvbGRlcih6aXBQYXRoKS5mb3JFYWNoKChyZWxhdGl2ZVBhdGgsIGFzc2V0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICBpZiAoZmlsZU51bWJlciA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcGouZS5sb2coMywgYE1vcmUgdGhhbiAxIGZpbGVzIGZvdW5kIHdoZW4gZXh0cmFjdGluZyBhIGZpbGUgam9iLmAsIHBqKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXdSZWxQYXRoID0gemlwUGF0aCArIHJlbGF0aXZlUGF0aDtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoYXNzZXQuZGlyID09PSBcInRydWVcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxGaWxlcy0tO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGouZXh0cmFjdEZpbGVzKHppcCwgc2luZ2xlLCBuZXdSZWxQYXRoLCBjYWxsYmFjaywgdG90YWxGaWxlcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB6aXAuZmlsZShuZXdSZWxQYXRoKS5hc3luYyhcIm5vZGVidWZmZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKChjb250ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU51bWJlcisrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaWxlUGF0aCA9IHRlbXBQYXRoICsgcGF0aC5zZXAgKyByZWxhdGl2ZVBhdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgY29udGVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZmlsZVBhdGgsIHJlbGF0aXZlUGF0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB6aXAuZm9sZGVyKHppcFBhdGgpLmZvckVhY2goKHJlbGF0aXZlUGF0aCwgYXNzZXQpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbmV3UmVsUGF0aCA9IHppcFBhdGggKyByZWxhdGl2ZVBhdGg7XG5cbiAgICAgICAgICAgICAgICBpZiAoYXNzZXQuZGlyID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvdGFsRmlsZXMtLTtcblxuICAgICAgICAgICAgICAgICAgICBwai5leHRyYWN0RmlsZXMoemlwLCBzaW5nbGUsIG5ld1JlbFBhdGgsIGNhbGxiYWNrLCB0b3RhbEZpbGVzKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIHppcC5maWxlKG5ld1JlbFBhdGgpLmFzeW5jKFwibm9kZWJ1ZmZlclwiKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoY29udGVudCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmlsZVBhdGggPSB0ZW1wUGF0aCArIHBhdGguc2VwICsgcmVsYXRpdmVQYXRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgY29udGVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b3RhbEZpbGVzID09PSBmaWxlTnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJvb3RGb2xkZXJOYW1lID0gbmV3UmVsUGF0aC5zcGxpdChwYXRoLnNlcClbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sodGVtcFBhdGgsIHJvb3RGb2xkZXJOYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVOdW1iZXIrKztcblxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICB9XG5cbn0iXX0=