"use strict"; var plugins = require("./npmci.plugins"); var paths = require("./npmci.paths"); var NpmciEnv = require("./npmci.env"); var npmci_bash_1 = require("./npmci.bash"); exports.build = function () { var done = plugins.q.defer(); exports.readDockerfiles() .then(exports.sortDockerfiles) .then(exports.mapDockerfiles) .then(exports.buildDockerfiles) .then(exports.pushDockerfiles) .then(function () { done.resolve(); }); return done.promise; }; exports.readDockerfiles = function () { var done = plugins.q.defer(); var readDockerfilesArray = []; plugins.gulp.src("./Dockerfile*") .pipe(plugins.through2.obj(function (file, enc, cb) { var myDockerfile = new Dockerfile({ filePath: file.path, read: true }); readDockerfilesArray.push(myDockerfile); cb(null, file); }, function () { done.resolve(readDockerfilesArray); })); return done.promise; }; exports.sortDockerfiles = function (sortableArrayArg) { var done = plugins.q.defer(); var sortedArray = []; var trackingArray = []; var sorterFunctionCounter = 0; var sorterFunction = function () { sortableArrayArg.forEach(function (dockerfileArg) { var cleanTags = exports.cleanTagsArrayFunction(sortableArrayArg, trackingArray); if (cleanTags.indexOf(dockerfileArg.baseImage) == -1 && trackingArray.indexOf(dockerfileArg) == -1) { sortedArray.push(dockerfileArg); trackingArray.push(dockerfileArg); } else if (cleanTags.indexOf(dockerfileArg.baseImage) != -1) { dockerfileArg.localBaseImageDependent = true; } ; }); if (sortableArrayArg.length == sortedArray.length) { done.resolve(sortedArray); } else if (sorterFunctionCounter < 10) { sorterFunctionCounter++; sorterFunction(); } ; }; sorterFunction(); return done.promise; }; exports.mapDockerfiles = function (sortedArray) { var done = plugins.q.defer(); sortedArray.forEach(function (dockerfileArg) { if (dockerfileArg.localBaseImageDependent) { sortedArray.forEach(function (dockfile2) { if (dockfile2.cleanTag == dockerfileArg.baseImage) { dockerfileArg.localBaseDockerfile = dockfile2; } }); } ; }); done.resolve(sortedArray); return done.promise; }; exports.buildDockerfiles = function (sortedArrayArg) { var done = plugins.q.defer(); sortedArrayArg.forEach(function (dockerfileArg) { dockerfileArg.build(); }); done.resolve(sortedArrayArg); return done.promise; }; exports.pushDockerfiles = function (sortedArrayArg) { var done = plugins.q.defer(); sortedArrayArg.forEach(function (dockerfileArg) { dockerfileArg.push(); }); done.resolve(sortedArrayArg); return done.promise; }; exports.pullDockerfileImages = function (sortableArrayArg) { var done = plugins.q.defer(); sortableArrayArg.forEach(function (dockerfileArg) { dockerfileArg.pull(); }); done.resolve(sortableArrayArg); return done.promise; }; exports.testDockerfiles = function (sortedArrayArg) { var done = plugins.q.defer(); sortedArrayArg.forEach(function (dockerfileArg) { dockerfileArg.test(); }); done.resolve(sortedArrayArg); return done.promise; }; exports.releaseDockerfiles = function (sortedArrayArg) { var done = plugins.q.defer(); sortedArrayArg.forEach(function (dockerfileArg) { dockerfileArg.release(); }); done.resolve(sortedArrayArg); return done.promise; }; var Dockerfile = (function () { function Dockerfile(options) { this.filePath = options.filePath; this.repo = NpmciEnv.repo.user + "/" + NpmciEnv.repo.repo; this.version = exports.dockerFileVersion(plugins.path.parse(options.filePath).base); this.cleanTag = this.repo + ":" + this.version; this.buildTag = exports.dockerTag(this.repo, this.version, "build"); this.releaseTag = exports.dockerTag(this.repo, this.version, "release"); this.containerName = "dockerfile-" + this.version; if (options.filePath && options.read) { this.content = plugins.smartfile.local.toStringSync(plugins.path.resolve(options.filePath)); } ; this.baseImage = exports.dockerBaseImage(this.content); this.localBaseImageDependent = false; } ; Dockerfile.prototype.build = function () { var done = plugins.q.defer(); this.patchContents(); npmci_bash_1.bashBare("docker build -t " + this.buildTag + " -f " + this.filePath + " ."); NpmciEnv.dockerFilesBuilt.push(this); this.restoreContents(); done.resolve(); return done.promise; }; ; Dockerfile.prototype.push = function () { var done = plugins.q.defer(); if (this.buildTag) { npmci_bash_1.bashBare("docker push " + this.buildTag); } else { plugins.beautylog.error("Dockerfile hasn't been built yet!"); } done.resolve(); return done.promise; }; Dockerfile.prototype.pull = function () { npmci_bash_1.bashBare("docker pull " + this.buildTag); }; ; Dockerfile.prototype.test = function () { var testExists = plugins.smartfile.checks.fileExistsSync(plugins.path.join(paths.NpmciProjectDir, ("./test/test_" + this.version + ".sh"))); if (testExists) { npmci_bash_1.bashBare("docker run -v " + plugins.path.join(paths.NpmciProjectDir, "./test") + ":/test/ " + "--name " + this.containerName + " /test/" + "test_" + this.version + ".sh"); } else { plugins.beautylog.warn("skipping tests for " + this.cleanTag + " because no testfile was found!"); } }; ; Dockerfile.prototype.release = function () { npmci_bash_1.bashBare("docker tag " + this.getId() + " " + this.releaseTag); npmci_bash_1.bashBare("docker push " + this.releaseTag); }; Dockerfile.prototype.getId = function () { var containerId = npmci_bash_1.bashBare("docker inspect --format=\"{{.Id}}\" " + this.buildTag); return containerId; }; ; Dockerfile.prototype.patchContents = function () { var done = plugins.q.defer(); if (this.localBaseImageDependent == true) { this.patchedContent = this.content.replace(/FROM\s[a-zA-Z0-9\/\-\:]*/, 'FROM ' + this.localBaseDockerfile.buildTag); plugins.smartfile.memory.toFsSync(this.patchedContent, { fileName: plugins.path.parse(this.filePath).name, filePath: plugins.path.parse(this.filePath).dir }); } done.resolve(); return done.promise; }; ; Dockerfile.prototype.restoreContents = function () { var done = plugins.q.defer(); if (this.localBaseImageDependent == true) { plugins.smartfile.memory.toFsSync(this.content, { fileName: plugins.path.parse(this.filePath).name, filePath: plugins.path.parse(this.filePath).dir }); } done.resolve(); return done.promise; }; ; return Dockerfile; }()); exports.Dockerfile = Dockerfile; exports.dockerFileVersion = function (dockerfileNameArg) { var versionString; var versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; var regexResultArray = versionRegex.exec(dockerfileNameArg); if (regexResultArray && regexResultArray.length == 2) { versionString = regexResultArray[1]; } else { versionString = "latest"; } return versionString; }; exports.dockerBaseImage = function (dockerfileContentArg) { var baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/; var regexResultArray = baseImageRegex.exec(dockerfileContentArg); return regexResultArray[1]; }; exports.dockerTag = function (repoArg, versionArg, stageArg) { var tagString; var registry = NpmciEnv.dockerRegistry; if (stageArg == "build" || stageArg == "test") { registry = "registry.gitlab.com"; } var repo = repoArg; var version = versionArg; if (NpmciEnv.buildStage == "build" || NpmciEnv.buildStage == "test") { version = version + "_test"; } tagString = registry + "/" + repo + ":" + version; return tagString; }; exports.cleanTagsArrayFunction = function (dockerfileArrayArg, trackingArrayArg) { var cleanTagsArray = []; dockerfileArrayArg.forEach(function (dockerfileArg) { if (trackingArrayArg.indexOf(dockerfileArg) == -1) { cleanTagsArray.push(dockerfileArg.cleanTag); } }); return cleanTagsArray; }; //# sourceMappingURL=data:application/json;charset=utf8;base64,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dCI6WyJpbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gXCIuL25wbWNpLnBsdWdpbnNcIjtcbmltcG9ydCAqIGFzIHBhdGhzIGZyb20gXCIuL25wbWNpLnBhdGhzXCI7XG5pbXBvcnQgKiBhcyBOcG1jaUVudiBmcm9tIFwiLi9ucG1jaS5lbnZcIjtcbmltcG9ydCB7YmFzaEJhcmV9IGZyb20gXCIuL25wbWNpLmJhc2hcIjtcblxuZXhwb3J0IGxldCBidWlsZCA9IGZ1bmN0aW9uKCl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICByZWFkRG9ja2VyZmlsZXMoKVxuICAgICAgICAudGhlbihzb3J0RG9ja2VyZmlsZXMpXG4gICAgICAgIC50aGVuKG1hcERvY2tlcmZpbGVzKVxuICAgICAgICAudGhlbihidWlsZERvY2tlcmZpbGVzKVxuICAgICAgICAudGhlbihwdXNoRG9ja2VyZmlsZXMpXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHJlYWREb2NrZXJmaWxlcyA9IGZ1bmN0aW9uKCl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBsZXQgcmVhZERvY2tlcmZpbGVzQXJyYXk6RG9ja2VyZmlsZVtdID0gW11cbiAgICBwbHVnaW5zLmd1bHAuc3JjKFwiLi9Eb2NrZXJmaWxlKlwiKVxuICAgICAgICAucGlwZShwbHVnaW5zLnRocm91Z2gyLm9iaihmdW5jdGlvbihmaWxlLGVuYyxjYil7XG4gICAgICAgICAgICBsZXQgbXlEb2NrZXJmaWxlID0gbmV3IERvY2tlcmZpbGUoe1xuICAgICAgICAgICAgICAgIGZpbGVQYXRoOmZpbGUucGF0aCxcbiAgICAgICAgICAgICAgICByZWFkOnRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVhZERvY2tlcmZpbGVzQXJyYXkucHVzaChteURvY2tlcmZpbGUpO1xuICAgICAgICAgICAgY2IobnVsbCxmaWxlKTtcbiAgICAgICAgIH0sZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICBkb25lLnJlc29sdmUocmVhZERvY2tlcmZpbGVzQXJyYXkpO1xuICAgICAgICAgfSkpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59XG5cbmV4cG9ydCBsZXQgc29ydERvY2tlcmZpbGVzID0gZnVuY3Rpb24oc29ydGFibGVBcnJheUFyZzpEb2NrZXJmaWxlW10pe1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgbGV0IHNvcnRlZEFycmF5OkRvY2tlcmZpbGVbXSA9IFtdOyBcbiAgICBsZXQgdHJhY2tpbmdBcnJheTpEb2NrZXJmaWxlW10gPSBbXTtcbiAgICBsZXQgc29ydGVyRnVuY3Rpb25Db3VudGVyOm51bWJlciA9IDA7XG4gICAgbGV0IHNvcnRlckZ1bmN0aW9uID0gZnVuY3Rpb24oKXtcbiAgICAgICAgc29ydGFibGVBcnJheUFyZy5mb3JFYWNoKChkb2NrZXJmaWxlQXJnKT0+e1xuICAgICAgICAgICAgbGV0IGNsZWFuVGFncyA9IGNsZWFuVGFnc0FycmF5RnVuY3Rpb24oc29ydGFibGVBcnJheUFyZyx0cmFja2luZ0FycmF5KTtcbiAgICAgICAgICAgIGlmKGNsZWFuVGFncy5pbmRleE9mKGRvY2tlcmZpbGVBcmcuYmFzZUltYWdlKSA9PSAtMSAmJiB0cmFja2luZ0FycmF5LmluZGV4T2YoZG9ja2VyZmlsZUFyZykgPT0gLTEpe1xuICAgICAgICAgICAgICAgIHNvcnRlZEFycmF5LnB1c2goZG9ja2VyZmlsZUFyZyk7XG4gICAgICAgICAgICAgICAgdHJhY2tpbmdBcnJheS5wdXNoKGRvY2tlcmZpbGVBcmcpO1xuICAgICAgICAgICAgfSBlbHNlIGlmKGNsZWFuVGFncy5pbmRleE9mKGRvY2tlcmZpbGVBcmcuYmFzZUltYWdlKSAhPSAtMSl7XG4gICAgICAgICAgICAgICAgZG9ja2VyZmlsZUFyZy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9IHRydWU7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgaWYoc29ydGFibGVBcnJheUFyZy5sZW5ndGggPT0gc29ydGVkQXJyYXkubGVuZ3RoKXtcbiAgICAgICAgICAgIGRvbmUucmVzb2x2ZShzb3J0ZWRBcnJheSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ydGVyRnVuY3Rpb25Db3VudGVyIDwgMTApIHtcbiAgICAgICAgICAgIHNvcnRlckZ1bmN0aW9uQ291bnRlcisrO1xuICAgICAgICAgICAgc29ydGVyRnVuY3Rpb24oKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgc29ydGVyRnVuY3Rpb24oKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufTtcblxuZXhwb3J0IGxldCBtYXBEb2NrZXJmaWxlcyA9IGZ1bmN0aW9uKHNvcnRlZEFycmF5OkRvY2tlcmZpbGVbXSl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBzb3J0ZWRBcnJheS5mb3JFYWNoKChkb2NrZXJmaWxlQXJnKSA9PiB7XG4gICAgICAgIGlmKGRvY2tlcmZpbGVBcmcubG9jYWxCYXNlSW1hZ2VEZXBlbmRlbnQpe1xuICAgICAgICAgICAgc29ydGVkQXJyYXkuZm9yRWFjaCgoZG9ja2ZpbGUyOkRvY2tlcmZpbGUpID0+IHtcbiAgICAgICAgICAgICAgICBpZihkb2NrZmlsZTIuY2xlYW5UYWcgPT0gZG9ja2VyZmlsZUFyZy5iYXNlSW1hZ2Upe1xuICAgICAgICAgICAgICAgICAgICBkb2NrZXJmaWxlQXJnLmxvY2FsQmFzZURvY2tlcmZpbGUgPSBkb2NrZmlsZTI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICB9KTtcbiAgICBkb25lLnJlc29sdmUoc29ydGVkQXJyYXkpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59XG5cbmV4cG9ydCBsZXQgYnVpbGREb2NrZXJmaWxlcyA9IChzb3J0ZWRBcnJheUFyZzpEb2NrZXJmaWxlW10pID0+IHtcbiAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgIHNvcnRlZEFycmF5QXJnLmZvckVhY2goZnVuY3Rpb24oZG9ja2VyZmlsZUFyZyl7XG4gICAgICAgIGRvY2tlcmZpbGVBcmcuYnVpbGQoKTtcbiAgICB9KVxuICAgIGRvbmUucmVzb2x2ZShzb3J0ZWRBcnJheUFyZyk7XG4gICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbn1cblxuZXhwb3J0IGxldCBwdXNoRG9ja2VyZmlsZXMgPSBmdW5jdGlvbihzb3J0ZWRBcnJheUFyZzpEb2NrZXJmaWxlW10pe1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5wdXNoKCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHB1bGxEb2NrZXJmaWxlSW1hZ2VzID0gKHNvcnRhYmxlQXJyYXlBcmc6RG9ja2VyZmlsZVtdKSA9PiB7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBzb3J0YWJsZUFycmF5QXJnLmZvckVhY2goKGRvY2tlcmZpbGVBcmcpID0+IHtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5wdWxsKCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRhYmxlQXJyYXlBcmcpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59XG5cbmV4cG9ydCBsZXQgdGVzdERvY2tlcmZpbGVzID0gKHNvcnRlZEFycmF5QXJnOkRvY2tlcmZpbGVbXSkgPT4ge1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy50ZXN0KCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufTtcblxuZXhwb3J0IGxldCByZWxlYXNlRG9ja2VyZmlsZXMgPSAoc29ydGVkQXJyYXlBcmc6RG9ja2VyZmlsZVtdKSA9PiB7XG4gICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5yZWxlYXNlKCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgY2xhc3MgRG9ja2VyZmlsZSB7XG4gICAgZmlsZVBhdGg6c3RyaW5nO1xuICAgIHJlcG86c3RyaW5nO1xuICAgIHZlcnNpb246c3RyaW5nO1xuICAgIGNsZWFuVGFnOnN0cmluZztcbiAgICBidWlsZFRhZzpzdHJpbmc7XG4gICAgcmVsZWFzZVRhZzpzdHJpbmc7XG4gICAgY29udGFpbmVyTmFtZTpzdHJpbmdcbiAgICBjb250ZW50OnN0cmluZztcbiAgICBwYXRjaGVkQ29udGVudDpzdHJpbmc7XG4gICAgYmFzZUltYWdlOnN0cmluZztcbiAgICBsb2NhbEJhc2VJbWFnZURlcGVuZGVudDpib29sZWFuO1xuICAgIGxvY2FsQmFzZURvY2tlcmZpbGU6RG9ja2VyZmlsZTtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOntmaWxlUGF0aD86c3RyaW5nLGZpbGVDb250ZW50cz86c3RyaW5nfEJ1ZmZlcixyZWFkPzpib29sZWFufSl7XG4gICAgICAgIHRoaXMuZmlsZVBhdGggPSBvcHRpb25zLmZpbGVQYXRoO1xuICAgICAgICB0aGlzLnJlcG8gPSBOcG1jaUVudi5yZXBvLnVzZXIgKyBcIi9cIiArIE5wbWNpRW52LnJlcG8ucmVwbztcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gZG9ja2VyRmlsZVZlcnNpb24ocGx1Z2lucy5wYXRoLnBhcnNlKG9wdGlvbnMuZmlsZVBhdGgpLmJhc2UpO1xuICAgICAgICB0aGlzLmNsZWFuVGFnID0gdGhpcy5yZXBvICsgXCI6XCIgKyB0aGlzLnZlcnNpb247XG4gICAgICAgIHRoaXMuYnVpbGRUYWcgPSBkb2NrZXJUYWcodGhpcy5yZXBvLHRoaXMudmVyc2lvbixcImJ1aWxkXCIpO1xuICAgICAgICB0aGlzLnJlbGVhc2VUYWcgPSBkb2NrZXJUYWcodGhpcy5yZXBvLHRoaXMudmVyc2lvbixcInJlbGVhc2VcIik7XG4gICAgICAgIHRoaXMuY29udGFpbmVyTmFtZSA9IFwiZG9ja2VyZmlsZS1cIiArIHRoaXMudmVyc2lvbjtcbiAgICAgICAgaWYob3B0aW9ucy5maWxlUGF0aCAmJiBvcHRpb25zLnJlYWQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZW50ID0gcGx1Z2lucy5zbWFydGZpbGUubG9jYWwudG9TdHJpbmdTeW5jKHBsdWdpbnMucGF0aC5yZXNvbHZlKG9wdGlvbnMuZmlsZVBhdGgpKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5iYXNlSW1hZ2UgPSBkb2NrZXJCYXNlSW1hZ2UodGhpcy5jb250ZW50KTtcbiAgICAgICAgdGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9IGZhbHNlO1xuICAgIH07XG4gICAgYnVpbGQoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgdGhpcy5wYXRjaENvbnRlbnRzKCk7XG4gICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIGJ1aWxkIC10IFwiICsgdGhpcy5idWlsZFRhZyArIFwiIC1mIFwiICsgdGhpcy5maWxlUGF0aCArIFwiIC5cIik7XG4gICAgICAgIE5wbWNpRW52LmRvY2tlckZpbGVzQnVpbHQucHVzaCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZXN0b3JlQ29udGVudHMoKTtcbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfTtcbiAgICBwdXNoKCl7XG4gICAgICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgICAgIGlmKHRoaXMuYnVpbGRUYWcpe1xuICAgICAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgcHVzaCBcIiArIHRoaXMuYnVpbGRUYWcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGx1Z2lucy5iZWF1dHlsb2cuZXJyb3IoXCJEb2NrZXJmaWxlIGhhc24ndCBiZWVuIGJ1aWx0IHlldCFcIik7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfVxuICAgIHB1bGwoKXtcbiAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgcHVsbCBcIiArIHRoaXMuYnVpbGRUYWcpO1xuICAgIH07XG4gICAgdGVzdCgpe1xuICAgICAgICBsZXQgdGVzdEV4aXN0cyA9IHBsdWdpbnMuc21hcnRmaWxlLmNoZWNrcy5maWxlRXhpc3RzU3luYyhcbiAgICAgICAgICAgIHBsdWdpbnMucGF0aC5qb2luKHBhdGhzLk5wbWNpUHJvamVjdERpciwoXCIuL3Rlc3QvdGVzdF9cIiArIHRoaXMudmVyc2lvbiArIFwiLnNoXCIpKVxuICAgICAgICApO1xuICAgICAgICBpZih0ZXN0RXhpc3RzKXtcbiAgICAgICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHJ1biAtdiBcIiArIFxuICAgICAgICAgICAgICAgIHBsdWdpbnMucGF0aC5qb2luKHBhdGhzLk5wbWNpUHJvamVjdERpcixcIi4vdGVzdFwiKSArIFwiOi90ZXN0LyBcIiArXG4gICAgICAgICAgICAgICAgXCItLW5hbWUgXCIgKyB0aGlzLmNvbnRhaW5lck5hbWUgKyBcIiAvdGVzdC9cIiArIFwidGVzdF9cIiArIHRoaXMudmVyc2lvbiAgKyBcIi5zaFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBsdWdpbnMuYmVhdXR5bG9nLndhcm4oXCJza2lwcGluZyB0ZXN0cyBmb3IgXCIgKyB0aGlzLmNsZWFuVGFnICsgXCIgYmVjYXVzZSBubyB0ZXN0ZmlsZSB3YXMgZm91bmQhXCIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZWxlYXNlKCl7XG4gICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHRhZyBcIiArIHRoaXMuZ2V0SWQoKSArIFwiIFwiICsgdGhpcy5yZWxlYXNlVGFnKTtcbiAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgcHVzaCBcIiArIHRoaXMucmVsZWFzZVRhZyk7XG4gICAgfVxuICAgIGdldElkKCl7XG4gICAgICAgIGxldCBjb250YWluZXJJZCA9IGJhc2hCYXJlKFwiZG9ja2VyIGluc3BlY3QgLS1mb3JtYXQ9XFxcInt7LklkfX1cXFwiIFwiICsgdGhpcy5idWlsZFRhZyk7XG4gICAgICAgIHJldHVybiBjb250YWluZXJJZDtcbiAgICB9O1xuICAgIHBhdGNoQ29udGVudHMoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgaWYodGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9PSB0cnVlKXtcbiAgICAgICAgICAgIHRoaXMucGF0Y2hlZENvbnRlbnQgPSB0aGlzLmNvbnRlbnQucmVwbGFjZSgvRlJPTVxcc1thLXpBLVowLTlcXC9cXC1cXDpdKi8sICdGUk9NICcgKyB0aGlzLmxvY2FsQmFzZURvY2tlcmZpbGUuYnVpbGRUYWcpO1xuICAgICAgICAgICAgcGx1Z2lucy5zbWFydGZpbGUubWVtb3J5LnRvRnNTeW5jKFxuICAgICAgICAgICAgICAgIHRoaXMucGF0Y2hlZENvbnRlbnQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZTpwbHVnaW5zLnBhdGgucGFyc2UodGhpcy5maWxlUGF0aCkubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZVBhdGg6cGx1Z2lucy5wYXRoLnBhcnNlKHRoaXMuZmlsZVBhdGgpLmRpclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfTtcbiAgICByZXN0b3JlQ29udGVudHMoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgaWYodGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9PSB0cnVlKXtcbiAgICAgICAgICAgIHBsdWdpbnMuc21hcnRmaWxlLm1lbW9yeS50b0ZzU3luYyhcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZTpwbHVnaW5zLnBhdGgucGFyc2UodGhpcy5maWxlUGF0aCkubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZVBhdGg6cGx1Z2lucy5wYXRoLnBhcnNlKHRoaXMuZmlsZVBhdGgpLmRpclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfTtcbn1cblxuZXhwb3J0IGxldCBkb2NrZXJGaWxlVmVyc2lvbiA9IGZ1bmN0aW9uKGRvY2tlcmZpbGVOYW1lQXJnOnN0cmluZyk6c3RyaW5ne1xuICAgIGxldCB2ZXJzaW9uU3RyaW5nOnN0cmluZztcbiAgICBsZXQgdmVyc2lvblJlZ2V4ID0gL0RvY2tlcmZpbGVfKFthLXpBLVowLTlcXC5dKikkLztcbiAgICBsZXQgcmVnZXhSZXN1bHRBcnJheSA9IHZlcnNpb25SZWdleC5leGVjKGRvY2tlcmZpbGVOYW1lQXJnKTtcbiAgICBpZihyZWdleFJlc3VsdEFycmF5ICYmIHJlZ2V4UmVzdWx0QXJyYXkubGVuZ3RoID09IDIpe1xuICAgICAgICB2ZXJzaW9uU3RyaW5nID0gcmVnZXhSZXN1bHRBcnJheVsxXTsgICAgICAgIFxuICAgIH0gZWxzZSB7XG4gICAgICAgIHZlcnNpb25TdHJpbmcgPSBcImxhdGVzdFwiO1xuICAgIH1cbiAgICByZXR1cm4gdmVyc2lvblN0cmluZztcbn1cblxuZXhwb3J0IGxldCBkb2NrZXJCYXNlSW1hZ2UgPSBmdW5jdGlvbihkb2NrZXJmaWxlQ29udGVudEFyZzpzdHJpbmcpe1xuICAgIGxldCBiYXNlSW1hZ2VSZWdleCA9IC9GUk9NXFxzKFthLXpBLXowLTlcXC9cXC1cXDpdKilcXG4/L1xuICAgIGxldCByZWdleFJlc3VsdEFycmF5ID0gYmFzZUltYWdlUmVnZXguZXhlYyhkb2NrZXJmaWxlQ29udGVudEFyZylcbiAgICByZXR1cm4gcmVnZXhSZXN1bHRBcnJheVsxXTtcbn1cblxuZXhwb3J0IGxldCBkb2NrZXJUYWcgPSBmdW5jdGlvbihyZXBvQXJnOnN0cmluZyx2ZXJzaW9uQXJnOnN0cmluZyxzdGFnZUFyZzpzdHJpbmcpOnN0cmluZ3tcbiAgICBsZXQgdGFnU3RyaW5nOnN0cmluZztcbiAgICBsZXQgcmVnaXN0cnkgPSBOcG1jaUVudi5kb2NrZXJSZWdpc3RyeTtcbiAgICBpZihzdGFnZUFyZyA9PSBcImJ1aWxkXCIgIHx8IHN0YWdlQXJnID09IFwidGVzdFwiKXtcbiAgICAgICAgcmVnaXN0cnkgPSBcInJlZ2lzdHJ5LmdpdGxhYi5jb21cIjtcbiAgICB9IFxuICAgIGxldCByZXBvID0gcmVwb0FyZztcbiAgICBsZXQgdmVyc2lvbiA9IHZlcnNpb25Bcmc7XG4gICAgaWYoTnBtY2lFbnYuYnVpbGRTdGFnZSA9PSBcImJ1aWxkXCIgfHwgTnBtY2lFbnYuYnVpbGRTdGFnZSA9PSBcInRlc3RcIil7XG4gICAgICAgIHZlcnNpb24gPSB2ZXJzaW9uICsgXCJfdGVzdFwiO1xuICAgIH1cbiAgICB0YWdTdHJpbmcgPSByZWdpc3RyeSArIFwiL1wiICsgcmVwbyArIFwiOlwiICsgdmVyc2lvbjtcbiAgICByZXR1cm4gdGFnU3RyaW5nO1xufTtcblxuZXhwb3J0IGxldCBjbGVhblRhZ3NBcnJheUZ1bmN0aW9uID0gZnVuY3Rpb24oZG9ja2VyZmlsZUFycmF5QXJnOkRvY2tlcmZpbGVbXSx0cmFja2luZ0FycmF5QXJnOkRvY2tlcmZpbGVbXSk6c3RyaW5nW117XG4gICAgbGV0IGNsZWFuVGFnc0FycmF5OnN0cmluZ1tdID0gW107XG4gICAgZG9ja2VyZmlsZUFycmF5QXJnLmZvckVhY2goZnVuY3Rpb24oZG9ja2VyZmlsZUFyZyl7XG4gICAgICAgIGlmKHRyYWNraW5nQXJyYXlBcmcuaW5kZXhPZihkb2NrZXJmaWxlQXJnKSA9PSAtMSl7XG4gICAgICAgICAgICBjbGVhblRhZ3NBcnJheS5wdXNoKGRvY2tlcmZpbGVBcmcuY2xlYW5UYWcpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNsZWFuVGFnc0FycmF5O1xufSJdfQ==