From 94abf689f80b72af3769ba9fa652a5a01687df71 Mon Sep 17 00:00:00 2001 From: Greg Magolan Date: Thu, 26 Sep 2019 14:00:23 -0700 Subject: [PATCH] fix(builtin): support for scoped modules in linker (#1199) --- internal/linker/index.js | 30 ++++++++++++++----- internal/linker/link_node_modules.ts | 29 ++++++++++++++---- internal/linker/test/integration/BUILD.bazel | 2 ++ .../dynamic_linked_scoped_pkg/BUILD.bazel | 10 +++++++ .../dynamic_linked_scoped_pkg/index.js | 5 ++++ internal/linker/test/integration/golden.txt | 2 +- internal/linker/test/integration/program.js | 12 ++++---- .../static_linked_scoped_pkg/BUILD.bazel | 9 ++++++ .../static_linked_scoped_pkg/index.js | 5 ++++ 9 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 internal/linker/test/integration/dynamic_linked_scoped_pkg/BUILD.bazel create mode 100644 internal/linker/test/integration/dynamic_linked_scoped_pkg/index.js create mode 100644 internal/linker/test/integration/static_linked_scoped_pkg/BUILD.bazel create mode 100644 internal/linker/test/integration/static_linked_scoped_pkg/index.js diff --git a/internal/linker/index.js b/internal/linker/index.js index 850fc0c041..099330946b 100644 --- a/internal/linker/index.js +++ b/internal/linker/index.js @@ -40,6 +40,16 @@ Include as much of the build output as you can without disclosing anything confi ${m} `); } + /** + * Create a new directory and any necessary subdirectories + * if they do not exist. + */ + function mkdirp(p) { + if (!fs.existsSync(p)) { + mkdirp(path.dirname(p)); + fs.mkdirSync(p); + } + } function symlink(target, path) { return __awaiter(this, void 0, void 0, function* () { log_verbose(`symlink( ${path} -> ${target} )`); @@ -62,7 +72,7 @@ Include as much of the build output as you can without disclosing anything confi // any unneeded file I/O if (!fs.existsSync(path)) { log_verbose('ERROR\n***\nLooks like we created a bad symlink:' + - `\n pwd ${process.cwd()}\n target ${target}\n***`); + `\n pwd ${process.cwd()}\n target ${target}\n path ${path}\n***`); } } }); @@ -178,8 +188,6 @@ Include as much of the build output as you can without disclosing anything confi if (this.manifest) { return this.lookupDirectory(modulePath); } - // how can we avoid this FS lookup every time? we don't know when process.cwd changed... - // const runfilesRelative = runfiles.dir ? path.relative('.', runfiles.dir) : undefined; if (exports.runfiles.dir) { return path.join(exports.runfiles.dir, modulePath); } @@ -239,7 +247,7 @@ Include as much of the build output as you can without disclosing anything confi yield symlink(rootDir, 'node_modules'); process.chdir(rootDir); // Symlinks to packages need to reach back to the workspace/runfiles directory - const workspaceRelative = path.relative('.', workspaceDir); + const workspaceAbs = path.resolve(workspaceDir); // Now add symlinks to each of our first-party packages so they appear under the node_modules tree const links = []; const linkModule = (name, root, modulePath) => __awaiter(this, void 0, void 0, function* () { @@ -247,7 +255,7 @@ Include as much of the build output as you can without disclosing anything confi switch (root) { case 'bin': // FIXME(#1196) - target = path.join(workspaceRelative, bin, toWorkspaceDir(modulePath)); + target = path.join(workspaceAbs, bin, toWorkspaceDir(modulePath)); // Spend an extra FS lookup to give better error in this case if (!(yield exists(target))) { // TODO: there should be some docs explaining how users are @@ -261,7 +269,7 @@ Include as much of the build output as you can without disclosing anything confi } break; case 'src': - target = path.join(workspaceRelative, toWorkspaceDir(modulePath)); + target = path.join(workspaceAbs, toWorkspaceDir(modulePath)); break; case 'runfiles': target = runfiles.resolve(modulePath) || ''; @@ -270,6 +278,14 @@ Include as much of the build output as you can without disclosing anything confi yield symlink(target, name); }); for (const m of Object.keys(modules)) { + const segments = m.split('/'); + if (segments.length > 2) { + throw new Error(`module ${m} has more than 2 segments which is not a valid node module name`); + } + if (segments.length == 2) { + // ensure the scope exists + mkdirp(segments[0]); + } const [kind, modulePath] = modules[m]; links.push(linkModule(m, kind, modulePath)); } @@ -289,4 +305,4 @@ Include as much of the build output as you can without disclosing anything confi }))(); } }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlua19ub2RlX21vZHVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9pbnRlcm5hbC9saW5rZXIvbGlua19ub2RlX21vZHVsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUFBOzs7O09BSUc7SUFDSCx5QkFBeUI7SUFDekIsNkJBQTZCO0lBRTdCLGdFQUFnRTtJQUNoRSxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUVuRCxTQUFTLFdBQVcsQ0FBQyxHQUFHLENBQVc7UUFDakMsSUFBSSxZQUFZO1lBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRCxTQUFTLEtBQUssQ0FBQyxDQUFTO1FBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUM7Ozs7OztJQU1kLENBQUM7R0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsU0FBZSxPQUFPLENBQUMsTUFBYyxFQUFFLElBQVk7O1lBQ2pELFdBQVcsQ0FBQyxZQUFZLElBQUksT0FBTyxNQUFNLElBQUksQ0FBQyxDQUFDO1lBQy9DLHVFQUF1RTtZQUN2RSx3REFBd0Q7WUFDeEQsSUFBSTtnQkFDRixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDckQ7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO29CQUN2QixNQUFNLENBQUMsQ0FBQztpQkFDVDtnQkFDRCx3RUFBd0U7Z0JBQ3hFLDJFQUEyRTtnQkFDM0UsNEVBQTRFO2FBQzdFO1lBRUQsSUFBSSxZQUFZLEVBQUU7Z0JBQ2hCLDBDQUEwQztnQkFDMUMsMkVBQTJFO2dCQUMzRSx3QkFBd0I7Z0JBQ3hC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OEIsQ0FBQzt3QkFDeEUsTUFBTTtpQkFDVDtnQkFFRCxNQUFNLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDOUIsQ0FBQyxDQUFBLENBQUE7WUFFRCxLQUFLLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ3BDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0QyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7YUFDN0M7WUFFRCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7WUFDYixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNqQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDO1lBQ1gsQ0FBQyxDQUFDLENBQUM7WUFFSCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7S0FBQTtJQXJGRCxvQkFxRkM7SUFFWSxRQUFBLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFbEQsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRTtRQUMzQixDQUFDLEdBQVMsRUFBRTtZQUNWLE9BQU8sQ0FBQyxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsZ0JBQVEsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQSxDQUFDLEVBQUUsQ0FBQztLQUNOIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IENyZWF0ZXMgYSBub2RlX21vZHVsZXMgZGlyZWN0b3J5IGluIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5XG4gKiBhbmQgc3ltbGlua3MgaW4gdGhlIG5vZGUgbW9kdWxlcyBuZWVkZWQgdG8gcnVuIGEgcHJvZ3JhbS5cbiAqIFRoaXMgcmVwbGFjZXMgdGhlIG5lZWQgZm9yIGN1c3RvbSBtb2R1bGUgcmVzb2x1dGlvbiBsb2dpYyBpbnNpZGUgdGhlIHByb2Nlc3MuXG4gKi9cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbi8vIFJ1biBCYXplbCB3aXRoIC0tZGVmaW5lPVZFUkJPU0VfTE9HUz0xIHRvIGVuYWJsZSB0aGlzIGxvZ2dpbmdcbmNvbnN0IFZFUkJPU0VfTE9HUyA9ICEhcHJvY2Vzcy5lbnZbJ1ZFUkJPU0VfTE9HUyddO1xuXG5mdW5jdGlvbiBsb2dfdmVyYm9zZSguLi5tOiBzdHJpbmdbXSkge1xuICBpZiAoVkVSQk9TRV9MT0dTKSBjb25zb2xlLmVycm9yKCdbbGlua19ub2RlX21vZHVsZXMuanNdJywgLi4ubSk7XG59XG5cbmZ1bmN0aW9uIHBhbmljKG06IHN0cmluZykge1xuICB0aHJvdyBuZXcgRXJyb3IoYEludGVybmFsIGVycm9yISBQbGVhc2UgcnVuIGFnYWluIHdpdGhcbiAgIC0tZGVmaW5lPVZFUkJPU0VfTE9HPTFcbmFuZCBmaWxlIGFuIGlzc3VlOiBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9ydWxlc19ub2RlanMvaXNzdWVzL25ldz90ZW1wbGF0ZT1idWdfcmVwb3J0Lm1kXG5JbmNsdWRlIGFzIG11Y2ggb2YgdGhlIGJ1aWxkIG91dHB1dCBhcyB5b3UgY2FuIHdpdGhvdXQgZGlzY2xvc2luZyBhbnl0aGluZyBjb25maWRlbnRpYWwuXG5cbiAgRXJyb3I6XG4gICR7bX1cbiAgYCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHN5bWxpbmsodGFyZ2V0OiBzdHJpbmcsIHBhdGg6IHN0cmluZykge1xuICBsb2dfdmVyYm9zZShgc3ltbGluayggJHtwYXRofSAtPiAke3RhcmdldH0gKWApO1xuICAvLyBVc2UganVuY3Rpb24gb24gV2luZG93cyBzaW5jZSBzeW1saW5rcyByZXF1aXJlIGVsZXZhdGVkIHBlcm1pc3Npb25zLlxuICAvLyBXZSBvbmx5IGxpbmsgdG8gZGlyZWN0b3JpZXMgc28ganVuY3Rpb25zIHdvcmsgZm9yIHVzLlxuICB0cnkge1xuICAgIGF3YWl0IGZzLnByb21pc2VzLnN5bWxpbmsodGFyZ2V0LCBwYXRoLCAnanVuY3Rpb24nKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlLmNvZGUgIT09ICdFRVhJU1QnKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgICAvLyBXZSBhc3N1bWUgaGVyZSB0aGF0IHRoZSBwYXRoIGlzIGFscmVhZHkgbGlua2VkIHRvIHRoZSBjb3JyZWN0IHRhcmdldC5cbiAgICAvLyBDb3VsZCBhZGQgc29tZSBsb2dpYyB0aGF0IGFzc2VydHMgaXQgaGVyZSwgYnV0IHdlIHdhbnQgdG8gYXZvaWQgYW4gZXh0cmFcbiAgICAvLyBmaWxlc3lzdGVtIGFjY2VzcyBzbyB3ZSBzaG91bGQgb25seSBkbyBpdCB1bmRlciBzb21lIGtpbmQgb2Ygc3RyaWN0IG1vZGUuXG4gIH1cblxuICBpZiAoVkVSQk9TRV9MT0dTKSB7XG4gICAgLy8gQmUgdmVyYm9zZSBhYm91dCBjcmVhdGluZyBhIGJhZCBzeW1saW5rXG4gICAgLy8gTWF5YmUgdGhpcyBzaG91bGQgZmFpbCBpbiBwcm9kdWN0aW9uIGFzIHdlbGwsIGJ1dCBhZ2FpbiB3ZSB3YW50IHRvIGF2b2lkXG4gICAgLy8gYW55IHVubmVlZGVkIGZpbGUgSS9PXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHBhdGgpKSB7XG4gICAgICBsb2dfdmVyYm9zZShcbiAgICAgICAgICAnRVJST1JcXG4qKipcXG5Mb29rcyBsaWtlIHdlIGNyZWF0ZWQgYSBiYWQgc3ltbGluazonICtcbiAgICAgICAgICBgXFxuICBwd2QgJHtwcm9jZXNzLmN3ZCgpfVxcbiAgdGFyZ2V0ICR7dGFyZ2V0fVxcbioqKmApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmUgYSByb290IGRpcmVjdG9yeSBzdHJpbmcgdG8gdGhlIGFjdHVhbCBsb2NhdGlvbiBvbiBkaXNrXG4gKiB3aGVyZSBub2RlX21vZHVsZXMgd2FzIGluc3RhbGxlZFxuICogQHBhcmFtIHJvb3QgYSBzdHJpbmcgbGlrZSAnbnBtL25vZGVfbW9kdWxlcydcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVJvb3Qocm9vdDogc3RyaW5nfHVuZGVmaW5lZCwgcnVuZmlsZXM6IFJ1bmZpbGVzKSB7XG4gIC8vIGNyZWF0ZSBhIG5vZGVfbW9kdWxlcyBkaXJlY3RvcnkgaWYgbm8gcm9vdFxuICAvLyB0aGlzIHdpbGwgYmUgdGhlIGNhc2UgaWYgb25seSBmaXJzdC1wYXJ0eSBtb2R1bGVzIGFyZSBpbnN0YWxsZWRcbiAgaWYgKCFyb290KSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKCdub2RlX21vZHVsZXMnKSkge1xuICAgICAgbG9nX3ZlcmJvc2UoJ25vIHRoaXJkLXBhcnR5IHBhY2thZ2VzOyBta2RpciBub2RlX21vZHVsZXMgaW4gJywgcHJvY2Vzcy5jd2QoKSk7XG4gICAgICBmcy5ta2RpclN5bmMoJ25vZGVfbW9kdWxlcycpO1xuICAgIH1cbiAgICByZXR1cm4gJ25vZGVfbW9kdWxlcyc7XG4gIH1cblxuICAvLyBJZiB3ZSBnb3QgYSBydW5maWxlc01hbmlmZXN0IG1hcCwgbG9vayB0aHJvdWdoIGl0IGZvciBhIHJlc29sdXRpb25cbiAgLy8gVGhpcyB3aWxsIGhhcHBlbiBpZiB3ZSBhcmUgcnVubmluZyBhIGJpbmFyeSB0aGF0IGhhZCBzb21lIG5wbSBwYWNrYWdlc1xuICAvLyBcInN0YXRpY2FsbHkgbGlua2VkXCIgaW50byBpdHMgcnVuZmlsZXNcbiAgY29uc3QgZnJvbU1hbmlmZXN0ID0gcnVuZmlsZXMubG9va3VwRGlyZWN0b3J5KHJvb3QpO1xuICBpZiAoZnJvbU1hbmlmZXN0KSByZXR1cm4gZnJvbU1hbmlmZXN0O1xuXG4gIC8vIEFjY291bnQgZm9yIEJhemVsIC0tbGVnYWN5X2V4dGVybmFsX3J1bmZpbGVzXG4gIC8vIHdoaWNoIGxvb2sgbGlrZSAnbXlfd2tzcC9leHRlcm5hbC9ucG0vbm9kZV9tb2R1bGVzJ1xuICBpZiAoZnMuZXhpc3RzU3luYyhwYXRoLmpvaW4oJ2V4dGVybmFsJywgcm9vdCkpKSB7XG4gICAgbG9nX3ZlcmJvc2UoJ0ZvdW5kIGxlZ2FjeV9leHRlcm5hbF9ydW5maWxlcywgc3dpdGNoaW5nIHJvb3QgdG8nLCBwYXRoLmpvaW4oJ2V4dGVybmFsJywgcm9vdCkpO1xuICAgIHJldHVybiBwYXRoLmpvaW4oJ2V4dGVybmFsJywgcm9vdCk7XG4gIH1cblxuICAvLyBUaGUgcmVwb3NpdG9yeSBzaG91bGQgYmUgbGF5ZWQgb3V0IGluIHRoZSBwYXJlbnQgZGlyZWN0b3J5XG4gIC8vIHNpbmNlIGJhemVsIHNldHMgb3VyIHdvcmtpbmcgZGlyZWN0b3J5IHRvIHRoZSByZXBvc2l0b3J5IHdoZXJlIHRoZSBidWlsZCBpcyBoYXBwZW5pbmdcbiAgcmV0dXJuIHBhdGguam9pbignLi4nLCByb290KTtcbn1cblxuZXhwb3J0IGNsYXNzIFJ1bmZpbGVzIHtcbiAgbWFuaWZlc3Q6IE1hcDxzdHJpbmcsIHN0cmluZz58dW5kZWZpbmVkO1xuICBkaXI6IHN0cmluZ3x1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBJZiB0aGUgZW52aXJvbm1lbnQgZ2l2ZXMgdXMgZW5vdWdoIGhpbnRzLCB3ZSBjYW4ga25vdyB0aGUgcGF0aCB0byB0aGUgcGFja2FnZVxuICAgKiBpbiB0aGUgZm9ybSB3b3Jrc3BhY2VfbmFtZS9wYXRoL3RvL3BhY2thZ2VcbiAgICovXG4gIHBhY2thZ2VQYXRoOiBzdHJpbmd8dW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKGVudjogdHlwZW9mIHByb2Nlc3MuZW52KSB7XG4gICAgLy8gSWYgQmF6ZWwgc2V0cyBhIHZhcmlhYmxlIHBvaW50aW5nIHRvIGEgcnVuZmlsZXMgbWFuaWZlc3QsXG4gICAgLy8gd2UnbGwgYWx3YXlzIHVzZSBpdC5cbiAgICAvLyBOb3RlIHRoYXQgdGhpcyBoYXMgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW1wbGljYXRpb24gb24gTWFjL0xpbnV4XG4gICAgLy8gd2hlcmUgd2UgY291bGQgdXNlIHRoZSBydW5maWxlcyB0cmVlIGFscmVhZHkgbGFpZCBvdXQgb24gZGlza1xuICAgIC8vIGJ1dCB0aGlzIGp1c3QgY29zdHMgb25lIGZpbGUgcmVhZCBmb3IgdGhlIGV4dGVybmFsIG5wbS9ub2RlX21vZHVsZXNcbiAgICAvLyBhbmQgb25lIGZvciBlYWNoIGZpcnN0LXBhcnR5IG1vZHVsZSwgbm90IG9uZSBwZXIgZmlsZS5cbiAgICBpZiAoISFlbnZbJ1JVTkZJTEVTX01BTklGRVNUX0ZJTEUnXSkge1xuICAgICAgdGhpcy5tYW5pZmVzdCA9IHRoaXMubG9hZFJ1bmZpbGVzTWFuaWZlc3QoZW52WydSVU5GSUxFU19NQU5JRkVTVF9GSUxFJ10hKTtcbiAgICB9IGVsc2UgaWYgKCEhZW52WydSVU5GSUxFU19ESVInXSkge1xuICAgICAgdGhpcy5kaXIgPSBwYXRoLnJlc29sdmUoZW52WydSVU5GSUxFU19ESVInXSEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYW5pYyhcbiAgICAgICAgICAnRXZlcnkgbm9kZSBwcm9ncmFtIHJ1biB1bmRlciBCYXplbCBtdXN0IGhhdmUgYSAkUlVORklMRVNfRElSIG9yICRSVU5GSUxFU19NQU5JRkVTVF9GSUxFIGVudmlyb25tZW50IHZhcmlhYmxlJyk7XG4gICAgfVxuICAgIC8vIFVuZGVyIC0tbm9lbmFibGVfcnVuZmlsZXMgKGluIHBhcnRpY3VsYXIgb24gV2luZG93cylcbiAgICAvLyBCYXplbCBzZXRzIFJVTkZJTEVTX01BTklGRVNUX09OTFk9MS5cbiAgICAvLyBXaGVuIHRoaXMgaGFwcGVucywgd2UgbmVlZCB0byByZWFkIHRoZSBtYW5pZmVzdCBmaWxlIHRvIGxvY2F0ZVxuICAgIC8vIGlucHV0c1xuICAgIGlmIChlbnZbJ1JVTkZJTEVTX01BTklGRVNUX09OTFknXSA9PT0gJzEnICYmICFlbnZbJ1JVTkZJTEVTX01BTklGRVNUX0ZJTEUnXSkge1xuICAgICAgbG9nX3ZlcmJvc2UoYFdvcmthcm91bmQgaHR0cHM6Ly9naXRodWIuY29tL2JhemVsYnVpbGQvYmF6ZWwvaXNzdWVzLzc5OTRcbiAgICAgICAgICAgICAgICAgUlVORklMRVNfTUFOSUZFU1RfRklMRSBzaG91bGQgaGF2ZSBiZWVuIHNldCBidXQgd2Fzbid0LlxuICAgICAgICAgICAgICAgICBmYWxsaW5nIGJhY2sgdG8gdXNpbmcgcnVuZmlsZXMgc3ltbGlua3MuXG4gICAgICAgICAgICAgICAgIElmIHlvdSB3YW50IHRvIHRlc3QgcnVuZmlsZXMgbWFuaWZlc3QgYmVoYXZpb3IsIGFkZFxuICAgICAgICAgICAgICAgICAtLXNwYXduX3N0cmF0ZWd5PXN0YW5kYWxvbmUgdG8gdGhlIGNvbW1hbmQgbGluZS5gKTtcbiAgICB9XG5cbiAgICBjb25zdCB3a3NwID0gZW52WydURVNUX1dPUktTUEFDRSddO1xuICAgIGNvbnN0IHRhcmdldCA9IGVudlsnVEVTVF9UQVJHRVQnXTtcbiAgICBpZiAoISF3a3NwICYmICEhdGFyZ2V0KSB7XG4gICAgICAvLyAvL3BhdGgvdG86dGFyZ2V0IC0+IC8vcGF0aC90b1xuICAgICAgY29uc3QgcGtnID0gdGFyZ2V0LnNwbGl0KCc6JylbMF07XG4gICAgICB0aGlzLnBhY2thZ2VQYXRoID0gcGF0aC5wb3NpeC5qb2luKHdrc3AsIHBrZyk7XG4gICAgfVxuICB9XG5cbiAgbG9va3VwRGlyZWN0b3J5KGRpcjogc3RyaW5nKTogc3RyaW5nfHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLm1hbmlmZXN0KSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBbaywgdl0gb2YgdGhpcy5tYW5pZmVzdCkge1xuICAgICAgLy8gQWNjb3VudCBmb3IgQmF6ZWwgLS1sZWdhY3lfZXh0ZXJuYWxfcnVuZmlsZXNcbiAgICAgIC8vIHdoaWNoIHBvbGx1dGVzIHRoZSB3b3Jrc3BhY2Ugd2l0aCAnbXlfd2tzcC9leHRlcm5hbC8uLi4nXG4gICAgICBpZiAoay5zdGFydHNXaXRoKGAke2Rpcn0vZXh0ZXJuYWxgKSkgY29udGludWU7XG5cbiAgICAgIC8vIEVudHJ5IGxvb2tzIGxpa2VcbiAgICAgIC8vIGs6IG5wbS9ub2RlX21vZHVsZXMvc2VtdmVyL0xJQ0VOU0VcbiAgICAgIC8vIHY6IC9wYXRoL3RvL2V4dGVybmFsL25wbS9ub2RlX21vZHVsZXMvc2VtdmVyL0xJQ0VOU0VcbiAgICAgIC8vIGNhbGN1bGF0ZSBsID0gbGVuZ3RoKGAvc2VtdmVyL0xJQ0VOU0VgKVxuICAgICAgaWYgKGsuc3RhcnRzV2l0aChkaXIpKSB7XG4gICAgICAgIGNvbnN0IGwgPSBrLmxlbmd0aCAtIGRpci5sZW5ndGg7XG4gICAgICAgIHJldHVybiB2LnN1YnN0cmluZygwLCB2Lmxlbmd0aCAtIGwpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFRoZSBydW5maWxlcyBtYW5pZmVzdCBtYXBzIGZyb20gc2hvcnRfcGF0aFxuICAgKiBodHRwczovL2RvY3MuYmF6ZWwuYnVpbGQvdmVyc2lvbnMvbWFzdGVyL3NreWxhcmsvbGliL0ZpbGUuaHRtbCNzaG9ydF9wYXRoXG4gICAqIHRvIHRoZSBhY3R1YWwgbG9jYXRpb24gb24gZGlzayB3aGVyZSB0aGUgZmlsZSBjYW4gYmUgcmVhZC5cbiAgICpcbiAgICogSW4gYSBzYW5kYm94ZWQgZXhlY3V0aW9uLCBpdCBkb2VzIG5vdCBleGlzdC4gSW4gdGhhdCBjYXNlLCBydW5maWxlcyBtdXN0IGJlXG4gICAqIHJlc29sdmVkIGZyb20gYSBzeW1saW5rIHRyZWUgdW5kZXIgdGhlIHJ1bmZpbGVzIGRpci5cbiAgICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL2JhemVsL2lzc3Vlcy8zNzI2XG4gICAqL1xuICBsb2FkUnVuZmlsZXNNYW5pZmVzdChtYW5pZmVzdFBhdGg6IHN0cmluZykge1xuICAgIGxvZ192ZXJib3NlKGB1c2luZyBydW5maWxlcyBtYW5pZmVzdCAke21hbmlmZXN0UGF0aH1gKTtcblxuICAgIGNvbnN0IHJ1bmZpbGVzRW50cmllcyA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBpbnB1dCA9IGZzLnJlYWRGaWxlU3luYyhtYW5pZmVzdFBhdGgsIHtlbmNvZGluZzogJ3V0Zi04J30pO1xuXG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGlucHV0LnNwbGl0KCdcXG4nKSkge1xuICAgICAgaWYgKCFsaW5lKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IFtydW5maWxlc1BhdGgsIHJlYWxQYXRoXSA9IGxpbmUuc3BsaXQoJyAnKTtcbiAgICAgIHJ1bmZpbGVzRW50cmllcy5zZXQocnVuZmlsZXNQYXRoLCByZWFsUGF0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJ1bmZpbGVzRW50cmllcztcbiAgfVxuXG4gIHJlc29sdmUobW9kdWxlUGF0aDogc3RyaW5nKSB7XG4gICAgLy8gTG9vayBpbiB0aGUgcnVuZmlsZXMgZmlyc3RcbiAgICBpZiAodGhpcy5tYW5pZmVzdCkge1xuICAgICAgcmV0dXJuIHRoaXMubG9va3VwRGlyZWN0b3J5KG1vZHVsZVBhdGgpO1xuICAgIH1cbiAgICAvLyBob3cgY2FuIHdlIGF2b2lkIHRoaXMgRlMgbG9va3VwIGV2ZXJ5IHRpbWU/IHdlIGRvbid0IGtub3cgd2hlbiBwcm9jZXNzLmN3ZCBjaGFuZ2VkLi4uXG4gICAgLy8gY29uc3QgcnVuZmlsZXNSZWxhdGl2ZSA9IHJ1bmZpbGVzLmRpciA/IHBhdGgucmVsYXRpdmUoJy4nLCBydW5maWxlcy5kaXIpIDogdW5kZWZpbmVkO1xuICAgIGlmIChydW5maWxlcy5kaXIpIHtcbiAgICAgIHJldHVybiBwYXRoLmpvaW4ocnVuZmlsZXMuZGlyLCBtb2R1bGVQYXRoKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb3VsZCBub3QgcmVzb2x2ZSBtb2R1bGVQYXRoICR7bW9kdWxlUGF0aH1gKTtcbiAgfVxuXG4gIHJlc29sdmVQYWNrYWdlUmVsYXRpdmUobW9kdWxlUGF0aDogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLnBhY2thZ2VQYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhY2thZ2VQYXRoIGNvdWxkIG5vdCBiZSBkZXRlcm1pbmVkIGZyb20gdGhlIGVudmlyb25tZW50Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlc29sdmUocGF0aC5wb3NpeC5qb2luKHRoaXMucGFja2FnZVBhdGgsIG1vZHVsZVBhdGgpKTtcbiAgfVxufVxuXG4vLyBUeXBlU2NyaXB0IGxpYi5lczUuZC50cyBoYXMgYSBtaXN0YWtlOiBKU09OLnBhcnNlIGRvZXMgYWNjZXB0IEJ1ZmZlci5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIEpTT04ge1xuICAgIHBhcnNlKGI6IHt0b1N0cmluZzogKCkgPT4gc3RyaW5nfSk6IGFueTtcbiAgfVxufVxuXG4vLyBUaGVyZSBpcyBubyBmcy5wcm9taXNlcy5leGlzdHMgZnVuY3Rpb24gYmVjYXVzZVxuLy8gbm9kZSBjb3JlIGlzIG9mIHRoZSBvcGluaW9uIHRoYXQgZXhpc3RzIGlzIGFsd2F5cyB0b28gcmFjZXkgdG8gcmVseSBvbi5cbmFzeW5jIGZ1bmN0aW9uIGV4aXN0cyhwOiBzdHJpbmcpIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmcy5wcm9taXNlcy5zdGF0KHApXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoZS5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG59XG5cbi8vIFNlZSBsaW5rX25vZGVfbW9kdWxlcy5iemwgd2hlcmUgdGhlc2UgdGhyZWUgc3RyaW5nc1xuLy8gYXJlIHVzZWQgdG8gaW5kaWNhdGUgd2hpY2ggcm9vdCB0aGUgbGlua2VyIHNob3VsZCB0YXJnZXRcbi8vIGZvciBlYWNoIHBhY2thZ2U6XG4vLyBiaW46IGJhemVsLWJpbi9wYXRoL3RvL3BhY2thZ2Vcbi8vIHNyYzogd29ya3NwYWNlL3BhdGgvdG8vcGFja2FnZVxuLy8gcnVuZmlsZXM6IGxvb2sgaW4gdGhlIHJ1bmZpbGVzIGRpci9tYW5pZmVzdFxudHlwZSBMaW5rZXJSb290ID0gJ2Jpbid8J3NyYyd8J3J1bmZpbGVzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oYXJnczogc3RyaW5nW10sIHJ1bmZpbGVzOiBSdW5maWxlcykge1xuICBpZiAoIWFyZ3MgfHwgYXJncy5sZW5ndGggPCAxKVxuICAgIHRocm93IG5ldyBFcnJvcignbGlua19ub2RlX21vZHVsZXMuanMgcmVxdWlyZXMgb25lIGFyZ3VtZW50OiBtb2R1bGVzTWFuaWZlc3QgcGF0aCcpO1xuXG4gIGNvbnN0IFttb2R1bGVzTWFuaWZlc3RdID0gYXJncztcbiAgbGV0IHtiaW4sIHJvb3QsIG1vZHVsZXMsIHdvcmtzcGFjZX0gPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhtb2R1bGVzTWFuaWZlc3QpKTtcbiAgbW9kdWxlcyA9IG1vZHVsZXMgfHwge307XG4gIGxvZ192ZXJib3NlKFxuICAgICAgYG1vZHVsZSBtYW5pZmVzdDogd29ya3NwYWNlICR7d29ya3NwYWNlfSwgYmluICR7YmlufSwgcm9vdCAke1xuICAgICAgICAgIHJvb3R9IHdpdGggZmlyc3QtcGFydHkgcGFja2FnZXNcXG5gLFxuICAgICAgbW9kdWxlcyk7XG5cbiAgY29uc3Qgcm9vdERpciA9IHJlc29sdmVSb290KHJvb3QsIHJ1bmZpbGVzKTtcbiAgbG9nX3ZlcmJvc2UoJ3Jlc29sdmVkIHJvb3QnLCByb290LCAndG8nLCByb290RGlyKTtcblxuICAvLyBCYXplbCBzdGFydHMgYWN0aW9ucyB3aXRoIHB3ZD1leGVjcm9vdC9teV93a3NwXG4gIGNvbnN0IHdvcmtzcGFjZURpciA9IHBhdGgucmVzb2x2ZSgnLicpO1xuXG4gIC8vIENvbnZlcnQgZnJvbSBydW5maWxlcyBwYXRoXG4gIC8vIHRoaXNfd2tzcC9wYXRoL3RvL2ZpbGUgT1Igb3RoZXJfd2tzcC9wYXRoL3RvL2ZpbGVcbiAgLy8gdG8gZXhlY3Jvb3QgcGF0aFxuICAvLyBwYXRoL3RvL2ZpbGUgT1IgZXh0ZXJuYWwvb3RoZXJfd2tzcC9wYXRoL3RvL2ZpbGVcbiAgZnVuY3Rpb24gdG9Xb3Jrc3BhY2VEaXIocDogc3RyaW5nKSB7XG4gICAgaWYgKHAgPT09IHdvcmtzcGFjZSkge1xuICAgICAgcmV0dXJuICcuJztcbiAgICB9XG4gICAgLy8gVGhlIG1hbmlmZXN0IGlzIHdyaXR0ZW4gd2l0aCBmb3J3YXJkIHNsYXNoIG9uIGFsbCBwbGF0Zm9ybXNcbiAgICBpZiAocC5zdGFydHNXaXRoKHdvcmtzcGFjZSArICcvJykpIHtcbiAgICAgIHJldHVybiBwLnN1YnN0cmluZyh3b3Jrc3BhY2UubGVuZ3RoICsgMSk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLmpvaW4oJ2V4dGVybmFsJywgcCk7XG4gIH1cblxuICAvLyBDcmVhdGUgdGhlICRwd2Qvbm9kZV9tb2R1bGVzIGRpcmVjdG9yeSB0aGF0IG5vZGUgd2lsbCByZXNvbHZlIGZyb21cbiAgYXdhaXQgc3ltbGluayhyb290RGlyLCAnbm9kZV9tb2R1bGVzJyk7XG4gIHByb2Nlc3MuY2hkaXIocm9vdERpcik7XG5cbiAgLy8gU3ltbGlua3MgdG8gcGFja2FnZXMgbmVlZCB0byByZWFjaCBiYWNrIHRvIHRoZSB3b3Jrc3BhY2UvcnVuZmlsZXMgZGlyZWN0b3J5XG4gIGNvbnN0IHdvcmtzcGFjZVJlbGF0aXZlID0gcGF0aC5yZWxhdGl2ZSgnLicsIHdvcmtzcGFjZURpcik7XG5cbiAgLy8gTm93IGFkZCBzeW1saW5rcyB0byBlYWNoIG9mIG91ciBmaXJzdC1wYXJ0eSBwYWNrYWdlcyBzbyB0aGV5IGFwcGVhciB1bmRlciB0aGUgbm9kZV9tb2R1bGVzIHRyZWVcbiAgY29uc3QgbGlua3MgPSBbXTtcblxuICBjb25zdCBsaW5rTW9kdWxlID1cbiAgICAgIGFzeW5jIChuYW1lOiBzdHJpbmcsIHJvb3Q6IExpbmtlclJvb3QsIG1vZHVsZVBhdGg6IHN0cmluZykgPT4ge1xuICAgIGxldCB0YXJnZXQ6IHN0cmluZyA9ICc8cGFja2FnZSBsaW5raW5nIGZhaWxlZD4nO1xuICAgIHN3aXRjaCAocm9vdCkge1xuICAgICAgY2FzZSAnYmluJzpcbiAgICAgICAgLy8gRklYTUUoIzExOTYpXG4gICAgICAgIHRhcmdldCA9IHBhdGguam9pbih3b3Jrc3BhY2VSZWxhdGl2ZSwgYmluLCB0b1dvcmtzcGFjZURpcihtb2R1bGVQYXRoKSk7XG4gICAgICAgIC8vIFNwZW5kIGFuIGV4dHJhIEZTIGxvb2t1cCB0byBnaXZlIGJldHRlciBlcnJvciBpbiB0aGlzIGNhc2VcbiAgICAgICAgaWYgKCFhd2FpdCBleGlzdHModGFyZ2V0KSkge1xuICAgICAgICAgIC8vIFRPRE86IHRoZXJlIHNob3VsZCBiZSBzb21lIGRvY3MgZXhwbGFpbmluZyBob3cgdXNlcnMgYXJlXG4gICAgICAgICAgLy8gZXhwZWN0ZWQgdG8gZGVjbGFyZSBhaGVhZCBvZiB0aW1lIHdoZXJlIHRoZSBwYWNrYWdlIGlzIGxvYWRlZCxcbiAgICAgICAgICAvLyBob3cgdGhhdCByZWxhdGVzIHRvIG5wbSBsaW5rIHNjZW5hcmlvcyxcbiAgICAgICAgICAvLyBhbmQgd2hlcmUgdGhlIGNvbmZpZ3VyYXRpb24gY2FuIGdvLlxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgRVJST1I6IG5vIG91dHB1dCBkaXJlY3RvcnkgZm91bmQgZm9yIHBhY2thZ2UgJHttb2R1bGVQYXRofVxuICAgICAgICBEaWQgeW91IG1lYW4gdG8gZGVjbGFyZSB0aGlzIGFzIGEgZnJvbS1zb3VyY2UgcGFja2FnZT9cbiAgICAgICAgU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL3J1bGVzX25vZGVqcy9wdWxsLzExOTdcbiAgICAgICAgdW50aWwgdGhpcyBmZWF0dXJlIGlzIHByb3Blcmx5IGRvY3VtZW50ZWQuYCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzcmMnOlxuICAgICAgICB0YXJnZXQgPSBwYXRoLmpvaW4od29ya3NwYWNlUmVsYXRpdmUsIHRvV29ya3NwYWNlRGlyKG1vZHVsZVBhdGgpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdydW5maWxlcyc6XG4gICAgICAgIHRhcmdldCA9IHJ1bmZpbGVzLnJlc29sdmUobW9kdWxlUGF0aCkgfHwgJzxydW5maWxlcyByZXNvbHV0aW9uIGZhaWxlZD4nO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBhd2FpdCBzeW1saW5rKHRhcmdldCwgbmFtZSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IG0gb2YgT2JqZWN0LmtleXMobW9kdWxlcykpIHtcbiAgICBjb25zdCBba2luZCwgbW9kdWxlUGF0aF0gPSBtb2R1bGVzW21dO1xuICAgIGxpbmtzLnB1c2gobGlua01vZHVsZShtLCBraW5kLCBtb2R1bGVQYXRoKSk7XG4gIH1cblxuICBsZXQgY29kZSA9IDA7XG4gIGF3YWl0IFByb21pc2UuYWxsKGxpbmtzKS5jYXRjaChlID0+IHtcbiAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgIGNvZGUgPSAxO1xuICB9KTtcblxuICByZXR1cm4gY29kZTtcbn1cblxuZXhwb3J0IGNvbnN0IHJ1bmZpbGVzID0gbmV3IFJ1bmZpbGVzKHByb2Nlc3MuZW52KTtcblxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIChhc3luYyAoKSA9PiB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IGF3YWl0IG1haW4ocHJvY2Vzcy5hcmd2LnNsaWNlKDIpLCBydW5maWxlcyk7XG4gIH0pKCk7XG59XG4iXX0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlua19ub2RlX21vZHVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9pbnRlcm5hbC9saW5rZXIvbGlua19ub2RlX21vZHVsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUFBOzs7O09BSUc7SUFDSCx5QkFBeUI7SUFDekIsNkJBQTZCO0lBRTdCLGdFQUFnRTtJQUNoRSxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUVuRCxTQUFTLFdBQVcsQ0FBQyxHQUFHLENBQVc7UUFDakMsSUFBSSxZQUFZO1lBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRCxTQUFTLEtBQUssQ0FBQyxDQUFTO1FBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUM7Ozs7OztJQU1kLENBQUM7R0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsU0FBUyxNQUFNLENBQUMsQ0FBUztRQUN2QixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNyQixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hCLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDakI7SUFDSCxDQUFDO0lBRUQsU0FBZSxPQUFPLENBQUMsTUFBYyxFQUFFLElBQVk7O1lBQ2pELFdBQVcsQ0FBQyxZQUFZLElBQUksT0FBTyxNQUFNLElBQUksQ0FBQyxDQUFDO1lBQy9DLHVFQUF1RTtZQUN2RSx3REFBd0Q7WUFDeEQsSUFBSTtnQkFDRixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDckQ7WUFB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QUFDLENBQUM7WUFDWCxDQUFDLENBQUMsQ0FBQztZQUVILE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztLQUFBO0lBN0ZELG9CQTZGQztJQUVZLFFBQUEsUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVsRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFO1FBQzNCLENBQUMsR0FBUyxFQUFFO1lBQ1YsT0FBTyxDQUFDLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxnQkFBUSxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFBLENBQUMsRUFBRSxDQUFDO0tBQ04iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlb3ZlcnZpZXcgQ3JlYXRlcyBhIG5vZGVfbW9kdWxlcyBkaXJlY3RvcnkgaW4gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnlcbiAqIGFuZCBzeW1saW5rcyBpbiB0aGUgbm9kZSBtb2R1bGVzIG5lZWRlZCB0byBydW4gYSBwcm9ncmFtLlxuICogVGhpcyByZXBsYWNlcyB0aGUgbmVlZCBmb3IgY3VzdG9tIG1vZHVsZSByZXNvbHV0aW9uIGxvZ2ljIGluc2lkZSB0aGUgcHJvY2Vzcy5cbiAqL1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuLy8gUnVuIEJhemVsIHdpdGggLS1kZWZpbmU9VkVSQk9TRV9MT0dTPTEgdG8gZW5hYmxlIHRoaXMgbG9nZ2luZ1xuY29uc3QgVkVSQk9TRV9MT0dTID0gISFwcm9jZXNzLmVudlsnVkVSQk9TRV9MT0dTJ107XG5cbmZ1bmN0aW9uIGxvZ192ZXJib3NlKC4uLm06IHN0cmluZ1tdKSB7XG4gIGlmIChWRVJCT1NFX0xPR1MpIGNvbnNvbGUuZXJyb3IoJ1tsaW5rX25vZGVfbW9kdWxlcy5qc10nLCAuLi5tKTtcbn1cblxuZnVuY3Rpb24gcGFuaWMobTogc3RyaW5nKSB7XG4gIHRocm93IG5ldyBFcnJvcihgSW50ZXJuYWwgZXJyb3IhIFBsZWFzZSBydW4gYWdhaW4gd2l0aFxuICAgLS1kZWZpbmU9VkVSQk9TRV9MT0c9MVxuYW5kIGZpbGUgYW4gaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL3J1bGVzX25vZGVqcy9pc3N1ZXMvbmV3P3RlbXBsYXRlPWJ1Z19yZXBvcnQubWRcbkluY2x1ZGUgYXMgbXVjaCBvZiB0aGUgYnVpbGQgb3V0cHV0IGFzIHlvdSBjYW4gd2l0aG91dCBkaXNjbG9zaW5nIGFueXRoaW5nIGNvbmZpZGVudGlhbC5cblxuICBFcnJvcjpcbiAgJHttfVxuICBgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGlyZWN0b3J5IGFuZCBhbnkgbmVjZXNzYXJ5IHN1YmRpcmVjdG9yaWVzXG4gKiBpZiB0aGV5IGRvIG5vdCBleGlzdC5cbiAqL1xuZnVuY3Rpb24gbWtkaXJwKHA6IHN0cmluZykge1xuICBpZiAoIWZzLmV4aXN0c1N5bmMocCkpIHtcbiAgICBta2RpcnAocGF0aC5kaXJuYW1lKHApKTtcbiAgICBmcy5ta2RpclN5bmMocCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc3ltbGluayh0YXJnZXQ6IHN0cmluZywgcGF0aDogc3RyaW5nKSB7XG4gIGxvZ192ZXJib3NlKGBzeW1saW5rKCAke3BhdGh9IC0+ICR7dGFyZ2V0fSApYCk7XG4gIC8vIFVzZSBqdW5jdGlvbiBvbiBXaW5kb3dzIHNpbmNlIHN5bWxpbmtzIHJlcXVpcmUgZWxldmF0ZWQgcGVybWlzc2lvbnMuXG4gIC8vIFdlIG9ubHkgbGluayB0byBkaXJlY3RvcmllcyBzbyBqdW5jdGlvbnMgd29yayBmb3IgdXMuXG4gIHRyeSB7XG4gICAgYXdhaXQgZnMucHJvbWlzZXMuc3ltbGluayh0YXJnZXQsIHBhdGgsICdqdW5jdGlvbicpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUuY29kZSAhPT0gJ0VFWElTVCcpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIC8vIFdlIGFzc3VtZSBoZXJlIHRoYXQgdGhlIHBhdGggaXMgYWxyZWFkeSBsaW5rZWQgdG8gdGhlIGNvcnJlY3QgdGFyZ2V0LlxuICAgIC8vIENvdWxkIGFkZCBzb21lIGxvZ2ljIHRoYXQgYXNzZXJ0cyBpdCBoZXJlLCBidXQgd2Ugd2FudCB0byBhdm9pZCBhbiBleHRyYVxuICAgIC8vIGZpbGVzeXN0ZW0gYWNjZXNzIHNvIHdlIHNob3VsZCBvbmx5IGRvIGl0IHVuZGVyIHNvbWUga2luZCBvZiBzdHJpY3QgbW9kZS5cbiAgfVxuXG4gIGlmIChWRVJCT1NFX0xPR1MpIHtcbiAgICAvLyBCZSB2ZXJib3NlIGFib3V0IGNyZWF0aW5nIGEgYmFkIHN5bWxpbmtcbiAgICAvLyBNYXliZSB0aGlzIHNob3VsZCBmYWlsIGluIHByb2R1Y3Rpb24gYXMgd2VsbCwgYnV0IGFnYWluIHdlIHdhbnQgdG8gYXZvaWRcbiAgICAvLyBhbnkgdW5uZWVkZWQgZmlsZSBJL09cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aCkpIHtcbiAgICAgIGxvZ192ZXJib3NlKFxuICAgICAgICAgICdFUlJPUlxcbioqKlxcbkxvb2tzIGxpa2Ugd2UgY3JlYXRlZCBhIGJhZCBzeW1saW5rOicgK1xuICAgICAgICAgIGBcXG4gIHB3ZCAke3Byb2Nlc3MuY3dkKCl9XFxuICB0YXJnZXQgJHt0YXJnZXR9XFxuICBwYXRoICR7cGF0aH1cXG4qKipgKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgcm9vdCBkaXJlY3Rvcnkgc3RyaW5nIHRvIHRoZSBhY3R1YWwgbG9jYXRpb24gb24gZGlza1xuICogd2hlcmUgbm9kZV9tb2R1bGVzIHdhcyBpbnN0YWxsZWRcbiAqIEBwYXJhbSByb290IGEgc3RyaW5nIGxpa2UgJ25wbS9ub2RlX21vZHVsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVSb290KHJvb3Q6IHN0cmluZ3x1bmRlZmluZWQsIHJ1bmZpbGVzOiBSdW5maWxlcykge1xuICAvLyBjcmVhdGUgYSBub2RlX21vZHVsZXMgZGlyZWN0b3J5IGlmIG5vIHJvb3RcbiAgLy8gdGhpcyB3aWxsIGJlIHRoZSBjYXNlIGlmIG9ubHkgZmlyc3QtcGFydHkgbW9kdWxlcyBhcmUgaW5zdGFsbGVkXG4gIGlmICghcm9vdCkge1xuICAgIGlmICghZnMuZXhpc3RzU3luYygnbm9kZV9tb2R1bGVzJykpIHtcbiAgICAgIGxvZ192ZXJib3NlKCdubyB0aGlyZC1wYXJ0eSBwYWNrYWdlczsgbWtkaXIgbm9kZV9tb2R1bGVzIGluICcsIHByb2Nlc3MuY3dkKCkpO1xuICAgICAgZnMubWtkaXJTeW5jKCdub2RlX21vZHVsZXMnKTtcbiAgICB9XG4gICAgcmV0dXJuICdub2RlX21vZHVsZXMnO1xuICB9XG5cbiAgLy8gSWYgd2UgZ290IGEgcnVuZmlsZXNNYW5pZmVzdCBtYXAsIGxvb2sgdGhyb3VnaCBpdCBmb3IgYSByZXNvbHV0aW9uXG4gIC8vIFRoaXMgd2lsbCBoYXBwZW4gaWYgd2UgYXJlIHJ1bm5pbmcgYSBiaW5hcnkgdGhhdCBoYWQgc29tZSBucG0gcGFja2FnZXNcbiAgLy8gXCJzdGF0aWNhbGx5IGxpbmtlZFwiIGludG8gaXRzIHJ1bmZpbGVzXG4gIGNvbnN0IGZyb21NYW5pZmVzdCA9IHJ1bmZpbGVzLmxvb2t1cERpcmVjdG9yeShyb290KTtcbiAgaWYgKGZyb21NYW5pZmVzdCkgcmV0dXJuIGZyb21NYW5pZmVzdDtcblxuICAvLyBBY2NvdW50IGZvciBCYXplbCAtLWxlZ2FjeV9leHRlcm5hbF9ydW5maWxlc1xuICAvLyB3aGljaCBsb29rIGxpa2UgJ215X3drc3AvZXh0ZXJuYWwvbnBtL25vZGVfbW9kdWxlcydcbiAgaWYgKGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKCdleHRlcm5hbCcsIHJvb3QpKSkge1xuICAgIGxvZ192ZXJib3NlKCdGb3VuZCBsZWdhY3lfZXh0ZXJuYWxfcnVuZmlsZXMsIHN3aXRjaGluZyByb290IHRvJywgcGF0aC5qb2luKCdleHRlcm5hbCcsIHJvb3QpKTtcbiAgICByZXR1cm4gcGF0aC5qb2luKCdleHRlcm5hbCcsIHJvb3QpO1xuICB9XG5cbiAgLy8gVGhlIHJlcG9zaXRvcnkgc2hvdWxkIGJlIGxheWVkIG91dCBpbiB0aGUgcGFyZW50IGRpcmVjdG9yeVxuICAvLyBzaW5jZSBiYXplbCBzZXRzIG91ciB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgcmVwb3NpdG9yeSB3aGVyZSB0aGUgYnVpbGQgaXMgaGFwcGVuaW5nXG4gIHJldHVybiBwYXRoLmpvaW4oJy4uJywgcm9vdCk7XG59XG5cbmV4cG9ydCBjbGFzcyBSdW5maWxlcyB7XG4gIG1hbmlmZXN0OiBNYXA8c3RyaW5nLCBzdHJpbmc+fHVuZGVmaW5lZDtcbiAgZGlyOiBzdHJpbmd8dW5kZWZpbmVkO1xuICAvKipcbiAgICogSWYgdGhlIGVudmlyb25tZW50IGdpdmVzIHVzIGVub3VnaCBoaW50cywgd2UgY2FuIGtub3cgdGhlIHBhdGggdG8gdGhlIHBhY2thZ2VcbiAgICogaW4gdGhlIGZvcm0gd29ya3NwYWNlX25hbWUvcGF0aC90by9wYWNrYWdlXG4gICAqL1xuICBwYWNrYWdlUGF0aDogc3RyaW5nfHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihlbnY6IHR5cGVvZiBwcm9jZXNzLmVudikge1xuICAgIC8vIElmIEJhemVsIHNldHMgYSB2YXJpYWJsZSBwb2ludGluZyB0byBhIHJ1bmZpbGVzIG1hbmlmZXN0LFxuICAgIC8vIHdlJ2xsIGFsd2F5cyB1c2UgaXQuXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaGFzIGEgc2xpZ2h0IHBlcmZvcm1hbmNlIGltcGxpY2F0aW9uIG9uIE1hYy9MaW51eFxuICAgIC8vIHdoZXJlIHdlIGNvdWxkIHVzZSB0aGUgcnVuZmlsZXMgdHJlZSBhbHJlYWR5IGxhaWQgb3V0IG9uIGRpc2tcbiAgICAvLyBidXQgdGhpcyBqdXN0IGNvc3RzIG9uZSBmaWxlIHJlYWQgZm9yIHRoZSBleHRlcm5hbCBucG0vbm9kZV9tb2R1bGVzXG4gICAgLy8gYW5kIG9uZSBmb3IgZWFjaCBmaXJzdC1wYXJ0eSBtb2R1bGUsIG5vdCBvbmUgcGVyIGZpbGUuXG4gICAgaWYgKCEhZW52WydSVU5GSUxFU19NQU5JRkVTVF9GSUxFJ10pIHtcbiAgICAgIHRoaXMubWFuaWZlc3QgPSB0aGlzLmxvYWRSdW5maWxlc01hbmlmZXN0KGVudlsnUlVORklMRVNfTUFOSUZFU1RfRklMRSddISk7XG4gICAgfSBlbHNlIGlmICghIWVudlsnUlVORklMRVNfRElSJ10pIHtcbiAgICAgIHRoaXMuZGlyID0gcGF0aC5yZXNvbHZlKGVudlsnUlVORklMRVNfRElSJ10hKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFuaWMoXG4gICAgICAgICAgJ0V2ZXJ5IG5vZGUgcHJvZ3JhbSBydW4gdW5kZXIgQmF6ZWwgbXVzdCBoYXZlIGEgJFJVTkZJTEVTX0RJUiBvciAkUlVORklMRVNfTUFOSUZFU1RfRklMRSBlbnZpcm9ubWVudCB2YXJpYWJsZScpO1xuICAgIH1cbiAgICAvLyBVbmRlciAtLW5vZW5hYmxlX3J1bmZpbGVzIChpbiBwYXJ0aWN1bGFyIG9uIFdpbmRvd3MpXG4gICAgLy8gQmF6ZWwgc2V0cyBSVU5GSUxFU19NQU5JRkVTVF9PTkxZPTEuXG4gICAgLy8gV2hlbiB0aGlzIGhhcHBlbnMsIHdlIG5lZWQgdG8gcmVhZCB0aGUgbWFuaWZlc3QgZmlsZSB0byBsb2NhdGVcbiAgICAvLyBpbnB1dHNcbiAgICBpZiAoZW52WydSVU5GSUxFU19NQU5JRkVTVF9PTkxZJ10gPT09ICcxJyAmJiAhZW52WydSVU5GSUxFU19NQU5JRkVTVF9GSUxFJ10pIHtcbiAgICAgIGxvZ192ZXJib3NlKGBXb3JrYXJvdW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL2JhemVsL2lzc3Vlcy83OTk0XG4gICAgICAgICAgICAgICAgIFJVTkZJTEVTX01BTklGRVNUX0ZJTEUgc2hvdWxkIGhhdmUgYmVlbiBzZXQgYnV0IHdhc24ndC5cbiAgICAgICAgICAgICAgICAgZmFsbGluZyBiYWNrIHRvIHVzaW5nIHJ1bmZpbGVzIHN5bWxpbmtzLlxuICAgICAgICAgICAgICAgICBJZiB5b3Ugd2FudCB0byB0ZXN0IHJ1bmZpbGVzIG1hbmlmZXN0IGJlaGF2aW9yLCBhZGRcbiAgICAgICAgICAgICAgICAgLS1zcGF3bl9zdHJhdGVneT1zdGFuZGFsb25lIHRvIHRoZSBjb21tYW5kIGxpbmUuYCk7XG4gICAgfVxuXG4gICAgY29uc3Qgd2tzcCA9IGVudlsnVEVTVF9XT1JLU1BBQ0UnXTtcbiAgICBjb25zdCB0YXJnZXQgPSBlbnZbJ1RFU1RfVEFSR0VUJ107XG4gICAgaWYgKCEhd2tzcCAmJiAhIXRhcmdldCkge1xuICAgICAgLy8gLy9wYXRoL3RvOnRhcmdldCAtPiAvL3BhdGgvdG9cbiAgICAgIGNvbnN0IHBrZyA9IHRhcmdldC5zcGxpdCgnOicpWzBdO1xuICAgICAgdGhpcy5wYWNrYWdlUGF0aCA9IHBhdGgucG9zaXguam9pbih3a3NwLCBwa2cpO1xuICAgIH1cbiAgfVxuXG4gIGxvb2t1cERpcmVjdG9yeShkaXI6IHN0cmluZyk6IHN0cmluZ3x1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5tYW5pZmVzdCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIHRoaXMubWFuaWZlc3QpIHtcbiAgICAgIC8vIEFjY291bnQgZm9yIEJhemVsIC0tbGVnYWN5X2V4dGVybmFsX3J1bmZpbGVzXG4gICAgICAvLyB3aGljaCBwb2xsdXRlcyB0aGUgd29ya3NwYWNlIHdpdGggJ215X3drc3AvZXh0ZXJuYWwvLi4uJ1xuICAgICAgaWYgKGsuc3RhcnRzV2l0aChgJHtkaXJ9L2V4dGVybmFsYCkpIGNvbnRpbnVlO1xuXG4gICAgICAvLyBFbnRyeSBsb29rcyBsaWtlXG4gICAgICAvLyBrOiBucG0vbm9kZV9tb2R1bGVzL3NlbXZlci9MSUNFTlNFXG4gICAgICAvLyB2OiAvcGF0aC90by9leHRlcm5hbC9ucG0vbm9kZV9tb2R1bGVzL3NlbXZlci9MSUNFTlNFXG4gICAgICAvLyBjYWxjdWxhdGUgbCA9IGxlbmd0aChgL3NlbXZlci9MSUNFTlNFYClcbiAgICAgIGlmIChrLnN0YXJ0c1dpdGgoZGlyKSkge1xuICAgICAgICBjb25zdCBsID0gay5sZW5ndGggLSBkaXIubGVuZ3RoO1xuICAgICAgICByZXR1cm4gdi5zdWJzdHJpbmcoMCwgdi5sZW5ndGggLSBsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBUaGUgcnVuZmlsZXMgbWFuaWZlc3QgbWFwcyBmcm9tIHNob3J0X3BhdGhcbiAgICogaHR0cHM6Ly9kb2NzLmJhemVsLmJ1aWxkL3ZlcnNpb25zL21hc3Rlci9za3lsYXJrL2xpYi9GaWxlLmh0bWwjc2hvcnRfcGF0aFxuICAgKiB0byB0aGUgYWN0dWFsIGxvY2F0aW9uIG9uIGRpc2sgd2hlcmUgdGhlIGZpbGUgY2FuIGJlIHJlYWQuXG4gICAqXG4gICAqIEluIGEgc2FuZGJveGVkIGV4ZWN1dGlvbiwgaXQgZG9lcyBub3QgZXhpc3QuIEluIHRoYXQgY2FzZSwgcnVuZmlsZXMgbXVzdCBiZVxuICAgKiByZXNvbHZlZCBmcm9tIGEgc3ltbGluayB0cmVlIHVuZGVyIHRoZSBydW5maWxlcyBkaXIuXG4gICAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9iYXplbC9pc3N1ZXMvMzcyNlxuICAgKi9cbiAgbG9hZFJ1bmZpbGVzTWFuaWZlc3QobWFuaWZlc3RQYXRoOiBzdHJpbmcpIHtcbiAgICBsb2dfdmVyYm9zZShgdXNpbmcgcnVuZmlsZXMgbWFuaWZlc3QgJHttYW5pZmVzdFBhdGh9YCk7XG5cbiAgICBjb25zdCBydW5maWxlc0VudHJpZXMgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgaW5wdXQgPSBmcy5yZWFkRmlsZVN5bmMobWFuaWZlc3RQYXRoLCB7ZW5jb2Rpbmc6ICd1dGYtOCd9KTtcblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBpbnB1dC5zcGxpdCgnXFxuJykpIHtcbiAgICAgIGlmICghbGluZSkgY29udGludWU7XG4gICAgICBjb25zdCBbcnVuZmlsZXNQYXRoLCByZWFsUGF0aF0gPSBsaW5lLnNwbGl0KCcgJyk7XG4gICAgICBydW5maWxlc0VudHJpZXMuc2V0KHJ1bmZpbGVzUGF0aCwgcmVhbFBhdGgpO1xuICAgIH1cblxuICAgIHJldHVybiBydW5maWxlc0VudHJpZXM7XG4gIH1cblxuICByZXNvbHZlKG1vZHVsZVBhdGg6IHN0cmluZykge1xuICAgIC8vIExvb2sgaW4gdGhlIHJ1bmZpbGVzIGZpcnN0XG4gICAgaWYgKHRoaXMubWFuaWZlc3QpIHtcbiAgICAgIHJldHVybiB0aGlzLmxvb2t1cERpcmVjdG9yeShtb2R1bGVQYXRoKTtcbiAgICB9XG4gICAgaWYgKHJ1bmZpbGVzLmRpcikge1xuICAgICAgcmV0dXJuIHBhdGguam9pbihydW5maWxlcy5kaXIsIG1vZHVsZVBhdGgpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYGNvdWxkIG5vdCByZXNvbHZlIG1vZHVsZVBhdGggJHttb2R1bGVQYXRofWApO1xuICB9XG5cbiAgcmVzb2x2ZVBhY2thZ2VSZWxhdGl2ZShtb2R1bGVQYXRoOiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMucGFja2FnZVBhdGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncGFja2FnZVBhdGggY291bGQgbm90IGJlIGRldGVybWluZWQgZnJvbSB0aGUgZW52aXJvbm1lbnQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZShwYXRoLnBvc2l4LmpvaW4odGhpcy5wYWNrYWdlUGF0aCwgbW9kdWxlUGF0aCkpO1xuICB9XG59XG5cbi8vIFR5cGVTY3JpcHQgbGliLmVzNS5kLnRzIGhhcyBhIG1pc3Rha2U6IEpTT04ucGFyc2UgZG9lcyBhY2NlcHQgQnVmZmVyLlxuZGVjbGFyZSBnbG9iYWwge1xuICBpbnRlcmZhY2UgSlNPTiB7XG4gICAgcGFyc2UoYjoge3RvU3RyaW5nOiAoKSA9PiBzdHJpbmd9KTogYW55O1xuICB9XG59XG5cbi8vIFRoZXJlIGlzIG5vIGZzLnByb21pc2VzLmV4aXN0cyBmdW5jdGlvbiBiZWNhdXNlXG4vLyBub2RlIGNvcmUgaXMgb2YgdGhlIG9waW5pb24gdGhhdCBleGlzdHMgaXMgYWx3YXlzIHRvbyByYWNleSB0byByZWx5IG9uLlxuYXN5bmMgZnVuY3Rpb24gZXhpc3RzKHA6IHN0cmluZykge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLnByb21pc2VzLnN0YXQocClcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbn1cblxuLy8gU2VlIGxpbmtfbm9kZV9tb2R1bGVzLmJ6bCB3aGVyZSB0aGVzZSB0aHJlZSBzdHJpbmdzXG4vLyBhcmUgdXNlZCB0byBpbmRpY2F0ZSB3aGljaCByb290IHRoZSBsaW5rZXIgc2hvdWxkIHRhcmdldFxuLy8gZm9yIGVhY2ggcGFja2FnZTpcbi8vIGJpbjogYmF6ZWwtYmluL3BhdGgvdG8vcGFja2FnZVxuLy8gc3JjOiB3b3Jrc3BhY2UvcGF0aC90by9wYWNrYWdlXG4vLyBydW5maWxlczogbG9vayBpbiB0aGUgcnVuZmlsZXMgZGlyL21hbmlmZXN0XG50eXBlIExpbmtlclJvb3QgPSAnYmluJ3wnc3JjJ3wncnVuZmlsZXMnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWFpbihhcmdzOiBzdHJpbmdbXSwgcnVuZmlsZXM6IFJ1bmZpbGVzKSB7XG4gIGlmICghYXJncyB8fCBhcmdzLmxlbmd0aCA8IDEpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdsaW5rX25vZGVfbW9kdWxlcy5qcyByZXF1aXJlcyBvbmUgYXJndW1lbnQ6IG1vZHVsZXNNYW5pZmVzdCBwYXRoJyk7XG5cbiAgY29uc3QgW21vZHVsZXNNYW5pZmVzdF0gPSBhcmdzO1xuICBsZXQge2Jpbiwgcm9vdCwgbW9kdWxlcywgd29ya3NwYWNlfSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKG1vZHVsZXNNYW5pZmVzdCkpO1xuICBtb2R1bGVzID0gbW9kdWxlcyB8fCB7fTtcbiAgbG9nX3ZlcmJvc2UoXG4gICAgICBgbW9kdWxlIG1hbmlmZXN0OiB3b3Jrc3BhY2UgJHt3b3Jrc3BhY2V9LCBiaW4gJHtiaW59LCByb290ICR7XG4gICAgICAgICAgcm9vdH0gd2l0aCBmaXJzdC1wYXJ0eSBwYWNrYWdlc1xcbmAsXG4gICAgICBtb2R1bGVzKTtcblxuICBjb25zdCByb290RGlyID0gcmVzb2x2ZVJvb3Qocm9vdCwgcnVuZmlsZXMpO1xuICBsb2dfdmVyYm9zZSgncmVzb2x2ZWQgcm9vdCcsIHJvb3QsICd0bycsIHJvb3REaXIpO1xuXG4gIC8vIEJhemVsIHN0YXJ0cyBhY3Rpb25zIHdpdGggcHdkPWV4ZWNyb290L215X3drc3BcbiAgY29uc3Qgd29ya3NwYWNlRGlyID0gcGF0aC5yZXNvbHZlKCcuJyk7XG5cbiAgLy8gQ29udmVydCBmcm9tIHJ1bmZpbGVzIHBhdGhcbiAgLy8gdGhpc193a3NwL3BhdGgvdG8vZmlsZSBPUiBvdGhlcl93a3NwL3BhdGgvdG8vZmlsZVxuICAvLyB0byBleGVjcm9vdCBwYXRoXG4gIC8vIHBhdGgvdG8vZmlsZSBPUiBleHRlcm5hbC9vdGhlcl93a3NwL3BhdGgvdG8vZmlsZVxuICBmdW5jdGlvbiB0b1dvcmtzcGFjZURpcihwOiBzdHJpbmcpIHtcbiAgICBpZiAocCA9PT0gd29ya3NwYWNlKSB7XG4gICAgICByZXR1cm4gJy4nO1xuICAgIH1cbiAgICAvLyBUaGUgbWFuaWZlc3QgaXMgd3JpdHRlbiB3aXRoIGZvcndhcmQgc2xhc2ggb24gYWxsIHBsYXRmb3Jtc1xuICAgIGlmIChwLnN0YXJ0c1dpdGgod29ya3NwYWNlICsgJy8nKSkge1xuICAgICAgcmV0dXJuIHAuc3Vic3RyaW5nKHdvcmtzcGFjZS5sZW5ndGggKyAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGguam9pbignZXh0ZXJuYWwnLCBwKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSB0aGUgJHB3ZC9ub2RlX21vZHVsZXMgZGlyZWN0b3J5IHRoYXQgbm9kZSB3aWxsIHJlc29sdmUgZnJvbVxuICBhd2FpdCBzeW1saW5rKHJvb3REaXIsICdub2RlX21vZHVsZXMnKTtcbiAgcHJvY2Vzcy5jaGRpcihyb290RGlyKTtcblxuICAvLyBTeW1saW5rcyB0byBwYWNrYWdlcyBuZWVkIHRvIHJlYWNoIGJhY2sgdG8gdGhlIHdvcmtzcGFjZS9ydW5maWxlcyBkaXJlY3RvcnlcbiAgY29uc3Qgd29ya3NwYWNlQWJzID0gcGF0aC5yZXNvbHZlKHdvcmtzcGFjZURpcik7XG5cbiAgLy8gTm93IGFkZCBzeW1saW5rcyB0byBlYWNoIG9mIG91ciBmaXJzdC1wYXJ0eSBwYWNrYWdlcyBzbyB0aGV5IGFwcGVhciB1bmRlciB0aGUgbm9kZV9tb2R1bGVzIHRyZWVcbiAgY29uc3QgbGlua3MgPSBbXTtcblxuICBjb25zdCBsaW5rTW9kdWxlID1cbiAgICAgIGFzeW5jIChuYW1lOiBzdHJpbmcsIHJvb3Q6IExpbmtlclJvb3QsIG1vZHVsZVBhdGg6IHN0cmluZykgPT4ge1xuICAgIGxldCB0YXJnZXQ6IHN0cmluZyA9ICc8cGFja2FnZSBsaW5raW5nIGZhaWxlZD4nO1xuICAgIHN3aXRjaCAocm9vdCkge1xuICAgICAgY2FzZSAnYmluJzpcbiAgICAgICAgLy8gRklYTUUoIzExOTYpXG4gICAgICAgIHRhcmdldCA9IHBhdGguam9pbih3b3Jrc3BhY2VBYnMsIGJpbiwgdG9Xb3Jrc3BhY2VEaXIobW9kdWxlUGF0aCkpO1xuICAgICAgICAvLyBTcGVuZCBhbiBleHRyYSBGUyBsb29rdXAgdG8gZ2l2ZSBiZXR0ZXIgZXJyb3IgaW4gdGhpcyBjYXNlXG4gICAgICAgIGlmICghYXdhaXQgZXhpc3RzKHRhcmdldCkpIHtcbiAgICAgICAgICAvLyBUT0RPOiB0aGVyZSBzaG91bGQgYmUgc29tZSBkb2NzIGV4cGxhaW5pbmcgaG93IHVzZXJzIGFyZVxuICAgICAgICAgIC8vIGV4cGVjdGVkIHRvIGRlY2xhcmUgYWhlYWQgb2YgdGltZSB3aGVyZSB0aGUgcGFja2FnZSBpcyBsb2FkZWQsXG4gICAgICAgICAgLy8gaG93IHRoYXQgcmVsYXRlcyB0byBucG0gbGluayBzY2VuYXJpb3MsXG4gICAgICAgICAgLy8gYW5kIHdoZXJlIHRoZSBjb25maWd1cmF0aW9uIGNhbiBnby5cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoYEVSUk9SOiBubyBvdXRwdXQgZGlyZWN0b3J5IGZvdW5kIGZvciBwYWNrYWdlICR7bW9kdWxlUGF0aH1cbiAgICAgICAgRGlkIHlvdSBtZWFuIHRvIGRlY2xhcmUgdGhpcyBhcyBhIGZyb20tc291cmNlIHBhY2thZ2U/XG4gICAgICAgIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9ydWxlc19ub2RlanMvcHVsbC8xMTk3XG4gICAgICAgIHVudGlsIHRoaXMgZmVhdHVyZSBpcyBwcm9wZXJseSBkb2N1bWVudGVkLmApO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc3JjJzpcbiAgICAgICAgdGFyZ2V0ID0gcGF0aC5qb2luKHdvcmtzcGFjZUFicywgdG9Xb3Jrc3BhY2VEaXIobW9kdWxlUGF0aCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3J1bmZpbGVzJzpcbiAgICAgICAgdGFyZ2V0ID0gcnVuZmlsZXMucmVzb2x2ZShtb2R1bGVQYXRoKSB8fCAnPHJ1bmZpbGVzIHJlc29sdXRpb24gZmFpbGVkPic7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGF3YWl0IHN5bWxpbmsodGFyZ2V0LCBuYW1lKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgbSBvZiBPYmplY3Qua2V5cyhtb2R1bGVzKSkge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gbS5zcGxpdCgnLycpO1xuICAgIGlmIChzZWdtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG1vZHVsZSAke219IGhhcyBtb3JlIHRoYW4gMiBzZWdtZW50cyB3aGljaCBpcyBub3QgYSB2YWxpZCBub2RlIG1vZHVsZSBuYW1lYCk7XG4gICAgfVxuICAgIGlmIChzZWdtZW50cy5sZW5ndGggPT0gMikge1xuICAgICAgLy8gZW5zdXJlIHRoZSBzY29wZSBleGlzdHNcbiAgICAgIG1rZGlycChzZWdtZW50c1swXSk7XG4gICAgfVxuICAgIGNvbnN0IFtraW5kLCBtb2R1bGVQYXRoXSA9IG1vZHVsZXNbbV07XG4gICAgbGlua3MucHVzaChsaW5rTW9kdWxlKG0sIGtpbmQsIG1vZHVsZVBhdGgpKTtcbiAgfVxuXG4gIGxldCBjb2RlID0gMDtcbiAgYXdhaXQgUHJvbWlzZS5hbGwobGlua3MpLmNhdGNoKGUgPT4ge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgY29kZSA9IDE7XG4gIH0pO1xuXG4gIHJldHVybiBjb2RlO1xufVxuXG5leHBvcnQgY29uc3QgcnVuZmlsZXMgPSBuZXcgUnVuZmlsZXMocHJvY2Vzcy5lbnYpO1xuXG5pZiAocmVxdWlyZS5tYWluID09PSBtb2R1bGUpIHtcbiAgKGFzeW5jICgpID0+IHtcbiAgICBwcm9jZXNzLmV4aXRDb2RlID0gYXdhaXQgbWFpbihwcm9jZXNzLmFyZ3Yuc2xpY2UoMiksIHJ1bmZpbGVzKTtcbiAgfSkoKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/internal/linker/link_node_modules.ts b/internal/linker/link_node_modules.ts index 60d106d19b..db5ea65774 100644 --- a/internal/linker/link_node_modules.ts +++ b/internal/linker/link_node_modules.ts @@ -24,6 +24,17 @@ Include as much of the build output as you can without disclosing anything confi `); } +/** + * Create a new directory and any necessary subdirectories + * if they do not exist. + */ +function mkdirp(p: string) { + if (!fs.existsSync(p)) { + mkdirp(path.dirname(p)); + fs.mkdirSync(p); + } +} + async function symlink(target: string, path: string) { log_verbose(`symlink( ${path} -> ${target} )`); // Use junction on Windows since symlinks require elevated permissions. @@ -46,7 +57,7 @@ async function symlink(target: string, path: string) { if (!fs.existsSync(path)) { log_verbose( 'ERROR\n***\nLooks like we created a bad symlink:' + - `\n pwd ${process.cwd()}\n target ${target}\n***`); + `\n pwd ${process.cwd()}\n target ${target}\n path ${path}\n***`); } } } @@ -179,8 +190,6 @@ export class Runfiles { if (this.manifest) { return this.lookupDirectory(modulePath); } - // how can we avoid this FS lookup every time? we don't know when process.cwd changed... - // const runfilesRelative = runfiles.dir ? path.relative('.', runfiles.dir) : undefined; if (runfiles.dir) { return path.join(runfiles.dir, modulePath); } @@ -262,7 +271,7 @@ export async function main(args: string[], runfiles: Runfiles) { process.chdir(rootDir); // Symlinks to packages need to reach back to the workspace/runfiles directory - const workspaceRelative = path.relative('.', workspaceDir); + const workspaceAbs = path.resolve(workspaceDir); // Now add symlinks to each of our first-party packages so they appear under the node_modules tree const links = []; @@ -273,7 +282,7 @@ export async function main(args: string[], runfiles: Runfiles) { switch (root) { case 'bin': // FIXME(#1196) - target = path.join(workspaceRelative, bin, toWorkspaceDir(modulePath)); + target = path.join(workspaceAbs, bin, toWorkspaceDir(modulePath)); // Spend an extra FS lookup to give better error in this case if (!await exists(target)) { // TODO: there should be some docs explaining how users are @@ -287,7 +296,7 @@ export async function main(args: string[], runfiles: Runfiles) { } break; case 'src': - target = path.join(workspaceRelative, toWorkspaceDir(modulePath)); + target = path.join(workspaceAbs, toWorkspaceDir(modulePath)); break; case 'runfiles': target = runfiles.resolve(modulePath) || ''; @@ -298,6 +307,14 @@ export async function main(args: string[], runfiles: Runfiles) { } for (const m of Object.keys(modules)) { + const segments = m.split('/'); + if (segments.length > 2) { + throw new Error(`module ${m} has more than 2 segments which is not a valid node module name`); + } + if (segments.length == 2) { + // ensure the scope exists + mkdirp(segments[0]); + } const [kind, modulePath] = modules[m]; links.push(linkModule(m, kind, modulePath)); } diff --git a/internal/linker/test/integration/BUILD.bazel b/internal/linker/test/integration/BUILD.bazel index f154e01c80..91ab65d977 100644 --- a/internal/linker/test/integration/BUILD.bazel +++ b/internal/linker/test/integration/BUILD.bazel @@ -21,6 +21,7 @@ sh_binary( ":program.js", "//internal/linker:index.js", "//internal/linker/test/integration/static_linked_pkg", + "//internal/linker/test/integration/static_linked_scoped_pkg", "@bazel_tools//tools/bash/runfiles", "@build_bazel_rules_nodejs//toolchains/node:node_bin", ], @@ -35,6 +36,7 @@ linked( "//%s/absolute_import:index.js" % package_name(), ":run_program", "//internal/linker/test/integration/dynamic_linked_pkg", + "//internal/linker/test/integration/dynamic_linked_scoped_pkg", "@npm//semver", ], ) diff --git a/internal/linker/test/integration/dynamic_linked_scoped_pkg/BUILD.bazel b/internal/linker/test/integration/dynamic_linked_scoped_pkg/BUILD.bazel new file mode 100644 index 0000000000..6e863cfbb7 --- /dev/null +++ b/internal/linker/test/integration/dynamic_linked_scoped_pkg/BUILD.bazel @@ -0,0 +1,10 @@ +load("//internal/js_library:js_library.bzl", "js_library") + +package(default_visibility = ["//internal/linker/test:__subpackages__"]) + +js_library( + name = "dynamic_linked_scoped_pkg", + srcs = ["index.js"], + module_from_src = True, + module_name = "@linker_scoped/dynamic_linked", +) diff --git a/internal/linker/test/integration/dynamic_linked_scoped_pkg/index.js b/internal/linker/test/integration/dynamic_linked_scoped_pkg/index.js new file mode 100644 index 0000000000..a88998bdb3 --- /dev/null +++ b/internal/linker/test/integration/dynamic_linked_scoped_pkg/index.js @@ -0,0 +1,5 @@ +function addD(str) { + return `${str}_d`; +} + +exports.addD = addD; \ No newline at end of file diff --git a/internal/linker/test/integration/golden.txt b/internal/linker/test/integration/golden.txt index 7fa3bafab1..7f08382f13 100644 --- a/internal/linker/test/integration/golden.txt +++ b/internal/linker/test/integration/golden.txt @@ -1 +1 @@ -1.2.3_c_b_a +1.2.3_a_b_c_d_e diff --git a/internal/linker/test/integration/program.js b/internal/linker/test/integration/program.js index 3bce634a48..b802f8d2e2 100644 --- a/internal/linker/test/integration/program.js +++ b/internal/linker/test/integration/program.js @@ -1,9 +1,11 @@ -// First-party package from ./static_linked_pkg -// it should get resolved through runfiles +// First-party "static linked" packages +// they should get resolved through runfiles const a = require('static_linked'); -// First-party package from ./dynamic_linked_pkg -// it should get resolved from the execroot +const e = require('@linker_scoped/static_linked'); +// First-party "dynamic linked" packages +// they should get resolved from the execroot const b = require('dynamic_linked'); +const d = require('@linker_scoped/dynamic_linked'); // We've always supported `require('my_workspace')` for absolute imports like Google does it const c = require('build_bazel_rules_nodejs/internal/linker/test/integration/absolute_import'); @@ -11,4 +13,4 @@ const c = require('build_bazel_rules_nodejs/internal/linker/test/integration/abs const semver = require('semver'); // This output should match what's in the golden.txt file -console.log(a.addA(b.addB(c.addC(semver.clean(' =v1.2.3 '))))); +console.log(e.addE(d.addD(c.addC(b.addB(a.addA(semver.clean(' =v1.2.3 '))))))); diff --git a/internal/linker/test/integration/static_linked_scoped_pkg/BUILD.bazel b/internal/linker/test/integration/static_linked_scoped_pkg/BUILD.bazel new file mode 100644 index 0000000000..74a8741930 --- /dev/null +++ b/internal/linker/test/integration/static_linked_scoped_pkg/BUILD.bazel @@ -0,0 +1,9 @@ +load("//internal/js_library:js_library.bzl", "js_library") + +package(default_visibility = ["//internal/linker/test:__subpackages__"]) + +js_library( + name = "static_linked_scoped_pkg", + srcs = ["index.js"], + module_name = "@linker_scoped/static_linked", +) diff --git a/internal/linker/test/integration/static_linked_scoped_pkg/index.js b/internal/linker/test/integration/static_linked_scoped_pkg/index.js new file mode 100644 index 0000000000..37a64cb21b --- /dev/null +++ b/internal/linker/test/integration/static_linked_scoped_pkg/index.js @@ -0,0 +1,5 @@ +function addE(str) { + return `${str}_e`; +} + +exports.addE = addE; \ No newline at end of file